Separation of kernel and application virtual address spaces
Operating systems typically have several applications or tasks running concurrently. Each of these has its own unique set of translation tables and the kernel switches from one to another as part of the process of context switching between one task and another. However, much of the memory system is used only by the kernel and has fixed virtual to physical address mappings where the translation table entries rarely change. The ARMv8-A architecture provides several features to efficiently handle this requirement.
The table base addresses are specified in the Translation Table Base Registers (TTBR0_EL1) and (TTBR1_EL1). The translation table pointed to by TTBR0 is selected when the upper bits of the virtual address (VA) are all set to 0. TTBR1 is selected when the upper bits of the VA are all set to 1. You can enable VA tagging to exclude the top 8 bits from the check.
The virtual address from the processor of an instruction fetch or data access is 64 bits. However, you must map both of the two regions that are defined within a single 48-bit physical address memory map.
EL2 and EL3 have a TTBR0, but no TTBR1. This means that is either EL2 or EL3 is using AArch64, they can only use virtual addresses in the range 0x0 to 0x0000FFFF_FFFFFFFF.
The following figure shows an example of how the kernel space can be mapped to the most significant area of memory while the virtual address space associated with each application can be mapped to the least significant area of memory. However, both of these can be mapped to a much smaller physical address space, as the following figure shows:
The Translation Control Register TCR_EL1 defines the exact number of most significant bits that are checked. TCR_EL1 contains the size fields T0SZ[5:0] and T1SZ[5:0]. The integer in the field gives the number of the most significant bits that must be either all 0s or all 1s. There are specified minimum and maximum values for these fields, which vary with granule size and starting table level. Therefore, you must always use both spaces and at least two translation tables are required in all systems. A simple bare metal system without an OS still requires a small upper table that contains only fault entries. This is shown in the following figure:
TCR_EL1 controls other memory management features at EL1 and EL0. The following figure shows only those fields that control address ranges and granule size.
The Intermediate Physical Address Size (IPS) field controls the maximum output address size. If translations specify output addresses outside this range, then access is faulted, 000=32 bits of physical address, 101=48 bits. The two-bit Translation Granule (TG) TG1 and TG0 fields give the granule size for kernel or user space respectively, 00=4KB, 01=16KB, 11=64KB. The size of the Translation Granule indicates the smallest block of memory that can be independently mapped in the translation tables.
You can configure the level of translation table that is used for the first lookup. The full translation process can require three or four levels of tables. You need not implement all levels. The first level of lookup is, in effect, determined by the granule size and TCR_ELn.TxSZ fields. You can configure it separately for TTBR0_EL1 and TTBR1_EL1.