Losing Debugger Control When Booting Cortex-A53 on S32G2 (Type 1 Hypervisor)

Hello everyone,

I’m working on a lightweight Type 1 Hypervisor for an ARM Cortex-A53 (ARMv8) on an S32G2 platform. We’re booting the Cortex-A53 from another core, a Cortex-M7.

The hypervisor runs at EL2, where we initialize the MMU, GIC, and scheduler (with a generic timer that triggers interrupts periodically).

Everything works fine when we boot through U-Boot—our hypervisor is initialized properly, and we can debug without issues using Lauterbach Trace32.

However, when using our own boot code, we lose control of the debugger entirely.

The CPU keeps running, and the only way to restore control is to reset the CPU.

This strongly suggests that we might be missing some key piece of setup in our custom boot code.

Here are the registers we configure and the values we set:

  • GICD_CTLR – Set with ARE_NS | ENABLE_GRP1_NS
  • GICD_IGROUPR[i] – Set each to ULONG_MAX for non-secure group 1 interrupts
  • GICR_IGROUPR[0] – Set to ULONG_MAX
  • GICR_WAKER – Clear the PROCESSOR_SLEEP bit and wait until CHILDREN_ASLEEP bit is cleared
  • SCTLR_EL2 – Reset to 0 (then later set to 0x30C50838)
  • HCR_EL2 – Reset to 0 (we let the Hypervisor configure it)
  • SCR_EL3 – Set to 0x501 (enabling next lower EL as AArch64, EL0/EL1 non-secure, HVC enabled)
  • CNTFRQ_EL0 – Set to 5000000 (generic timer clock frequency)
  • SCTLR_EL1 – Set to 0x00C50838
  • SCTLR_EL3 – Set to 0x00C50830
  • VBAR_EL3 – Set to 0x8000E800 (our vector base address)
  • ICC_SRE_EL3 – Set to 0xF
  • ICC_IGRPEN1_EL3 – Set to 1
  • ICC_CTLR_EL3 – Set to 0x400
  • ICC_BPR1_EL1 – Set to 0x3

After configuring all this, we exit secure mode by setting SPSR_EL3 to 0x1c9.

And in the end we jump to our Hypervisor entry point by setting it on ELR_EL3 and then running eret.

NOTE: We start it with no cache enabled and the Hypervisor typically enables it at EL2 after finishing the initialization, but we had to remove it because enabling it was also causing the debugger to lose control. 

Could anyone provide insights into what might be missing or misconfigured that would cause the debugger to lose control?

Any guidance or suggestions would be greatly appreciated!

Thank you!

  • Hello, 

    After some investigation, we found that the interrupt is actually being throwed and signaled at the CPU.

    We are able to reach the irq_handler configured at the exception vector table.

    The actual CPU shutdown occurs when we run AT S12E1R, x0, where x0 = 0x00000000.

    We have the stage 2 MMU at EL1 and stage 1 MMU at EL2 configured and there isn't much different in the registers when using u-boot or our bootloader.

    However, the system enters in shutdown when using our bootloader and not when using u-boot.

    Is the shutdown expected when trying to translate address 0x00000000?