|
| static void | set_page_table_entry_address (table_desc_t *entry, const phy_addr phys_addr) |
| | Set the physical Next-Level Table Address (NLTA) in a table descriptor.
|
| |
| static void | set_page_desc_entry_address (page_desc_t *entry, const phy_addr phys_addr) |
| | Set the physical Output Address (OA) in a block or page data descriptor.
|
| |
| static phy_addr | get_page_table_entry_address (const table_desc_t *entry) |
| | Get the physical address from a page table entry.
|
| |
| static bool | check_table_permissions (const table_desc_t *entry, const page_permissions_t perms) |
| | Checks if a table descriptor's hierarchical permissions allow the requested page permissions.
|
| |
| static void | print_indent (int level) |
| | Helper to generate visual indentation based on the current tree depth.
|
| |
| static void | page_table_init (page_table_t *table) |
| | Initialize a page table.
|
| |
| static void | set_next_level_table (page_table_entry_t *entry, phy_addr next_table_addr) |
| | Set the next level table address in a page table entry union.
|
| |
| static bool | allocate_new_table (table_desc_t *entry) |
| | Allocate and zero-initialize a new page table, then install it as the next level table in the entry.
|
| |
| static page_table_t * | get_next_level_table (table_desc_t *entry, const page_permissions_t perms) |
| | Get the next level table from a page table entry, allocating it on demand if the entry is not yet valid.
|
| |
| static bool | map_mem_region (memory_region_t *region, page_table_t *root_table) |
| | Maps one physical region into the higher-half kernel map.
|
| |
| void | print_page_descriptor (const page_desc_t desc) |
| | Pretty-prints the contents of a Stage 1 Block/Page descriptor.
|
| |
| void | print_table_descriptor (const table_desc_t desc) |
| | Pretty-prints the contents of a Stage 1 Table descriptor (Levels 0, 1, or 2).
|
| |
| void | print_page_table_tree (const page_table_entry_t *table_base, int current_level, uint64_t base_va) |
| | Recursively prints the structure of the page table tree starting from a given base table.
|
| |
| bool | map_page (page_table_t *root, const virt_addr v_addr, const phy_addr phy_addr, const page_permissions_t perms, const mem_type_t mem_type) |
| | Map a virtual address to a physical address in the page table.
|
| |
| void | dump_memory_map (page_table_t *root) |
| | Dump the memory map for debugging.
|
| |
| bool | setup_kernel_id_map (phy_addr serial_device_addr_base) |
| | Set up the initial identity-mapped region for the kernel.
|
| |
| bool | setup_kernel_map (memory_map_t *const mmap) |
| | Set up the kernel's higher-half virtual-memory map.
|
| |
Page table support implementation for kernel virtual memory.
This module contains the kernel page table implementation used to manage virtual memory mappings and page table creation routines.
- Author
- Abhin Parekadan Jose
- Date
- 2026-05-17
AP[2:1] data access permission encodings for Stage 1 leaf descriptors.
Encodes the direct permissions written into bits [7:6] of a block or page descriptor. For a stage 1 translation supporting two Exception levels (Table D8-63, ARMv8/ARMv9 ARM):
+-------—+----------------------------------------—+ | AP[2:1] | Permissions | +-------—+----------------------------------------—+ | 0b00 | PrivRead, PrivWrite | | 0b01 | PrivRead, PrivWrite, UnprivRead, UnprivWrite | | 0b10 | PrivRead | | 0b11 | PrivRead, UnprivRead | +-------—+----------------------------------------—+
"Priv" == EL1 (kernel), "Unpriv" == EL0 (user).
| Enumerator |
|---|
| AP_PRIV_RW | [0b00] EL1 read/write. EL0 no access.
|
| AP_PRIV_UNPRIV_RW | [0b01] EL1 and EL0 read/write.
|
| AP_PRIV_RO | [0b10] EL1 read-only. EL0 no access.
|
| AP_PRIV_UNPRIV_RO | [0b11] EL1 and EL0 read-only.
|
Access Permission Table bits (APTable[1:0]) for Stage 1 Table Descriptors.
This hierarchical control restricts the maximum permissions allowed for all downstream block or page descriptors reachable through this table entry.
- Note
- These controls can only restrict permissions down the chain; they cannot grant more privileges than what a leaf L3 page descriptor specifies.
+---—+-------------------------—+-------------------------—+ |Value | EL0 (Unprivileged) | EL1 (Privileged) | +---—+-------------------------—+-------------------------—+ | 0b00 | No restriction | No restriction | | 0b01 | No Access | No restriction | | 0b10 | Read-Only (No write) | Read-Only (No write) | | 0b11 | No Access | Read-Only (No write) | +---—+-------------------------—+-------------------------—+
- Note
- APTable[0] is treated as 0 when virtualization is active and HCR_EL2.{NV,NV1} == {1,1}.
| Enumerator |
|---|
| APTABLE_EL0_NO_RESTRICTION_EL1_NO_RESTRICTION | [0b00] No downstream permission modifications applied.
|
| APTABLE_EL0_NO_ACCESS_EL1_NO_RESTRICTION | [0b01] APTable[0]=1: strip EL0 access entirely. EL1 unaffected.
|
| APTABLE_EL0_NO_WRITE_EL1_NO_WRITE | [0b10] APTable[1]=1: force read-only for all ELs.
|
| APTABLE_EL0_NO_ACCESS_EL1_NO_WRITE | [0b11] Highly restricted. EL0: No Access, EL1: Forced Read-Only.
|
SH[1:0] shareability domain encodings for Stage 1 leaf descriptors.
Written into bits [9:8] of a block or page descriptor. Controls which observers share the coherency domain for Normal memory accesses. For Device memory the shareability is always Outer Shareable regardless of this field.
+-----—+---------------—+ | SH[1:0]| Domain | +-----—+---------------—+ | 0b00 | Non-shareable | | 0b01 | RESERVED | | 0b10 | Outer Shareable | | 0b11 | Inner Shareable | +-----—+---------------—+
| Enumerator |
|---|
| SH_NON_SHAREABLE | [0b00] Non-shareable — no coherency requirement with other observers.
|
| SH_RESERVED | [0b01] RESERVED — must not be used.
|
| SH_OUTER_SHAREABLE | [0b10] Outer Shareable — coherent with the outer shareability domain (typically all CPUs + GPU + DMA-capable devices).
|
| SH_INNER_SHAREABLE | [0b11] Inner Shareable — coherent within the inner shareability domain (typically all CPUs in the same cluster).
|