QEMUのRaspberry Pi 3モデルをベアメタルで使うと、デフォルトで4つのコアでロードしたコードが動いて不便なので、不要なコアを無理やり止めてみました。
QEMUは2.12を使いました。
コアの識別方法
Raspberry Pi 3には、Cortex-A53が4個載っています。 Cortex-A53で、コアを識別するには、各コアが持つ Multiprocessor Affinity Register (MPIDR_EL1) の下位8ビットを読めばよいです。詳しくはCoretex-A53のTRMをみてください。(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500g/BABHBJCI.html)
このレジスタを読むココードをインラインアセブラを使って書いてみました。
uint32_t get_core_id(void)
{
uint64_t id;
asm volatile("mrs %0, mpidr_el1" : "=r" (id));
id &= 0xff;
return id;
}
このレジスタは、circl64のブート部分 (https://github.com/rsta2/circle64/blob/master/lib/startup.S) を見ていて発見しました。
コアの止め方
とりあえず、不要なコアに対して、HALT命令を発行して止めました。
HALTはアセンブラで記述しました。
.section .text
.globl io_hlt
io_hlt:
wfe
ret
コアのIDが1-3だったら、io_hlt()を呼びます。
// disable core1 , core2 and core3
if (get_core_id() != 0) {
while (1) { io_hlt(); }
}
動作例
サンプルコード
void io_hlt(void);
void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags)
{
// disable core1 , core2 and core3
if (get_core_id() != 0) {
while (1) { io_hlt(); }
}
printf("core_id %u\n", get_core_id());
}
コアを止めないと、4コア分の表示がされます。
qemu-system-aarch64 -m 128 -M raspi3 -nographic -kernel kernel.elf
core_id 0
core_id 1
core_id 2
core_id 3
コアを止めると、表示が1回になります。
qemu-system-aarch64 -m 128 -M raspi3 -nographic -kernel kernel.elf
core_id 0
よくわからない
コアを止めない場合、4回出力されるのですが、idの値が変な場合が多々あります。
おそらくUARTデバイスをアクセスする際に競合がおきているんだと思われます。
qemu-system-aarch64 -m 128 -M raspi3 -nographic -kernel kernel.elf
core_id 3
core_id 1
core_id 1
core_id 0
qemu-system-aarch64 -m 128 -M raspi3 -nographic -kernel kernel.elf
core_id 3
core_id 0
core_id 0
core_id 0
/qemu-system-aarch64 -m 128 -M raspi3 -nographic -kernel kernel.elf
core_id 2
core_id 2
3
core_id 2
3
1
core_id 2
3
1
core_id 2