Changeset 6a3c9a7 in mainline
- Timestamp:
- 2006-01-30T23:44:00Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fc1e4f6
- Parents:
- a60c748
- Location:
- generic
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/include/mm/as.h
ra60c748 r6a3c9a7 66 66 size_t size; /**< Size of this area in multiples of PAGE_SIZE. */ 67 67 __address base; /**< Base address of this area. */ 68 index_t *mapping; /**< Map of physical frame numbers mapped to virtual page numbers in this area. */69 68 }; 70 69 … … 77 76 */ 78 77 struct as { 79 /** Protected by asidlock. Must be acquired before as-> 78 /** Protected by asidlock. Must be acquired before as->lock. */ 80 79 link_t as_with_asid_link; 81 80 … … 88 87 extern as_t * as_create(pte_t *ptl0, int flags); 89 88 extern as_area_t *as_area_create(as_t *as, as_area_type_t type, size_t size, __address base); 90 extern void as_ area_set_mapping(as_area_t *a, index_t vpn, index_t pfn);89 extern void as_set_mapping(as_t *as, __address page, __address frame); 91 90 extern int as_page_fault(__address page); 92 91 extern void as_install(as_t *m); -
generic/src/main/kinit.c
ra60c748 r6a3c9a7 72 72 as_t *as; 73 73 as_area_t *a; 74 index_t frame, frames; 75 index_t pfn; 74 __address frame; 75 count_t frames; 76 int i; 76 77 task_t *u; 77 78 … … 161 162 */ 162 163 163 frame = KA2PA(config.init_addr) / FRAME_SIZE;164 frame = KA2PA(config.init_addr); 164 165 frames = config.init_size / FRAME_SIZE; 165 166 if (config.init_size % FRAME_SIZE > 0) … … 170 171 panic("as_area_create: text\n"); 171 172 172 for (pfn = 0; pfn < frames; pfn++)173 as_area_set_mapping(a, pfn, frame + pfn);174 175 173 /* 176 174 * Create the data as_area. … … 179 177 if (!a) 180 178 panic("as_area_create: stack\n"); 179 180 /* 181 * Initialize text area mapping. 182 */ 183 for (i = 0; i < frames; i++) 184 as_set_mapping(as, UTEXT_ADDRESS + i * PAGE_SIZE, frame + i * FRAME_SIZE); 185 181 186 182 187 thread_ready(t); -
generic/src/mm/as.c
ra60c748 r6a3c9a7 60 60 #define KAS_INDICES (1+(KAS_END_INDEX-KAS_START_INDEX)) 61 61 62 /* 63 * Here we assume that PFN (Physical Frame Number) space 64 * is smaller than the width of index_t. UNALLOCATED_PFN 65 * can be then used to mark mappings wich were not 66 * yet allocated a physical frame. 67 */ 68 #define UNALLOCATED_PFN ((index_t) -1) 62 static int get_area_flags(as_area_t *a); 69 63 70 64 /** Create address space. */ … … 134 128 135 129 a = (as_area_t *) malloc(sizeof(as_area_t)); 136 if (a) { 137 int i; 138 139 a->mapping = (index_t *) malloc(size * sizeof(index_t)); 140 if (!a->mapping) { 141 free(a); 142 spinlock_unlock(&as->lock); 143 interrupts_restore(ipl); 144 return NULL; 145 } 146 147 for (i=0; i<size; i++) { 148 /* 149 * Frames will be allocated on-demand by 150 * as_page_fault() or preloaded by 151 * as_area_set_mapping(). 152 */ 153 a->mapping[i] = UNALLOCATED_PFN; 154 } 155 130 if (a) { 156 131 spinlock_initialize(&a->lock, "as_area_lock"); 157 132 … … 162 137 163 138 list_append(&a->link, &as->as_area_head); 164 165 139 } 166 140 … … 171 145 } 172 146 173 /** Load mapping for address space area.174 * 175 * Initialize a->mapping.176 * 177 * @param a Target address space area.178 * @param vpn Page number relative to area start.179 * @param pfn Frame number to map.180 * /181 void as_area_set_mapping(as_area_t *a, index_t vpn, index_t pfn) 182 { 183 ASSERT(vpn < a->size); 184 ASSERT(a->mapping[vpn] == UNALLOCATED_PFN); 185 ASSERT(pfn != UNALLOCATED_PFN);186 147 /** Initialize mapping for one page of address space. 148 * 149 * This functions maps 'page' to 'frame' according 150 * to attributes of the address space area to 151 * wich 'page' belongs. 152 * 153 * @param a Target address space. 154 * @param page Virtual page within the area. 155 * @param frame Physical frame to which page will be mapped. 156 */ 157 void as_set_mapping(as_t *as, __address page, __address frame) 158 { 159 as_area_t *a, *area = NULL; 160 link_t *cur; 187 161 ipl_t ipl; 188 162 189 163 ipl = interrupts_disable(); 190 spinlock_lock(&a->lock); 191 192 a->mapping[vpn] = pfn; 193 194 spinlock_unlock(&a->lock); 164 spinlock_lock(&as->lock); 165 166 /* 167 * First, try locate an area. 168 */ 169 for (cur = as->as_area_head.next; cur != &as->as_area_head; cur = cur->next) { 170 a = list_get_instance(cur, as_area_t, link); 171 spinlock_lock(&a->lock); 172 173 if ((page >= a->base) && (page < a->base + a->size * PAGE_SIZE)) { 174 area = a; 175 break; 176 } 177 178 spinlock_unlock(&a->lock); 179 } 180 181 if (!area) { 182 panic("page not part of any as_area\n"); 183 } 184 185 /* 186 * Note: area->lock is held. 187 */ 188 189 page_mapping_insert(page, as->asid, frame, get_area_flags(area), (__address) as->ptl0); 190 191 spinlock_unlock(&area->lock); 192 spinlock_unlock(&as->lock); 195 193 interrupts_restore(ipl); 196 194 } … … 207 205 int as_page_fault(__address page) 208 206 { 209 int flags;210 207 link_t *cur; 211 208 as_area_t *a, *area = NULL; 212 index_t vpn;213 209 __address frame; 214 210 … … 229 225 * TODO: access checking 230 226 */ 231 232 vpn = (page - a->base) / PAGE_SIZE;233 227 area = a; 234 228 break; … … 252 246 253 247 /* 254 * Decide if a frame needs to be allocated. 255 * If so, allocate it and adjust area->mapping map. 256 */ 257 if (area->mapping[vpn] == UNALLOCATED_PFN) { 258 frame = frame_alloc(0, ONE_FRAME, NULL); 259 memsetb(PA2KA(frame), FRAME_SIZE, 0); 260 area->mapping[vpn] = frame / FRAME_SIZE; 261 ASSERT(area->mapping[vpn] != UNALLOCATED_PFN); 262 } else 263 frame = area->mapping[vpn] * FRAME_SIZE; 264 265 switch (area->type) { 248 * In general, there can be several reasons that 249 * can have caused this fault. 250 * 251 * - non-existent mapping: the area is a scratch 252 * area (e.g. stack) and so far has not been 253 * allocated a frame for the faulting page 254 * 255 * - non-present mapping: another possibility, 256 * currently not implemented, would be frame 257 * reuse; when this becomes a possibility, 258 * do not forget to distinguish between 259 * the different causes 260 */ 261 frame = frame_alloc(0, ONE_FRAME, NULL); 262 memsetb(PA2KA(frame), FRAME_SIZE, 0); 263 264 /* 265 * Map 'page' to 'frame'. 266 * Note that TLB shootdown is not attempted as only new information is being 267 * inserted into page tables. 268 */ 269 page_mapping_insert(page, AS->asid, frame, get_area_flags(area), (__address) AS->ptl0); 270 271 spinlock_unlock(&area->lock); 272 spinlock_unlock(&AS->lock); 273 274 return 1; 275 } 276 277 /** Install address space on CPU. 278 * 279 * @param as Address space. 280 */ 281 void as_install(as_t *as) 282 { 283 ipl_t ipl; 284 285 asid_install(as); 286 287 ipl = interrupts_disable(); 288 spinlock_lock(&as->lock); 289 ASSERT(as->ptl0); 290 SET_PTL0_ADDRESS(as->ptl0); 291 spinlock_unlock(&as->lock); 292 interrupts_restore(ipl); 293 294 /* 295 * Perform architecture-specific steps. 296 * (e.g. write ASID to hardware register etc.) 297 */ 298 as_install_arch(as); 299 300 AS = as; 301 } 302 303 /** Compute flags for virtual address translation subsytem. 304 * 305 * The address space area must be locked. 306 * Interrupts must be disabled. 307 * 308 * @param a Address space area. 309 * 310 * @return Flags to be used in page_mapping_insert(). 311 */ 312 int get_area_flags(as_area_t *a) 313 { 314 int flags; 315 316 switch (a->type) { 266 317 case AS_AREA_TEXT: 267 318 flags = PAGE_EXEC | PAGE_READ | PAGE_USER | PAGE_PRESENT | PAGE_CACHEABLE; … … 272 323 break; 273 324 default: 274 panic("unexpected as_area_type_t %d", area->type); 275 } 276 277 /* 278 * Map 'page' to 'frame'. 279 * Note that TLB shootdown is not attempted as only new information is being 280 * inserted into page tables. 281 */ 282 page_mapping_insert(page, AS->asid, frame, flags, (__address) AS->ptl0); 283 284 spinlock_unlock(&area->lock); 285 spinlock_unlock(&AS->lock); 286 287 return 1; 288 } 289 290 /** Install address space on CPU. 291 * 292 * @param as Address space. 293 */ 294 void as_install(as_t *as) 295 { 296 ipl_t ipl; 297 298 asid_install(as); 299 300 ipl = interrupts_disable(); 301 spinlock_lock(&as->lock); 302 ASSERT(as->ptl0); 303 SET_PTL0_ADDRESS(as->ptl0); 304 spinlock_unlock(&as->lock); 305 interrupts_restore(ipl); 306 307 /* 308 * Perform architecture-specific steps. 309 * (e.g. write ASID to hardware register etc.) 310 */ 311 as_install_arch(as); 312 313 AS = as; 314 } 325 panic("unexpected as_area_type_t %d", a->type); 326 } 327 328 return flags; 329 }
Note:
See TracChangeset
for help on using the changeset viewer.