Changeset a1f60f3 in mainline for kernel/arch/amd64/src/mm
- Timestamp:
- 2010-06-27T23:04:20Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 64f6ef04
- Parents:
- 33dac7d
- File:
-
- 1 edited
-
kernel/arch/amd64/src/mm/page.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/mm/page.c
r33dac7d ra1f60f3 52 52 pte_t helper_ptl2[512] __attribute__((aligned (PAGE_SIZE))); 53 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 54 55 static uintptr_t oldpage = 0; 56 57 extern pte_t ptl_0; /* From boot.S */ 58 59 #define PTL1_PRESENT(ptl0, page) \ 60 (!(GET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) 61 62 #define PTL2_PRESENT(ptl1, page) \ 63 (!(GET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) 64 65 #define PTL3_PRESENT(ptl2, page) \ 66 (!(GET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) 67 68 #define PTL1_ADDR(ptl0, page) \ 69 ((pte_t *) PA2KA(GET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page)))) 70 71 #define PTL2_ADDR(ptl1, page) \ 72 ((pte_t *) PA2KA(GET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page)))) 73 74 #define PTL3_ADDR(ptl2, page) \ 75 ((pte_t *) PA2KA(GET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page)))) 76 77 #define SETUP_PTL1(ptl0, page, tgt) \ 78 { \ 79 SET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 80 SET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 81 } 82 83 #define SETUP_PTL2(ptl1, page, tgt) \ 84 { \ 85 SET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 86 SET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 87 } 88 89 #define SETUP_PTL3(ptl2, page, tgt) \ 90 { \ 91 SET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 92 SET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 93 } 94 95 #define SETUP_FRAME(ptl3, page, tgt) \ 96 { \ 97 SET_FRAME_ADDRESS_ARCH(ptl3, PTL3_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \ 98 SET_FRAME_FLAGS_ARCH(ptl3, PTL3_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ 99 } 81 100 82 101 void page_arch_init(void) 83 102 { 84 uintptr_t cur;85 unsigned int i;86 int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;87 88 103 if (config.cpu_active == 1) { 104 uintptr_t cur; 105 unsigned int identity_flags = 106 PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE; 107 89 108 page_mapping_operations = &pt_mapping_operations; 90 109 91 110 page_table_lock(AS_KERNEL, true); 92 111 93 112 /* 94 113 * PA2KA(identity) mapping for all frames. 95 114 */ 96 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { 97 /* Standard identity mapping */ 115 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) 98 116 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags); 99 } 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 117 116 118 page_table_unlock(AS_KERNEL, true); 117 119 118 120 exc_register(14, "page_fault", true, (iroutine_t) page_fault); 119 121 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); … … 122 124 } 123 125 124 125 126 /** Identity page mapper 126 127 * … … 128 129 * is initializaed. This thing clears page table and fills in the specific 129 130 * items. 131 * 130 132 */ 131 133 void ident_page_fault(unsigned int n, istate_t *istate) 132 134 { 133 uintptr_t page; 134 static uintptr_t oldpage = 0; 135 pte_t *aptl_1, *aptl_2, *aptl_3; 136 137 page = read_cr2(); 135 pte_t *aptl_1; 136 pte_t *aptl_2; 137 pte_t *aptl_3; 138 139 uintptr_t page = read_cr2(); 140 141 /* Unmap old address */ 138 142 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 143 pte_t *aptl_1 = PTL1_ADDR(&ptl_0, oldpage); 144 pte_t *aptl_2 = PTL2_ADDR(aptl_1, oldpage); 145 pte_t *aptl_3 = PTL3_ADDR(aptl_2, oldpage); 146 144 147 SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 148 145 149 if (KA2PA(aptl_3) == KA2PA(helper_ptl3)) 146 150 SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 151 147 152 if (KA2PA(aptl_2) == KA2PA(helper_ptl2)) 148 153 SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 154 149 155 if (KA2PA(aptl_1) == KA2PA(helper_ptl1)) 150 156 SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); 151 157 } 158 152 159 if (PTL1_PRESENT(&ptl_0, page)) 153 160 aptl_1 = PTL1_ADDR(&ptl_0, page); … … 156 163 aptl_1 = helper_ptl1; 157 164 } 158 165 159 166 if (PTL2_PRESENT(aptl_1, page)) 160 167 aptl_2 = PTL2_ADDR(aptl_1, page); … … 163 170 aptl_2 = helper_ptl2; 164 171 } 165 172 166 173 if (PTL3_PRESENT(aptl_2, page)) 167 174 aptl_3 = PTL3_ADDR(aptl_2, page); … … 172 179 173 180 SETUP_FRAME(aptl_3, page, page); 174 181 175 182 oldpage = page; 176 183 } 177 184 178 179 185 void page_fault(unsigned int n, istate_t *istate) 180 186 { 181 uintptr_t page; 182 pf_access_t access; 183 184 page = read_cr2(); 187 uintptr_t page = read_cr2(); 185 188 186 189 if (istate->error_word & PFERR_CODE_RSVD) 187 190 panic("Reserved bit set in page table entry."); 191 192 pf_access_t access; 188 193 189 194 if (istate->error_word & PFERR_CODE_RW) … … 195 200 196 201 if (as_page_fault(page, access, istate) == AS_PF_FAULT) { 197 fault_if_from_uspace(istate, "Page fault: %#x.", page); 198 202 fault_if_from_uspace(istate, "Page fault: %p.", page); 199 203 decode_istate(n, istate); 200 printf("Page fault address: %llx.\n", page); 201 panic("Page fault."); 202 } 203 } 204 204 panic("Page fault: %p", page); 205 } 206 } 205 207 206 208 uintptr_t hw_map(uintptr_t physaddr, size_t size) 207 209 { 208 210 if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) 209 panic("Unable to map physical memory %p (% dbytes).", physaddr,211 panic("Unable to map physical memory %p (%" PRIs " bytes).", physaddr, 210 212 size); 211 213 212 214 uintptr_t virtaddr = PA2KA(last_frame); 213 215 pfn_t i; 214 216 215 217 page_table_lock(AS_KERNEL, true); 218 216 219 for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) 217 220 page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); 221 218 222 page_table_unlock(AS_KERNEL, true); 219 223
Note:
See TracChangeset
for help on using the changeset viewer.
