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 <andre.przywara@arm.com>
This commit is contained in:
Andre Przywara 2021-08-24 10:03:57 +01:00
parent 4d585fe52f
commit 73a643eed9
3 changed files with 23 additions and 0 deletions

View File

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

View File

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

View File

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