From 73a643eed9d88910a09ca666bc7ab7f5e532324e Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 24 Aug 2021 10:03:57 +0100 Subject: [PATCH] feat(gicv3): introduce GIC component identification The GIC specification describes ID registers in each GIC register frame (PIDRx), which can be used to identify a GIC component. The Arm Ltd. GIC implementations use certain ID values to identify the distributor, the redistributors and other parts like ITSes. Introduce a function that reads those part number IDs, which are spread over two registers. The actual numbers are only meaningful in connection with a certain GIC model, which would need to be checked beforehand, by the caller. Change-Id: Ia6ff326a1e8b12664e4637bc8e2683d2b5c7721c Signed-off-by: Andre Przywara --- drivers/arm/gic/v3/gicv3_helpers.c | 15 +++++++++++++++ include/drivers/arm/arm_gicv3_common.h | 4 ++++ include/drivers/arm/gicv3.h | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index d752013e2..753d995d7 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -393,3 +393,18 @@ unsigned int gicv3_rdistif_get_number_frames(const uintptr_t gicr_frame) return count; } + +unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame) +{ + unsigned int part_id; + + /* + * The lower 8 bits of PIDR0, complemented by the lower 4 bits of + * PIDR1 contain a part number identifying the GIC component at a + * particular base address. + */ + part_id = mmio_read_32(gic_frame + GICD_PIDR0_GICV3) & 0xff; + part_id |= (mmio_read_32(gic_frame + GICD_PIDR1_GICV3) << 8) & 0xf00; + + return part_id; +} diff --git a/include/drivers/arm/arm_gicv3_common.h b/include/drivers/arm/arm_gicv3_common.h index e5df31136..d1e93be67 100644 --- a/include/drivers/arm/arm_gicv3_common.h +++ b/include/drivers/arm/arm_gicv3_common.h @@ -21,4 +21,8 @@ #define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b) #define IIDR_MODEL_ARM_GIC_700 U(0x0400043b) +#define PIDR_COMPONENT_ARM_DIST U(0x492) +#define PIDR_COMPONENT_ARM_REDIST U(0x493) +#define PIDR_COMPONENT_ARM_ITS U(0x494) + #endif /* ARM_GICV3_COMMON_H */ diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index fa8946b16..973a58b67 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -104,6 +104,8 @@ #define GICD_IROUTER U(0x6000) #define GICD_IROUTERE U(0x8000) +#define GICD_PIDR0_GICV3 U(0xffe0) +#define GICD_PIDR1_GICV3 U(0xffe4) #define GICD_PIDR2_GICV3 U(0xffe8) #define IGRPMODR_SHIFT 5 @@ -324,6 +326,8 @@ static inline uintptr_t gicv3_redist_size(uint64_t typer_val) #endif } +unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame); + static inline bool gicv3_is_intr_id_special_identifier(unsigned int id) { return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT);