【问题标题】:QEMU/vExpress issue regarding SMP and U-boot关于 SMP 和 U-boot 的 QEMU/vExpress 问题
【发布时间】:2019-06-25 09:56:31
【问题描述】:

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

【问题讨论】:

    标签: qemu u-boot smp


    【解决方案1】:

    这听起来像是问题在于来宾代码不希望以 QEMU 启动它的方式启动。对于 vexpress,QEMU 有两种启动方式:

    1. 您启动 Linux 内核,我们在 vexpress bootrom 启动 Linux 内核时启动它,这是通过启动主 CPU 并将辅助 CPU 置于 WFI 循环中等待内核到达它希望它们到达的点开始
    2. 您启动一些“裸机”,我们通过一次启动所有 CPU 来启动它,并期望裸机映像将它们分类(即在其早期启动时有一些代码查看CPU ID 注册并将辅助 CPU 转移到保持循环中。

    如果您进行了裸机启动,但您的客户映像没有必要的代码来处理辅助 CPU,结果将是所有这些都尝试遵循主 CPU 代码路径,这是行不通的非常好(控制台输出的多个副本、奇怪的崩溃、其他混乱)。

    我不完全确定真正的硬件是如何做到这一点的,但这里的部分问题是 QEMU 没有在真正的硬件上模拟“配置控制器”微控制器,而且我们没有运行“启动Monitor” 硬件通常执行的软件/固件,因此 QEMU 的裸机映像必须做一些硬件上的工作,这些工作将由其中一个或另一个完成。

    【讨论】:

    • 谢谢 Peter,我会尝试修补 U-boot/vExpress 以正确管理 CPU 启动并将其作为 U-boot 补丁提交。
    【解决方案2】:

    我终于成功地在 Qemu/vExpress 上用多个 CPU 启动了 U-boot。 停止辅助 CPU 的方法类似于 Qemu 在启动 Linux 内核映像时所做的。

    只需在 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 1970-01-01
      • 1970-01-01
      • 2018-12-26
      • 2014-12-01
      • 2020-05-03
      • 1970-01-01
      相关资源
      最近更新 更多