1 /* 2 * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU) 3 * Licensed under the Mulan PSL v2. 4 * You can use this software according to the terms and conditions of the Mulan PSL v2. 5 * You may obtain a copy of Mulan PSL v2 at: 6 * http://license.coscl.org.cn/MulanPSL2 7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR 8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR 9 * PURPOSE. 10 * See the Mulan PSL v2 for more details. 11 */ 12 #ifndef ARCH_AARCH64_ARCH_MM_PAGE_TABLE_H 13 #define ARCH_AARCH64_ARCH_MM_PAGE_TABLE_H 14 15 #include <common/types.h> 16 17 #define INNER_SHAREABLE (0x3) 18 /* Please search mair_el1 for these memory types. */ 19 #define NORMAL_MEMORY (4) 20 #define NORMAL_MEMORY_NOCACHE (3) 21 #define DEVICE_MEMORY (0) 22 23 /* Description bits in page table entries. */ 24 25 /* Read-write permission. */ 26 #define AARCH64_MMU_ATTR_PAGE_AP_HIGH_RW_EL0_RW (1) 27 #define AARCH64_MMU_ATTR_PAGE_AP_HIGH_RO_EL0_RO (3) 28 29 /* X: execution permission. U: unprivileged. P: privileged. */ 30 #define AARCH64_MMU_ATTR_PAGE_UX (0) 31 #define AARCH64_MMU_ATTR_PAGE_UXN (1) 32 #define AARCH64_MMU_ATTR_PAGE_PXN (1) 33 34 /* Access flag bit. */ 35 #define AARCH64_MMU_ATTR_PAGE_AF_ACCESSED (1) 36 37 /* Non-secure bit */ 38 #define AARCH64_MMU_ATTR_PAGE_NS_NON_SECURE (1) 39 40 /* Present (valid) bit. */ 41 #define AARCH64_MMU_PTE_INVALID_MASK (1 << 0) 42 /* Table bit: whether the next level is aonther pte or physical memory page. */ 43 #define AARCH64_MMU_PTE_TABLE_MASK (1 << 1) 44 #define IS_PTE_INVALID(pte) (!((pte)&AARCH64_MMU_PTE_INVALID_MASK)) 45 #define IS_PTE_TABLE(pte) (!!((pte)&AARCH64_MMU_PTE_TABLE_MASK)) 46 47 /* PAGE_SIZE (4k) == (1 << (PAGE_SHIFT)) */ 48 #define PAGE_SHIFT (12) 49 #define PAGE_MASK (PAGE_SIZE - 1) 50 #define PAGE_ORDER (9) 51 52 #define PTP_INDEX_MASK ((1 << (PAGE_ORDER)) - 1) 53 #define L0_INDEX_SHIFT ((3 * PAGE_ORDER) + PAGE_SHIFT) 54 #define L1_INDEX_SHIFT ((2 * PAGE_ORDER) + PAGE_SHIFT) 55 #define L2_INDEX_SHIFT ((1 * PAGE_ORDER) + PAGE_SHIFT) 56 #define L3_INDEX_SHIFT ((0 * PAGE_ORDER) + PAGE_SHIFT) 57 58 #define GET_L0_INDEX(addr) (((addr) >> L0_INDEX_SHIFT) & PTP_INDEX_MASK) 59 #define GET_L1_INDEX(addr) (((addr) >> L1_INDEX_SHIFT) & PTP_INDEX_MASK) 60 #define GET_L2_INDEX(addr) (((addr) >> L2_INDEX_SHIFT) & PTP_INDEX_MASK) 61 #define GET_L3_INDEX(addr) (((addr) >> L3_INDEX_SHIFT) & PTP_INDEX_MASK) 62 63 #define PTP_ENTRIES (1UL << PAGE_ORDER) 64 /* Number of 4KB-pages that an Lx-block describes */ 65 #define L0_PER_ENTRY_PAGES ((PTP_ENTRIES) * (L1_PER_ENTRY_PAGES)) 66 #define L1_PER_ENTRY_PAGES ((PTP_ENTRIES) * (L2_PER_ENTRY_PAGES)) 67 #define L2_PER_ENTRY_PAGES ((PTP_ENTRIES) * (L3_PER_ENTRY_PAGES)) 68 #define L3_PER_ENTRY_PAGES (1) 69 70 /* Bitmask used by GET_VA_OFFSET_Lx */ 71 #define L1_BLOCK_MASK ((L1_PER_ENTRY_PAGES << PAGE_SHIFT) - 1) 72 #define L2_BLOCK_MASK ((L2_PER_ENTRY_PAGES << PAGE_SHIFT) - 1) 73 #define L3_PAGE_MASK ((L3_PER_ENTRY_PAGES << PAGE_SHIFT) - 1) 74 75 #define GET_VA_OFFSET_L1(va) ((va)&L1_BLOCK_MASK) 76 #define GET_VA_OFFSET_L2(va) ((va)&L2_BLOCK_MASK) 77 #define GET_VA_OFFSET_L3(va) ((va)&L3_PAGE_MASK) 78 79 // clang-format off 80 /* table format, which cannot be recognized by clang-format 1.10 */ 81 typedef union { 82 struct { 83 u64 is_valid : 1, 84 is_table : 1, 85 ignored1 : 10, 86 next_table_addr : 36, 87 reserved : 4, 88 ignored2 : 7, 89 PXNTable : 1, // Privileged Execute-never for next level 90 XNTable : 1, // Execute-never for next level 91 APTable : 2, // Access permissions for next level 92 NSTable : 1; 93 } table; 94 struct { 95 u64 is_valid : 1, 96 is_table : 1, 97 attr_index : 3, // Memory attributes index 98 NS : 1, // Non-secure 99 AP : 2, // Data access permissions 100 SH : 2, // Shareability 101 AF : 1, // Accesss flag 102 nG : 1, // Not global bit 103 reserved1 : 4, 104 nT : 1, 105 reserved2 : 13, 106 pfn : 18, 107 reserved3 : 2, 108 GP : 1, 109 reserved4 : 1, 110 DBM : 1, // Dirty bit modifier 111 Contiguous : 1, 112 PXN : 1, // Privileged execute-never 113 UXN : 1, // Execute never 114 soft_reserved : 4, 115 PBHA : 4; // Page based hardware attributes 116 } l1_block; 117 struct { 118 u64 is_valid : 1, 119 is_table : 1, 120 attr_index : 3, // Memory attributes index 121 NS : 1, // Non-secure 122 AP : 2, // Data access permissions 123 SH : 2, // Shareability 124 AF : 1, // Accesss flag 125 nG : 1, // Not global bit 126 reserved1 : 4, 127 nT : 1, 128 reserved2 : 4, 129 pfn : 27, 130 reserved3 : 2, 131 GP : 1, 132 reserved4 : 1, 133 DBM : 1, // Dirty bit modifier 134 Contiguous : 1, 135 PXN : 1, // Privileged execute-never 136 UXN : 1, // Execute never 137 soft_reserved : 4, 138 PBHA : 4; // Page based hardware attributes 139 } l2_block; 140 struct { 141 u64 is_valid : 1, 142 is_page : 1, 143 attr_index : 3, // Memory attributes index 144 NS : 1, // Non-secure 145 AP : 2, // Data access permissions 146 SH : 2, // Shareability 147 AF : 1, // Accesss flag 148 nG : 1, // Not global bit 149 pfn : 36, 150 reserved : 3, 151 DBM : 1, // Dirty bit modifier 152 Contiguous : 1, 153 PXN : 1, // Privileged execute-never 154 UXN : 1, // Execute never 155 soft_reserved : 4, 156 PBHA : 4, // Page based hardware attributes 157 ignored : 1; 158 } l3_page; 159 u64 pte; 160 } pte_t; 161 // clang-format on 162 163 #define PTE_DESCRIPTOR_INVALID (0) 164 165 /* page_table_page type */ 166 typedef struct { 167 pte_t ent[PTP_ENTRIES]; 168 } ptp_t; 169 170 #endif /* ARCH_AARCH64_ARCH_MM_PAGE_TABLE_H */