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
00029
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include <typedefs.h>
00055 #include <arch/types.h>
00056 #include <mm/frame.h>
00057 #include <mm/as.h>
00058 #include <panic.h>
00059 #include <debug.h>
00060 #include <adt/list.h>
00061 #include <synch/spinlock.h>
00062 #include <arch/asm.h>
00063 #include <arch.h>
00064 #include <print.h>
00065 #include <align.h>
00066 #include <mm/slab.h>
00067 #include <bitops.h>
00068 #include <macros.h>
00069
00070 typedef struct {
00071 count_t refcount;
00072 __u8 buddy_order;
00073 link_t buddy_link;
00074 void *parent;
00075 } frame_t;
00076
00077 typedef struct {
00078 SPINLOCK_DECLARE(lock);
00079 pfn_t base;
00080 count_t count;
00082 frame_t *frames;
00083 count_t free_count;
00084 count_t busy_count;
00086 buddy_system_t * buddy_system;
00087 int flags;
00088 } zone_t;
00089
00090
00091
00092
00093
00094
00095 struct {
00096 SPINLOCK_DECLARE(lock);
00097 int count;
00098 zone_t *info[ZONES_MAX];
00099 } zones;
00100
00101
00102
00103
00104 static inline index_t frame_index(zone_t *zone, frame_t *frame)
00105 {
00106 return (index_t)(frame - zone->frames);
00107 }
00108 static inline index_t frame_index_abs(zone_t *zone, frame_t *frame)
00109 {
00110 return (index_t)(frame - zone->frames) + zone->base;
00111 }
00112 static inline int frame_index_valid(zone_t *zone, index_t index)
00113 {
00114 return index >= 0 && index < zone->count;
00115 }
00116
00118 static index_t make_frame_index(zone_t *zone, frame_t *frame)
00119 {
00120 return frame - zone->frames;
00121 }
00122
00129 static void frame_initialize(frame_t *frame)
00130 {
00131 frame->refcount = 1;
00132 frame->buddy_order = 0;
00133 }
00134
00135
00136
00137
00144 static int zones_add_zone(zone_t *newzone)
00145 {
00146 int i,j;
00147 ipl_t ipl;
00148 zone_t *z;
00149
00150 ipl = interrupts_disable();
00151 spinlock_lock(&zones.lock);
00152
00153 if (zones.count + 1 == ZONES_MAX)
00154 panic("Maximum zone(%d) count exceeded.", ZONES_MAX);
00155 for (i = 0; i < zones.count; i++) {
00156
00157 z = zones.info[i];
00158 if (overlaps(newzone->base,newzone->count,
00159 z->base, z->count)) {
00160 printf("Zones overlap!\n");
00161 return -1;
00162 }
00163 if (newzone->base < z->base)
00164 break;
00165 }
00166
00167 for (j = i;j < zones.count; j++)
00168 zones.info[j + 1] = zones.info[j];
00169 zones.info[i] = newzone;
00170 zones.count++;
00171 spinlock_unlock(&zones.lock);
00172 interrupts_restore(ipl);
00173
00174 return i;
00175 }
00176
00187 static zone_t * find_zone_and_lock(pfn_t frame, int *pzone)
00188 {
00189 int i;
00190 int hint = pzone ? *pzone : 0;
00191 zone_t *z;
00192
00193 spinlock_lock(&zones.lock);
00194
00195 if (hint >= zones.count || hint < 0)
00196 hint = 0;
00197
00198 i = hint;
00199 do {
00200 z = zones.info[i];
00201 spinlock_lock(&z->lock);
00202 if (z->base <= frame && z->base + z->count > frame) {
00203 spinlock_unlock(&zones.lock);
00204 if (pzone)
00205 *pzone = i;
00206 return z;
00207 }
00208 spinlock_unlock(&z->lock);
00209
00210 i++;
00211 if (i >= zones.count)
00212 i = 0;
00213 } while(i != hint);
00214
00215 spinlock_unlock(&zones.lock);
00216 return NULL;
00217 }
00218
00220 static int zone_can_alloc(zone_t *z, __u8 order)
00221 {
00222 return buddy_system_can_alloc(z->buddy_system, order);
00223 }
00224
00233 static zone_t * find_free_zone_lock(__u8 order, int *pzone)
00234 {
00235 int i;
00236 zone_t *z;
00237 int hint = pzone ? *pzone : 0;
00238
00239 spinlock_lock(&zones.lock);
00240 if (hint >= zones.count)
00241 hint = 0;
00242 i = hint;
00243 do {
00244 z = zones.info[i];
00245
00246 spinlock_lock(&z->lock);
00247
00248
00249 if (zone_can_alloc(z, order)) {
00250 spinlock_unlock(&zones.lock);
00251 if (pzone)
00252 *pzone = i;
00253 return z;
00254 }
00255 spinlock_unlock(&z->lock);
00256 if (++i >= zones.count)
00257 i = 0;
00258 } while(i != hint);
00259 spinlock_unlock(&zones.lock);
00260 return NULL;
00261 }
00262
00263
00264
00265
00273 static link_t *zone_buddy_find_block(buddy_system_t *b, link_t *child,
00274 __u8 order)
00275 {
00276 frame_t * frame;
00277 zone_t * zone;
00278 index_t index;
00279
00280 frame = list_get_instance(child, frame_t, buddy_link);
00281 zone = (zone_t *) b->data;
00282
00283 index = frame_index(zone, frame);
00284 do {
00285 if (zone->frames[index].buddy_order != order) {
00286 return &zone->frames[index].buddy_link;
00287 }
00288 } while(index-- > 0);
00289 return NULL;
00290 }
00291
00292 static void zone_buddy_print_id(buddy_system_t *b, link_t *block)
00293 {
00294 frame_t * frame;
00295 zone_t * zone;
00296 index_t index;
00297
00298 frame = list_get_instance(block, frame_t, buddy_link);
00299 zone = (zone_t *) b->data;
00300 index = frame_index(zone, frame);
00301 printf("%zd", index);
00302 }
00303
00311 static link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * block)
00312 {
00313 frame_t * frame;
00314 zone_t * zone;
00315 index_t index;
00316 bool is_left, is_right;
00317
00318 frame = list_get_instance(block, frame_t, buddy_link);
00319 zone = (zone_t *) b->data;
00320 ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame), frame->buddy_order));
00321
00322 is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
00323 is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame);
00324
00325 ASSERT(is_left ^ is_right);
00326 if (is_left) {
00327 index = (frame_index(zone, frame)) + (1 << frame->buddy_order);
00328 } else {
00329 index = (frame_index(zone, frame)) - (1 << frame->buddy_order);
00330 }
00331
00332 if (frame_index_valid(zone, index)) {
00333 if (zone->frames[index].buddy_order == frame->buddy_order &&
00334 zone->frames[index].refcount == 0) {
00335 return &zone->frames[index].buddy_link;
00336 }
00337 }
00338
00339 return NULL;
00340 }
00341
00349 static link_t * zone_buddy_bisect(buddy_system_t *b, link_t * block) {
00350 frame_t * frame_l, * frame_r;
00351
00352 frame_l = list_get_instance(block, frame_t, buddy_link);
00353 frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
00354
00355 return &frame_r->buddy_link;
00356 }
00357
00366 static link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * block_1,
00367 link_t * block_2)
00368 {
00369 frame_t *frame1, *frame2;
00370
00371 frame1 = list_get_instance(block_1, frame_t, buddy_link);
00372 frame2 = list_get_instance(block_2, frame_t, buddy_link);
00373
00374 return frame1 < frame2 ? block_1 : block_2;
00375 }
00376
00383 static void zone_buddy_set_order(buddy_system_t *b, link_t * block, __u8 order) {
00384 frame_t * frame;
00385 frame = list_get_instance(block, frame_t, buddy_link);
00386 frame->buddy_order = order;
00387 }
00388
00396 static __u8 zone_buddy_get_order(buddy_system_t *b, link_t * block) {
00397 frame_t * frame;
00398 frame = list_get_instance(block, frame_t, buddy_link);
00399 return frame->buddy_order;
00400 }
00401
00408 static void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) {
00409 frame_t * frame;
00410
00411 frame = list_get_instance(block, frame_t, buddy_link);
00412 frame->refcount = 1;
00413 }
00414
00421 static void zone_buddy_mark_available(buddy_system_t *b, link_t * block) {
00422 frame_t * frame;
00423 frame = list_get_instance(block, frame_t, buddy_link);
00424 frame->refcount = 0;
00425 }
00426
00427 static struct buddy_system_operations zone_buddy_system_operations = {
00428 .find_buddy = zone_buddy_find_buddy,
00429 .bisect = zone_buddy_bisect,
00430 .coalesce = zone_buddy_coalesce,
00431 .set_order = zone_buddy_set_order,
00432 .get_order = zone_buddy_get_order,
00433 .mark_busy = zone_buddy_mark_busy,
00434 .mark_available = zone_buddy_mark_available,
00435 .find_block = zone_buddy_find_block,
00436 .print_id = zone_buddy_print_id
00437 };
00438
00439
00440
00441
00453 static pfn_t zone_frame_alloc(zone_t *zone, __u8 order)
00454 {
00455 pfn_t v;
00456 link_t *tmp;
00457 frame_t *frame;
00458
00459
00460 tmp = buddy_system_alloc(zone->buddy_system, order);
00461
00462 ASSERT(tmp);
00463
00464
00465 zone->free_count -= (1 << order);
00466 zone->busy_count += (1 << order);
00467
00468
00469 frame = list_get_instance(tmp, frame_t, buddy_link);
00470
00471
00472 v = make_frame_index(zone, frame);
00473 return v;
00474 }
00475
00483 static void zone_frame_free(zone_t *zone, index_t frame_idx)
00484 {
00485 frame_t *frame;
00486 __u8 order;
00487
00488 frame = &zone->frames[frame_idx];
00489
00490
00491 order = frame->buddy_order;
00492
00493 ASSERT(frame->refcount);
00494
00495 if (!--frame->refcount) {
00496 buddy_system_free(zone->buddy_system, &frame->buddy_link);
00497
00498
00499 zone->free_count += (1 << order);
00500 zone->busy_count -= (1 << order);
00501 }
00502 }
00503
00505 static frame_t * zone_get_frame(zone_t *zone, index_t frame_idx)
00506 {
00507 ASSERT(frame_idx < zone->count);
00508 return &zone->frames[frame_idx];
00509 }
00510
00512 static void zone_mark_unavailable(zone_t *zone, index_t frame_idx)
00513 {
00514 frame_t *frame;
00515 link_t *link;
00516
00517 frame = zone_get_frame(zone, frame_idx);
00518 if (frame->refcount)
00519 return;
00520 link = buddy_system_alloc_block(zone->buddy_system,
00521 &frame->buddy_link);
00522 ASSERT(link);
00523 zone->free_count--;
00524 }
00525
00538 static void _zone_merge(zone_t *z, zone_t *z1, zone_t *z2)
00539 {
00540 __u8 max_order;
00541 int i, z2idx;
00542 pfn_t frame_idx;
00543 frame_t *frame;
00544
00545 ASSERT(!overlaps(z1->base,z1->count,z2->base,z2->count));
00546 ASSERT(z1->base < z2->base);
00547
00548 spinlock_initialize(&z->lock, "zone_lock");
00549 z->base = z1->base;
00550 z->count = z2->base+z2->count - z1->base;
00551 z->flags = z1->flags & z2->flags;
00552
00553 z->free_count = z1->free_count + z2->free_count;
00554 z->busy_count = z1->busy_count + z2->busy_count;
00555
00556 max_order = fnzb(z->count);
00557
00558 z->buddy_system = (buddy_system_t *)&z[1];
00559 buddy_system_create(z->buddy_system, max_order,
00560 &zone_buddy_system_operations,
00561 (void *) z);
00562
00563 z->frames = (frame_t *)((void *)z->buddy_system+buddy_conf_size(max_order));
00564 for (i = 0; i < z->count; i++) {
00565
00566 frame_initialize(&z->frames[i]);
00567 }
00568
00569
00570
00571
00572
00573
00574
00575 for (i=0; i<z1->count; i++)
00576 z->frames[i] = z1->frames[i];
00577 for (i=0; i < z2->count; i++) {
00578 z2idx = i + (z2->base - z1->base);
00579 z->frames[z2idx] = z2->frames[i];
00580 }
00581 i = 0;
00582 while (i < z->count) {
00583 if (z->frames[i].refcount) {
00584
00585 i += 1 << z->frames[i].buddy_order;
00586 } else {
00587
00588
00589 z->frames[i].refcount = 1;
00590 z->frames[i].buddy_order = 0;
00591 i++;
00592 }
00593 }
00594
00595 while (zone_can_alloc(z1, 0)) {
00596 frame_idx = zone_frame_alloc(z1, 0);
00597 frame = &z->frames[frame_idx];
00598 frame->refcount = 0;
00599 buddy_system_free(z->buddy_system, &frame->buddy_link);
00600 }
00601 while (zone_can_alloc(z2, 0)) {
00602 frame_idx = zone_frame_alloc(z2, 0);
00603 frame = &z->frames[frame_idx + (z2->base-z1->base)];
00604 frame->refcount = 0;
00605 buddy_system_free(z->buddy_system, &frame->buddy_link);
00606 }
00607 }
00608
00620 static void return_config_frames(zone_t *newzone, zone_t *oldzone)
00621 {
00622 pfn_t pfn;
00623 frame_t *frame;
00624 count_t cframes;
00625 int i;
00626
00627 pfn = ADDR2PFN((__address)KA2PA(oldzone));
00628 cframes = SIZE2FRAMES(zone_conf_size(oldzone->count));
00629
00630 if (pfn < newzone->base || pfn >= newzone->base + newzone->count)
00631 return;
00632
00633 frame = &newzone->frames[pfn - newzone->base];
00634 ASSERT(!frame->buddy_order);
00635
00636 for (i=0; i < cframes; i++) {
00637 newzone->busy_count++;
00638 zone_frame_free(newzone, pfn+i-newzone->base);
00639 }
00640 }
00641
00653 static void zone_reduce_region(zone_t *zone, pfn_t frame_idx, count_t count)
00654 {
00655 count_t i;
00656 __u8 order;
00657 frame_t *frame;
00658
00659 ASSERT(frame_idx+count < zone->count);
00660
00661 order = zone->frames[frame_idx].buddy_order;
00662 ASSERT((1 << order) >= count);
00663
00664
00665 for (i=0; i < (1 << order); i++) {
00666 frame = &zone->frames[i + frame_idx];
00667 frame->buddy_order = 0;
00668 if (! frame->refcount)
00669 frame->refcount = 1;
00670 ASSERT(frame->refcount == 1);
00671 }
00672
00673 for (i=count; i < (1 << order); i++) {
00674 zone_frame_free(zone, i + frame_idx);
00675 }
00676 }
00677
00687 void zone_merge(int z1, int z2)
00688 {
00689 ipl_t ipl;
00690 zone_t *zone1, *zone2, *newzone;
00691 int cframes;
00692 __u8 order;
00693 int i;
00694 pfn_t pfn;
00695
00696 ipl = interrupts_disable();
00697 spinlock_lock(&zones.lock);
00698
00699 if (z1 < 0 || z1 >= zones.count || z2 < 0 || z2 >= zones.count)
00700 goto errout;
00701
00702 if (z2-z1 != 1)
00703 goto errout;
00704
00705 zone1 = zones.info[z1];
00706 zone2 = zones.info[z2];
00707 spinlock_lock(&zone1->lock);
00708 spinlock_lock(&zone2->lock);
00709
00710 cframes = SIZE2FRAMES(zone_conf_size(zone2->base+zone2->count-zone1->base));
00711 if (cframes == 1)
00712 order = 0;
00713 else
00714 order = fnzb(cframes - 1) + 1;
00715
00716
00717 if (zone_can_alloc(zone1, order))
00718 pfn = zone1->base + zone_frame_alloc(zone1, order);
00719 else if (zone_can_alloc(zone2, order))
00720 pfn = zone2->base + zone_frame_alloc(zone2, order);
00721 else
00722 goto errout2;
00723
00724 newzone = (zone_t *)PA2KA(PFN2ADDR(pfn));
00725
00726 _zone_merge(newzone, zone1, zone2);
00727
00728
00729 zone_reduce_region(newzone, pfn - newzone->base, cframes);
00730
00731 newzone->busy_count -= cframes;
00732
00733
00734 zones.info[z1] = newzone;
00735 for (i = z2 + 1; i < zones.count; i++)
00736 zones.info[i - 1] = zones.info[i];
00737 zones.count--;
00738
00739
00740 return_config_frames(newzone, zone1);
00741 return_config_frames(newzone, zone2);
00742 errout2:
00743
00744
00745 spinlock_unlock(&zone1->lock);
00746 spinlock_unlock(&zone2->lock);
00747 errout:
00748 spinlock_unlock(&zones.lock);
00749 interrupts_restore(ipl);
00750 }
00751
00758 void zone_merge_all(void)
00759 {
00760 int count = zones.count;
00761
00762 while (zones.count > 1 && --count) {
00763 zone_merge(0,1);
00764 break;
00765 }
00766 }
00767
00779 static void zone_construct(pfn_t start, count_t count, zone_t *z, int flags)
00780 {
00781 int i;
00782 __u8 max_order;
00783
00784 spinlock_initialize(&z->lock, "zone_lock");
00785 z->base = start;
00786 z->count = count;
00787 z->flags = flags;
00788 z->free_count = count;
00789 z->busy_count = 0;
00790
00791
00792
00793
00794 max_order = fnzb(count);
00795 z->buddy_system = (buddy_system_t *)&z[1];
00796
00797 buddy_system_create(z->buddy_system, max_order,
00798 &zone_buddy_system_operations,
00799 (void *) z);
00800
00801
00802
00803 z->frames = (frame_t *)((void *)z->buddy_system+buddy_conf_size(max_order));
00804 for (i = 0; i<count; i++) {
00805 frame_initialize(&z->frames[i]);
00806 }
00807
00808
00809 for (i = 0; i < count; i++) {
00810 z->frames[i].refcount = 0;
00811 buddy_system_free(z->buddy_system, &z->frames[i].buddy_link);
00812 }
00813 }
00814
00820 __address zone_conf_size(count_t count)
00821 {
00822 int size = sizeof(zone_t) + count*sizeof(frame_t);
00823 int max_order;
00824
00825 max_order = fnzb(count);
00826 size += buddy_conf_size(max_order);
00827 return size;
00828 }
00829
00845 int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags)
00846 {
00847 zone_t *z;
00848 __address addr;
00849 count_t confcount;
00850 int i;
00851 int znum;
00852
00853
00854
00855
00856
00857 ASSERT(confframe);
00858
00859
00860
00861 confcount = SIZE2FRAMES(zone_conf_size(count));
00862 if (confframe >= start && confframe < start+count) {
00863 for (;confframe < start + count; confframe++) {
00864 addr = PFN2ADDR(confframe);
00865 if (overlaps(addr, PFN2ADDR(confcount), KA2PA(config.base), config.kernel_size))
00866 continue;
00867
00868 bool overlap = false;
00869 count_t i;
00870 for (i = 0; i < init.cnt; i++)
00871 if (overlaps(addr, PFN2ADDR(confcount), KA2PA(init.tasks[i].addr), init.tasks[i].size)) {
00872 overlap = true;
00873 break;
00874 }
00875 if (overlap)
00876 continue;
00877
00878 break;
00879 }
00880 if (confframe >= start + count)
00881 panic("Cannot find configuration data for zone.");
00882 }
00883
00884 z = (zone_t *)PA2KA(PFN2ADDR(confframe));
00885 zone_construct(start, count, z, flags);
00886 znum = zones_add_zone(z);
00887 if (znum == -1)
00888 return -1;
00889
00890
00891 if (confframe >= start && confframe < start+count)
00892 for (i=confframe; i<confframe+confcount; i++) {
00893 zone_mark_unavailable(z, i - z->base);
00894 }
00895 return znum;
00896 }
00897
00898
00899
00900
00902 void frame_set_parent(pfn_t pfn, void *data, int hint)
00903 {
00904 zone_t *zone = find_zone_and_lock(pfn, &hint);
00905
00906 ASSERT(zone);
00907
00908 zone_get_frame(zone, pfn-zone->base)->parent = data;
00909 spinlock_unlock(&zone->lock);
00910 }
00911
00912 void * frame_get_parent(pfn_t pfn, int hint)
00913 {
00914 zone_t *zone = find_zone_and_lock(pfn, &hint);
00915 void *res;
00916
00917 ASSERT(zone);
00918 res = zone_get_frame(zone, pfn - zone->base)->parent;
00919
00920 spinlock_unlock(&zone->lock);
00921 return res;
00922 }
00923
00934 pfn_t frame_alloc_generic(__u8 order, int flags, int *status, int *pzone)
00935 {
00936 ipl_t ipl;
00937 int freed;
00938 pfn_t v;
00939 zone_t *zone;
00940
00941 loop:
00942 ipl = interrupts_disable();
00943
00944
00945
00946
00947 zone = find_free_zone_lock(order, pzone);
00948
00949
00950
00951 if (!zone && !(flags & FRAME_NO_RECLAIM)) {
00952 freed = slab_reclaim(0);
00953 if (freed)
00954 zone = find_free_zone_lock(order, pzone);
00955 if (!zone) {
00956 freed = slab_reclaim(SLAB_RECLAIM_ALL);
00957 if (freed)
00958 zone = find_free_zone_lock(order, pzone);
00959 }
00960 }
00961 if (!zone) {
00962 if (flags & FRAME_PANIC)
00963 panic("Can't allocate frame.\n");
00964
00965
00966
00967
00968 interrupts_restore(ipl);
00969
00970 if (flags & FRAME_ATOMIC) {
00971 ASSERT(status != NULL);
00972 if (status)
00973 *status = FRAME_NO_MEMORY;
00974 return NULL;
00975 }
00976
00977 panic("Sleep not implemented.\n");
00978 goto loop;
00979 }
00980
00981 v = zone_frame_alloc(zone, order);
00982 v += zone->base;
00983
00984 spinlock_unlock(&zone->lock);
00985 interrupts_restore(ipl);
00986
00987 if (status)
00988 *status = FRAME_OK;
00989 return v;
00990 }
00991
01000 void frame_free(pfn_t pfn)
01001 {
01002 ipl_t ipl;
01003 zone_t *zone;
01004
01005 ipl = interrupts_disable();
01006
01007
01008
01009
01010 zone = find_zone_and_lock(pfn,NULL);
01011 ASSERT(zone);
01012
01013 zone_frame_free(zone, pfn-zone->base);
01014
01015 spinlock_unlock(&zone->lock);
01016 interrupts_restore(ipl);
01017 }
01018
01026 void frame_reference_add(pfn_t pfn)
01027 {
01028 ipl_t ipl;
01029 zone_t *zone;
01030 frame_t *frame;
01031
01032 ipl = interrupts_disable();
01033
01034
01035
01036
01037 zone = find_zone_and_lock(pfn,NULL);
01038 ASSERT(zone);
01039
01040 frame = &zone->frames[pfn-zone->base];
01041 frame->refcount++;
01042
01043 spinlock_unlock(&zone->lock);
01044 interrupts_restore(ipl);
01045 }
01046
01048 void frame_mark_unavailable(pfn_t start, count_t count)
01049 {
01050 int i;
01051 zone_t *zone;
01052 int prefzone = 0;
01053
01054 for (i=0; i < count; i++) {
01055 zone = find_zone_and_lock(start+i,&prefzone);
01056 if (!zone)
01057 continue;
01058 zone_mark_unavailable(zone, start+i-zone->base);
01059
01060 spinlock_unlock(&zone->lock);
01061 }
01062 }
01063
01068 void frame_init(void)
01069 {
01070 if (config.cpu_active == 1) {
01071 zones.count = 0;
01072 spinlock_initialize(&zones.lock,"zones_glob_lock");
01073 }
01074
01075 frame_arch_init();
01076 if (config.cpu_active == 1) {
01077 pfn_t firstframe = ADDR2PFN(KA2PA(config.base));
01078 pfn_t lastframe = ADDR2PFN(KA2PA(config.base+config.kernel_size));
01079 frame_mark_unavailable(firstframe,lastframe-firstframe+1);
01080
01081 count_t i;
01082 for (i = 0; i < init.cnt; i++)
01083 frame_mark_unavailable(ADDR2PFN(KA2PA(init.tasks[i].addr)), SIZE2FRAMES(init.tasks[i].size));
01084
01085
01086
01087 frame_mark_unavailable(0, 1);
01088 }
01089 }
01090
01091
01092
01096 void zone_print_list(void) {
01097 zone_t *zone = NULL;
01098 int i;
01099 ipl_t ipl;
01100
01101 ipl = interrupts_disable();
01102 spinlock_lock(&zones.lock);
01103 printf("# Base address\tFree Frames\tBusy Frames\n");
01104 printf(" ------------\t-----------\t-----------\n");
01105 for (i = 0; i < zones.count; i++) {
01106 zone = zones.info[i];
01107 spinlock_lock(&zone->lock);
01108 printf("%d: %.*p \t%10zd\t%10zd\n", i, sizeof(__address) * 2, PFN2ADDR(zone->base), zone->free_count, zone->busy_count);
01109 spinlock_unlock(&zone->lock);
01110 }
01111 spinlock_unlock(&zones.lock);
01112 interrupts_restore(ipl);
01113 }
01114
01119 void zone_print_one(int num) {
01120 zone_t *zone = NULL;
01121 ipl_t ipl;
01122 int i;
01123
01124 ipl = interrupts_disable();
01125 spinlock_lock(&zones.lock);
01126
01127 for (i = 0; i < zones.count; i++) {
01128 if (i == num || PFN2ADDR(zones.info[i]->base) == num) {
01129 zone = zones.info[i];
01130 break;
01131 }
01132 }
01133 if (!zone) {
01134 printf("Zone not found.\n");
01135 goto out;
01136 }
01137
01138 spinlock_lock(&zone->lock);
01139 printf("Memory zone information\n");
01140 printf("Zone base address: %#.*p\n", sizeof(__address) * 2, PFN2ADDR(zone->base));
01141 printf("Zone size: %zd frames (%zdK)\n", zone->count, ((zone->count) * FRAME_SIZE) >> 10);
01142 printf("Allocated space: %zd frames (%zdK)\n", zone->busy_count, (zone->busy_count * FRAME_SIZE) >> 10);
01143 printf("Available space: %zd (%zdK)\n", zone->free_count, (zone->free_count * FRAME_SIZE) >> 10);
01144 buddy_system_structure_print(zone->buddy_system, FRAME_SIZE);
01145
01146 spinlock_unlock(&zone->lock);
01147 out:
01148 spinlock_unlock(&zones.lock);
01149 interrupts_restore(ipl);
01150 }
01151
01152