AArch64 (Cortex-A53) - Понимание таблицы перевода

Я пытаюсь понять таблицу перевода из Cortex-A53. В настоящее время безуспешно. Не могу включить MMU. Я хотел бы знать, как правильно настроить MMU. Попробовали это руководство от ARM. .

Соответствующий код (включение):

__el2_cache:
    mrs x0, SCTLR_EL2
    bic x0, x0, #(1 << 0)  /* Disable MMU */
    bic x0, x0, #(1 << 2)  /* Disable D-Cache */
    bic x0, x0, #(1 << 12) /* Disable I-Cache */
    msr SCTLR_EL2, x0
    isb

    /* Invalidate and clean I/D-Cache */
    bl _cpu_icache_invalidate
    bl _cpu_dcache_l1_invalidate
    bl _cpu_dcache_l2_invalidate
    
__el2_pagetable:
    /* Create pagetable for EL2 */
    bl _cpu_el2_tlb_create
    
    /* Invalidate (old) Pagetable */
    tlbi ALLE2
    dsb sy
    isb
    
    mrs x0, SCTLR_EL2
    orr x0, x0, #(1 << 0)  /* Enable MMU */
    orr x0, x0, #(1 << 2)  /* Enable D-Cache */
    orr x0, x0, #(1 << 12) /* Enable I-Cache */
    msr SCTLR_EL2, x0 
    isb /* <-- CPU hangs here */
    nop
    nop
    nop
    nop

Это также не работает, когда я не включаю кеши. код в вызове подпроцедуры для аннулирования кеши также основаны на учебнике ARM.

Я создаю таблицу перевода в _cpu_el2_tlb_create и устанавливаю соответствующие регистры:

    ldr x1, =0x80803520
    msr TCR_EL2, x1
    ldr x1, =0x4400FF00
    msr MAIR_EL2, x1
    ldr x1, =_tlb_el2_tbb0_lv1
    msr TTBR0_EL2, x1
    mov x8, xzr
    dsb sy
    ret

Использовали ту же настройку (тип памяти, совместно используемая и т. д.), что и U-Boot, но все равно не работает.

_cpu_el2_tlb_create создает следующие таблицы:

Level 1          Level 2
0000000010006003 0000000000000711 0000000040000711 0000000080000711 00000000c0000711 00000000ff000401  
0000000010007003 0000000000200711 0000000040200711 0000000080200711 00000000c0200711 00000000ff200401     
0000000010008003 0000000000400711 0000000040400711 0000000080400711 00000000c0400711 00000000ff400401
0000000010009003 0000000000600711 0000000040600711 0000000080600711 00000000c0600711 00000000ff600401
000000001000a003 0000000000800711 0000000040800711 0000000080800711 00000000c0800711 00000000ff800401
0000000000000000 0000000000a00711 0000000040a00711 0000000080a00711 00000000c0a00711 00000000ffa00401
0000000000000000 0000000000c00711 0000000040c00711 0000000080c00711 00000000c0c00711 00000000ffc00401
0000000000000000 0000000000e00711 0000000040e00711 0000000080e00711 00000000c0e00711 00000000ffe00401
0000000000000000 0000000001000711 0000000041000711 0000000081000711 00000000c1000711 0000000000000000
[...]
0000000000000000 000000003ee00711 000000007ee00711 00000000bee00711 00000000fee00711 0000000000000000
0000000000000000 000000003f000711 000000007f000711 00000000bf000711 0000000000000000 0000000000000000
0000000000000000 000000003f200711 000000007f200711 00000000bf200711 0000000000000000 0000000000000000
0000000000000000 000000003f400711 000000007f400711 00000000bf400711 0000000000000000 0000000000000000
0000000000000000 000000003f600711 000000007f600711 00000000bf600711 0000000000000000 0000000000000000
0000000000000000 000000003f800711 000000007f800711 00000000bf800711 0000000000000000 0000000000000000
0000000000000000 000000003fa00711 000000007fa00711 00000000bfa00711 0000000000000000 0000000000000000
0000000000000000 000000003fc00711 000000007fc00711 00000000bfc00711 0000000000000000 0000000000000000
0000000000000000 000000003fe00711 000000007fe00711 00000000bfe00711 0000000000000000 0000000000000000

TTBR0_EL2 также указывает на правильное местоположение и соответствует выравниванию 4 КБ.

Карта памяти с б/у платы:

0x00000000 - 0xFF000000 DDR-RAM
0xFF000000 - 0xFFFF0000 Memory-Mapped I/O

person krjdev    schedule 22.01.2021    source источник
comment
Почему у вас есть запись 000000001000a003 в вашей таблице L1? При T0SZ=32 это выходит за пределы вашего виртуального адресного пространства.   -  person Siguza    schedule 22.01.2021
comment
@Siguza Спасибо за эту подсказку. Я сделал, может быть, ужасную ошибку с генерацией таблиц. Возможна ошибка при создании таблицы. Таблица уровня 1 является фактической таблицей уровня 0. Таблица уровня 0 указывает на таблицы уровня 2 объемом 2 МБ. Но должны быть записи 1GiB. Но я должен проверить эту ошибку.   -  person krjdev    schedule 22.01.2021
comment
Имейте в виду, что с T0SZ=32 у вас не будет таблицы L0...   -  person Siguza    schedule 23.01.2021
comment
@Siguza Хотя я вас понимаю, если TOSZ = 32, я могу пропустить таблицу уровня 0 и настроить TBBR0_EL2 на таблицу уровня 1?   -  person krjdev    schedule 23.01.2021


Ответы (1)


Я решил проблему.

К сожалению, я не разобрался с таблицей перевода и необходимыми настройками.

Теперь моя текущая настройка для EL2:
приложение Bare-Metal имеет размер 0x80000000 и размер 512 МиБ, определенный в скрипте компоновщика.

Выдержка из моего текущего скрипта компоновщика:

ENTRY(_start)

MEMORY {
    RAM_KERN (rwx) : ORIGIN = 0x80000000, LENGTH = 512M
}

STACK_EL3 = 4K;
STACK_EL2 = 4K;
STACK_EL1 = 64M;
STACK_EL0 = 1M;

Некоторые настройки для TCR_EL2:
В настоящее время я использую диапазон 1 ТБ для TOSZ (0x17), поэтому у меня также есть таблица уровня 0 только с одной записью. Но уменьшите это значение позже. Спасибо @Siguza за эту подсказку. Я использую гранулы 4KiB для таблиц.

Уровень 0:
Содержит только одну запись с индексом 0, которая указывает на первую (и единственную) таблицу уровня 1. Все остальные записи недействительны (ноль).

Уровень 1 (индекс 0):
Эта таблица содержит две допустимые записи таблицы. Поскольку пустое приложение начинается с 0x80000000, первые записи 1 ГиБ в настоящее время недействительны. Таким образом, приложение с индексом 2 находится на «голом железе». Индекс 3 уровня содержит запись в таблицу MMIO. Все остальные последующие записи недействительны.

Уровень 2 (приложение Bare-Metal):
Эта таблица содержит 256 записей блоков размером 2 МиБ, поскольку в скрипте компоновщика я определил для приложения 512 МиБ. Начальной точкой является индекс 0 таблицы уровня 2. Последующие записи (256) недействительны.

Уровень 2 (устройства MMIO):
Эта таблица содержит 8 записей блоков размером 2 МиБ, начиная с индекса 503, поскольку ввод-вывод сопоставляется с начальной точкой 0xFF000000. Первые 502 записи в настоящее время недействительны.

Теперь я могу успешно включить MMU.

person krjdev    schedule 23.01.2021