On 11.08.20 20:16, Alice Guo wrote:
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 <alice....@nxp.com>
---
  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 */
                /*

Let's split hypervisor and inmate changes.

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

I do net get yet how that is NOT affecting AARCH64. It comes before MPIDR_AFFINITY_LEVEL usage below.

Why not using some arch-defined MPIDR_CPUID_MASK to ensure the correct masking?

        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;


Jan

--
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux

--
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 jailhouse-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/0316b236-5b86-7fe9-90b1-9fa10d1803a9%40siemens.com.

Reply via email to