Zynq 7000: минимальный asm-код для инициализации cpu1 из cpu0 - PullRequest
3 голосов
/ 26 марта 2020

Я пытаюсь выяснить минимальные требования для инициализации cpu1 из cpu0 в конфигурации усилителя на zynq-7000.

У меня есть заданный FSBL, который передается на u-boot, с которой я копирую обе программы (cpu0 / 1) из fla sh в разные места в ram (с sf read ...).

Я могу запустить обе программы на cpu0 из u-boot с go [adr], где adr - это начальный адрес любой программы. Я получаю ожидаемый вывод на уартс.

Что не работает, так это то, что cpu0 должен запустить cpu1, записав свой начальный адрес в регистр 0xffff_fff0 и после этого выдав системное событие 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» и «.» на uart 1, когда я запускаю приведенный выше код на процессоре 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 */

Здесь я вижу «1» на uart 0, когда я запускаю его на процессоре 0.

новичок в этом, и я немного растерялся. Я что-то упустил? Что я могу попытаться заставить это работать?

Я смотрел на xapp-1079, но он использует автономные библиотеки Xilinx, и мне очень сложно отфильтровать то, что действительно нужно. Мне нужен минимальный рабочий пример, чтобы я мог портировать его на exoti c OS, которую мы запускаем на первом ядре.

1 Ответ

0 голосов
/ 16 апреля 2020

Оказалось, что процессор1 не был в состоянии wfe. Я полагаю, что u-boot уже разбудил его, хотя он не использовал его, то есть состояние cpu1 не было smp.

Мне пришлось выполнить сброс программного обеспечения на процессоре 1 и вернуть его в состояние wfe, прежде чем выдача команды sev в соответствии с AR # 53828 из xilinx .

Шаги для ссылки d ie:

  • Резервное копирование регистров, которые перезаписываются в следующих шагах.
  • Восстановите код WFE (ожидание события) в области OCM. (Я использовал ассемблер вместо показанных команд 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, которая получает процессор из 0x0 в область wfe в 0xffffff00:
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.
  • Issue sev.
  • Убедитесь, что cpu1 действительно запущен, или просто подождите несколько циклов.
  • Восстановите резервные регистры.
...