Hello,
I'm trying to get MMU working on Cortex-A53. But still fails since at least 3 days. :(
I created following tables:
Level 1
0 0000000010006003 1 0000000010007003 2 0000000010008003 3 0000000010009003 4 000000001000a003 5 0000000000000000 [...] 511 0000000000000000
Level 2
Table 0 @ 0x10006000 (DDR RAM)
0 0000000000000701 1 0000000000200701 [...] 510 000000003fc00701 511 000000003fe00701
Table 1 @ 0x10007000 (DDR RAM)
0 0000000040000701 1 0000000040200701 [...] 510 000000007fc00701 511 000000007fe00701
Table 2 @ 0x10008000T (DDR RAM)
0 0000000080000701 1 0000000080200701 [...] 510 00000000bfc00701 511 00000000bfe00701
Table 3 @ 0x10009000 (DDR RAM)
0 00000000c0000701 1 00000000c0200701 [...] 503 00000000fee00701 504 0000000000000000 [...] 511 0000000000000000
Table 3 @ 0x1000a000 (Memory-Mapped Devices)
0 00000000ff000705 1 00000000ff200705 [...] 7 00000000ffe00705 8 0000000000000000 [...] 511 0000000000000000
The relevant setup for setup the pagetable:
ldr x1, =0x3519 msr TCR_EL2, x1 mov x1, 0x00FF msr MAIR_EL2, x1 ldr x1, =_tlb_el2_tbb0_lv1 msr TTBR0_EL2, x1 mov x8, xzr dsb sy ret
The relevant code for enabling the MMU:
__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 nop nop nop nop
I'm using U-Boot as bootloader (starting at EL2).
Have I something misunderstood? Have also tried several configurations. But still fails.
I have finally solved it.
Unfortunately I didn't understand the translation table and the required settings.
Now my current setup for EL2: Bare-Metal application is at 0x80000000 with a size of 512MiB defined in the linker script.
0x80000000
Extract from my current linker script:
ENTRY(_start) MEMORY { RAM_KERN (rwx) : ORIGIN = 0x80000000, LENGTH = 512M } STACK_EL3 = 4K; STACK_EL2 = 4K; STACK_EL1 = 64M; STACK_EL0 = 1M;
Some settings for TCR_EL2: Currently I use a 1TiB range for TOSZ (0x17), so i also have a level 0 table with only one entry. But decrease this value later. I use 4KiB granule for the tables.
TCR_EL2
TOSZ
0x17
Level 0: Contains only one entry at index 0 which points to the first (and only) level 1 table. All other entries are invalid (zero).
Level 1 (Index 0): These table contains two valid table entries. Because the bare-metal application starts at 0x80000000, the first 1GiB entries are currently invalid. So there is the bare-metal application at index 2. Index 3 in the level contains the entry to the MMIO table. All other subsequent entries are invalid.
Level 2 (Bare-Metal application): These table contains 256 2MiB block entries because in linker script i defined 512MiB for the application. Start point is index 0 of the level 2 table. The subsequent entries (256) are invalid.
Level 2 (MMIO devices): These table contains 8 2MiB block entries starting at index 503, because the IO is mapped at start point 0xFF000000. The first 502 entries are currently invalid.
0xFF000000
Now I can successfully enable the MMU.