Zynq 7000:从cpu0初始化cpu1的最小asm代码

问题描述 投票:3回答:1

我试图找出在zynq-7000的放大器配置中从cpu0初始化cpu1的最低要求。

我有一个给定的FSBL,可以移交给u-boot,通过它我将两个程序(cpu0 / 1)从闪存复制到ram中的不同位置(使用sf read ...)。

我可以使用go [adr]在u-boot之外的cpu0上运行两个程序,其中adr是两个程序的起始地址。我在uart上获得了预期的输出。

[不起作用的是,cpu0应该通过将其起始地址写入寄存器0xffff_fff0并随后发出系统事件sev来启动cpu1。

我不启用任何高速缓存,MMU或SCU,因为我想使其尽可能简单(不进行同步或刷新),直到实现启动cpu1为止。还是这实际上是问题所在,我确实需要其中的任何一个吗?

当前,我只初始化向量表,打印到uart,另外,对于核心0,尝试启动核心1:

/* CPU 0 */
.section .vector_table, "x"
.global _init
_init:
    b reset     /* reset handler */
    b .         /* software interrupt */
    b .         /* prefetch abort */
    b .         /* data abort */
    b .         /* reserved */
    b .         /* irq */
    b .         /* fiq */

/* ASCII control chars */
.equ asciiLF, 0x0a
.equ asciiCR, 0x0d

.section .text
    uart1fifo: .word 0xe0001030     /* UART 1 rx/tx fifo register */

reset:
    /* Output "0" on UART 1 */
    ldr r0, uart1fifo
    mov r1, #'0'
    str r1, [r0]
    mov r1, #asciiCR
    str r1, [r0]
    mov r1, #asciiLF
    str r1, [r0]

    /* Set cpu1 start address */
    ldr r0, =0x20000000     /* CPU 1 start address */
    ldr r1, =0xfffffff0     /* Register to point to the CPU 1 start address */
    str r0, [r1]

    /* I added a 0.5s wait here which did not help */

    sev     /* Execute SEV to cause CPU 1 to wake up */

    /* Output "." on UART 1 to indicate that we actually went so far */
    ldr r0, uart1fifo
    mov r1, #'.'
    str r1, [r0]
    mov r1, #asciiCR
    str r1, [r0]
    mov r1, #asciiLF
    str r1, [r0]

    b .     /* Endless loop */

我可以看到'0'和'。'当我在CPU 0上运行上述代码时,在uart 1上运行。

/* CPU 1 */
.section .vector_table, "x"
.global _init
_init:
    b reset     /* reset handler */
    b .         /* software interrupt */
    b .         /* prefetch abort */
    b .         /* data abort */
    b .         /* reserved */
    b .         /* irq */
    b .         /* fiq */

/* ASCII control chars */
.equ asciiLF, 0x0a
.equ asciiCR, 0x0d

.section .text
    uart0fifo: .word 0xe0000030     /* UART 0 rx/tx fifo register */

reset:
    /* Output "1" on UART 0 */
    ldr r0, uart0fifo
    mov r1, #'1'
    str r1, [r0]
    mov r1, #asciiCR
    str r1, [r0]
    mov r1, #asciiLF
    str r1, [r0]

    b .     /* Endless loop */

在CPU 0上运行时,在uart 0上可以看到'1'。

我对此并不陌生,我有点迷茫。我缺少基本的东西吗?我怎样才能使它正常工作?

我一直在查看xapp-1079,但这使用了Xilinx的独立库,因此我很难筛选出实际需要的内容。我需要一个最低限度的工作示例,以便可以将其移植到我们在第一个内核上运行的特殊操作系统。

assembly armv7 zynq cortex-a
1个回答
0
投票

事实证明cpu1不在wfe状态。我想u-boot虽然没有使用它,但已经把它唤醒了,即cpu1的状态不是smp。

在根据sev发出AR#53828 from xilinx命令之前,我必须对cpu 1执行软件重置,并将其恢复为wfe状态。

链接应该消失的步骤是:

  • 备份在后续步骤中被覆盖的寄存器。
  • 在OCM区域中恢复WFE(等待事件)代码。 (由于我无法访问其IDE,因此我使用了汇编而不是所示的xilinx xsct命令):
mwr 0xFFFFFF00 0xe3e0000f
mwr 0xFFFFFF04 0xe3a01000
mwr 0xFFFFFF08 0xe5801000
mwr 0xFFFFFF0C 0xe320f002
mwr 0xFFFFFF10 0xe5902000
mwr 0xFFFFFF14 0xe1520001
mwr 0xFFFFFF18 0x0afffffb
mwr 0xFFFFFF1C 0xe1a0f002
  • 将跳转指令写入0x0,该指令将cpu1从0x0传送到0xffffff00处的wfe区域:
mwr 0x00000000 0xe3e0f0ff
  • 在cpu1上执行软件重置:
mwr 0xf8000008 0xdf0d    # slcr unlock
mwr 0xf8000244 0x2       # A9_RST1_ASSERT
mwr 0xf8000244 0x22      # A9_RST1_ASSERT | A9_CLKSTOP1
mwr 0xf8000244 0x20      # A9_CLKSTOP1
mwr 0xf8000244 0x0       # de-assert / start all
mwr 0xf8000004 0x767b    # slcr lock
  • 将cpu1的起始地址写入0xfffffff0
  • 问题sev
  • 确保cpu1实际启动或仅等待几个周期。
  • 还原备份的寄存器。
© www.soinside.com 2019 - 2024. All rights reserved.