mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-22 20:38:03 +00:00
Merge "feat(gicv3): validate multichip data for GIC-700" into integration
This commit is contained in:
commit
c6957b66e6
2 changed files with 117 additions and 5 deletions
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Arm Limited. All rights reserved.
|
* Copyright (c) 2019, Arm Limited. All rights reserved.
|
||||||
|
* Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -97,16 +98,28 @@ static void set_gicd_chipr_n(uintptr_t base,
|
||||||
spi_id_max = GIC600_SPI_ID_MIN;
|
spi_id_max = GIC600_SPI_ID_MIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch ((gicd_iidr_val & IIDR_MODEL_MASK)) {
|
||||||
|
case IIDR_MODEL_ARM_GIC_600:
|
||||||
spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
|
spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
|
||||||
spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
|
spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
|
||||||
|
|
||||||
switch ((gicd_iidr_val & IIDR_MODEL_MASK)) {
|
|
||||||
case IIDR_MODEL_ARM_GIC_600:
|
|
||||||
chipr_n_val = GICD_CHIPR_VALUE_GIC_600(chip_addr,
|
chipr_n_val = GICD_CHIPR_VALUE_GIC_600(chip_addr,
|
||||||
spi_block_min,
|
spi_block_min,
|
||||||
spi_blocks);
|
spi_blocks);
|
||||||
break;
|
break;
|
||||||
case IIDR_MODEL_ARM_GIC_700:
|
case IIDR_MODEL_ARM_GIC_700:
|
||||||
|
/* Calculate the SPI_ID_MIN value for ESPI */
|
||||||
|
if (spi_id_min >= GIC700_ESPI_ID_MIN) {
|
||||||
|
spi_block_min = ESPI_BLOCK_MIN_VALUE(spi_id_min);
|
||||||
|
spi_block_min += SPI_BLOCKS_VALUE(GIC700_SPI_ID_MIN,
|
||||||
|
GIC700_SPI_ID_MAX);
|
||||||
|
} else {
|
||||||
|
spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the total number of blocks */
|
||||||
|
spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
|
||||||
|
|
||||||
chipr_n_val = GICD_CHIPR_VALUE_GIC_700(chip_addr,
|
chipr_n_val = GICD_CHIPR_VALUE_GIC_700(chip_addr,
|
||||||
spi_block_min,
|
spi_block_min,
|
||||||
spi_blocks);
|
spi_blocks);
|
||||||
|
@ -202,13 +215,104 @@ static void gic600_multichip_validate_data(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Intialize GIC-600 Multichip operation.
|
* Validates the GIC-700 Multichip data structure passed by the platform.
|
||||||
|
******************************************************************************/
|
||||||
|
static void gic700_multichip_validate_data(
|
||||||
|
struct gic600_multichip_data *multichip_data)
|
||||||
|
{
|
||||||
|
unsigned int i, spi_id_min, spi_id_max, blocks_of_32;
|
||||||
|
unsigned int multichip_spi_blocks = 0U, multichip_espi_blocks = 0U;
|
||||||
|
|
||||||
|
assert(multichip_data != NULL);
|
||||||
|
|
||||||
|
if (multichip_data->chip_count > GIC600_MAX_MULTICHIP) {
|
||||||
|
ERROR("GIC-700 Multichip count (%u) should not exceed %u\n",
|
||||||
|
multichip_data->chip_count, GIC600_MAX_MULTICHIP);
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0U; i < multichip_data->chip_count; i++) {
|
||||||
|
spi_id_min = multichip_data->spi_ids[i][SPI_MIN_INDEX];
|
||||||
|
spi_id_max = multichip_data->spi_ids[i][SPI_MAX_INDEX];
|
||||||
|
|
||||||
|
if ((spi_id_min == 0U) || (spi_id_max == 0U)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MIN SPI ID check */
|
||||||
|
if ((spi_id_min < GIC700_SPI_ID_MIN) ||
|
||||||
|
((spi_id_min >= GIC700_SPI_ID_MAX) &&
|
||||||
|
(spi_id_min < GIC700_ESPI_ID_MIN))) {
|
||||||
|
ERROR("Invalid MIN SPI ID {%u} passed for "
|
||||||
|
"Chip %u\n", spi_id_min, i);
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((spi_id_min > spi_id_max) ||
|
||||||
|
((spi_id_max - spi_id_min + 1) % 32 != 0)) {
|
||||||
|
ERROR("Unaligned SPI IDs {%u, %u} passed for "
|
||||||
|
"Chip %u\n", spi_id_min,
|
||||||
|
spi_id_max, i);
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ESPI IDs range check */
|
||||||
|
if ((spi_id_min >= GIC700_ESPI_ID_MIN) &&
|
||||||
|
(spi_id_max > GIC700_ESPI_ID_MAX)) {
|
||||||
|
ERROR("Invalid ESPI IDs {%u, %u} passed for "
|
||||||
|
"Chip %u\n", spi_id_min,
|
||||||
|
spi_id_max, i);
|
||||||
|
panic();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SPI IDs range check */
|
||||||
|
if (((spi_id_min < GIC700_SPI_ID_MAX) &&
|
||||||
|
(spi_id_max > GIC700_SPI_ID_MAX))) {
|
||||||
|
ERROR("Invalid SPI IDs {%u, %u} passed for "
|
||||||
|
"Chip %u\n", spi_id_min,
|
||||||
|
spi_id_max, i);
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SPI IDs overlap check */
|
||||||
|
if (spi_id_max < GIC700_SPI_ID_MAX) {
|
||||||
|
blocks_of_32 = BLOCKS_OF_32(spi_id_min, spi_id_max);
|
||||||
|
if ((multichip_spi_blocks & blocks_of_32) != 0) {
|
||||||
|
ERROR("SPI IDs of Chip %u overlapping\n", i);
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
multichip_spi_blocks |= blocks_of_32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ESPI IDs overlap check */
|
||||||
|
if (spi_id_max > GIC700_ESPI_ID_MIN) {
|
||||||
|
blocks_of_32 = BLOCKS_OF_32(spi_id_min - GIC700_ESPI_ID_MIN,
|
||||||
|
spi_id_max - GIC700_ESPI_ID_MIN);
|
||||||
|
if ((multichip_espi_blocks & blocks_of_32) != 0) {
|
||||||
|
ERROR("SPI IDs of Chip %u overlapping\n", i);
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
multichip_espi_blocks |= blocks_of_32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Intialize GIC-600 and GIC-700 Multichip operation.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void gic600_multichip_init(struct gic600_multichip_data *multichip_data)
|
void gic600_multichip_init(struct gic600_multichip_data *multichip_data)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
uint32_t gicd_iidr_val = gicd_read_iidr(multichip_data->rt_owner_base);
|
||||||
|
|
||||||
|
if ((gicd_iidr_val & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) {
|
||||||
gic600_multichip_validate_data(multichip_data);
|
gic600_multichip_validate_data(multichip_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((gicd_iidr_val & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700) {
|
||||||
|
gic700_multichip_validate_data(multichip_data);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure that G0/G1S/G1NS interrupts are disabled. This also ensures
|
* Ensure that G0/G1S/G1NS interrupts are disabled. This also ensures
|
||||||
|
|
|
@ -41,6 +41,11 @@
|
||||||
#define GIC600_SPI_ID_MIN 32
|
#define GIC600_SPI_ID_MIN 32
|
||||||
#define GIC600_SPI_ID_MAX 960
|
#define GIC600_SPI_ID_MAX 960
|
||||||
|
|
||||||
|
#define GIC700_SPI_ID_MIN 32
|
||||||
|
#define GIC700_SPI_ID_MAX 991
|
||||||
|
#define GIC700_ESPI_ID_MIN 4096
|
||||||
|
#define GIC700_ESPI_ID_MAX 5119
|
||||||
|
|
||||||
/* Number of retries for PUP update */
|
/* Number of retries for PUP update */
|
||||||
#define GICD_PUP_UPDATE_RETRIES 10000
|
#define GICD_PUP_UPDATE_RETRIES 10000
|
||||||
|
|
||||||
|
@ -53,6 +58,9 @@
|
||||||
#define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \
|
#define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \
|
||||||
(((spi_id_max) - (spi_id_min) + 1) / \
|
(((spi_id_max) - (spi_id_min) + 1) / \
|
||||||
GIC600_SPI_ID_MIN)
|
GIC600_SPI_ID_MIN)
|
||||||
|
#define ESPI_BLOCK_MIN_VALUE(spi_id_min) \
|
||||||
|
(((spi_id_min) - GIC700_ESPI_ID_MIN + 1) / \
|
||||||
|
GIC700_SPI_ID_MIN)
|
||||||
#define GICD_CHIPR_VALUE_GIC_700(chip_addr, spi_block_min, spi_blocks) \
|
#define GICD_CHIPR_VALUE_GIC_700(chip_addr, spi_block_min, spi_blocks) \
|
||||||
(((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
|
(((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
|
||||||
((spi_block_min) << GIC_700_SPI_BLOCK_MIN_SHIFT) | \
|
((spi_block_min) << GIC_700_SPI_BLOCK_MIN_SHIFT) | \
|
||||||
|
|
Loading…
Add table
Reference in a new issue