Changeset 7e4e532 in mainline for generic/src/mm/as.c
- Timestamp:
- 2006-02-08T23:37:38Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 874878a
- Parents:
- bb68433
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/src/mm/as.c
rbb68433 r7e4e532 57 57 as_operations_t *as_operations = NULL; 58 58 59 /** Address space lock. It protects inactive_as_with_asid_head. */ 60 SPINLOCK_INITIALIZE(as_lock); 61 62 /** 63 * This list contains address spaces that are not active on any 64 * processor and that have valid ASID. 65 */ 66 LIST_INITIALIZE(inactive_as_with_asid_head); 67 59 68 /** Kernel address space. */ 60 69 as_t *AS_KERNEL = NULL; … … 80 89 81 90 as = (as_t *) malloc(sizeof(as_t), 0); 82 83 list_initialize(&as->as_with_asid_link); 91 link_initialize(&as->inactive_as_with_asid_link); 84 92 spinlock_initialize(&as->lock, "as_lock"); 85 93 list_initialize(&as->as_area_head); … … 90 98 as->asid = ASID_INVALID; 91 99 100 as->refcount = 0; 92 101 as->page_table = page_table_create(flags); 93 102 … … 268 277 } 269 278 270 /** Install address space on CPU. 271 * 272 * @param as Address space. 273 */ 274 void as_install(as_t *as) 279 /** Switch address spaces. 280 * 281 * @param old Old address space or NULL. 282 * @param new New address space. 283 */ 284 void as_switch(as_t *old, as_t *new) 275 285 { 276 286 ipl_t ipl; 277 278 asid_install(as); 287 bool needs_asid = false; 279 288 280 289 ipl = interrupts_disable(); 281 spinlock_lock(&as->lock); 282 SET_PTL0_ADDRESS(as->page_table); 283 spinlock_unlock(&as->lock); 290 spinlock_lock(&as_lock); 291 292 /* 293 * First, take care of the old address space. 294 */ 295 if (old) { 296 spinlock_lock(&old->lock); 297 ASSERT(old->refcount); 298 if((--old->refcount == 0) && (old != AS_KERNEL)) { 299 /* 300 * The old address space is no longer active on 301 * any processor. It can be appended to the 302 * list of inactive address spaces with assigned 303 * ASID. 304 */ 305 ASSERT(old->asid != ASID_INVALID); 306 list_append(&old->inactive_as_with_asid_link, &inactive_as_with_asid_head); 307 } 308 spinlock_unlock(&old->lock); 309 } 310 311 /* 312 * Second, prepare the new address space. 313 */ 314 spinlock_lock(&new->lock); 315 if ((new->refcount++ == 0) && (new != AS_KERNEL)) { 316 if (new->asid != ASID_INVALID) 317 list_remove(&new->inactive_as_with_asid_link); 318 else 319 needs_asid = true; /* defer call to asid_get() until new->lock is released */ 320 } 321 SET_PTL0_ADDRESS(new->page_table); 322 spinlock_unlock(&new->lock); 323 324 if (needs_asid) { 325 /* 326 * Allocation of new ASID was deferred 327 * until now in order to avoid deadlock. 328 */ 329 asid_t asid; 330 331 asid = asid_get(); 332 spinlock_lock(&new->lock); 333 new->asid = asid; 334 spinlock_unlock(&new->lock); 335 } 336 spinlock_unlock(&as_lock); 284 337 interrupts_restore(ipl); 285 338 286 339 /* 287 340 * Perform architecture-specific steps. 288 341 * (e.g. write ASID to hardware register etc.) 289 342 */ 290 as_install_arch( as);291 292 AS = as;343 as_install_arch(new); 344 345 AS = new; 293 346 } 294 347
Note:
See TracChangeset
for help on using the changeset viewer.