有关SMP和U-boot的QEMU / vExpress问题

时间:2019-06-25 09:56:31

标签: qemu u-boot smp

很长一段时间以来,QEMU / vExpress和使用多个CPU内核的U-boot仍然存在问题(vExpress指的是ARM Cortex-A15 CPU)。在深入研究Qemu / U-boot代码之前,是否有人对此进行了进一步调查? (我准备进一步研究vExpress的引导代码,以尝试使第一个CPU以外的其他CPU停顿)。当前,听起来Qemu启动的U-boot实例数量与声明的CPU数量一样(使用-smp选项)。

2 个答案:

答案 0 :(得分:0)

这听起来好像是访客代码中的问题不希望QEMU启动它的方式启动。对于vexpress,QEMU有两种引导方式:

  1. 您启动一个Linux内核,当vexpress bootrom引导Linux内核时,我们将其启动,即通过启动主CPU并将辅助CPU置于WFI循环中,以等待内核达到其希望的状态。开始
  2. 您启动了“裸机”,我们通过一次启动所有CPU来启动,并期望裸机映像将它们清理掉(例如,在其早期启动中有一些代码可以查看CPU ID进行注册并将辅助CPU转移到保持循环中。

如果您执行裸机启动,但是您的来宾映像没有处理辅助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