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



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

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

我可以在使用go [adr]的u引导之外的cpu0上运行这两个程序,其中adr是任一程序的起始地址。我得到了uarts的预期输出。

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

我不启用任何缓存、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"one_answers"。"当我在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的独立库,我很难筛选出实际需要的内容。我需要一个最低限度的工作示例,这样我就可以将它移植到我们在第一个核心上运行的奇异操作系统。

事实证明cpu1不处于wfe状态。我想u-boot已经唤醒了它,尽管它没有使用它,即cpu1的状态不是smp。

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

链接应该死的步骤是:

  • 备份在接下来的步骤中被覆盖的寄存器
  • 恢复OCM区域中的WFE(等待事件(代码。(我使用了汇编,而不是显示的xilinx-xsct命令,因为我无法访问它们的IDE(:
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确实启动了,或者只是等待几个周期
  • 恢复备份的寄存器

最新更新