00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00038 #include <genarch/mm/page_pt.h>
00039 #include <mm/page.h>
00040 #include <mm/frame.h>
00041 #include <mm/as.h>
00042 #include <arch/mm/page.h>
00043 #include <arch/mm/as.h>
00044 #include <arch/types.h>
00045 #include <typedefs.h>
00046 #include <arch/asm.h>
00047 #include <memstr.h>
00048
00049 static void pt_mapping_insert(as_t *as, __address page, __address frame, int flags);
00050 static void pt_mapping_remove(as_t *as, __address page);
00051 static pte_t *pt_mapping_find(as_t *as, __address page);
00052
00053 page_mapping_operations_t pt_mapping_operations = {
00054 .mapping_insert = pt_mapping_insert,
00055 .mapping_remove = pt_mapping_remove,
00056 .mapping_find = pt_mapping_find
00057 };
00058
00071 void pt_mapping_insert(as_t *as, __address page, __address frame, int flags)
00072 {
00073 pte_t *ptl0, *ptl1, *ptl2, *ptl3;
00074 __address newpt;
00075
00076 ptl0 = (pte_t *) PA2KA((__address) as->page_table);
00077
00078 if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
00079 newpt = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA)));
00080 memsetb(newpt, PAGE_SIZE, 0);
00081 SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
00082 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
00083 }
00084
00085 ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
00086
00087 if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
00088 newpt = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA)));
00089 memsetb(newpt, PAGE_SIZE, 0);
00090 SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
00091 SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
00092 }
00093
00094 ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
00095
00096 if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
00097 newpt = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA)));
00098 memsetb(newpt, PAGE_SIZE, 0);
00099 SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
00100 SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
00101 }
00102
00103 ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
00104
00105 SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(page), frame);
00106 SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags);
00107 }
00108
00122 void pt_mapping_remove(as_t *as, __address page)
00123 {
00124 pte_t *ptl0, *ptl1, *ptl2, *ptl3;
00125 bool empty = true;
00126 int i;
00127
00128
00129
00130
00131
00132 ptl0 = (pte_t *) PA2KA((__address) as->page_table);
00133
00134 if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
00135 return;
00136
00137 ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
00138
00139 if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
00140 return;
00141
00142 ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
00143
00144 if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
00145 return;
00146
00147 ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
00148
00149
00150 memsetb((__address) &ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
00151
00152
00153
00154
00155
00156
00157 for (i = 0; i < PTL3_ENTRIES; i++) {
00158 if (PTE_VALID(&ptl3[i])) {
00159 empty = false;
00160 break;
00161 }
00162 }
00163 if (empty) {
00164
00165
00166
00167
00168 frame_free(ADDR2PFN(KA2PA((__address) ptl3)));
00169 if (PTL2_ENTRIES)
00170 memsetb((__address) &ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0);
00171 else if (PTL1_ENTRIES)
00172 memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
00173 else
00174 memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
00175 } else {
00176
00177
00178
00179
00180
00181 return;
00182 }
00183
00184
00185 if (PTL2_ENTRIES) {
00186 for (i = 0; i < PTL2_ENTRIES; i++) {
00187 if (PTE_VALID(&ptl2[i])) {
00188 empty = false;
00189 break;
00190 }
00191 }
00192 if (empty) {
00193
00194
00195
00196
00197 frame_free(ADDR2PFN(KA2PA((__address) ptl2)));
00198 if (PTL1_ENTRIES)
00199 memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
00200 else
00201 memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
00202 }
00203 else {
00204
00205
00206
00207
00208
00209 return;
00210 }
00211 }
00212
00213
00214 if (PTL1_ENTRIES) {
00215 for (i = 0; i < PTL1_ENTRIES; i++) {
00216 if (PTE_VALID(&ptl1[i])) {
00217 empty = false;
00218 break;
00219 }
00220 }
00221 if (empty) {
00222
00223
00224
00225
00226 frame_free(ADDR2PFN(KA2PA((__address) ptl1)));
00227 memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
00228 }
00229 }
00230
00231 }
00232
00244 pte_t *pt_mapping_find(as_t *as, __address page)
00245 {
00246 pte_t *ptl0, *ptl1, *ptl2, *ptl3;
00247
00248 ptl0 = (pte_t *) PA2KA((__address) as->page_table);
00249
00250 if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
00251 return NULL;
00252
00253 ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
00254
00255 if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
00256 return NULL;
00257
00258 ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
00259
00260 if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
00261 return NULL;
00262
00263 ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
00264
00265 return &ptl3[PTL3_INDEX(page)];
00266 }
00267