When the inmate cell is in AArch32 execution state, using mmio_read64() to obtain the value of GICR_TYPER will cause error because mmio_read64() generates "ldrd" instruction when compiling 32-bit gic_demo.bin, and "ldrd" belongs to A64 assembly language which is cannot be used in AArch32. So use mmio_read32() to read 64-bit GICR_ TYPER in twice and add processing case for reading the higher 32 bits of GICR_ TYPER in gicv3_handle_redist_access().
In ARMv8-A, AArch64 state supports four levels of affinity. but AArch32 state can only support three levels of affinity. So set bit[31:24] of mpidr to be 0 for AArch32, without affecting AArch64 because "MPIDR_AFFINITY_LEVEL" used in AArch32 and AArch64 is different. Signed-off-by: Alice Guo <[email protected]> --- hypervisor/arch/arm-common/gic-v3.c | 3 +++ inmates/lib/arm-common/gic-v3.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/hypervisor/arch/arm-common/gic-v3.c b/hypervisor/arch/arm-common/gic-v3.c index 6a1d90f8..584c2c79 100644 --- a/hypervisor/arch/arm-common/gic-v3.c +++ b/hypervisor/arch/arm-common/gic-v3.c @@ -351,6 +351,9 @@ static enum mmio_result gicv3_handle_redist_access(void *arg, if (cpu_public->cpu_id == last_gicr) mmio->value |= GICR_TYPER_Last; return MMIO_HANDLED; + case GICR_TYPER + 4: + mmio_perform_access(cpu_public->gicr.base, mmio); + return MMIO_HANDLED; case GICR_IIDR: case 0xffd0 ... 0xfffc: /* ID registers */ /* diff --git a/inmates/lib/arm-common/gic-v3.c b/inmates/lib/arm-common/gic-v3.c index 35ee9a6a..12978ea5 100644 --- a/inmates/lib/arm-common/gic-v3.c +++ b/inmates/lib/arm-common/gic-v3.c @@ -76,6 +76,7 @@ static int gic_v3_init(void) map_range(redist_addr, PAGE_SIZE, MAP_UNCACHED); arm_read_sysreg(MPIDR, mpidr); + mpidr &= ~(0xFF << 24); aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 | MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 | MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 | @@ -87,7 +88,8 @@ static int gic_v3_init(void) if (GICR_PIDR2_ARCH(pidr) != 3) break; - typer = mmio_read64(redist_addr + GICR_TYPER); + typer = mmio_read32(redist_addr + GICR_TYPER); + typer |= (u64)mmio_read32(redist_addr + GICR_TYPER + 4) << 32; if ((typer >> 32) == aff) { gicr = redist_addr; break; -- 2.17.1 -- 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]. To view this discussion on the web visit https://groups.google.com/d/msgid/jailhouse-dev/20200811181641.7282-3-alice.guo%40nxp.com.
