Changes in kernel/arch/amd64/src/mm/page.c [fabc883:c15b374] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/mm/page.c
rfabc883 rc15b374 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 58 page_table_lock(AS_KERNEL, true); 59 91 60 /* 92 61 * PA2KA(identity) mapping for all frames. 93 62 */ 94 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { 95 /* Standard identity mapping */ 63 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) 96 64 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags); 97 }98 65 99 /* Upper kernel mapping 100 * - from zero to top of kernel (include bottom addresses 101 * because some are needed for init) 102 */ 103 for (cur = PA2KA_CODE(0); cur < config.base + config.kernel_size; cur += FRAME_SIZE) 104 page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags); 66 page_table_unlock(AS_KERNEL, true); 105 67 106 for (cur = config.stack_base; cur < config.stack_base + config.stack_size; cur += FRAME_SIZE) 107 page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags); 108 109 for (i = 0; i < init.cnt; i++) { 110 for (cur = init.tasks[i].addr; cur < init.tasks[i].addr + init.tasks[i].size; cur += FRAME_SIZE) 111 page_mapping_insert(AS_KERNEL, PA2KA_CODE(KA2PA(cur)), KA2PA(cur), identity_flags); 112 } 113 114 exc_register(14, "page_fault", (iroutine) page_fault); 68 exc_register(14, "page_fault", true, (iroutine_t) page_fault); 115 69 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); 116 } else 70 } else 117 71 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); 118 72 } 119 73 120 121 /** Identity page mapper 122 * 123 * We need to map whole physical memory identically before the page subsystem 124 * is initializaed. This thing clears page table and fills in the specific 125 * items. 126 */ 127 void ident_page_fault(int n, istate_t *istate) 74 void page_fault(unsigned int n, istate_t *istate) 128 75 { 129 uintptr_t page; 130 static uintptr_t oldpage = 0; 131 pte_t *aptl_1, *aptl_2, *aptl_3; 132 133 page = read_cr2(); 134 if (oldpage) { 135 /* Unmap old address */ 136 aptl_1 = PTL1_ADDR(&ptl_0, oldpage); 137 aptl_2 = PTL2_ADDR(aptl_1, oldpage); 138 aptl_3 = PTL3_ADDR(aptl_2, oldpage); 139 140 SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 141 if (KA2PA(aptl_3) == KA2PA(helper_ptl3)) 142 SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 143 if (KA2PA(aptl_2) == KA2PA(helper_ptl2)) 144 SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 145 if (KA2PA(aptl_1) == KA2PA(helper_ptl1)) 146 SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 147 } 148 if (PTL1_PRESENT(&ptl_0, page)) 149 aptl_1 = PTL1_ADDR(&ptl_0, page); 150 else { 151 SETUP_PTL1(&ptl_0, page, helper_ptl1); 152 aptl_1 = helper_ptl1; 153 } 154 155 if (PTL2_PRESENT(aptl_1, page)) 156 aptl_2 = PTL2_ADDR(aptl_1, page); 157 else { 158 SETUP_PTL2(aptl_1, page, helper_ptl2); 159 aptl_2 = helper_ptl2; 160 } 161 162 if (PTL3_PRESENT(aptl_2, page)) 163 aptl_3 = PTL3_ADDR(aptl_2, page); 164 else { 165 SETUP_PTL3(aptl_2, page, helper_ptl3); 166 aptl_3 = helper_ptl3; 167 } 168 169 SETUP_FRAME(aptl_3, page, page); 170 171 oldpage = page; 172 } 173 174 175 void page_fault(int n, istate_t *istate) 176 { 177 uintptr_t page; 178 pf_access_t access; 179 180 page = read_cr2(); 76 uintptr_t page = read_cr2(); 181 77 182 78 if (istate->error_word & PFERR_CODE_RSVD) 183 79 panic("Reserved bit set in page table entry."); 80 81 pf_access_t access; 184 82 185 83 if (istate->error_word & PFERR_CODE_RW) … … 192 90 if (as_page_fault(page, access, istate) == AS_PF_FAULT) { 193 91 fault_if_from_uspace(istate, "Page fault: %#x.", page); 194 195 decode_istate(n, istate); 196 printf("Page fault address: %llx.\n", page); 197 panic("Page fault."); 92 panic_memtrap(istate, access, page, NULL); 198 93 } 199 94 } 200 201 95 202 96 uintptr_t hw_map(uintptr_t physaddr, size_t size) 203 97 { 204 98 if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) 205 panic("Unable to map physical memory %p (% dbytes).", physaddr,99 panic("Unable to map physical memory %p (%" PRIs " bytes).", physaddr, 206 100 size); 207 101 208 102 uintptr_t virtaddr = PA2KA(last_frame); 209 103 pfn_t i; 104 105 page_table_lock(AS_KERNEL, true); 106 210 107 for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) 211 108 page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); 109 110 page_table_unlock(AS_KERNEL, true); 212 111 213 112 last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
Note:
See TracChangeset
for help on using the changeset viewer.