很长一段时间以来,QEMU / vExpress和使用多个CPU内核的U-boot仍然存在问题(vExpress指的是ARM Cortex-A15 CPU)。在深入研究Qemu / U-boot代码之前,是否有人对此进行了进一步调查? (我准备进一步研究vExpress的引导代码,以尝试使第一个CPU以外的其他CPU停顿)。当前,听起来Qemu启动的U-boot实例数量与声明的CPU数量一样(使用-smp选项)。
答案 0 :(得分:0)
这听起来好像是访客代码中的问题不希望QEMU启动它的方式启动。对于vexpress,QEMU有两种引导方式:
如果您执行裸机启动,但是您的来宾映像没有处理辅助CPU所需的代码,则结果是它们所有人都尝试遵循主CPU的代码路径,但这不起作用很好(控制台输出的多个副本,奇怪的崩溃,其他混乱)。
我不完全确定真正的硬件是如何做到的,但是这里的部分问题是QEMU不能在真实的硬件上模拟“配置控制器”微控制器,并且我们不运行“引导”监视”软件/固件,通常使用硬件,因此QEMU的裸机映像必须执行某些工作,而其中的一项或多项工作将由硬件完成。
答案 1 :(得分:0)
我终于成功通过一个以上CPU在Qemu / vExpress上启动了U-boot。 停止辅助CPU的方法类似于启动Linux内核映像时Qemu的操作。
只需在U-boot根目录中应用以下补丁(已在版本> 2018上测试)
From bf0fb125a3d85a5f0a6d7da744ebf110fc7e0f47 Mon Sep 17 00:00:00 2001
From: Daniel Rossier <daniel.rossier@heig-vd.ch>
Date: Thu, 4 Jul 2019 13:06:39 +0200
Subject: [PATCH] ARM vExpress: stalling secondary CPUs when Qemu starts U-boot
Signed-off-by: Daniel Rossier <daniel.rossier@heig-vd.ch>
---
board/armltd/vexpress/Makefile | 3 +-
board/armltd/vexpress/lowlevel_init.S | 91 +++++++++++++++++++++++++++
2 files changed, 93 insertions(+), 1 deletion(-)
create mode 100644 board/armltd/vexpress/lowlevel_init.S
diff --git a/board/armltd/vexpress/Makefile b/board/armltd/vexpress/Makefile
index 2a659de012..9048f9b39e 100644
--- a/board/armltd/vexpress/Makefile
+++ b/board/armltd/vexpress/Makefile
@@ -3,5 +3,6 @@
# (C) Copyright 2000-2004
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-obj-y := vexpress_common.o
+obj-y := vexpress_common.o
+obj-y += lowlevel_init.o
obj-$(CONFIG_TARGET_VEXPRESS_CA15_TC2) += vexpress_tc2.o
diff --git a/board/armltd/vexpress/lowlevel_init.S b/board/armltd/vexpress/lowlevel_init.S
new file mode 100644
index 0000000000..dca03d9606
--- /dev/null
+++ b/board/armltd/vexpress/lowlevel_init.S
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Daniel Rossier <daniel.rossier@heig-vd.ch>
+ */
+
+#include <config.h>
+
+/*
+ * Routine: save_boot_params (called after reset from start.S)
+ * Description: check the running CPU and stall it if not running on
+ * the primary CPU.
+ * This allows U-boot to run on Qemu/vExpress with a number of CPU
+ * greater than 1 (-smp > 1)
+ */
+
+.global save_boot_params
+
+/*
+ * The stalling code is mainly based on the bootcode portion (smpboot)
+ * from Qemu.
+ */
+__start:
+stall_secondary_cpu:
+ ldr r2, GIC_CPU_IF
+ ldr r0, BOOT_REG
+ mov r1, #1
+ str r1, [r2]
+ mov r1, #0xff
+ str r1, [r2, #4]
+ dsb sy
+
+__wfi:
+ wfi
+ ldr r1, [r0]
+ tst r1, r1
+ beq __wfi
+ bx r1
+ @ Never reach this point
+
+ @ GIC CPI IF address
+GIC_CPU_IF:
+ .word 0x2c002000
+
+@ Store the entry point used at CPU wake-up
+BOOT_REG:
+ .word 0x1c010030
+
+@ vExpress SRAM
+DEST_ADDR:
+ .word 0x14000000
+
+__end:
+
+save_boot_params:
+
+ @ Check if we are on the primary (CPU #0)
+ @ Read Multiprocessor ID register
+ mrc p15, 0, r0, c0, c0, 5
+ ands r0, r0, #0x3
+ beq out_primary
+
+ @ Relocate the code handling the secondary CPUs to SRAM
+ @ thus allowing U-boot to be relocated itself in the DRAM
+ @ without interfering with this code.
+
+ ldr r0, =__start
+ ldr r1, DEST_ADDR
+
+ ldr r2, __code_size
+
+relocate:
+
+ ldr r3, [r0], #1
+ str r3, [r1], #1
+
+ subs r2, r2, #1
+ bne relocate
+
+ @ Now, jump to the stalling code
+ ldr pc, DEST_ADDR
+
+out_primary:
+
+ /* Returns */
+ b save_boot_params_ret
+
+__code_size:
+ .word __end - __start
+
+
+
--
2.17.1