Changes in kernel/arch/amd64/src/mm/page.c [214ec25c:64f6ef04] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/mm/page.c
r214ec25c r64f6ef04 39 39 #include <mm/frame.h> 40 40 #include <mm/as.h> 41 #include <arch/interrupt.h>42 41 #include <arch/asm.h> 43 42 #include <config.h> … … 48 47 #include <align.h> 49 48 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 82 49 void page_arch_init(void) 83 50 { 84 uintptr_t cur;85 unsigned int i;86 int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;87 88 51 if (config.cpu_active == 1) { 52 uintptr_t cur; 53 unsigned int identity_flags = 54 PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE; 55 89 56 page_mapping_operations = &pt_mapping_operations; 90 57 91 58 page_table_lock(AS_KERNEL, true); 92 59 93 60 /* 94 61 * PA2KA(identity) mapping for all frames. 95 62 */ 96 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { 97 /* Standard identity mapping */ 63 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) 98 64 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags); 99 }100 65 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); 66 page_table_unlock(AS_KERNEL, true); 107 67 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 116 page_table_unlock(AS_KERNEL, true);117 118 68 exc_register(14, "page_fault", true, (iroutine_t) page_fault); 119 69 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); … … 122 72 } 123 73 124 125 /** Identity page mapper126 *127 * We need to map whole physical memory identically before the page subsystem128 * is initializaed. This thing clears page table and fills in the specific129 * 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 179 74 void page_fault(unsigned int n, istate_t *istate) 180 75 { 181 uintptr_t page; 182 pf_access_t access; 183 184 page = read_cr2(); 76 uintptr_t page = read_cr2(); 185 77 186 78 if (istate->error_word & PFERR_CODE_RSVD) 187 79 panic("Reserved bit set in page table entry."); 80 81 pf_access_t access; 188 82 189 83 if (istate->error_word & PFERR_CODE_RW) … … 195 89 196 90 if (as_page_fault(page, access, istate) == AS_PF_FAULT) { 197 fault_if_from_uspace(istate, "Page fault: %#x.", page); 198 91 fault_if_from_uspace(istate, "Page fault: %p.", page); 199 92 decode_istate(n, istate); 200 printf("Page fault address: %llx.\n", page); 201 panic("Page fault."); 93 panic("Page fault: %p", page); 202 94 } 203 95 } 204 205 96 206 97 uintptr_t hw_map(uintptr_t physaddr, size_t size) 207 98 { 208 99 if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) 209 panic("Unable to map physical memory %p (% dbytes).", physaddr,100 panic("Unable to map physical memory %p (%" PRIs " bytes).", physaddr, 210 101 size); 211 102 212 103 uintptr_t virtaddr = PA2KA(last_frame); 213 104 pfn_t i; 214 105 215 106 page_table_lock(AS_KERNEL, true); 107 216 108 for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) 217 109 page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); 110 218 111 page_table_unlock(AS_KERNEL, true); 219 112
Note:
See TracChangeset
for help on using the changeset viewer.