Getting GICv3's redistributor might look a bit clumsy, but we will need those stubs as soon as we allow to kick secondary CPUs on ARM via PSCI.
Signed-off-by: Ralf Ramsauer <[email protected]> --- inmates/lib/arm-common/gic-v2.c | 23 +++++++-------- inmates/lib/arm-common/gic-v3.c | 50 +++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/inmates/lib/arm-common/gic-v2.c b/inmates/lib/arm-common/gic-v2.c index e2c271c3..ab85fd27 100644 --- a/inmates/lib/arm-common/gic-v2.c +++ b/inmates/lib/arm-common/gic-v2.c @@ -39,11 +39,6 @@ #include <mach.h> #include <gic.h> -#ifndef GICD_V2_BASE -#define GICD_V2_BASE ((void *)-1) -#define GICC_V2_BASE ((void *)-1) -#endif - #define GICC_CTLR 0x0000 #define GICC_PMR 0x0004 #define GICC_IAR 0x000c @@ -55,29 +50,35 @@ #define GICC_PMR_DEFAULT 0xf0 +static void *gicc_v2_base; +static void *gicd_v2_base; + static void gic_v2_enable(unsigned int irqn) { - mmio_write32(GICD_V2_BASE + GICD_ISENABLER + ((irqn >> 3) & ~0x3), + mmio_write32(gicd_v2_base + GICD_ISENABLER + ((irqn >> 3) & ~0x3), 1 << (irqn & 0x1f)); } static int gic_v2_init(void) { - mmio_write32(GICC_V2_BASE + GICC_CTLR, GICC_CTLR_GRPEN1); - mmio_write32(GICC_V2_BASE + GICC_PMR, GICC_PMR_DEFAULT); - mmio_write32(GICD_V2_BASE + GICD_CTLR, GICD_CTLR_ENABLE); + gicc_v2_base = (void*)(unsigned long)comm_region->gicc_base; + gicd_v2_base = (void*)(unsigned long)comm_region->gicd_base; + + mmio_write32(gicc_v2_base + GICC_CTLR, GICC_CTLR_GRPEN1); + mmio_write32(gicc_v2_base + GICC_PMR, GICC_PMR_DEFAULT); + mmio_write32(gicd_v2_base + GICD_CTLR, GICD_CTLR_ENABLE); return 0; } static void gic_v2_write_eoi(u32 irqn) { - mmio_write32(GICC_V2_BASE + GICC_EOIR, irqn); + mmio_write32(gicc_v2_base + GICC_EOIR, irqn); } static u32 gic_v2_read_ack(void) { - return mmio_read32(GICC_V2_BASE + GICC_IAR) & 0x3ff; + return mmio_read32(gicc_v2_base + GICC_IAR) & 0x3ff; } const struct gic gic_v2 = { diff --git a/inmates/lib/arm-common/gic-v3.c b/inmates/lib/arm-common/gic-v3.c index f9278f71..530374c6 100644 --- a/inmates/lib/arm-common/gic-v3.c +++ b/inmates/lib/arm-common/gic-v3.c @@ -40,14 +40,18 @@ #include <mach.h> #include <gic.h> -#ifndef GICD_V3_BASE -#define GICD_V3_BASE ((void *)-1) -#define GICR_V3_BASE ((void *)-1) -#endif +static void *gicd_v3_base; +static void *gicr_v3_base; +#define GICR_TYPER 0x0008 +#define GICR_TYPER_Last (1 << 4) +#define GICR_PIDR2 0xffe8 #define GICR_SGI_BASE 0x10000 #define GICR_ISENABLER GICD_ISENABLER +#define GICD_PIDR2_ARCH(pidr) (((pidr) & 0xf0) >> 4) +#define GICR_PIDR2_ARCH GICD_PIDR2_ARCH + #define ICC_IAR1_EL1 SYSREG_32(0, c12, c12, 0) #define ICC_EOIR1_EL1 SYSREG_32(0, c12, c12, 1) #define ICC_PMR_EL1 SYSREG_32(0, c4, c6, 0) @@ -59,15 +63,49 @@ static void gic_v3_enable(unsigned int irqn) { if (is_sgi_ppi(irqn)) - mmio_write32(GICR_V3_BASE + GICR_SGI_BASE + GICR_ISENABLER, + mmio_write32(gicr_v3_base + GICR_SGI_BASE + GICR_ISENABLER, 1 << irqn); else if (is_spi(irqn)) - mmio_write32(GICD_V3_BASE + GICD_ISENABLER + irqn / 32, + mmio_write32(gicd_v3_base + GICD_ISENABLER + irqn / 32, 1 << (irqn % 32)); } static int gic_v3_init(void) { + void *redist_addr = (void*)(unsigned long)comm_region->gicr_base; + unsigned long mpidr; + void *gicr = NULL; + u64 typer; + u32 pidr, aff; + + gicd_v3_base = (void*)(unsigned long)comm_region->gicd_base; + + arm_read_sysreg(MPIDR_EL1, mpidr); + aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 | + MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 | + MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 | + MPIDR_AFFINITY_LEVEL(mpidr, 0)); + + /* Find redistributor */ + do { + pidr = mmio_read32(redist_addr + GICR_PIDR2); + if (GICR_PIDR2_ARCH(pidr) != 3) + break; + + typer = mmio_read64(redist_addr + GICR_TYPER); + if ((typer >> 32) == aff) { + gicr = redist_addr; + break; + } + + redist_addr += 0x20000; + } while (!(typer & GICR_TYPER_Last)); + + if (!gicr) + return -1; + + gicr_v3_base = gicr; + arm_write_sysreg(ICC_CTLR_EL1, 0); arm_write_sysreg(ICC_PMR_EL1, 0xf0); arm_write_sysreg(ICC_IGRPEN1_EL1, ICC_IGRPEN1_EN); -- 2.17.0 -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
