Changeset 6e8b3c8 in mainline
- Timestamp:
- 2005-11-11T18:50:41Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 30187eb
- Parents:
- 8a0b3730
- Location:
- generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/include/mm/frame.h
r8a0b3730 r6e8b3c8 34 34 #include <list.h> 35 35 #include <synch/spinlock.h> 36 #include <mm/buddy.h> 36 37 37 38 #define FRAME_KA 1 /* skip frames conflicting with user address space */ 38 39 #define FRAME_PANIC 2 /* panic on failure */ 40 41 #define FRAME2ADDR(zone, frame) ((zone)->base + ((frame) - (zone)->frames) * FRAME_SIZE) 42 #define ADDR2FRAME(zone, addr) (&((zone)->frames[((addr) - (zone)->base) / FRAME_SIZE])) 39 43 40 44 struct zone { … … 47 51 count_t free_count; /**< number of frame_t structures in free list */ 48 52 count_t busy_count; /**< number of frame_t structures not in free list */ 53 54 buddy_system_t * buddy_system; /**< buddy system allocator for the zone */ 49 55 int flags; 50 56 }; … … 53 59 count_t refcount; /**< when == 0, the frame is in free list */ 54 60 link_t link; /**< link to zone free list when refcount == 0 */ 61 __u8 order; /**< buddy system block order */ 62 link_t buddy_link; /**< link to the next free block inside one order*/ 55 63 }; 56 64 … … 70 78 71 79 /* 80 * Buddy system operations 81 */ 82 link_t * zone_buddy_find_buddy(link_t * buddy); 83 link_t * zone_buddy_bisect(link_t * block); 84 link_t * zone_buddy_coalesce(link_t * buddy_l, link_t * buddy_r); 85 void zone_buddy_set_order(link_t * block, __u8 order); 86 __u8 zone_buddy_get_order(link_t * block); 87 88 __address zone_buddy_frame_alloc(int flags, __u8 order); 89 void zone_buddy_frame_free(__address addr); 90 91 /* 72 92 * TODO: Implement the following functions. 73 93 */ -
generic/src/mm/frame.c
r8a0b3730 r6e8b3c8 42 42 link_t zone_head; /**< list of all zones in the system */ 43 43 44 static struct buddy_system_operations zone_buddy_system_operations = { 45 .find_buddy = zone_buddy_find_buddy, 46 .bisect = zone_buddy_bisect, 47 .coalesce = zone_buddy_coalesce, 48 .set_order = zone_buddy_set_order, 49 .get_order = zone_buddy_get_order, 50 }; 51 44 52 /** Initialize physical memory management 45 53 * … … 119 127 zone->busy_count++; 120 128 121 v = zone->base + (frame - zone->frames) * FRAME_SIZE; 129 //v = zone->base + (frame - zone->frames) * FRAME_SIZE; 130 v = FRAME2ADDR(zone, frame); 122 131 123 132 if (flags & FRAME_KA) … … 176 185 ASSERT(zone != NULL); 177 186 178 frame = &zone->frames[(addr - zone->base)/FRAME_SIZE]; 187 frame = ADDR2FRAME(zone, addr); 188 // frame = &zone->frames[(addr - zone->base)/FRAME_SIZE]; 179 189 ASSERT(frame->refcount); 180 190 … … 234 244 ASSERT(zone != NULL); 235 245 236 frame = &zone->frames[(addr - zone->base)/FRAME_SIZE]; 246 //frame = &zone->frames[(addr - zone->base)/FRAME_SIZE]; 247 frame = ADDR2FRAME(zone, addr); 237 248 238 249 if (!frame->refcount) { … … 293 304 count_t cnt; 294 305 int i; 306 __u8 max_order; 295 307 296 308 ASSERT(start % FRAME_SIZE == 0); … … 323 335 } 324 336 337 /* 338 * Create buddy system for the zone 339 */ 340 for (max_order = 0; cnt >> max_order; max_order++); 341 z->buddy_system = buddy_system_create(max_order, &zone_buddy_system_operations); 325 342 } 326 343 … … 359 376 link_initialize(&frame->link); 360 377 } 378 379 380 381 /* 382 * buddy system functions (under construction) 383 * 384 */ 385 386 387 /** Allocate 2^order frames 388 * 389 */ 390 __address zone_buddy_frame_alloc(int flags, __u8 order) { 391 ipl_t ipl; 392 link_t *cur, *tmp; 393 zone_t *z; 394 zone_t *zone = NULL; 395 frame_t *frame = NULL; 396 __address v; 397 398 loop: 399 ipl = interrupts_disable(); 400 spinlock_lock(&zone_head_lock); 401 402 /* 403 * First, find suitable frame zone. 404 */ 405 for (cur = zone_head.next; cur != &zone_head; cur = cur->next) { 406 z = list_get_instance(cur, zone_t, link); 407 408 spinlock_lock(&z->lock); 409 /* 410 * Check if the zone has 2^order frames area available 411 * TODO: Must check if buddy system has at least block in order >= given order 412 */ 413 if (z->free_count == (1 >> order)) { 414 zone = z; 415 break; 416 } 417 418 spinlock_unlock(&z->lock); 419 } 420 421 if (!zone) { 422 if (flags & FRAME_PANIC) 423 panic("Can't allocate frame.\n"); 424 425 /* 426 * TODO: Sleep until frames are available again. 427 */ 428 spinlock_unlock(&zone_head_lock); 429 interrupts_restore(ipl); 430 431 panic("Sleep not implemented.\n"); 432 goto loop; 433 } 434 435 436 /* Allocate frames from zone buddy system */ 437 cur = buddy_system_alloc(zone->buddy_system, order); 438 439 /* frame will be actually a first frame of the block */ 440 frame = list_get_instance(cur, frame_t, buddy_link); 441 442 /* get frame address */ 443 v = FRAME2ADDR(zone, frame); 444 445 if (flags & FRAME_KA) 446 v = PA2KA(v); 447 448 spinlock_unlock(&zone->lock); 449 spinlock_unlock(&zone_head_lock); 450 interrupts_restore(ipl); 451 452 return v; 453 } 454 455 456 /** Free frame(s) 457 * 458 * @param addr Address of the frame(s) to be freed. It must be a multiple of FRAME_SIZE. 459 */ 460 void zone_buddy_frame_free(__address addr) 461 { 462 ipl_t ipl; 463 link_t *cur; 464 zone_t *z; 465 zone_t *zone = NULL; 466 frame_t *frame; 467 468 ASSERT(addr % FRAME_SIZE == 0); 469 470 ipl = interrupts_disable(); 471 spinlock_lock(&zone_head_lock); 472 473 /* 474 * First, find host frame zone for addr. 475 */ 476 for (cur = zone_head.next; cur != &zone_head; cur = cur->next) { 477 z = list_get_instance(cur, zone_t, link); 478 479 spinlock_lock(&z->lock); 480 481 if (IS_KA(addr)) 482 addr = KA2PA(addr); 483 484 /* 485 * Check if addr belongs to z. 486 */ 487 if ((addr >= z->base) && (addr <= z->base + (z->free_count + z->busy_count) * FRAME_SIZE)) { 488 zone = z; 489 break; 490 } 491 spinlock_unlock(&z->lock); 492 } 493 494 ASSERT(zone != NULL); 495 496 frame = ADDR2FRAME(zone, addr); 497 498 ASSERT(frame->refcount); 499 500 if (!--frame->refcount) { 501 buddy_system_free(zone->buddy_system, &frame->buddy_link); 502 } 503 504 spinlock_unlock(&zone->lock); 505 506 spinlock_unlock(&zone_head_lock); 507 interrupts_restore(ipl); 508 } 509 510 511 /** Buddy system find_buddy implementation 512 * 513 */ 514 link_t * zone_buddy_find_buddy(link_t * buddy) { 515 516 } 517 518 /** Buddy system bisect implementation 519 * 520 */ 521 link_t * zone_buddy_bisect(link_t * block) { 522 523 } 524 525 /** Buddy system coalesce implementation 526 * 527 */ 528 link_t * zone_buddy_coalesce(link_t * buddy_l, link_t * buddy_r) { 529 530 } 531 532 /** Buddy system set_order implementation 533 * 534 */ 535 void zone_buddy_set_order(link_t * block, __u8 order) { 536 537 } 538 539 /** Buddy system get_order implementation 540 * 541 */ 542 __u8 zone_buddy_get_order(link_t * block) { 543 544 545 }
Note:
See TracChangeset
for help on using the changeset viewer.