Subversion Repositories HelenOS-historic

Rev

Rev 820 | Rev 824 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 820 Rev 822
Line 48... Line 48...
48
#include <arch/asm.h>
48
#include <arch/asm.h>
49
#include <arch.h>
49
#include <arch.h>
50
#include <print.h>
50
#include <print.h>
51
#include <align.h>
51
#include <align.h>
52
#include <mm/slab.h>
52
#include <mm/slab.h>
-
 
53
#include <bitops.h>
53
 
54
 
54
typedef struct {
55
typedef struct {
55
    count_t refcount;   /**< tracking of shared frames  */
56
    count_t refcount;   /**< tracking of shared frames  */
56
    __u8 buddy_order;   /**< buddy system block order */
57
    __u8 buddy_order;   /**< buddy system block order */
57
    link_t buddy_link;  /**< link to the next free block inside one order */
58
    link_t buddy_link;  /**< link to the next free block inside one order */
Line 119... Line 120...
119
/*************************************/
120
/*************************************/
120
/* Zoneinfo functions */
121
/* Zoneinfo functions */
121
 
122
 
122
/**
123
/**
123
 * Insert-sort zone into zones list
124
 * Insert-sort zone into zones list
-
 
125
 *
-
 
126
 * @return zone number on success, -1 on error
124
 */
127
 */
125
static void zones_add_zone(zone_t *zone)
128
static int zones_add_zone(zone_t *newzone)
126
{
129
{
127
    int i;
130
    int i,j;
-
 
131
    ipl_t ipl;
-
 
132
    zone_t *z;
128
 
133
 
-
 
134
    ipl = interrupts_disable();
129
    spinlock_lock(&zones.lock);
135
    spinlock_lock(&zones.lock);
130
    /* Try to merge */
136
    /* Try to merge */
131
    if (zone->flags & ZONE_JOIN) {
137
    if (zones.count+1 == ZONES_MAX)
-
 
138
        panic("Maximum zone(%d) count exceeded.", ZONES_MAX);
-
 
139
 
132
        for (i=0; i < zones.count; i++) {
140
    for (i=0; i < zones.count; i++) {
133
            spinlock_lock(&zones.info[i]->lock);
141
        /* Check for overflow */
134
           
-
 
135
            /* Join forward, join backward */
142
        z = zones.info[zones.count];
-
 
143
        if (overlaps(newzone->base,newzone->count,
136
            panic("Not implemented");
144
                 z->base, z->count)) {
137
 
-
 
138
            spinlock_unlock(&zones.info[i]->lock);
145
            printf("Zones overlap!\n");
-
 
146
            return -1;
139
        }
147
        }
140
        spinlock_unlock(&zones.lock);
148
        if (z->base < newzone->base)
141
    } else {
149
            break;
142
        if (zones.count+1 == ZONES_MAX)
-
 
143
            panic("Maximum zone(%d) count exceeded.", ZONES_MAX);
-
 
144
        zones.info[zones.count++] = zone;
-
 
145
    }
150
    }
-
 
151
    /* Move other zones up */
-
 
152
    for (j=i;j < zones.count;j++)
-
 
153
        zones.info[j+1] = zones.info[j];
-
 
154
 
-
 
155
    zones.info[i] = newzone;
-
 
156
    zones.count++;
-
 
157
 
146
    spinlock_unlock(&zones.lock);
158
    spinlock_unlock(&zones.lock);
-
 
159
    interrupts_restore(ipl);
-
 
160
 
-
 
161
    return i;
147
}
162
}
148
 
163
 
149
/**
164
/**
150
 * Try to find a zone where can we find the frame
165
 * Try to find a zone where can we find the frame
151
 *
166
 *
Line 184... Line 199...
184
 
199
 
185
    spinlock_unlock(&zones.lock);
200
    spinlock_unlock(&zones.lock);
186
    return NULL;
201
    return NULL;
187
}
202
}
188
 
203
 
-
 
204
/** @return True if zone can allocate specified order */
-
 
205
static int zone_can_alloc(zone_t *z, __u8 order)
-
 
206
{
-
 
207
    return buddy_system_can_alloc(z->buddy_system, order);
-
 
208
}
-
 
209
 
189
/**
210
/**
190
 * Find AND LOCK zone that can allocate order frames
211
 * Find AND LOCK zone that can allocate order frames
191
 *
212
 *
192
 * Assume interrupts are disabled!!
213
 * Assume interrupts are disabled!!
193
 *
214
 *
Line 207... Line 228...
207
        z = zones.info[i];
228
        z = zones.info[i];
208
       
229
       
209
        spinlock_lock(&z->lock);
230
        spinlock_lock(&z->lock);
210
 
231
 
211
        /* Check if the zone has 2^order frames area available  */
232
        /* Check if the zone has 2^order frames area available  */
212
        if (buddy_system_can_alloc(z->buddy_system, order)) {
233
        if (zone_can_alloc(z, order)) {
213
            spinlock_unlock(&zones.lock);
234
            spinlock_unlock(&zones.lock);
214
            if (pzone)
235
            if (pzone)
215
                *pzone = i;
236
                *pzone = i;
216
            return z;
237
            return z;
217
        }
238
        }
Line 250... Line 271...
250
        }
271
        }
251
    } while(index-- > 0);
272
    } while(index-- > 0);
252
    return NULL;
273
    return NULL;
253
}
274
}
254
 
275
 
-
 
276
static void zone_buddy_print_id(buddy_system_t *b, link_t *block)
-
 
277
{
-
 
278
    frame_t * frame;
-
 
279
    zone_t * zone;
-
 
280
    index_t index;
-
 
281
 
-
 
282
    frame = list_get_instance(block, frame_t, buddy_link);
-
 
283
    zone = (zone_t *) b->data;
-
 
284
    index = frame_index(zone, frame);
-
 
285
    printf("%d", index);
255
                     
286
}                    
256
 
287
 
257
/** Buddy system find_buddy implementation
288
/** Buddy system find_buddy implementation
258
 *
289
 *
259
 * @param b Buddy system.
290
 * @param b Buddy system.
260
 * @param block Block for which buddy should be found
291
 * @param block Block for which buddy should be found
Line 316... Line 347...
316
 * @param block_2 First block's buddy
347
 * @param block_2 First block's buddy
317
 *
348
 *
318
 * @return Coalesced block (actually block that represents lower address)
349
 * @return Coalesced block (actually block that represents lower address)
319
 */
350
 */
320
static link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * block_1,
351
static link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * block_1,
321
                    link_t * block_2) {
352
                    link_t * block_2)
-
 
353
{
322
    frame_t *frame1, *frame2;
354
    frame_t *frame1, *frame2;
323
   
355
   
324
    frame1 = list_get_instance(block_1, frame_t, buddy_link);
356
    frame1 = list_get_instance(block_1, frame_t, buddy_link);
325
    frame2 = list_get_instance(block_2, frame_t, buddy_link);
357
    frame2 = list_get_instance(block_2, frame_t, buddy_link);
326
   
358
   
Line 358... Line 390...
358
 * @param block Buddy system block
390
 * @param block Buddy system block
359
 *
391
 *
360
 */
392
 */
361
static void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) {
393
static void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) {
362
    frame_t * frame;
394
    frame_t * frame;
-
 
395
 
363
    frame = list_get_instance(block, frame_t, buddy_link);
396
    frame = list_get_instance(block, frame_t, buddy_link);
364
    frame->refcount = 1;
397
    frame->refcount = 1;
365
}
398
}
366
 
399
 
367
/** Buddy system mark_available implementation
400
/** Buddy system mark_available implementation
Line 382... Line 415...
382
    .coalesce = zone_buddy_coalesce,
415
    .coalesce = zone_buddy_coalesce,
383
    .set_order = zone_buddy_set_order,
416
    .set_order = zone_buddy_set_order,
384
    .get_order = zone_buddy_get_order,
417
    .get_order = zone_buddy_get_order,
385
    .mark_busy = zone_buddy_mark_busy,
418
    .mark_busy = zone_buddy_mark_busy,
386
    .mark_available = zone_buddy_mark_available,
419
    .mark_available = zone_buddy_mark_available,
387
    .find_block = zone_buddy_find_block
420
    .find_block = zone_buddy_find_block,
-
 
421
    .print_id = zone_buddy_print_id
388
};
422
};
389
 
423
 
390
/*************************************/
424
/*************************************/
391
/* Zone functions */
425
/* Zone functions */
392
 
426
 
393
/** Allocate frame in particular zone
427
/** Allocate frame in particular zone
394
 *
428
 *
395
 * Assume zone is locked
429
 * Assume zone is locked
-
 
430
 * Panics, if allocation is impossible.
396
 *
431
 *
397
 * @return Frame index in zone
432
 * @return Frame index in zone
398
 */
433
 */
399
static pfn_t zone_frame_alloc(zone_t *zone,__u8 order, int flags, int *status)
434
static pfn_t zone_frame_alloc(zone_t *zone,__u8 order)
400
{
435
{
401
    pfn_t v;
436
    pfn_t v;
402
    link_t *tmp;
437
    link_t *tmp;
403
    frame_t *frame;
438
    frame_t *frame;
404
 
439
 
Line 456... Line 491...
456
{
491
{
457
    frame_t *frame;
492
    frame_t *frame;
458
    link_t *link;
493
    link_t *link;
459
 
494
 
460
    frame = zone_get_frame(zone, frame_idx);
495
    frame = zone_get_frame(zone, frame_idx);
-
 
496
    if (frame->refcount)
-
 
497
        return;
461
    link = buddy_system_alloc_block(zone->buddy_system,
498
    link = buddy_system_alloc_block(zone->buddy_system,
462
                    &frame->buddy_link);
499
                    &frame->buddy_link);
463
    ASSERT(link);
500
    ASSERT(link);
464
    zone->free_count--;
501
    zone->free_count--;
465
}
502
}
466
 
503
 
-
 
504
/**
-
 
505
 * Join 2 zones
-
 
506
 *
-
 
507
 * Expect zone_t *z to point to space at least zone_conf_size large
-
 
508
 *
-
 
509
 * Assume z1 & z2 are locked
-
 
510
 */
-
 
511
 
-
 
512
static void _zone_merge(zone_t *z, zone_t *z1, zone_t *z2)
-
 
513
{
-
 
514
    __u8 max_order;
-
 
515
    int i, z2idx;
-
 
516
    pfn_t frame_idx;
-
 
517
    frame_t *frame;
-
 
518
 
-
 
519
    ASSERT(!overlaps(z1->base,z1->count,z2->base,z2->count));
-
 
520
    ASSERT(z1->base < z2->base);
-
 
521
 
-
 
522
    spinlock_initialize(&z->lock, "zone_lock");
-
 
523
    z->base = z1->base;
-
 
524
    z->count = z2->base+z2->count - z1->base;
-
 
525
    z->flags = z1->flags & z2->flags;
-
 
526
 
-
 
527
    z->free_count = z1->free_count + z2->free_count;
-
 
528
    z->busy_count = z1->busy_count + z2->busy_count;
-
 
529
   
-
 
530
    max_order = fnzb(z->count);
-
 
531
 
-
 
532
    z->buddy_system = (buddy_system_t *)&z[1];
-
 
533
    buddy_system_create(z->buddy_system, max_order,
-
 
534
                &zone_buddy_system_operations,
-
 
535
                (void *) z);
-
 
536
 
-
 
537
    z->frames = (frame_t *)((void *)z->buddy_system+buddy_conf_size(max_order));
-
 
538
    for (i = 0; i < z->count; i++) {
-
 
539
        /* This marks all frames busy */
-
 
540
        frame_initialize(&z->frames[i]);
-
 
541
    }
-
 
542
    /* Copy frames from both zones to preserve full frame orders,
-
 
543
     * parents etc. Set all frames with refcount=0 to 1, because
-
 
544
     * we add all free frames to buddy allocator later again, clear
-
 
545
     * order to 0.
-
 
546
     */
-
 
547
    for (i=0; i<z1->count; i++)
-
 
548
        z->frames[i] = z1->frames[i];
-
 
549
    for (i=0; i < z2->count; i++) {
-
 
550
        z2idx = i + (z2->base - z1->base);
-
 
551
        z->frames[z2idx] = z2->frames[i];
-
 
552
    }
-
 
553
    for (i=0; i < z->count; i++) {
-
 
554
        if (!z->frames[i].refcount) {
-
 
555
            z->frames[i].refcount = 1;
-
 
556
            z->frames[i].buddy_order = 0;
-
 
557
        }
-
 
558
    }
-
 
559
    /* Add free blocks from the 2 original zones */
-
 
560
    while (zone_can_alloc(z1, 0)) {
-
 
561
        frame_idx = zone_frame_alloc(z1, 0);
-
 
562
        frame = &z->frames[frame_idx];
-
 
563
        frame->refcount = 0;
-
 
564
        buddy_system_free(z->buddy_system, &frame->buddy_link);
-
 
565
    }
-
 
566
    while (zone_can_alloc(z2, 0)) {
-
 
567
        frame_idx = zone_frame_alloc(z2, 0);
-
 
568
        frame = &z->frames[frame_idx + (z2->base-z1->base)];
-
 
569
        frame->refcount = 0;
-
 
570
        buddy_system_free(z->buddy_system, &frame->buddy_link);
-
 
571
    }
-
 
572
}
-
 
573
 
-
 
574
/** Return old configuration frames into the zone
-
 
575
 *
-
 
576
 * We have several cases
-
 
577
 * - the conf. data is outside of zone -> exit, shall we call frame_free??
-
 
578
 * - the conf. data was created by zone_create -> free every frame
-
 
579
 * - the conf. data was created by merge in frame_alloc -> free first frame
-
 
580
 *   (the difference is in order)
-
 
581
 */
-
 
582
static void return_config_frames(zone_t *newzone, zone_t *oldzone)
-
 
583
{
-
 
584
    pfn_t pfn;
-
 
585
    frame_t *frame;
-
 
586
    count_t cframes;
-
 
587
    int i;
-
 
588
 
-
 
589
    pfn = ADDR2PFN((__address)KA2PA(oldzone));
-
 
590
    cframes = SIZE2FRAMES(zone_conf_size(oldzone->count));
-
 
591
   
-
 
592
    if (pfn < newzone->base || pfn >= newzone->base + newzone->count)
-
 
593
        return;
-
 
594
 
-
 
595
    frame = &newzone->frames[pfn - newzone->base];
-
 
596
    if (frame->buddy_order) {
-
 
597
        /* Normally zone config data is hidden, show it again */
-
 
598
        newzone->busy_count += (1 << frame->buddy_order);
-
 
599
        zone_frame_free(newzone, pfn - newzone->base);
-
 
600
        return;
-
 
601
    }
-
 
602
 
-
 
603
    for (i=0; i < cframes; i++) {
-
 
604
        newzone->busy_count++;
-
 
605
        zone_frame_free(newzone, pfn+i-newzone->base);
-
 
606
    }
-
 
607
}
-
 
608
 
-
 
609
/** Merge zones z1 and z2
-
 
610
 *
-
 
611
 * - the zones must be 2 zones with no zone existing in between,
-
 
612
 *   which means that z2 = z1+1
-
 
613
 *
-
 
614
 * - When you create a new zone, the frame allocator configuration does
-
 
615
 *   not to be 2^order size. Once the allocator is running it is no longer
-
 
616
 *   possible, merged configuration data occupies more space :-/
-
 
617
 */
-
 
618
void zone_merge(int z1, int z2)
-
 
619
{
-
 
620
    ipl_t ipl;
-
 
621
    zone_t *zone1, *zone2, *newzone;
-
 
622
    int cframes;
-
 
623
    __u8 order;
-
 
624
    int i;
-
 
625
    pfn_t pfn;
-
 
626
 
-
 
627
    ipl = interrupts_disable();
-
 
628
    spinlock_lock(&zones.lock);
-
 
629
 
-
 
630
    if (z1 < 0 || z1 >= zones.count || z2 < 0 || z2 >= zones.count)
-
 
631
        goto errout;
-
 
632
    /* We can join only 2 zones with none existing inbetween */
-
 
633
    if (z2-z1 != 1)
-
 
634
        goto errout;
-
 
635
 
-
 
636
    zone1 = zones.info[z1];
-
 
637
    zone2 = zones.info[z2];
-
 
638
    spinlock_lock(&zone1->lock);
-
 
639
    spinlock_lock(&zone2->lock);
-
 
640
 
-
 
641
    cframes = SIZE2FRAMES(zone_conf_size(zone2->base+zone2->count-zone1->base));
-
 
642
    order = fnzb(cframes) + 1;
-
 
643
 
-
 
644
    /* Allocate zonedata inside one of the zones */
-
 
645
    if (zone_can_alloc(zone1, order))
-
 
646
        pfn = zone1->base + zone_frame_alloc(zone1, order);
-
 
647
    else if (zone_can_alloc(zone2, order))
-
 
648
        pfn = zone2->base + zone_frame_alloc(zone2, order);
-
 
649
    else
-
 
650
        goto errout2;
-
 
651
 
-
 
652
    newzone = (zone_t *)PA2KA(PFN2ADDR(pfn));
-
 
653
 
-
 
654
    _zone_merge(newzone, zone1, zone2);
-
 
655
 
-
 
656
    /* Subtract zone information from busy frames */
-
 
657
    newzone->busy_count -= (1 << order);
-
 
658
 
-
 
659
    zones.info[z1] = newzone;
-
 
660
    for (i=z2+1;i < zones.count;i++)
-
 
661
        zones.info[i-1] = zones.info[i];
-
 
662
    zones.count--;
-
 
663
 
-
 
664
    /* Free old zone information */
-
 
665
    return_config_frames(newzone, zone1);
-
 
666
    return_config_frames(newzone, zone2);
-
 
667
errout2:
-
 
668
    /* Nobody is allowed to enter to zone, so we are safe
-
 
669
     * to touch the spinlocks last time */
-
 
670
    spinlock_unlock(&zone1->lock);
-
 
671
    spinlock_unlock(&zone2->lock);
-
 
672
errout:
-
 
673
    spinlock_unlock(&zones.lock);
-
 
674
    interrupts_restore(ipl);
-
 
675
}
-
 
676
 
-
 
677
 
-
 
678
/**
-
 
679
 * Merge all zones into one big zone
-
 
680
 *
-
 
681
 * It is reasonable to do this on systems whose bios reports parts in chunks,
-
 
682
 * so that we could have 1 zone (it's faster).
-
 
683
 */
-
 
684
void zone_merge_all(void)
-
 
685
{
-
 
686
    int count = zones.count;
-
 
687
 
-
 
688
    while (zones.count > 1 && --count) {
-
 
689
        zone_merge(0,1);
-
 
690
        break;
-
 
691
    }
-
 
692
}
-
 
693
 
467
/** Create frame zone
694
/** Create frame zone
468
 *
695
 *
469
 * Create new frame zone.
696
 * Create new frame zone.
470
 *
697
 *
471
 * @param start Physical address of the first frame within the zone.
698
 * @param start Physical address of the first frame within the zone.
Line 473... Line 700...
473
 * @param conffram Address of configuration frame
700
 * @param conffram Address of configuration frame
474
 * @param flags Zone flags.
701
 * @param flags Zone flags.
475
 *
702
 *
476
 * @return Initialized zone.
703
 * @return Initialized zone.
477
 */
704
 */
478
static zone_t * zone_construct(pfn_t start, count_t count,
705
static void zone_construct(pfn_t start, count_t count, zone_t *z, int flags)
479
                   zone_t *z, int flags)
-
 
480
{
706
{
481
    int i;
707
    int i;
482
    __u8 max_order;
708
    __u8 max_order;
483
 
709
 
484
    spinlock_initialize(&z->lock, "zone_lock");
710
    spinlock_initialize(&z->lock, "zone_lock");
Line 489... Line 715...
489
    z->busy_count = 0;
715
    z->busy_count = 0;
490
 
716
 
491
    /*
717
    /*
492
     * Compute order for buddy system, initialize
718
     * Compute order for buddy system, initialize
493
     */
719
     */
494
    for (max_order = 0; count >> max_order; max_order++)
720
    max_order = fnzb(count);
495
        ;
-
 
496
    z->buddy_system = (buddy_system_t *)&z[1];
721
    z->buddy_system = (buddy_system_t *)&z[1];
497
   
722
   
498
    buddy_system_create(z->buddy_system, max_order,
723
    buddy_system_create(z->buddy_system, max_order,
499
                &zone_buddy_system_operations,
724
                &zone_buddy_system_operations,
500
                (void *) z);
725
                (void *) z);
501
   
726
   
502
    /* Allocate frames _after_ the conframe */
727
    /* Allocate frames _after_ the conframe */
503
    /* Check sizes */
728
    /* Check sizes */
504
    z->frames = (frame_t *)((void *)z->buddy_system+buddy_conf_size(max_order));
729
    z->frames = (frame_t *)((void *)z->buddy_system+buddy_conf_size(max_order));
505
 
-
 
506
    for (i = 0; i<count; i++) {
730
    for (i = 0; i<count; i++) {
507
        frame_initialize(&z->frames[i]);
731
        frame_initialize(&z->frames[i]);
508
    }
732
    }
-
 
733
 
509
    /* Stuffing frames */
734
    /* Stuffing frames */
510
    for (i = 0; i < count; i++) {
735
    for (i = 0; i < count; i++) {
511
        z->frames[i].refcount = 0;
736
        z->frames[i].refcount = 0;
512
        buddy_system_free(z->buddy_system, &z->frames[i].buddy_link);
737
        buddy_system_free(z->buddy_system, &z->frames[i].buddy_link);
513
    }
738
    }
514
    return z;
-
 
515
}
739
}
516
 
740
 
517
 
741
 
518
/** Compute configuration data size for zone */
742
/** Compute configuration data size for zone */
519
__address zone_conf_size(pfn_t start, count_t count)
743
__address zone_conf_size(count_t count)
520
{
744
{
521
    int size = sizeof(zone_t) + count*sizeof(frame_t);
745
    int size = sizeof(zone_t) + count*sizeof(frame_t);
522
    int max_order;
746
    int max_order;
523
 
747
 
524
    for (max_order = 0; count >> max_order; max_order++)
748
    max_order = fnzb(count);
525
        ;
-
 
526
    size += buddy_conf_size(max_order);
749
    size += buddy_conf_size(max_order);
527
    return size;
750
    return size;
528
}
751
}
529
 
752
 
-
 
753
 
530
/** Create and add zone to system
754
/** Create and add zone to system
531
 *
755
 *
532
 * @param confframe Where configuration frame is supposed to be.
756
 * @param confframe Where configuration frame is supposed to be.
533
 *                  Always check, that we will not disturb the kernel and possibly init.
757
 *                  Always check, that we will not disturb the kernel and possibly init.
534
 *                  If confframe is given _outside_ this zone, it is expected,
758
 *                  If confframe is given _outside_ this zone, it is expected,
535
 *                  that the area is already marked BUSY and big enough
759
 *                  that the area is already marked BUSY and big enough
536
 *                  to contain zone_conf_size() amount of data
760
 *                  to contain zone_conf_size() amount of data
-
 
761
 *
-
 
762
 * @return Zone number or -1 on error
537
 */
763
 */
538
void zone_create(pfn_t start, count_t count, pfn_t confframe, int flags)
764
int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags)
539
{
765
{
540
    zone_t *z;
766
    zone_t *z;
541
    __address addr,endaddr;
767
    __address addr;
542
    count_t confcount;
768
    count_t confcount;
543
    int i;
769
    int i;
-
 
770
    int znum;
544
 
771
 
545
    /* Theoretically we could have here 0, practically make sure
772
    /* Theoretically we could have here 0, practically make sure
546
     * nobody tries to do that. If some platform requires, remove
773
     * nobody tries to do that. If some platform requires, remove
547
     * the assert
774
     * the assert
548
     */
775
     */
549
    ASSERT(confframe);
776
    ASSERT(confframe);
550
    /* If conframe is supposed to be inside our zone, then make sure
777
    /* If conframe is supposed to be inside our zone, then make sure
551
     * it does not span kernel & init
778
     * it does not span kernel & init
552
     */
779
     */
553
    confcount = SIZE2FRAMES(zone_conf_size(start,count));
780
    confcount = SIZE2FRAMES(zone_conf_size(count));
554
    if (confframe >= start && confframe < start+count) {
781
    if (confframe >= start && confframe < start+count) {
555
        for (;confframe < start+count;confframe++) {
782
        for (;confframe < start+count;confframe++) {
556
            addr = PFN2ADDR(confframe);
783
            addr = PFN2ADDR(confframe);
557
            endaddr =  PFN2ADDR (confframe + confcount);
-
 
558
            if (overlaps(addr, endaddr, KA2PA(config.base),
784
            if (overlaps(addr, PFN2ADDR(confcount),
559
                     KA2PA(config.base+config.kernel_size)))
785
                     KA2PA(config.base),config.kernel_size))
560
                continue;
786
                continue;
561
            if (config.init_addr)
787
            if (config.init_addr)
562
                if (overlaps(addr,endaddr,
788
                if (overlaps(addr,PFN2ADDR(confcount),
563
                         KA2PA(config.init_addr),
789
                         KA2PA(config.init_addr),
564
                         KA2PA(config.init_addr+config.init_size)))
790
                         config.init_size))
565
                    continue;
791
                    continue;
566
            break;
792
            break;
567
        }
793
        }
568
        if (confframe >= start+count)
794
        if (confframe >= start+count)
569
            panic("Cannot find configuration data for zone.");
795
            panic("Cannot find configuration data for zone.");
570
    }
796
    }
571
 
797
 
572
    z = zone_construct(start, count, (zone_t *)PA2KA(PFN2ADDR(confframe)), flags);
798
    z = (zone_t *)PA2KA(PFN2ADDR(confframe));
-
 
799
    zone_construct(start, count, z, flags);
573
    zones_add_zone(z);
800
    znum = zones_add_zone(z);
-
 
801
    if (znum == -1)
-
 
802
        return -1;
574
   
803
 
575
    /* If confdata in zone, mark as unavailable */
804
    /* If confdata in zone, mark as unavailable */
576
    if (confframe >= start && confframe < start+count)
805
    if (confframe >= start && confframe < start+count)
577
        for (i=confframe; i<confframe+confcount; i++) {
806
        for (i=confframe; i<confframe+confcount; i++) {
578
            zone_mark_unavailable(z, i - z->base);
807
            zone_mark_unavailable(z, i - z->base);
579
        }
808
        }
-
 
809
 
-
 
810
    return znum;
580
}
811
}
581
 
812
 
582
/***************************************/
813
/***************************************/
583
/* Frame functions */
814
/* Frame functions */
584
 
815
 
Line 655... Line 886...
655
        }
886
        }
656
       
887
       
657
        panic("Sleep not implemented.\n");
888
        panic("Sleep not implemented.\n");
658
        goto loop;
889
        goto loop;
659
    }
890
    }
660
    v = zone_frame_alloc(zone,order,flags,status);
891
    v = zone_frame_alloc(zone,order);
661
    v += zone->base;
892
    v += zone->base;
662
 
893
 
663
    spinlock_unlock(&zone->lock);
894
    spinlock_unlock(&zone->lock);
664
    interrupts_restore(ipl);
895
    interrupts_restore(ipl);
665
 
896
 
Line 668... Line 899...
668
    return v;
899
    return v;
669
}
900
}
670
 
901
 
671
/** Free a frame.
902
/** Free a frame.
672
 *
903
 *
673
 * Find respective frame structrue for supplied addr.
904
 * Find respective frame structure for supplied addr.
674
 * Decrement frame reference count.
905
 * Decrement frame reference count.
675
 * If it drops to zero, move the frame structure to free list.
906
 * If it drops to zero, move the frame structure to free list.
676
 *
907
 *
677
 * @param frame Frame no to be freed.
908
 * @param frame Frame no to be freed.
678
 */
909
 */
Line 702... Line 933...
702
{
933
{
703
    int i;
934
    int i;
704
    zone_t *zone;
935
    zone_t *zone;
705
    int prefzone = 0;
936
    int prefzone = 0;
706
 
937
 
707
    for (i=0; i<count; i++) {
938
    for (i=0; i < count; i++) {
708
        zone = find_zone_and_lock(start+i,&prefzone);
939
        zone = find_zone_and_lock(start+i,&prefzone);
709
        if (!zone) /* PFN not found */
940
        if (!zone) /* PFN not found */
710
            continue;
941
            continue;
711
        zone_mark_unavailable(zone, start+i-zone->base);
942
        zone_mark_unavailable(zone, start+i-zone->base);
712
 
943
 
Line 745... Line 976...
745
    int i;
976
    int i;
746
    ipl_t ipl;
977
    ipl_t ipl;
747
 
978
 
748
    ipl = interrupts_disable();
979
    ipl = interrupts_disable();
749
    spinlock_lock(&zones.lock);
980
    spinlock_lock(&zones.lock);
750
    printf("Base address\tFree Frames\tBusy Frames\n");
981
    printf("#  Base address\tFree Frames\tBusy Frames\n");
751
    printf("------------\t-----------\t-----------\n");
982
    printf("   ------------\t-----------\t-----------\n");
752
    for (i=0;i<zones.count;i++) {
983
    for (i=0;i<zones.count;i++) {
753
        zone = zones.info[i];
984
        zone = zones.info[i];
754
        spinlock_lock(&zone->lock);
985
        spinlock_lock(&zone->lock);
755
        printf("%L\t%d\t\t%d\n",PFN2ADDR(zone->base),
986
        printf("%d  %L\t%d\t\t%d\n",i,PFN2ADDR(zone->base),
756
               zone->free_count, zone->busy_count);
987
               zone->free_count, zone->busy_count);
757
        spinlock_unlock(&zone->lock);
988
        spinlock_unlock(&zone->lock);
758
    }
989
    }
759
    spinlock_unlock(&zones.lock);
990
    spinlock_unlock(&zones.lock);
760
    interrupts_restore(ipl);
991
    interrupts_restore(ipl);
761
}
992
}
762
 
993
 
763
/** Prints zone details
994
/** Prints zone details
764
 *
995
 *
765
 * @param base Zone base address
996
 * @param base Zone base address OR zone number
766
 */
997
 */
767
void zone_print_one(int znum) {
998
void zone_print_one(int num) {
768
    zone_t *zone = NULL;
999
    zone_t *zone = NULL;
769
    ipl_t ipl;
1000
    ipl_t ipl;
-
 
1001
    int i;
770
 
1002
 
771
    ipl = interrupts_disable();
1003
    ipl = interrupts_disable();
772
    spinlock_lock(&zones.lock);
1004
    spinlock_lock(&zones.lock);
773
   
1005
 
774
    if (znum >= zones.count || znum < 0) {
1006
    for (i=0;i < zones.count; i++) {
775
        printf("Zone number out of bounds.\n");
1007
        if (i == num || zones.info[i]->base == ADDR2PFN(num)) {
776
        spinlock_unlock(&zones.lock);
1008
            zone = zones.info[i];
-
 
1009
            break;
-
 
1010
        }
-
 
1011
    }
-
 
1012
    if (!zone) {
777
        interrupts_restore(ipl);
1013
        printf("Zone not found.\n");
778
        return;
1014
        goto out;
779
    }
1015
    }
780
   
-
 
781
    zone = zones.info[znum];
-
 
782
   
1016
   
783
    spinlock_lock(&zone->lock);
1017
    spinlock_lock(&zone->lock);
784
    printf("Memory zone information\n\n");
1018
    printf("Memory zone information\n");
785
    printf("Zone base address: %P\n", PFN2ADDR(zone->base));
1019
    printf("Zone base address: %P\n", PFN2ADDR(zone->base));
786
    printf("Zone size: %d frames (%dK)\n", zone->count, ((zone->count) * FRAME_SIZE) >> 10);
1020
    printf("Zone size: %d frames (%dK)\n", zone->count, ((zone->count) * FRAME_SIZE) >> 10);
787
    printf("Allocated space: %d frames (%dK)\n", zone->busy_count, (zone->busy_count * FRAME_SIZE) >> 10);
1021
    printf("Allocated space: %d frames (%dK)\n", zone->busy_count, (zone->busy_count * FRAME_SIZE) >> 10);
788
    printf("Available space: %d (%dK)\n", zone->free_count, (zone->free_count * FRAME_SIZE) >> 10);
1022
    printf("Available space: %d (%dK)\n", zone->free_count, (zone->free_count * FRAME_SIZE) >> 10);
789
   
-
 
790
    printf("\nBuddy allocator structures:\n\n");
-
 
791
    buddy_system_structure_print(zone->buddy_system, FRAME_SIZE);
1023
    buddy_system_structure_print(zone->buddy_system, FRAME_SIZE);
792
   
1024
   
793
    spinlock_unlock(&zone->lock);
1025
    spinlock_unlock(&zone->lock);
-
 
1026
out:
794
    spinlock_unlock(&zones.lock);
1027
    spinlock_unlock(&zones.lock);
795
    interrupts_restore(ipl);
1028
    interrupts_restore(ipl);
796
}
1029
}
797
 
1030