Я бил головой об этом в течение последних 3-4 дней, и я не могу найти объяснительную документацию DECENT (от ARM или неофициальную), чтобы помочь мне. У меня есть плата ODROID-XU (большая. LITTLE 2 x Cortex-A15 + 2 x Cortex-A7), и я пытаюсь понять немного больше об архитектуре ARM. В моем "экспериментирующем" коде теперь я пришел на сцену, где я хочу ОБРАТИТЬ ДРУГИЕ КОРЫ ИЗ ИХ WIF (ожидания для прерывания).
Отсутствующая информация, которую я все еще пытаюсь найти, это:
1. При получении базового адреса GIC-карты GIC я понимаю, что мне нужно прочитать CBAR; Но никакая часть документации не объясняет, как биты в CBAR (2 значения PERIPHBASE) должны быть организованы, чтобы добраться до конечного базового адреса GIC
2. При отправке SGI через регистр GICD_SGIR, какой идентификатор прерывания между 0 и 15 должен выбрать? Это имеет значение?
3. При отправке SGI через регистр GICD_SGIR, как я могу рассказать о других ядрах ГДЕ НАЧАТЬ ИСПОЛНЕНИЕ ОТ?
4. Как влияет на этот контекст тот факт, что мой код загружен загрузчиком U-BOOT?
Руководство по программированию Cortex-A v3.0 (найдено здесь: ссылка) гласит следующее в разделе 22.5. 2 (загрузка SMP в Linux, страница 271):
В то время как основное ядро загружается, вторичные ядра будут находиться в режиме ожидания, используя Инструкция WFI. Он (первичное ядро) предоставит начальный адрес вторичным ядрам и разбудит их, используя Inter-Processor Interrupt (IPI), что означает SGI, сигнализированный через GIC
Как Linux это делает? Документация S не содержит никаких других подробностей относительно ". Она предоставит адрес запуска для вторичных ядер".
Мое разочарование растет, и я буду очень благодарен за ответы. Большое вам спасибо заранее!
ДОПОЛНИТЕЛЬНЫЕ ДАННЫЕ
Документация, которую я использую:
- Справочное руководство по архитектуре ARMv7-A & R
- Cortex-A15 TRM (техническое справочное руководство)
- Cortex-A15 MPCore TRM
- Руководство для программистов серии Cortex-A v3.0
- Спецификация архитектуры GICv2
Что я сделал сейчас:
- UBOOT загружает меня на 0x40008000; Я установил таблицы перевода (TTB), написал соответственно TTBR0 и TTBCR и отобразил 0x40008000 на 0x8000_0000 (2 ГБ), поэтому я также включил MMU
- Настройка обработчиков исключений моего собственного
- У меня есть функция Printf над последовательностью (UART2 на ODROID-XU)
Все вышеизложенное работает нормально.
То, что я пытаюсь сделать сейчас:
- Получить базовый адрес GIC = > в тот момент, когда я читаю CBAR, и я просто AND (&) его значение с 0xFFFF8000 и использовать это как базовый адрес GIC, хотя я почти уверен, что это не вправо
- Включить дистрибьютор GIC (со смещением 0x1000 от базового адреса GIC?), нажимая GICD_CTLR со значением 0x1
- Построить SGI со следующими параметрами: Group = 0, ID = 0, TargetListFilter = "Все CPU за исключением меня" и отправить его (записать) через регистр GICD_SGIR GIC
- Поскольку я не передал начальный адрес запуска для других ядер, ничего не происходит после всего этого
.... UPDATE....
Я начал смотреть на ядро Linux и исходные коды QEMU в поисках ответа. Вот что я узнал (пожалуйста, поправьте меня, если я ошибаюсь):
- При включении платы ВСЕ КОРЫ начинают выполнение из reset vector
- Компонент программного обеспечения (прошивки) выполняет WFI на вторичных ядрах и некоторый другой код, который будет действовать как протокол между этими вторичными ядрами и основным ядром, когда последний хочет снова разбудить их
- Например, протокол, используемый на плате EnergyCore ECX-1000 (Highbank), выглядит следующим образом:
**(1)** the secondary cores enter WFI and when
**(2)** the primary core sends an SGI to wake them up
**(3)** they check if the value at address (0x40 + 0x10 * coreid) is non-null;
**(4)** if it is non-null, they use it as an address to jump to (execute a BX)
**(5)** otherwise, they re-enter standby state, by re-executing WFI
**(6)** So, if I had an EnergyCore ECX-1000 board, I should write (0x40 + 0x10 * coreid) with the address I want each of the cores to jump to and send an SGI
Вопросы:
- 1. Что такое программный компонент, который делает это? Является ли это бинарным BL1, который я написал на SD-карте, или это U-BOOT?
- 2. Насколько я понимаю, этот программный протокол отличается от платы. Это так или зависит только от основного процессора?
- 3. Где я могу найти информацию об этом протоколе для одной платы ARM? - могу ли я найти его на официальном веб-сайте ARM или на веб-странице борта?