1 /* 2 * Copyright 2018 The Hafnium Authors. 3 * 4 * Use of this source code is governed by a BSD-style 5 * license that can be found in the LICENSE file or at 6 * https://opensource.org/licenses/BSD-3-Clause. 7 */ 8 9 #pragma once 10 11 #include <stdbool.h> 12 #include <stddef.h> 13 14 #include "hf/addr.h" 15 16 #include "vmapi/hf/ffa.h" 17 18 /* 19 * A page table entry (PTE) will take one of the following forms: 20 * 21 * 1. absent : There is no mapping. 22 * 2. invalid block : Represents a block that is not in the address space. 23 * 3. valid block : Represents a block that is in the address space. 24 * 4. table : Represents a reference to a table of PTEs. 25 */ 26 27 /** 28 * Creates an absent PTE. 29 */ 30 pte_t arch_mm_absent_pte(uint8_t level); 31 32 /** 33 * Creates a table PTE. 34 */ 35 pte_t arch_mm_table_pte(uint8_t level, paddr_t pa); 36 37 /** 38 * Creates a block PTE. 39 */ 40 pte_t arch_mm_block_pte(uint8_t level, paddr_t pa, uint64_t attrs); 41 42 /** 43 * Checks whether a block is allowed at the given level of the page table. 44 */ 45 bool arch_mm_is_block_allowed(uint8_t level); 46 47 /** 48 * Determines if a PTE is present i.e. it contains information and therefore 49 * needs to exist in the page table. Any non-absent PTE is present. 50 */ 51 bool arch_mm_pte_is_present(pte_t pte, uint8_t level); 52 53 /** 54 * Determines if a PTE is valid i.e. it can affect the address space. Tables and 55 * valid blocks fall into this category. Invalid blocks do not as they hold 56 * information about blocks that are not in the address space. 57 */ 58 bool arch_mm_pte_is_valid(pte_t pte, uint8_t level); 59 60 /** 61 * Determines if a PTE is a block and represents an address range, valid or 62 * invalid. 63 */ 64 bool arch_mm_pte_is_block(pte_t pte, uint8_t level); 65 66 /** 67 * Determines if a PTE represents a reference to a table of PTEs. 68 */ 69 bool arch_mm_pte_is_table(pte_t pte, uint8_t level); 70 71 /** 72 * Clears the bits of an address that are ignored by the page table. In effect, 73 * the address is rounded down to the start of the corresponding PTE range. 74 */ 75 paddr_t arch_mm_clear_pa(paddr_t pa); 76 77 /** 78 * Extracts the start address of the PTE range. 79 */ 80 paddr_t arch_mm_block_from_pte(pte_t pte, uint8_t level); 81 82 /** 83 * Extracts the address of the table referenced by the PTE. 84 */ 85 paddr_t arch_mm_table_from_pte(pte_t pte, uint8_t level); 86 87 /** 88 * Extracts the attributes of the PTE. 89 */ 90 uint64_t arch_mm_pte_attrs(pte_t pte, uint8_t level); 91 92 /** 93 * Merges the attributes of a block into those of its containing table. 94 */ 95 uint64_t arch_mm_combine_table_entry_attrs(uint64_t table_attrs, 96 uint64_t block_attrs); 97 98 /** 99 * Invalidates the given range of stage-1 TLB. 100 */ 101 void arch_mm_invalidate_stage1_range(uint16_t asid, vaddr_t va_begin, 102 vaddr_t va_end); 103 104 /** 105 * Invalidates the given range of stage-2 TLB. 106 */ 107 void arch_mm_invalidate_stage2_range(uint16_t vmid, ipaddr_t va_begin, 108 ipaddr_t va_end); 109 110 /** 111 * Writes back the given range of virtual memory to such a point that all cores 112 * and devices will see the updated values. The corresponding cache lines are 113 * also invalidated. 114 */ 115 void arch_mm_flush_dcache(void *base, size_t size); 116 117 /** 118 * Sets the maximum level allowed in the page table for stage-1. 119 */ 120 void arch_mm_stage1_max_level_set(uint32_t pa_bits); 121 122 /** 123 * Gets the maximum level allowed in the page table for stage-1. 124 */ 125 uint8_t arch_mm_stage1_max_level(void); 126 127 /** 128 * Gets the maximum level allowed in the page table for stage-2. 129 */ 130 uint8_t arch_mm_stage2_max_level(void); 131 132 /** 133 * Gets the number of concatenated page tables used at the root for stage-1. 134 * 135 * Tables are concatenated at the root to avoid introducing another level in the 136 * page table meaning the table is shallow and wide. Each level is an extra 137 * memory access when walking the table so keeping it shallow reduces the memory 138 * accesses to aid performance. 139 */ 140 uint8_t arch_mm_stage1_root_table_count(void); 141 142 /** 143 * Gets the number of concatenated page tables used at the root for stage-2. 144 */ 145 uint8_t arch_mm_stage2_root_table_count(void); 146 147 /** 148 * Converts the mode into stage-1 attributes for a block PTE. 149 */ 150 uint64_t arch_mm_mode_to_stage1_attrs(uint32_t mode); 151 152 /** 153 * Converts the mode into stage-2 attributes for a block PTE. 154 */ 155 uint64_t arch_mm_mode_to_stage2_attrs(uint32_t mode); 156 157 /** 158 * Converts the stage-2 block attributes back to the corresponding mode. 159 */ 160 uint32_t arch_mm_stage2_attrs_to_mode(uint64_t attrs); 161 162 /** 163 * Converts the stage-1 block attributes back to the corresponding mode. 164 */ 165 uint32_t arch_mm_stage1_attrs_to_mode(uint64_t attrs); 166 167 /** 168 * Initializes the arch specific memory management. 169 */ 170 bool arch_mm_init(paddr_t table); 171 172 /** 173 * Return the arch specific mm mode for send/recv pages of given VM ID. 174 */ 175 uint32_t arch_mm_extra_attributes_from_vm(ffa_vm_id_t id); 176 177 /** 178 * Execute any barriers or synchronization that is required 179 * by a given architecture, after page table writes. 180 */ 181 void arch_mm_sync_table_writes(void); 182 183 /** 184 * Returns the maximum supported PA Range in bits. 185 */ 186 uint32_t arch_mm_get_pa_range(void); 187 188 /** 189 * Returns VTCR_EL2 configured in arch_mm_init. 190 */ 191 uintptr_t arch_mm_get_vtcr_el2(void); 192 193 /** 194 * Returns VSTCR_EL2 configured in arch_mm_init. 195 */ 196 uintptr_t arch_mm_get_vstcr_el2(void); 197