33.10.7.1. NienfengYao/armv8-bare-metal
The only QEMU -m virt
aarch64 example set that I can find on the web. Awesome.
A large part of the code is taken from the awesome educational OS under 2-clause BSD as can be seen from file headers: https://github.com/takeharukato/sample-tsk-sw/tree/ce7973aa5d46c9eedb58309de43df3b09d4f8d8d/hal/aarch64 but Nienfeng largely minimized it.
I needed the following minor patches: https://github.com/NienfengYao/armv8-bare-metal/pull/1
Handles an SVC and setups and handles the timer about once per second.
The source claims GICv3, however if I try to add -machine gic_version=3
on their command line with our QEMU v4.0.0, then it blows up at:
static void init_gicc(void) { uint32_t pending_irq; /* Disable CPU interface */ *REG_GIC_GICC_CTLR = GICC_CTLR_DISABLE;
which tries to write to 0x8010000 according to GDB.
Without -machine
, QEMU’s DTB clearly states GICv2, so I’m starting to wonder if Nienfeng just made a mistake there? The QEMU GICv3 DTB contains:
reg = <0x0 0x8000000 0x0 0x10000 0x0 0x80a0000 0x0 0xf60000>;
and the GICv2 one:
reg = <0x0 0x8000000 0x0 0x10000 0x0 0x8010000 0x0 0x10000>;
which further confirms that the exception is correct: v2 has a register range at 0x8010000 while in v3 it moved to 0x80a0000 and 0x8010000 is empty.
The original source does not mention GICv3 anywhere, only pl390, which is a specific GIC model that predates the GICv2 spec I believe.
TODO if I hack #define GIC_GICC_BASE (GIC_BASE + 0xa0000)
, then it goes a bit further, but the next loop never ends.