Merge "feat(gicv3): validate multichip data for GIC-700" into integration

This commit is contained in:
Manish Pandey 2022-09-15 11:04:41 +02:00 committed by TrustedFirmware Code Review
commit c6957b66e6
2 changed files with 117 additions and 5 deletions

View file

@ -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

View file

@ -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) | \