I'm trying to figure out the minimum requirements to initialize cpu1 from cpu0 in an amp configuration on a zynq-7000.
I have a given FSBL that hands over to u-boot with which I copy both programs (cpu0/1) from flash to different locations in ram (with sf read ...
).
I can run both programs on cpu0 out of u-boot with go [adr]
where adr is the start address of either program. I get the expected output on the uarts.
What does not work is that cpu0 should start cpu1 by writing its start address to register 0xffff_fff0
and after that issuing a system event sev
.
I do not enable any caches, MMUs or the SCU because I want to keep it as simple as possible (no synchronizations or flushes) until I achieved to start up cpu1. Or is this actually the problem and I do need any of these?
Currently I only initialize the vector table, print to the uart and additionally for core 0 try to start core 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 */
I can see the '0' and the '.' on uart 1 when I run the above code on cpu 0.
/* 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 */
Here I can see the '1' on uart 0 when I run it on cpu 0.
I'm new to this and I'm a bit lost. Am I missing something fundamental? What can I try to get this to work?
I've been looking at xapp-1079 but this uses Xilinx' Standalone Libs and it's very difficult for me to filter out what is actually needed. I need a minimum working example so that I can port it to the exotic OS that we run on the first core.