Changes in kernel/arch/amd64/src/mm/page.c [64f6ef04:214ec25c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/mm/page.c
r64f6ef04 r214ec25c 39 39 #include <mm/frame.h> 40 40 #include <mm/as.h> 41 #include <arch/interrupt.h> 41 42 #include <arch/asm.h> 42 43 #include <config.h> … … 47 48 #include <align.h> 48 49 50 /* Definitions for identity page mapper */ 51 pte_t helper_ptl1[512] __attribute__((aligned (PAGE_SIZE))); 52 pte_t helper_ptl2[512] __attribute__((aligned (PAGE_SIZE))); 53 pte_t helper_ptl3[512] __attribute__((aligned (PAGE_SIZE))); 54 extern pte_t ptl_0; /* From boot.S */ 55 56 #define PTL1_PRESENT(ptl0, page) (!(GET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) 57 #define PTL2_PRESENT(ptl1, page) (!(GET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) 58 #define PTL3_PRESENT(ptl2, page) (!(GET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) 59 60 #define PTL1_ADDR(ptl0, page) ((pte_t *)PA2KA(GET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page)))) 61 #define PTL2_ADDR(ptl1, page) ((pte_t *)PA2KA(GET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page)))) 62 #define PTL3_ADDR(ptl2, page) ((pte_t *)PA2KA(GET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page)))) 63 64 #define SETUP_PTL1(ptl0, page, tgt) { \ 65 SET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 66 SET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 67 } 68 #define SETUP_PTL2(ptl1, page, tgt) { \ 69 SET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 70 SET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 71 } 72 #define SETUP_PTL3(ptl2, page, tgt) { \ 73 SET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 74 SET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 75 } 76 #define SETUP_FRAME(ptl3, page, tgt) { \ 77 SET_FRAME_ADDRESS_ARCH(ptl3, PTL3_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 78 SET_FRAME_FLAGS_ARCH(ptl3, PTL3_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 79 } 80 81 49 82 void page_arch_init(void) 50 83 { 84 uintptr_t cur; 85 unsigned int i; 86 int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE; 87 51 88 if (config.cpu_active == 1) { 52 uintptr_t cur;53 unsigned int identity_flags =54 PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;55 56 89 page_mapping_operations = &pt_mapping_operations; 57 90 58 91 page_table_lock(AS_KERNEL, true); 59 92 60 93 /* 61 94 * PA2KA(identity) mapping for all frames. 62 95 */ 63 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) 96 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { 97 /* Standard identity mapping */ 64 98 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags); 99 } 65 100 101 /* Upper kernel mapping 102 * - from zero to top of kernel (include bottom addresses 103 * because some are needed for init) 104 */ 105 for (cur = PA2KA_CODE(0); cur < config.base + config.kernel_size; cur += FRAME_SIZE) 106 page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags); 107 108 for (cur = config.stack_base; cur < config.stack_base + config.stack_size; cur += FRAME_SIZE) 109 page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags); 110 111 for (i = 0; i < init.cnt; i++) { 112 for (cur = init.tasks[i].addr; cur < init.tasks[i].addr + init.tasks[i].size; cur += FRAME_SIZE) 113 page_mapping_insert(AS_KERNEL, PA2KA_CODE(KA2PA(cur)), KA2PA(cur), identity_flags); 114 } 115 66 116 page_table_unlock(AS_KERNEL, true); 67 117 68 118 exc_register(14, "page_fault", true, (iroutine_t) page_fault); 69 119 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); … … 72 122 } 73 123 124 125 /** Identity page mapper 126 * 127 * We need to map whole physical memory identically before the page subsystem 128 * is initializaed. This thing clears page table and fills in the specific 129 * items. 130 */ 131 void ident_page_fault(unsigned int n, istate_t *istate) 132 { 133 uintptr_t page; 134 static uintptr_t oldpage = 0; 135 pte_t *aptl_1, *aptl_2, *aptl_3; 136 137 page = read_cr2(); 138 if (oldpage) { 139 /* Unmap old address */ 140 aptl_1 = PTL1_ADDR(&ptl_0, oldpage); 141 aptl_2 = PTL2_ADDR(aptl_1, oldpage); 142 aptl_3 = PTL3_ADDR(aptl_2, oldpage); 143 144 SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 145 if (KA2PA(aptl_3) == KA2PA(helper_ptl3)) 146 SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 147 if (KA2PA(aptl_2) == KA2PA(helper_ptl2)) 148 SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 149 if (KA2PA(aptl_1) == KA2PA(helper_ptl1)) 150 SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 151 } 152 if (PTL1_PRESENT(&ptl_0, page)) 153 aptl_1 = PTL1_ADDR(&ptl_0, page); 154 else { 155 SETUP_PTL1(&ptl_0, page, helper_ptl1); 156 aptl_1 = helper_ptl1; 157 } 158 159 if (PTL2_PRESENT(aptl_1, page)) 160 aptl_2 = PTL2_ADDR(aptl_1, page); 161 else { 162 SETUP_PTL2(aptl_1, page, helper_ptl2); 163 aptl_2 = helper_ptl2; 164 } 165 166 if (PTL3_PRESENT(aptl_2, page)) 167 aptl_3 = PTL3_ADDR(aptl_2, page); 168 else { 169 SETUP_PTL3(aptl_2, page, helper_ptl3); 170 aptl_3 = helper_ptl3; 171 } 172 173 SETUP_FRAME(aptl_3, page, page); 174 175 oldpage = page; 176 } 177 178 74 179 void page_fault(unsigned int n, istate_t *istate) 75 180 { 76 uintptr_t page = read_cr2(); 181 uintptr_t page; 182 pf_access_t access; 183 184 page = read_cr2(); 77 185 78 186 if (istate->error_word & PFERR_CODE_RSVD) 79 187 panic("Reserved bit set in page table entry."); 80 81 pf_access_t access;82 188 83 189 if (istate->error_word & PFERR_CODE_RW) … … 89 195 90 196 if (as_page_fault(page, access, istate) == AS_PF_FAULT) { 91 fault_if_from_uspace(istate, "Page fault: %p.", page); 197 fault_if_from_uspace(istate, "Page fault: %#x.", page); 198 92 199 decode_istate(n, istate); 93 panic("Page fault: %p", page); 94 } 95 } 200 printf("Page fault address: %llx.\n", page); 201 panic("Page fault."); 202 } 203 } 204 96 205 97 206 uintptr_t hw_map(uintptr_t physaddr, size_t size) 98 207 { 99 208 if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) 100 panic("Unable to map physical memory %p (% " PRIs "bytes).", physaddr,209 panic("Unable to map physical memory %p (%d bytes).", physaddr, 101 210 size); 102 211 103 212 uintptr_t virtaddr = PA2KA(last_frame); 104 213 pfn_t i; 105 214 106 215 page_table_lock(AS_KERNEL, true); 107 108 216 for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) 109 217 page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); 110 111 218 page_table_unlock(AS_KERNEL, true); 112 219
Note:
See TracChangeset
for help on using the changeset viewer.