Merge changes from topic "mb/gic600-errata" into integration

* changes:
  refactor(arm): update BL2 base address
  refactor(nxp): use DPG0 mask from Arm GICv3 header
  fix(gic600): implement workaround to forward highest priority interrupt
This commit is contained in:
Manish Pandey 2022-06-21 14:11:47 +02:00 committed by TrustedFirmware Code Review
commit 84adb0519e
8 changed files with 190 additions and 16 deletions
docs/design
drivers/arm/gic/v3
include
drivers
arm
nxp/gic/gicv3
plat/arm/common

View file

@ -634,9 +634,17 @@ architecture that can be enabled by the platform as desired.
This is used to control how the LL_CACHE* PMU events count.
Default value is 0 (Disabled).
GIC Errata Workarounds
----------------------
- ``GIC600_ERRATA_WA_2384374``: This flag applies part 2 of errata 2384374
workaround for the affected GIC600 and GIC600-AE implementations. It applies
to implementations of GIC600 and GIC600-AE with revisions less than or equal
to r1p6 and r0p2 respectively. If the platform sets GICV3_SUPPORT_GIC600,
then this flag is enabled; otherwise, it is 0 (Disabled).
--------------
*Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.*
*Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved.*
.. _CVE-2017-5715: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
.. _CVE-2018-3639: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@ -42,6 +42,8 @@
#define PWRR_ON (0U << PWRR_RDPD_SHIFT)
#define PWRR_OFF (1U << PWRR_RDPD_SHIFT)
static bool gic600_errata_wa_2384374 __unused;
#if GICV3_SUPPORT_GIC600
/* GIC-600/700 specific accessor functions */
@ -170,3 +172,60 @@ void gicv3_rdistif_on(unsigned int proc_num)
}
#endif
}
#if GIC600_ERRATA_WA_2384374
/*******************************************************************************
* Apply part 2 of workaround for errata-2384374 as per SDEN:
* https://developer.arm.com/documentation/sden892601/latest/
******************************************************************************/
void gicv3_apply_errata_wa_2384374(uintptr_t gicr_base)
{
if (gic600_errata_wa_2384374) {
uint32_t gicr_ctlr_val = gicr_read_ctlr(gicr_base);
gicr_write_ctlr(gicr_base, gicr_ctlr_val |
(GICR_CTLR_DPG0_BIT | GICR_CTLR_DPG1NS_BIT |
GICR_CTLR_DPG1S_BIT));
gicr_write_ctlr(gicr_base, gicr_ctlr_val &
~(GICR_CTLR_DPG0_BIT | GICR_CTLR_DPG1NS_BIT |
GICR_CTLR_DPG1S_BIT));
}
}
#endif /* GIC600_ERRATA_WA_2384374 */
void gicv3_check_erratas_applies(uintptr_t gicd_base)
{
unsigned int gic_prod_id;
uint8_t gic_rev;
assert(gicd_base != 0UL);
gicv3_get_component_prodid_rev(gicd_base, &gic_prod_id, &gic_rev);
/*
* This workaround applicable only to GIC600 and GIC600AE products with
* revision less than r1p6 and r0p2 respectively.
* As per GIC600/GIC600AE specification -
* r1p6 = 0x17 => GICD_IIDR[19:12]
* r0p2 = 0x04 => GICD_IIDR[19:12]
*/
if ((gic_prod_id == GIC_PRODUCT_ID_GIC600) ||
(gic_prod_id == GIC_PRODUCT_ID_GIC600AE)) {
if (((gic_prod_id == GIC_PRODUCT_ID_GIC600) &&
(gic_rev <= GIC_REV(GIC_VARIANT_R1, GIC_REV_P6))) ||
((gic_prod_id == GIC_PRODUCT_ID_GIC600AE) &&
(gic_rev <= GIC_REV(GIC_VARIANT_R0, GIC_REV_P2)))) {
#if GIC600_ERRATA_WA_2384374
gic600_errata_wa_2384374 = true;
VERBOSE("%s applies\n",
"GIC600/GIC600AE errata workaround 2384374");
#else
WARN("%s missing\n",
"GIC600/GIC600AE errata workaround 2384374");
#endif /* GIC600_ERRATA_WA_2384374 */
} else {
VERBOSE("%s not applies\n",
"GIC600/GIC600AE errata workaround 2384374");
}
}
}

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
# Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
# Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
@ -12,6 +12,7 @@ GICV3_IMPL_GIC600_MULTICHIP ?= 0
GICV3_OVERRIDE_DISTIF_PWR_OPS ?= 0
GIC_ENABLE_V4_EXTN ?= 0
GIC_EXT_INTID ?= 0
GIC600_ERRATA_WA_2384374 ?= ${GICV3_SUPPORT_GIC600}
GICV3_SOURCES += drivers/arm/gic/v3/gicv3_main.c \
drivers/arm/gic/v3/gicv3_helpers.c \
@ -47,3 +48,7 @@ $(eval $(call add_define,GIC_ENABLE_V4_EXTN))
# Set support for extended PPI and SPI range
$(eval $(call assert_boolean,GIC_EXT_INTID))
$(eval $(call add_define,GIC_EXT_INTID))
# Set errata workaround for GIC600/GIC600AE
$(eval $(call assert_boolean,GIC600_ERRATA_WA_2384374))
$(eval $(call add_define,GIC600_ERRATA_WA_2384374))

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -408,3 +408,34 @@ unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame)
return part_id;
}
/*******************************************************************************
* Helper function to return product ID and revision of GIC
* @gicd_base: base address of the GIC distributor
* @gic_prod_id: retrieved product id of GIC
* @gic_rev: retrieved revision of GIC
******************************************************************************/
void gicv3_get_component_prodid_rev(const uintptr_t gicd_base,
unsigned int *gic_prod_id,
uint8_t *gic_rev)
{
unsigned int gicd_iidr;
uint8_t gic_variant;
gicd_iidr = gicd_read_iidr(gicd_base);
*gic_prod_id = gicd_iidr >> IIDR_PRODUCT_ID_SHIFT;
*gic_prod_id &= IIDR_PRODUCT_ID_MASK;
gic_variant = gicd_iidr >> IIDR_VARIANT_SHIFT;
gic_variant &= IIDR_VARIANT_MASK;
*gic_rev = gicd_iidr >> IIDR_REV_SHIFT;
*gic_rev &= IIDR_REV_MASK;
/*
* pack gic variant and gic_rev in 1 byte
* gic_rev = gic_variant[7:4] and gic_rev[0:3]
*/
*gic_rev = *gic_rev | gic_variant << 0x4;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -169,6 +169,8 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data)
flush_dcache_range((uintptr_t)gicv3_driver_data,
sizeof(*gicv3_driver_data));
#endif
gicv3_check_erratas_applies(plat_driver_data->gicd_base);
INFO("GICv%u with%s legacy support detected.\n", gic_version,
(gicv2_compat == 0U) ? "" : "out");
INFO("ARM GICv%u driver initialized in EL3\n", gic_version);
@ -362,9 +364,17 @@ void gicv3_cpuif_disable(unsigned int proc_num)
/* Add DSB to ensure visibility of System register writes */
dsb();
/* Mark the connected core as asleep */
gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
assert(gicr_base != 0U);
assert(gicr_base != 0UL);
/*
* dsb() already issued previously after clearing the CPU group
* enabled, apply below workaround to toggle the "DPG*"
* bits of GICR_CTLR register for unblocking event.
*/
gicv3_apply_errata_wa_2384374(gicr_base);
/* Mark the connected core as asleep */
gicv3_rdistif_mark_core_asleep(gicr_base);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -76,6 +76,8 @@
#endif /* GIC_EXT_INTID */
#define GIC_REV(r, p) ((r << 4) | p)
/*******************************************************************************
* GICv3 and 3.1 specific Distributor interface register offsets and constants
******************************************************************************/
@ -192,6 +194,15 @@
#define GICR_CTLR_UWP_SHIFT 31
#define GICR_CTLR_UWP_MASK U(0x1)
#define GICR_CTLR_UWP_BIT BIT_32(GICR_CTLR_UWP_SHIFT)
#define GICR_CTLR_DPG1S_SHIFT 26
#define GICR_CTLR_DPG1S_MASK U(0x1)
#define GICR_CTLR_DPG1S_BIT BIT_32(GICR_CTLR_DPG1S_SHIFT)
#define GICR_CTLR_DPG1NS_SHIFT 25
#define GICR_CTLR_DPG1NS_MASK U(0x1)
#define GICR_CTLR_DPG1NS_BIT BIT_32(GICR_CTLR_DPG1NS_SHIFT)
#define GICR_CTLR_DPG0_SHIFT 24
#define GICR_CTLR_DPG0_MASK U(0x1)
#define GICR_CTLR_DPG0_BIT BIT_32(GICR_CTLR_DPG0_SHIFT)
#define GICR_CTLR_RWP_SHIFT 3
#define GICR_CTLR_RWP_MASK U(0x1)
#define GICR_CTLR_RWP_BIT BIT_32(GICR_CTLR_RWP_SHIFT)
@ -224,12 +235,40 @@
#define TYPER_PPI_NUM_MASK U(0x1f)
/* GICR_IIDR bit definitions */
#define IIDR_PRODUCT_ID_MASK U(0xff000000)
#define IIDR_VARIANT_MASK U(0x000f0000)
#define IIDR_REVISION_MASK U(0x0000f000)
#define IIDR_IMPLEMENTER_MASK U(0x00000fff)
#define IIDR_MODEL_MASK (IIDR_PRODUCT_ID_MASK | \
IIDR_IMPLEMENTER_MASK)
#define IIDR_PRODUCT_ID_MASK U(0xff)
#define IIDR_VARIANT_MASK U(0xf)
#define IIDR_REV_MASK U(0xf)
#define IIDR_IMPLEMENTER_MASK U(0xfff)
#define IIDR_PRODUCT_ID_SHIFT 24
#define IIDR_VARIANT_SHIFT 16
#define IIDR_REV_SHIFT 12
#define IIDR_IMPLEMENTER_SHIFT 0
#define IIDR_PRODUCT_ID_BIT BIT_32(IIDR_PRODUCT_ID_SHIFT)
#define IIDR_VARIANT_BIT BIT_32(IIDR_VARIANT_SHIFT)
#define IIDR_REV_BIT BIT_32(IIDR_REVISION_SHIFT)
#define IIDR_IMPLEMENTER_BIT BIT_32(IIDR_IMPLEMENTER_SHIFT)
#define IIDR_MODEL_MASK (IIDR_PRODUCT_ID_MASK << IIDR_PRODUCT_ID_SHIFT | \
IIDR_IMPLEMENTER_MASK << IIDR_IMPLEMENTER_SHIFT)
#define GIC_PRODUCT_ID_GIC600 U(0x2)
#define GIC_PRODUCT_ID_GIC600AE U(0x3)
#define GIC_PRODUCT_ID_GIC700 U(0x4)
/*
* Note that below revisions and variants definations are as per GIC600/GIC600AE
* specification.
*/
#define GIC_REV_P0 U(0x1)
#define GIC_REV_P1 U(0x3)
#define GIC_REV_P2 U(0x4)
#define GIC_REV_P3 U(0x5)
#define GIC_REV_P4 U(0x6)
#define GIC_REV_P6 U(0x7)
#define GIC_VARIANT_R0 U(0x0)
#define GIC_VARIANT_R1 U(0x1)
#define GIC_VARIANT_R2 U(0x2)
/*******************************************************************************
* GICv3 and 3.1 CPU interface registers & constants
@ -543,5 +582,17 @@ void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num);
void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num);
unsigned int gicv3_set_pmr(unsigned int mask);
void gicv3_get_component_prodid_rev(const uintptr_t gicd_base,
unsigned int *gic_prod_id,
uint8_t *gic_rev);
void gicv3_check_erratas_applies(const uintptr_t gicd_base);
#if GIC600_ERRATA_WA_2384374
void gicv3_apply_errata_wa_2384374(const uintptr_t gicr_base);
#else
static inline void gicv3_apply_errata_wa_2384374(const uintptr_t gicr_base)
{
}
#endif /* GIC600_ERRATA_WA_2384374 */
#endif /* __ASSEMBLER__ */
#endif /* GICV3_H */

View file

@ -61,7 +61,6 @@
#define GICR_ICENABLER0_SGI15 0x00008000
#define GICR_CTLR_RWP 0x8
#define GICR_CTLR_DPG0_MASK 0x2000000
#define GICR_IGROUPR0_SGI15 0x00008000
#define GICR_IGRPMODR0_SGI15 0x00008000
#define GICR_ISENABLER0_SGI15 0x00008000

View file

@ -520,9 +520,20 @@
* BL2 specific defines.
******************************************************************************/
#if BL2_AT_EL3
#if ENABLE_PIE
/*
* As the BL31 image size appears to be increased when built with the ENABLE_PIE
* option, set BL2 base address to have enough space for BL31 in Trusted SRAM.
*/
#define BL2_BASE (ARM_TRUSTED_SRAM_BASE + \
(PLAT_ARM_TRUSTED_SRAM_SIZE >> 1) + \
0x3000)
#else
/* Put BL2 towards the middle of the Trusted SRAM */
#define BL2_BASE (ARM_TRUSTED_SRAM_BASE + \
(PLAT_ARM_TRUSTED_SRAM_SIZE >> 1) + 0x2000)
(PLAT_ARM_TRUSTED_SRAM_SIZE >> 1) + \
0x2000)
#endif /* ENABLE_PIE */
#define BL2_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
#else