This post illustrates ARM virtual - physical memory translation. Based on TCC8900.
TCC8900 built based on ARM1176JZF-S, ARM’s proprietary RISC CPU core. The ARM1176JZF-S processor incorporates an integer core that implements the ARM11 ARM architecture v6.
The ARM MMU supports memory accesses based on SECTIONs or PAGEs.
The MMU translates virtual addresses generated by CPU into physical addresses to access external memory, and also derives and checks the access permission.
A translation starts with a first level fetch. A SECTION-mapped access only requires a first-level fetch, whereas a PAGE-mapped access also requires a seconds-level fetch.
The translation table held in main memory has two levels:
FIRST-LEVEL table: Holds section translations, and pointers to second-level tables.
SECOND-LEVEL table: Hold both page translation.
Since 'A translation starts with a first level fetch', the first thing we need to know is the start address of the first-level table. ARM put the physical address of the base of the first-level table into TTBR (Translation Table Base Register, CP15 register 2). Only bits[31:14] are significant, and bits[13:0] should be zero(SBZ). This means the first-level table must reside on a 16KB boundary. (14bits = 0x4000 = 16KB).
BTW, ARM also specified that the default fist-level table must reside at 0xc00fc000, Linux store this address in variable swapper_pg_dir.
The translation process:
A. Locate a first-level entry
Bits[31-14] of the TTBR are concatenated with bit[31:20] of the virtual address and two ZERO bits to produce a 32-bits physical address. This address select a four-bytes table entry
B. First-level fetch.
Get the value resides in above address. We call this four-bytes long data first-level descriptor. Depending on the bits[1:0] of the descriptor, it be:
a section descriptor for a 1MB section.
OR
a pointer to a second-level page table.
See below figure for details of the first-level descriptor format.
C.1 Section translation
If bits[1:0] equal 0b10, the first-level descriptor is a 1MB section-descriptor. Then concatenate the section base address (bits[31:20] of the section-descriptor) with the section index(bits[19:0] of the virtual address. This 4-bytes long is the physical address of the given virtual address.
C.2 Locate the second-level descriptor
If bits[1:0] equal 0b01, the first-level descriptor is a page table descriptor. Concatenates the page table base address ( bits[31:10] of the page table-descriptor) with the second-level table index (bits[19:12] of the virtual address and two ZEROs to get the address of the second-level descriptor.
C.2.1 Second-level fetch.
Get the value resides in above address, This is a second-level descriptor.
C.2.2 Page translation
Concatenates the page base address (bits[31:12] of the second-level descriptor with the page-index (bits[11:0] of the virtual address. This is the physical address of the given virtual address.