Subversion Repositories HelenOS

Rev

Rev 2128 | Rev 2712 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2128 Rev 2133
Line 68... Line 68...
68
#include <config.h>
68
#include <config.h>
69
 
69
 
70
typedef struct {
70
typedef struct {
71
    count_t refcount;   /**< tracking of shared frames  */
71
    count_t refcount;   /**< tracking of shared frames  */
72
    uint8_t buddy_order;    /**< buddy system block order */
72
    uint8_t buddy_order;    /**< buddy system block order */
73
    link_t buddy_link;  /**< link to the next free block inside one order */
73
    link_t buddy_link;  /**< link to the next free block inside one
-
 
74
                     order */
74
    void *parent;           /**< If allocated by slab, this points there */
75
    void *parent;           /**< If allocated by slab, this points there */
75
} frame_t;
76
} frame_t;
76
 
77
 
77
typedef struct {
78
typedef struct {
78
    SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
79
    SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
79
    pfn_t base;     /**< frame_no of the first frame in the frames array */
80
    pfn_t base;     /**< frame_no of the first frame in the frames
-
 
81
                     array */
80
    count_t count;          /**< Size of zone */
82
    count_t count;          /**< Size of zone */
81
 
83
 
82
    frame_t *frames;    /**< array of frame_t structures in this zone */
84
    frame_t *frames;    /**< array of frame_t structures in this
-
 
85
                     zone */
83
    count_t free_count; /**< number of free frame_t structures */
86
    count_t free_count; /**< number of free frame_t structures */
84
    count_t busy_count; /**< number of busy frame_t structures */
87
    count_t busy_count; /**< number of busy frame_t structures */
85
   
88
   
86
    buddy_system_t *buddy_system; /**< buddy system for the zone */
89
    buddy_system_t *buddy_system; /**< buddy system for the zone */
87
    int flags;
90
    int flags;
Line 155... Line 158...
155
    if (zones.count + 1 == ZONES_MAX)
158
    if (zones.count + 1 == ZONES_MAX)
156
        panic("Maximum zone(%d) count exceeded.", ZONES_MAX);
159
        panic("Maximum zone(%d) count exceeded.", ZONES_MAX);
157
    for (i = 0; i < zones.count; i++) {
160
    for (i = 0; i < zones.count; i++) {
158
        /* Check for overflow */
161
        /* Check for overflow */
159
        z = zones.info[i];
162
        z = zones.info[i];
160
        if (overlaps(newzone->base,newzone->count,
163
        if (overlaps(newzone->base,newzone->count, z->base,
161
                 z->base, z->count)) {
164
            z->count)) {
162
            printf("Zones overlap!\n");
165
            printf("Zones overlap!\n");
163
            return -1;
166
            return -1;
164
        }
167
        }
165
        if (newzone->base < z->base)
168
        if (newzone->base < z->base)
166
            break;
169
            break;
Line 200... Line 203...
200
    i = hint;
203
    i = hint;
201
    do {
204
    do {
202
        z = zones.info[i];
205
        z = zones.info[i];
203
        spinlock_lock(&z->lock);
206
        spinlock_lock(&z->lock);
204
        if (z->base <= frame && z->base + z->count > frame) {
207
        if (z->base <= frame && z->base + z->count > frame) {
-
 
208
            /* Unlock the global lock */
205
            spinlock_unlock(&zones.lock); /* Unlock the global lock */
209
            spinlock_unlock(&zones.lock);
206
            if (pzone)
210
            if (pzone)
207
                *pzone = i;
211
                *pzone = i;
208
            return z;
212
            return z;
209
        }
213
        }
210
        spinlock_unlock(&z->lock);
214
        spinlock_unlock(&z->lock);
Line 227... Line 231...
227
/** Find and lock zone that can allocate order frames.
231
/** Find and lock zone that can allocate order frames.
228
 *
232
 *
229
 * Assume interrupts are disabled.
233
 * Assume interrupts are disabled.
230
 *
234
 *
231
 * @param order Size (2^order) of free space we are trying to find
235
 * @param order Size (2^order) of free space we are trying to find
232
 * @param pzone Pointer to preferred zone or NULL, on return contains zone number
236
 * @param pzone Pointer to preferred zone or NULL, on return contains zone
-
 
237
 *      number
233
 */
238
 */
234
static zone_t * find_free_zone_and_lock(uint8_t order, unsigned int *pzone)
239
static zone_t * find_free_zone_and_lock(uint8_t order, unsigned int *pzone)
235
{
240
{
236
    unsigned int i;
241
    unsigned int i;
237
    zone_t *z;
242
    zone_t *z;
Line 317... Line 322...
317
    index_t index;
322
    index_t index;
318
    bool is_left, is_right;
323
    bool is_left, is_right;
319
 
324
 
320
    frame = list_get_instance(block, frame_t, buddy_link);
325
    frame = list_get_instance(block, frame_t, buddy_link);
321
    zone = (zone_t *) b->data;
326
    zone = (zone_t *) b->data;
322
    ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame), frame->buddy_order));
327
    ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame),
-
 
328
        frame->buddy_order));
323
   
329
   
324
    is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
330
    is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
325
    is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame);
331
    is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame);
326
 
332
 
327
    ASSERT(is_left ^ is_right);
333
    ASSERT(is_left ^ is_right);
Line 380... Line 386...
380
 *
386
 *
381
 * @param b Buddy system.
387
 * @param b Buddy system.
382
 * @param block Buddy system block
388
 * @param block Buddy system block
383
 * @param order Order to set
389
 * @param order Order to set
384
 */
390
 */
385
static void zone_buddy_set_order(buddy_system_t *b, link_t * block, uint8_t order) {
391
static void zone_buddy_set_order(buddy_system_t *b, link_t *block,
-
 
392
    uint8_t order) {
386
    frame_t * frame;
393
    frame_t *frame;
387
    frame = list_get_instance(block, frame_t, buddy_link);
394
    frame = list_get_instance(block, frame_t, buddy_link);
388
    frame->buddy_order = order;
395
    frame->buddy_order = order;
389
}
396
}
390
 
397
 
Line 558... Line 565...
558
   
565
   
559
    max_order = fnzb(z->count);
566
    max_order = fnzb(z->count);
560
 
567
 
561
    z->buddy_system = (buddy_system_t *)&z[1];
568
    z->buddy_system = (buddy_system_t *) &z[1];
562
    buddy_system_create(z->buddy_system, max_order,
569
    buddy_system_create(z->buddy_system, max_order,
563
                &zone_buddy_system_operations,
570
        &zone_buddy_system_operations, (void *) z);
564
                (void *) z);
-
 
565
 
571
 
566
    z->frames = (frame_t *)((uint8_t *) z->buddy_system + buddy_conf_size(max_order));
572
    z->frames = (frame_t *)((uint8_t *) z->buddy_system +
-
 
573
        buddy_conf_size(max_order));
567
    for (i = 0; i < z->count; i++) {
574
    for (i = 0; i < z->count; i++) {
568
        /* This marks all frames busy */
575
        /* This marks all frames busy */
569
        frame_initialize(&z->frames[i]);
576
        frame_initialize(&z->frames[i]);
570
    }
577
    }
571
    /* Copy frames from both zones to preserve full frame orders,
578
    /* Copy frames from both zones to preserve full frame orders,
Line 708... Line 715...
708
    zone1 = zones.info[z1];
715
    zone1 = zones.info[z1];
709
    zone2 = zones.info[z2];
716
    zone2 = zones.info[z2];
710
    spinlock_lock(&zone1->lock);
717
    spinlock_lock(&zone1->lock);
711
    spinlock_lock(&zone2->lock);
718
    spinlock_lock(&zone2->lock);
712
 
719
 
713
    cframes = SIZE2FRAMES(zone_conf_size(zone2->base+zone2->count-zone1->base));
720
    cframes = SIZE2FRAMES(zone_conf_size(zone2->base + zone2->count -
-
 
721
        zone1->base));
714
    if (cframes == 1)
722
    if (cframes == 1)
715
        order = 0;
723
        order = 0;
716
    else
724
    else
717
        order = fnzb(cframes - 1) + 1;
725
        order = fnzb(cframes - 1) + 1;
718
 
726
 
Line 801... Line 809...
801
                &zone_buddy_system_operations,
809
                &zone_buddy_system_operations,
802
                (void *) z);
810
                (void *) z);
803
   
811
   
804
    /* Allocate frames _after_ the conframe */
812
    /* Allocate frames _after_ the conframe */
805
    /* Check sizes */
813
    /* Check sizes */
806
    z->frames = (frame_t *)((uint8_t *) z->buddy_system + buddy_conf_size(max_order));
814
    z->frames = (frame_t *)((uint8_t *) z->buddy_system +
-
 
815
        buddy_conf_size(max_order));
807
    for (i = 0; i < count; i++) {
816
    for (i = 0; i < count; i++) {
808
        frame_initialize(&z->frames[i]);
817
        frame_initialize(&z->frames[i]);
809
    }
818
    }
810
   
819
   
811
    /* Stuffing frames */
820
    /* Stuffing frames */
Line 863... Line 872...
863
     */
872
     */
864
    confcount = SIZE2FRAMES(zone_conf_size(count));
873
    confcount = SIZE2FRAMES(zone_conf_size(count));
865
    if (confframe >= start && confframe < start+count) {
874
    if (confframe >= start && confframe < start+count) {
866
        for (;confframe < start + count; confframe++) {
875
        for (;confframe < start + count; confframe++) {
867
            addr = PFN2ADDR(confframe);
876
            addr = PFN2ADDR(confframe);
-
 
877
            if (overlaps(addr, PFN2ADDR(confcount),
868
            if (overlaps(addr, PFN2ADDR(confcount), KA2PA(config.base), config.kernel_size))
878
                KA2PA(config.base), config.kernel_size))
869
                continue;
879
                continue;
870
           
880
           
-
 
881
            if (overlaps(addr, PFN2ADDR(confcount),
871
            if (overlaps(addr, PFN2ADDR(confcount), KA2PA(config.stack_base), config.stack_size))
882
                KA2PA(config.stack_base), config.stack_size))
872
                continue;
883
                continue;
873
           
884
           
874
            bool overlap = false;
885
            bool overlap = false;
875
            count_t i;
886
            count_t i;
876
            for (i = 0; i < init.cnt; i++)
887
            for (i = 0; i < init.cnt; i++)
877
                if (overlaps(addr, PFN2ADDR(confcount), KA2PA(init.tasks[i].addr), init.tasks[i].size)) {
888
                if (overlaps(addr, PFN2ADDR(confcount),
-
 
889
                    KA2PA(init.tasks[i].addr),
-
 
890
                    init.tasks[i].size)) {
878
                    overlap = true;
891
                    overlap = true;
879
                    break;
892
                    break;
880
                }
893
                }
881
            if (overlap)
894
            if (overlap)
882
                continue;
895
                continue;
Line 1071... Line 1084...
1071
        spinlock_initialize(&zones.lock, "zones.lock");
1084
        spinlock_initialize(&zones.lock, "zones.lock");
1072
    }
1085
    }
1073
    /* Tell the architecture to create some memory */
1086
    /* Tell the architecture to create some memory */
1074
    frame_arch_init();
1087
    frame_arch_init();
1075
    if (config.cpu_active == 1) {
1088
    if (config.cpu_active == 1) {
1076
        frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)), SIZE2FRAMES(config.kernel_size));
1089
        frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)),
-
 
1090
            SIZE2FRAMES(config.kernel_size));
1077
        frame_mark_unavailable(ADDR2PFN(KA2PA(config.stack_base)), SIZE2FRAMES(config.stack_size));
1091
        frame_mark_unavailable(ADDR2PFN(KA2PA(config.stack_base)),
-
 
1092
            SIZE2FRAMES(config.stack_size));
1078
       
1093
       
1079
        count_t i;
1094
        count_t i;
1080
        for (i = 0; i < init.cnt; i++)
1095
        for (i = 0; i < init.cnt; i++) {
1081
            frame_mark_unavailable(ADDR2PFN(KA2PA(init.tasks[i].addr)), SIZE2FRAMES(init.tasks[i].size));
1096
            pfn_t pfn = ADDR2PFN(KA2PA(init.tasks[i].addr));
-
 
1097
            frame_mark_unavailable(pfn,
-
 
1098
                SIZE2FRAMES(init.tasks[i].size));
-
 
1099
        }
1082
 
1100
 
1083
        if (ballocs.size)
1101
        if (ballocs.size)
1084
            frame_mark_unavailable(ADDR2PFN(KA2PA(ballocs.base)), SIZE2FRAMES(ballocs.size));
1102
            frame_mark_unavailable(ADDR2PFN(KA2PA(ballocs.base)),
-
 
1103
                SIZE2FRAMES(ballocs.size));
1085
 
1104
 
1086
        /* Black list first frame, as allocating NULL would
1105
        /* Black list first frame, as allocating NULL would
1087
         * fail in some places */
1106
         * fail in some places */
1088
        frame_mark_unavailable(0, 1);
1107
        frame_mark_unavailable(0, 1);
1089
    }
1108
    }
Line 1104... Line 1123...
1104
    printf("#  base address free frames  busy frames\n");
1123
    printf("#  base address free frames  busy frames\n");
1105
    printf("-- ------------ ------------ ------------\n");
1124
    printf("-- ------------ ------------ ------------\n");
1106
    for (i = 0; i < zones.count; i++) {
1125
    for (i = 0; i < zones.count; i++) {
1107
        zone = zones.info[i];
1126
        zone = zones.info[i];
1108
        spinlock_lock(&zone->lock);
1127
        spinlock_lock(&zone->lock);
1109
        printf("%-2d %12p %12zd %12zd\n", i, PFN2ADDR(zone->base), zone->free_count, zone->busy_count);
1128
        printf("%-2d %12p %12zd %12zd\n", i, PFN2ADDR(zone->base),
-
 
1129
            zone->free_count, zone->busy_count);
1110
        spinlock_unlock(&zone->lock);
1130
        spinlock_unlock(&zone->lock);
1111
    }
1131
    }
1112
    spinlock_unlock(&zones.lock);
1132
    spinlock_unlock(&zones.lock);
1113
    interrupts_restore(ipl);
1133
    interrupts_restore(ipl);
1114
}
1134
}
Line 1136... Line 1156...
1136
        goto out;
1156
        goto out;
1137
    }
1157
    }
1138
   
1158
   
1139
    spinlock_lock(&zone->lock);
1159
    spinlock_lock(&zone->lock);
1140
    printf("Memory zone information\n");
1160
    printf("Memory zone information\n");
1141
    printf("Zone base address: %#.*p\n", sizeof(uintptr_t) * 2, PFN2ADDR(zone->base));
1161
    printf("Zone base address: %#.*p\n", sizeof(uintptr_t) * 2,
-
 
1162
        PFN2ADDR(zone->base));
1142
    printf("Zone size: %zd frames (%zdK)\n", zone->count, ((zone->count) * FRAME_SIZE) >> 10);
1163
    printf("Zone size: %zd frames (%zdK)\n", zone->count,
-
 
1164
        ((zone->count) * FRAME_SIZE) >> 10);
1143
    printf("Allocated space: %zd frames (%zdK)\n", zone->busy_count, (zone->busy_count * FRAME_SIZE) >> 10);
1165
    printf("Allocated space: %zd frames (%zdK)\n", zone->busy_count,
-
 
1166
        (zone->busy_count * FRAME_SIZE) >> 10);
1144
    printf("Available space: %zd frames (%zdK)\n", zone->free_count, (zone->free_count * FRAME_SIZE) >> 10);
1167
    printf("Available space: %zd frames (%zdK)\n", zone->free_count,
-
 
1168
        (zone->free_count * FRAME_SIZE) >> 10);
1145
    buddy_system_structure_print(zone->buddy_system, FRAME_SIZE);
1169
    buddy_system_structure_print(zone->buddy_system, FRAME_SIZE);
1146
   
1170
   
1147
    spinlock_unlock(&zone->lock);
1171
    spinlock_unlock(&zone->lock);
1148
out:
1172
out:
1149
    spinlock_unlock(&zones.lock);
1173
    spinlock_unlock(&zones.lock);
1150
    interrupts_restore(ipl);
1174
    interrupts_restore(ipl);
1151
}
1175
}
1152
 
1176
 
1153
/** @}
1177
/** @}
1154
 */
1178
 */
-
 
1179