mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-23 13:36:05 +00:00
Merge "fix(gicv3): workaround for NVIDIA erratum T241-FABRIC-4" into integration
This commit is contained in:
commit
5a63aed223
11 changed files with 149 additions and 65 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
|
||||
* Copyright (c) 2022-2023, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -19,6 +19,29 @@
|
|||
#include "../common/gic_common_private.h"
|
||||
#include "gic600_multichip_private.h"
|
||||
|
||||
static struct gic600_multichip_data *plat_gic_multichip_data;
|
||||
|
||||
/*******************************************************************************
|
||||
* Retrieve the address of the chip owner for a given SPI ID
|
||||
******************************************************************************/
|
||||
uintptr_t gic600_multichip_gicd_base_for_spi(uint32_t spi_id)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Find the multichip instance */
|
||||
for (i = 0U; i < GIC600_MAX_MULTICHIP; i++) {
|
||||
if ((spi_id <= plat_gic_multichip_data->spi_ids[i].spi_id_max) &&
|
||||
(spi_id >= plat_gic_multichip_data->spi_ids[i].spi_id_min)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure that plat_gic_multichip_data contains valid values */
|
||||
assert(i < GIC600_MAX_MULTICHIP);
|
||||
|
||||
return plat_gic_multichip_data->spi_ids[i].gicd_base;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* GIC-600 multichip operation related helper functions
|
||||
******************************************************************************/
|
||||
|
@ -27,7 +50,7 @@ static void gicd_dchipr_wait_for_power_update_progress(uintptr_t base)
|
|||
unsigned int retry = GICD_PUP_UPDATE_RETRIES;
|
||||
|
||||
while ((read_gicd_dchipr(base) & GICD_DCHIPR_PUP_BIT) != 0U) {
|
||||
if (retry-- == 0) {
|
||||
if (retry-- == 0U) {
|
||||
ERROR("GIC-600 connection to Routing Table Owner timed "
|
||||
"out\n");
|
||||
panic();
|
||||
|
@ -186,11 +209,11 @@ static void gic600_multichip_validate_data(
|
|||
panic();
|
||||
}
|
||||
|
||||
for (i = 0; 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];
|
||||
for (i = 0U; i < multichip_data->chip_count; i++) {
|
||||
spi_id_min = multichip_data->spi_ids[i].spi_id_min;
|
||||
spi_id_max = multichip_data->spi_ids[i].spi_id_max;
|
||||
|
||||
if ((spi_id_min != 0) || (spi_id_max != 0)) {
|
||||
if ((spi_id_min != 0U) || (spi_id_max != 0U)) {
|
||||
|
||||
/* SPI IDs range check */
|
||||
if (!(spi_id_min >= GIC600_SPI_ID_MIN) ||
|
||||
|
@ -232,8 +255,8 @@ static void gic700_multichip_validate_data(
|
|||
}
|
||||
|
||||
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];
|
||||
spi_id_min = multichip_data->spi_ids[i].spi_id_min;
|
||||
spi_id_max = multichip_data->spi_ids[i].spi_id_max;
|
||||
|
||||
if ((spi_id_min == 0U) || (spi_id_max == 0U)) {
|
||||
continue;
|
||||
|
@ -342,9 +365,9 @@ void gic600_multichip_init(struct gic600_multichip_data *multichip_data)
|
|||
set_gicd_chipr_n(multichip_data->rt_owner_base, multichip_data->rt_owner,
|
||||
multichip_data->chip_addrs[multichip_data->rt_owner],
|
||||
multichip_data->
|
||||
spi_ids[multichip_data->rt_owner][SPI_MIN_INDEX],
|
||||
spi_ids[multichip_data->rt_owner].spi_id_min,
|
||||
multichip_data->
|
||||
spi_ids[multichip_data->rt_owner][SPI_MAX_INDEX]);
|
||||
spi_ids[multichip_data->rt_owner].spi_id_max);
|
||||
|
||||
for (i = 0; i < multichip_data->chip_count; i++) {
|
||||
if (i == multichip_data->rt_owner)
|
||||
|
@ -352,7 +375,17 @@ void gic600_multichip_init(struct gic600_multichip_data *multichip_data)
|
|||
|
||||
set_gicd_chipr_n(multichip_data->rt_owner_base, i,
|
||||
multichip_data->chip_addrs[i],
|
||||
multichip_data->spi_ids[i][SPI_MIN_INDEX],
|
||||
multichip_data->spi_ids[i][SPI_MAX_INDEX]);
|
||||
multichip_data->spi_ids[i].spi_id_min,
|
||||
multichip_data->spi_ids[i].spi_id_max);
|
||||
}
|
||||
|
||||
plat_gic_multichip_data = multichip_data;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Allow a way to query the status of the GIC600 multichip driver
|
||||
******************************************************************************/
|
||||
bool gic600_multichip_is_initialized(void)
|
||||
{
|
||||
return (plat_gic_multichip_data != NULL);
|
||||
}
|
||||
|
|
|
@ -49,9 +49,6 @@
|
|||
/* Number of retries for PUP update */
|
||||
#define GICD_PUP_UPDATE_RETRIES 10000
|
||||
|
||||
#define SPI_MIN_INDEX 0
|
||||
#define SPI_MAX_INDEX 1
|
||||
|
||||
#define SPI_BLOCK_MIN_VALUE(spi_id_min) \
|
||||
(((spi_id_min) - GIC600_SPI_ID_MIN) / \
|
||||
GIC600_SPI_ID_MIN)
|
||||
|
|
|
@ -41,6 +41,10 @@ $(eval $(call add_define,GICV3_SUPPORT_GIC600))
|
|||
$(eval $(call assert_boolean,GICV3_SUPPORT_GIC600AE_FMU))
|
||||
$(eval $(call add_define,GICV3_SUPPORT_GIC600AE_FMU))
|
||||
|
||||
# Set GIC-600 multichip support
|
||||
$(eval $(call assert_boolean,GICV3_IMPL_GIC600_MULTICHIP))
|
||||
$(eval $(call add_define,GICV3_IMPL_GIC600_MULTICHIP))
|
||||
|
||||
# Set GICv4 extension
|
||||
$(eval $(call assert_boolean,GIC_ENABLE_V4_EXTN))
|
||||
$(eval $(call add_define,GIC_ENABLE_V4_EXTN))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -10,6 +11,7 @@
|
|||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <common/interrupt_props.h>
|
||||
#include <drivers/arm/gic600_multichip.h>
|
||||
#include <drivers/arm/gic_common.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
@ -17,6 +19,16 @@
|
|||
#include "../common/gic_common_private.h"
|
||||
#include "gicv3_private.h"
|
||||
|
||||
uintptr_t gicv3_get_multichip_base(uint32_t spi_id, uintptr_t gicd_base)
|
||||
{
|
||||
#if GICV3_IMPL_GIC600_MULTICHIP
|
||||
if (gic600_multichip_is_initialized()) {
|
||||
return gic600_multichip_gicd_base_for_spi(spi_id);
|
||||
}
|
||||
#endif
|
||||
return gicd_base;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This function marks the core as awake in the re-distributor and
|
||||
* ensures that the interface is active.
|
||||
|
@ -148,7 +160,7 @@ void gicv3_spis_config_defaults(uintptr_t gicd_base)
|
|||
|
||||
/* Treat all (E)SPIs as G1NS by default. We do 32 at a time. */
|
||||
for (i = MIN_SPI_ID; i < num_ints; i += (1U << IGROUPR_SHIFT)) {
|
||||
gicd_write_igroupr(gicd_base, i, ~0U);
|
||||
gicd_write_igroupr(gicv3_get_multichip_base(i, gicd_base), i, ~0U);
|
||||
}
|
||||
|
||||
#if GIC_EXT_INTID
|
||||
|
@ -158,7 +170,7 @@ void gicv3_spis_config_defaults(uintptr_t gicd_base)
|
|||
|
||||
for (i = MIN_ESPI_ID; i < num_eints;
|
||||
i += (1U << IGROUPR_SHIFT)) {
|
||||
gicd_write_igroupr(gicd_base, i, ~0U);
|
||||
gicd_write_igroupr(gicv3_get_multichip_base(i, gicd_base), i, ~0U);
|
||||
}
|
||||
} else {
|
||||
INFO("ESPI range is not implemented.\n");
|
||||
|
@ -167,25 +179,25 @@ void gicv3_spis_config_defaults(uintptr_t gicd_base)
|
|||
|
||||
/* Setup the default (E)SPI priorities doing four at a time */
|
||||
for (i = MIN_SPI_ID; i < num_ints; i += (1U << IPRIORITYR_SHIFT)) {
|
||||
gicd_write_ipriorityr(gicd_base, i, GICD_IPRIORITYR_DEF_VAL);
|
||||
gicd_write_ipriorityr(gicv3_get_multichip_base(i, gicd_base), i, GICD_IPRIORITYR_DEF_VAL);
|
||||
}
|
||||
|
||||
#if GIC_EXT_INTID
|
||||
for (i = MIN_ESPI_ID; i < num_eints;
|
||||
i += (1U << IPRIORITYR_SHIFT)) {
|
||||
gicd_write_ipriorityr(gicd_base, i, GICD_IPRIORITYR_DEF_VAL);
|
||||
gicd_write_ipriorityr(gicv3_get_multichip_base(i, gicd_base), i, GICD_IPRIORITYR_DEF_VAL);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Treat all (E)SPIs as level triggered by default, write 16 at a time
|
||||
*/
|
||||
for (i = MIN_SPI_ID; i < num_ints; i += (1U << ICFGR_SHIFT)) {
|
||||
gicd_write_icfgr(gicd_base, i, 0U);
|
||||
gicd_write_icfgr(gicv3_get_multichip_base(i, gicd_base), i, 0U);
|
||||
}
|
||||
|
||||
#if GIC_EXT_INTID
|
||||
for (i = MIN_ESPI_ID; i < num_eints; i += (1U << ICFGR_SHIFT)) {
|
||||
gicd_write_icfgr(gicd_base, i, 0U);
|
||||
gicd_write_icfgr(gicv3_get_multichip_base(i, gicd_base), i, 0U);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -211,6 +223,7 @@ unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base,
|
|||
current_prop = &interrupt_props[i];
|
||||
|
||||
unsigned int intr_num = current_prop->intr_num;
|
||||
uintptr_t multichip_gicd_base = gicv3_get_multichip_base(intr_num, gicd_base);
|
||||
|
||||
/* Skip SGI, (E)PPI and LPI interrupts */
|
||||
if (!IS_SPI(intr_num)) {
|
||||
|
@ -218,35 +231,36 @@ unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base,
|
|||
}
|
||||
|
||||
/* Configure this interrupt as a secure interrupt */
|
||||
gicd_clr_igroupr(gicd_base, intr_num);
|
||||
gicd_clr_igroupr(multichip_gicd_base, intr_num);
|
||||
|
||||
/* Configure this interrupt as G0 or a G1S interrupt */
|
||||
assert((current_prop->intr_grp == INTR_GROUP0) ||
|
||||
(current_prop->intr_grp == INTR_GROUP1S));
|
||||
|
||||
if (current_prop->intr_grp == INTR_GROUP1S) {
|
||||
gicd_set_igrpmodr(gicd_base, intr_num);
|
||||
gicd_set_igrpmodr(multichip_gicd_base, intr_num);
|
||||
ctlr_enable |= CTLR_ENABLE_G1S_BIT;
|
||||
} else {
|
||||
gicd_clr_igrpmodr(gicd_base, intr_num);
|
||||
gicd_clr_igrpmodr(multichip_gicd_base, intr_num);
|
||||
ctlr_enable |= CTLR_ENABLE_G0_BIT;
|
||||
}
|
||||
|
||||
/* Set interrupt configuration */
|
||||
gicd_set_icfgr(gicd_base, intr_num, current_prop->intr_cfg);
|
||||
gicd_set_icfgr(multichip_gicd_base, intr_num,
|
||||
current_prop->intr_cfg);
|
||||
|
||||
/* Set the priority of this interrupt */
|
||||
gicd_set_ipriorityr(gicd_base, intr_num,
|
||||
current_prop->intr_pri);
|
||||
gicd_set_ipriorityr(multichip_gicd_base, intr_num,
|
||||
current_prop->intr_pri);
|
||||
|
||||
/* Target (E)SPIs to the primary CPU */
|
||||
gic_affinity_val =
|
||||
gicd_irouter_val_from_mpidr(read_mpidr(), 0U);
|
||||
gicd_write_irouter(gicd_base, intr_num,
|
||||
gic_affinity_val);
|
||||
gicd_write_irouter(multichip_gicd_base, intr_num,
|
||||
gic_affinity_val);
|
||||
|
||||
/* Enable this interrupt */
|
||||
gicd_set_isenabler(gicd_base, intr_num);
|
||||
gicd_set_isenabler(multichip_gicd_base, intr_num);
|
||||
}
|
||||
|
||||
return ctlr_enable;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -10,6 +11,7 @@
|
|||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <common/interrupt_props.h>
|
||||
#include <drivers/arm/gic600_multichip.h>
|
||||
#include <drivers/arm/gicv3.h>
|
||||
#include <lib/spinlock.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
@ -430,6 +432,7 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, unsigned int proc_num)
|
|||
{
|
||||
unsigned int igroup, grpmodr;
|
||||
uintptr_t gicr_base;
|
||||
uintptr_t gicd_base;
|
||||
|
||||
assert(IS_IN_EL3());
|
||||
assert(gicv3_driver_data != NULL);
|
||||
|
@ -453,8 +456,9 @@ unsigned int gicv3_get_interrupt_type(unsigned int id, unsigned int proc_num)
|
|||
} else {
|
||||
/* SPIs: 32-1019, ESPIs: 4096-5119 */
|
||||
assert(gicv3_driver_data->gicd_base != 0U);
|
||||
igroup = gicd_get_igroupr(gicv3_driver_data->gicd_base, id);
|
||||
grpmodr = gicd_get_igrpmodr(gicv3_driver_data->gicd_base, id);
|
||||
gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
|
||||
igroup = gicd_get_igroupr(gicd_base, id);
|
||||
grpmodr = gicd_get_igrpmodr(gicd_base, id);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -930,6 +934,8 @@ unsigned int gicv3_get_running_priority(void)
|
|||
******************************************************************************/
|
||||
unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num)
|
||||
{
|
||||
uintptr_t gicd_base;
|
||||
|
||||
assert(gicv3_driver_data != NULL);
|
||||
assert(gicv3_driver_data->gicd_base != 0U);
|
||||
assert(proc_num < gicv3_driver_data->rdistif_num);
|
||||
|
@ -943,7 +949,8 @@ unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num)
|
|||
}
|
||||
|
||||
/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
|
||||
return gicd_get_isactiver(gicv3_driver_data->gicd_base, id);
|
||||
gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
|
||||
return gicd_get_isactiver(gicd_base, id);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -953,6 +960,8 @@ unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num)
|
|||
******************************************************************************/
|
||||
void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num)
|
||||
{
|
||||
uintptr_t gicd_base;
|
||||
|
||||
assert(gicv3_driver_data != NULL);
|
||||
assert(gicv3_driver_data->gicd_base != 0U);
|
||||
assert(proc_num < gicv3_driver_data->rdistif_num);
|
||||
|
@ -971,7 +980,8 @@ void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num)
|
|||
gicv3_driver_data->rdistif_base_addrs[proc_num], id);
|
||||
} else {
|
||||
/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
|
||||
gicd_set_isenabler(gicv3_driver_data->gicd_base, id);
|
||||
gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
|
||||
gicd_set_isenabler(gicd_base, id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -982,6 +992,8 @@ void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num)
|
|||
******************************************************************************/
|
||||
void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num)
|
||||
{
|
||||
uintptr_t gicd_base;
|
||||
|
||||
assert(gicv3_driver_data != NULL);
|
||||
assert(gicv3_driver_data->gicd_base != 0U);
|
||||
assert(proc_num < gicv3_driver_data->rdistif_num);
|
||||
|
@ -1003,10 +1015,11 @@ void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num)
|
|||
gicv3_driver_data->rdistif_base_addrs[proc_num]);
|
||||
} else {
|
||||
/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
|
||||
gicd_set_icenabler(gicv3_driver_data->gicd_base, id);
|
||||
gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
|
||||
gicd_set_icenabler(gicd_base, id);
|
||||
|
||||
/* Write to clear enable requires waiting for pending writes */
|
||||
gicd_wait_for_pending_write(gicv3_driver_data->gicd_base);
|
||||
gicd_wait_for_pending_write(gicd_base);
|
||||
}
|
||||
|
||||
dsbishst();
|
||||
|
@ -1020,6 +1033,7 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num,
|
|||
unsigned int priority)
|
||||
{
|
||||
uintptr_t gicr_base;
|
||||
uintptr_t gicd_base;
|
||||
|
||||
assert(gicv3_driver_data != NULL);
|
||||
assert(gicv3_driver_data->gicd_base != 0U);
|
||||
|
@ -1033,7 +1047,8 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num,
|
|||
gicr_set_ipriorityr(gicr_base, id, priority);
|
||||
} else {
|
||||
/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
|
||||
gicd_set_ipriorityr(gicv3_driver_data->gicd_base, id, priority);
|
||||
gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
|
||||
gicd_set_ipriorityr(gicd_base, id, priority);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1047,6 +1062,7 @@ void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
|
|||
{
|
||||
bool igroup = false, grpmod = false;
|
||||
uintptr_t gicr_base;
|
||||
uintptr_t gicd_base;
|
||||
|
||||
assert(gicv3_driver_data != NULL);
|
||||
assert(gicv3_driver_data->gicd_base != 0U);
|
||||
|
@ -1086,10 +1102,12 @@ void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
|
|||
/* Serialize read-modify-write to Distributor registers */
|
||||
spin_lock(&gic_lock);
|
||||
|
||||
igroup ? gicd_set_igroupr(gicv3_driver_data->gicd_base, id) :
|
||||
gicd_clr_igroupr(gicv3_driver_data->gicd_base, id);
|
||||
grpmod ? gicd_set_igrpmodr(gicv3_driver_data->gicd_base, id) :
|
||||
gicd_clr_igrpmodr(gicv3_driver_data->gicd_base, id);
|
||||
gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
|
||||
|
||||
igroup ? gicd_set_igroupr(gicd_base, id) :
|
||||
gicd_clr_igroupr(gicd_base, id);
|
||||
grpmod ? gicd_set_igrpmodr(gicd_base, id) :
|
||||
gicd_clr_igrpmodr(gicd_base, id);
|
||||
|
||||
spin_unlock(&gic_lock);
|
||||
}
|
||||
|
@ -1165,6 +1183,7 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr
|
|||
{
|
||||
unsigned long long aff;
|
||||
uint64_t router;
|
||||
uintptr_t gicd_base;
|
||||
|
||||
assert(gicv3_driver_data != NULL);
|
||||
assert(gicv3_driver_data->gicd_base != 0U);
|
||||
|
@ -1174,14 +1193,15 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr
|
|||
assert(IS_SPI(id));
|
||||
|
||||
aff = gicd_irouter_val_from_mpidr(mpidr, irm);
|
||||
gicd_write_irouter(gicv3_driver_data->gicd_base, id, aff);
|
||||
gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
|
||||
gicd_write_irouter(gicd_base, id, aff);
|
||||
|
||||
/*
|
||||
* In implementations that do not require 1 of N distribution of SPIs,
|
||||
* IRM might be RAZ/WI. Read back and verify IRM bit.
|
||||
*/
|
||||
if (irm == GICV3_IRM_ANY) {
|
||||
router = gicd_read_irouter(gicv3_driver_data->gicd_base, id);
|
||||
router = gicd_read_irouter(gicd_base, id);
|
||||
if (((router >> IROUTER_IRM_SHIFT) & IROUTER_IRM_MASK) == 0U) {
|
||||
ERROR("GICv3 implementation doesn't support routing ANY\n");
|
||||
panic();
|
||||
|
@ -1196,6 +1216,8 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr
|
|||
******************************************************************************/
|
||||
void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num)
|
||||
{
|
||||
uintptr_t gicd_base;
|
||||
|
||||
assert(gicv3_driver_data != NULL);
|
||||
assert(gicv3_driver_data->gicd_base != 0U);
|
||||
assert(proc_num < gicv3_driver_data->rdistif_num);
|
||||
|
@ -1213,7 +1235,8 @@ void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num)
|
|||
gicv3_driver_data->rdistif_base_addrs[proc_num], id);
|
||||
} else {
|
||||
/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
|
||||
gicd_set_icpendr(gicv3_driver_data->gicd_base, id);
|
||||
gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
|
||||
gicd_set_icpendr(gicd_base, id);
|
||||
}
|
||||
|
||||
dsbishst();
|
||||
|
@ -1226,6 +1249,8 @@ void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num)
|
|||
******************************************************************************/
|
||||
void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num)
|
||||
{
|
||||
uintptr_t gicd_base;
|
||||
|
||||
assert(gicv3_driver_data != NULL);
|
||||
assert(gicv3_driver_data->gicd_base != 0U);
|
||||
assert(proc_num < gicv3_driver_data->rdistif_num);
|
||||
|
@ -1244,7 +1269,8 @@ void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num)
|
|||
gicv3_driver_data->rdistif_base_addrs[proc_num], id);
|
||||
} else {
|
||||
/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
|
||||
gicd_set_ispendr(gicv3_driver_data->gicd_base, id);
|
||||
gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
|
||||
gicd_set_ispendr(gicd_base, id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -233,6 +234,7 @@ void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg);
|
|||
/*******************************************************************************
|
||||
* Private GICv3 helper function prototypes
|
||||
******************************************************************************/
|
||||
uintptr_t gicv3_get_multichip_base(uint32_t spi_id, uintptr_t gicd_base);
|
||||
unsigned int gicv3_get_spi_limit(uintptr_t gicd_base);
|
||||
unsigned int gicv3_get_espi_limit(uintptr_t gicd_base);
|
||||
void gicv3_spis_config_defaults(uintptr_t gicd_base);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2019, ARM Limited. All rights reserved.
|
||||
* Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -15,8 +16,11 @@
|
|||
*/
|
||||
#define GIC600_MAX_MULTICHIP 16
|
||||
|
||||
/* SPI IDs array consist of min and max ids */
|
||||
#define GIC600_SPI_IDS_SIZE 2
|
||||
typedef struct multichip_spi_ids_desc {
|
||||
uintptr_t gicd_base;
|
||||
uint32_t spi_id_min;
|
||||
uint32_t spi_id_max;
|
||||
} multichip_spi_ids_desc_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* GIC-600 multichip data structure describes platform specific attributes
|
||||
|
@ -37,19 +41,23 @@
|
|||
* The 'chip_addrs' field contains array of chip addresses. These addresses are
|
||||
* implementation specific values.
|
||||
*
|
||||
* The 'spi_ids' field contains array of minimum and maximum SPI interrupt ids
|
||||
* that each chip owns. Note that SPI interrupt ids can range from 32 to 960 and
|
||||
* it should be group of 32 (i.e., SPI minimum and (SPI maximum + 1) should be
|
||||
* a multiple of 32). If a chip doesn't own any SPI interrupts a value of {0, 0}
|
||||
* should be passed.
|
||||
* The 'multichip_spi_ids_desc_t' field contains array of descriptors used to
|
||||
* provide minimum and maximum SPI interrupt ids that each chip owns and the
|
||||
* corresponding chip base address. Note that SPI interrupt ids can range from
|
||||
* 32 to 960 and it should be group of 32 (i.e., SPI minimum and (SPI maximum +
|
||||
* 1) should be a multiple of 32). If a chip doesn't own any SPI interrupts a
|
||||
* value of {0, 0, 0} should be passed.
|
||||
******************************************************************************/
|
||||
struct gic600_multichip_data {
|
||||
uintptr_t rt_owner_base;
|
||||
unsigned int rt_owner;
|
||||
unsigned int chip_count;
|
||||
uint64_t chip_addrs[GIC600_MAX_MULTICHIP];
|
||||
unsigned int spi_ids[GIC600_MAX_MULTICHIP][GIC600_SPI_IDS_SIZE];
|
||||
multichip_spi_ids_desc_t spi_ids[GIC600_MAX_MULTICHIP];
|
||||
};
|
||||
|
||||
uintptr_t gic600_multichip_gicd_base_for_spi(uint32_t spi_id);
|
||||
void gic600_multichip_init(struct gic600_multichip_data *multichip_data);
|
||||
bool gic600_multichip_is_initialized(void);
|
||||
|
||||
#endif /* GIC600_MULTICHIP_H */
|
||||
|
|
|
@ -51,8 +51,8 @@ static struct gic600_multichip_data n1sdp_multichip_data __init = {
|
|||
PLAT_ARM_GICD_BASE >> 16
|
||||
},
|
||||
.spi_ids = {
|
||||
{32, 479},
|
||||
{512, 959}
|
||||
{PLAT_ARM_GICD_BASE, 32, 479},
|
||||
{PLAT_ARM_GICD_BASE, 512, 959}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@ static struct gic600_multichip_data rdn1e1_multichip_data __init = {
|
|||
(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16
|
||||
},
|
||||
.spi_ids = {
|
||||
{32, 255},
|
||||
{0, 0}
|
||||
{PLAT_ARM_GICD_BASE, 32, 255},
|
||||
{0, 0, 0}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -47,15 +47,15 @@ static struct gic600_multichip_data rdn2mc_multichip_data __init = {
|
|||
#endif
|
||||
},
|
||||
.spi_ids = {
|
||||
{32, 511},
|
||||
{PLAT_ARM_GICD_BASE, 32, 511},
|
||||
#if CSS_SGI_CHIP_COUNT > 1
|
||||
{512, 991},
|
||||
{PLAT_ARM_GICD_BASE, 512, 991},
|
||||
#endif
|
||||
#if CSS_SGI_CHIP_COUNT > 2
|
||||
{4096, 4575},
|
||||
{PLAT_ARM_GICD_BASE, 4096, 4575},
|
||||
#endif
|
||||
#if CSS_SGI_CHIP_COUNT > 3
|
||||
{4576, 5055},
|
||||
{PLAT_ARM_GICD_BASE, 4576, 5055},
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
|
|
@ -43,13 +43,13 @@ static struct gic600_multichip_data rdv1mc_multichip_data __init = {
|
|||
#endif
|
||||
},
|
||||
.spi_ids = {
|
||||
{32, 255},
|
||||
{0, 0},
|
||||
{PLAT_ARM_GICD_BASE, 32, 255},
|
||||
{0, 0, 0},
|
||||
#if (CSS_SGI_CHIP_COUNT > 2)
|
||||
{0, 0},
|
||||
{0, 0, 0},
|
||||
#endif
|
||||
#if (CSS_SGI_CHIP_COUNT > 3)
|
||||
{0, 0},
|
||||
{0, 0, 0},
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue