You copied the Doc URL to your clipboard.

Translating a virtual address to a physical address

When the processor issues a virtual address for an instruction fetch, or data access, the MMU hardware translates the virtual address to the corresponding physical address. For a virtual address in an n -bit address space, the top 64-n bits VA[63:n] must be all 0s or 1s, otherwise the address triggers a fault.

The least significant bits are then used to give an offset within the selected section, so that the MMU combines the physical address bits from the block table entry with the least significant bits from the original address to produce the final address.

In a simple address translation involving only one level of look-up, and assumes that we are using a 64KB granule with a 42-bit virtual address space. The MMU translates a virtual address as follows:

  1. If VA[63:42] = 1 then TTBR1 is used for the base address for the first translation table. When VA[63:42] = 0, TTBR0 is used for the base address for the first translation table.
  2. The translation table contains 8192 ×64-bit translation table entries, and is indexed using VA[41:29]. The MMU reads the pertinent Level 2 translation table entry from the table.
  3. The MMU checks the translation table entry for validity and whether the requested memory access is allowed. Assuming it is valid, the memory access is allowed.
  4. In the following figure, the translation table entry refers to a 512MB page (it is a block descriptor).
512_block_translation.png

Bits [47:29] are taken from this translation table entry and form bits [47:29] of the physical address.

  1. Because we have a 512MB page, bits [28:0] of the VA are taken to form PA[28:0].

The full PA[47:0] is returned, along with additional information from the translation table entry.

In practice, such a simple translation process severely limits how finely the address space can be divided.

Instead of using only this first-level translation table, a first-level table entry can also point to a second-level translation table. In this way, an OS can further divide a large section of virtual memory into smaller pages. For a second-level table, the first-level descriptor contains the physical base address of the second-level translation table. The physical address that corresponds to the virtual address requested by the processor is found in the second-level descriptor.

The following figure shows an example of translation for a 64KB granule starting at stage 1, level 2 for a normal 64KB page. It describes a situation where there are two levels of look-up. Again, this assumes a 64KB granule and 42-bit virtual address space.

64kb_translation.png

Each second-level table is associated with one or more first-level entries. You can have multiple first-level descriptors that point to the same second-level table, which means you can alias several virtual locations to the same physical address.

  1. If VA[63:42] = 1 then TTBR1 is used for the base address for the first translation table. When VA[63:42] = 0, TTBR0 is used for the base address for the first translation table.
  2. The translation table contains 8192 64-bit translation table entries, and is indexed via VA[41:29]. The MMU reads the pertinent level 2 translation table entry from the table.
  3. The MMU checks the level 2 translation table entry for validity and whether the requested memory access is allowed. Assuming it is valid, the memory access is allowed.
  4. In the figure, the level 2 translation table entry refers to the address of the level 3 translation table (it is a table descriptor).
  5. Bits [47:16] are taken from the level 2 translation table entry and form the base address of the level 3 translation table.
  6. Bits [28:16] of the VA are used to index the level 3 translation table entry. The MMU reads the pertinent level 3 translation table entry from the table.
  7. The MMU checks the level 3 translation table entry for validity and whether the requested memory access is allowed. Assuming it is valid, the memory access is allowed.
  8. In the figure, the level 3 translation table entry refers to a 64KB page (it is a page descriptor).
  9. Bits [47:16] are taken from the level 3 translation table entry and used to form PA[47:16].
  10. Because there is a 64KB page, VA[15:0] is taken to form PA[15:0].
  11. The full PA[47:0] is returned, along with additional information from the translation table entries.

Secure and Non-secure addresses

The ARM architecture defines two physical address spaces. A Secure address space and a Non-secure address space. In theory the Secure and Non-secure physical address spaces are independent of each other, and exist in parallel. A system could be designed to have two entirely separate memory systems. However, most real systems treat Secure and Non-secure as an attribute for access control. The Normal (Non-secure) world can only access the Non-secure physical address space. The Secure world can access both physical address spaces when the MMU is enabled. This is controlled through translation tables.

This also has cache coherency implications. For example, because Secure 0x8000 and Non-secure 0x8000 are, technically speaking, different physical addresses, they could both be in the cache at the same time.

In a system where Secure and Non-secure memory are in different locations, there would be no problem. It is more likely that they would be in the same location. Ideally a memory system would block Secure accesses to Non-secure memory and Non-secure accesses to Secure memory.

In practice most only block Non-secure access to Secure memory. Again, this means you could end up with the same physical memory in the cache twice, Secure, and Non-secure. This is always a programming error. To avoid this the Secure world must always use Non-secure accesses to Non-secure memory.

secure_nonsecure.png

Multiple virtual address spaces

At any one time, only one virtual address space is being used (that for the current security state Exception level). However, conceptually, because there are three different TTBRs, there are three parallel virtual address spaces (EL0/1, EL2, and EL3).

virtual_address_spaces.png

You can also have a Secure and Non-secure EL1/0. However, there is only one physical set of TTBR0_EL1, TTBR1_EL1 and TCR_EL1. So when switching between worlds, the Secure monitor has to save and restore these registers.

Operation when the Memory Management Unit is disabled

When the MMU is enabled the translation tables control the memory type and attributes of memory. When the MMU is not enabled, such as immediately after reset, memory takes a default type.

The default type used for instruction fetches is Normal memory with a cacheability attribute controlled by SCTLR_ELx.I:

  • When I=0, fetches use the Non-cacheable and Outer Shareable attributes.
  • When I=1, the Cacheable, Inner Write-Through Read-Allocate No Write-Allocate, Outer Write-Through Read-Allocate No Write-Allocate Outer Shareable attribute is used.

In systems that use virtualization it might be necessary to allow the Hypervisor to override the default memory types used by guests. When the stage 1 MMU is disabled, for Non-secure EL0 and EL1 accesses when the HCR_EL2.DC bit is set to enable the data cache, the default memory type is Normal, Non-shareable, Inner Write-Back, read and Write Allocate, Outer Write-Back read and Write Allocate. This might be useful in situations where caches have already been configured by a Hypervisor.

Configuring and enabling the MMU

Writes to the system registers controlling the MMU are context-changing events and there are no ordering requirements between them. The results of these events are not guaranteed to be seen until a context synchronization event.

MSR TTBR0_EL1, X0			// Set TTBR0
MSR TTBR1_EL1, X1			// Set TTBR1
MSR TCR_EL1, X2			  // Set TCR
ISB					 // The ISB forces these changes to be 
					    // seen before the MMU is enabled.
MRS X0, SCTLR_EL1			// Read System Control Register 
					    // configuration data 
ORR X0, X0, #1			   // Set [M] bit and enable the MMU.
MSR SCTLR_EL1, X0			// Write System Control Register 
					    // configuration data 
ISB					 // The ISB forces these changes to be 
					    // seen by the next instruction

This is separate from the requirement for flat mapping, which is to make sure that we know which instruction is executed directly after the write to SCTLR_EL1.M. If we see the result of the write it is the instruction at VA+4 using the new translation regime. If the result is not seen, it is still the instruction at VA+4 but where the VA = PA. The ISB does not help here as it cannot be guaranteed to be the next instruction that is executed unless memory is flat mapped.

Was this page helpful? Yes No