33.10.3. ARM baremetal multicore

Examples:

./run --arch aarch64 --baremetal baremetal/arch/aarch64/no_bootloader/multicore_asm.S --cpus 2
./run --arch aarch64 --baremetal baremetal/arch/aarch64/no_bootloader/multicore_asm.S --cpus 2 --emulator gem5
./run --arch aarch64 --baremetal baremetal/arch/aarch64/multicore.c --cpus 2
./run --arch aarch64 --baremetal baremetal/arch/aarch64/multicore.c --cpus 2 --emulator gem5
./run --arch arm --baremetal baremetal/arch/arm/no_bootloader/multicore_asm.S --cpus 2
./run --arch arm --baremetal baremetal/arch/arm/no_bootloader/multicore_asm.S --cpus 2 --emulator gem5
# TODO not working, hangs.
# ./run --arch arm --baremetal baremetal/arch/arm/multicore.c --cpus 2
./run --arch arm --baremetal baremetal/arch/arm/multicore.c --cpus 2 --emulator gem5

Sources:

CPU 0 of this program enters a spinlock loop: it repeatedly checks if a given memory address is 1.

So, we need CPU 1 to come to the rescue and set that memory address to 1, otherwise CPU 0 will be stuck there forever!

Don’t believe me? Then try:

./run --arch aarch64 --baremetal baremetal/arch/aarch64/multicore.c --cpus 1

and watch it hang forever.

Note that if you try the same thing on gem5:

./run --arch aarch64 --baremetal baremetal/arch/aarch64/multicore.c --cpus 1 --emulator gem5

then the gem5 actually exits with gem5 simulate() limit reached as opposed to the expected:

Exiting @ tick 36500 because m5_exit instruction encountered

since gem5 is able to detect when nothing will ever happen, and exits.

When GDB step debugging, switch between cores with the usual thread commands, see also: Section 3.9, “GDB step debug multicore userland”.