From 2f55111defebffc8e87e47ecd07d82a270a399c6 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sun, 18 Feb 2024 13:51:13 +0000 Subject: [PATCH] uart0-helloworld-sdboot: rework SRAM version register detection The SRAM controller's version register, which we use to identify a SoC, is mapped at different locations in the different SoC generations. To find the right MMIO address, we try to read some GICD_IIDR register, which tells us which SoC generation we are dealing with. Looking forward, this will need to be more flexible, as the A80 and A523 will not work with this scheme anymore: the A80 uses a completely different memory map, and the A523 has a GICv3. Rework the generation detection to be more flexible and easier to extend: - First read the MIDR, and check for a Cortex-A8 core. This is the early generation of SoCs (A10/A10s/A13), which don't have a GIC at all. Use the legacy SRAM controller address in this case. - Next check the address of the GIC in the H6 generation ("NCAT"). Its base address is unmapped at all the other SoCs tested, so this is safe. - Finally check the GIC address of the "legacy" generation of SoCs (A20-A64). - If nothing matches, we are dealing with an unknown SoC, and must stop. The A80 detection was a nice idea, but didn't work, since the boot cluster is the one with the A7 cores, so the boot CPU looks like all the other 32-bit SoCs. Remove that, as the A80 is not supported anyways. Signed-off-by: Andre Przywara --- uart0-helloworld-sdboot.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/uart0-helloworld-sdboot.c b/uart0-helloworld-sdboot.c index 1727842..7119307 100644 --- a/uart0-helloworld-sdboot.c +++ b/uart0-helloworld-sdboot.c @@ -276,28 +276,22 @@ static u32 soc_id; void soc_detection_init(void) { + u32 reg; u32 midr; + asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (midr)); - - if (((midr >> 4) & 0xFFF) == 0xC0F) { - soc_id = 0x1639; /* ARM Cortex-A15, so likely Allwinner A80 */ + if (((midr >> 4) & 0xFFF) == 0xc08) { /* ARM Cortex-A8: A10/A10s/A13 */ + reg = VER_REG; + } else if ((readl(0x03021008) & 0xfff) == 0x43b) {// GICD_IIDR @ NCAT + reg = H6_VER_REG; + } else if ((readl(0x01c81008) & 0xfff) == 0x43b) {// GICD_IIDR @ legacy + reg = VER_REG; } else { - u32 reg; - - /* - * This register is GICD_IIDR on H6, but unmapped according to - * other known SoCs' user manuals. - */ - reg = readl(0x03021008); - - if ((reg & 0xfff) == 0x43b) /* Found GICv2 here, so it's a H6 */ - reg = H6_VER_REG; - else - reg = VER_REG; - - set_wbit(reg, 1 << 15); - soc_id = readl(reg) >> 16; + while (1); // unknown } + + set_wbit(reg, 1U << 15); + soc_id = readl(reg) >> 16; } /* Most SoCs can reliably be distinguished by simply checking their ID value */