Changeset 328f2934 in mainline


Ignore:
Timestamp:
2005-12-04T19:37:13Z (19 years ago)
Author:
Sergey Bondari <bondari@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cf585c9
Parents:
d7ac642
Message:

Buddy allocator for physical memory complete implementation.
Tested on IA32, AMD64, MIPS32. RWLock Test #5 is not passed.
NOTE: Other architectures could be broken (but should not be)

Files:
16 edited

Legend:

Unmodified
Added
Removed
  • arch/amd64/src/mm/page.c

    rd7ac642 r328f2934  
    4545
    4646        if (config.cpu_active == 1) {
    47                 dba = frame_alloc(FRAME_KA | FRAME_PANIC);
     47                dba = frame_alloc(FRAME_KA | FRAME_PANIC, 0);
    4848                memsetb(dba, PAGE_SIZE, 0);
    4949
     
    6868                 */
    6969
    70                 dba = frame_alloc(FRAME_KA | FRAME_PANIC);
     70                dba = frame_alloc(FRAME_KA | FRAME_PANIC, 0);
    7171                memcpy((void *)dba, (void *)bootstrap_dba , PAGE_SIZE);
    7272                write_cr3(KA2PA(dba));
  • arch/ia32/src/mm/frame.c

    rd7ac642 r328f2934  
    3434#include <arch/boot/memmap.h>
    3535#include <panic.h>
     36#include <debug.h>
    3637
    3738size_t hardcoded_unmapped_ktext_size = 0;
     
    4142{
    4243        zone_t *z;
     44        __address start, stop;
     45        size_t size;
    4346        __u8 i;
    4447       
    4548        if (config.cpu_active == 1) {
     49
     50                /* Reserve frame 0 (BIOS data) */
     51                frame_region_not_free(0, FRAME_SIZE);
     52               
     53                /* Reserve real mode bootstrap memory */
     54                frame_region_not_free(BOOTSTRAP_OFFSET, hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size);
     55               
    4656                for (i=0;i<e820counter;i++) {
    4757                        if (e820table[i].type==MEMMAP_MEMORY_AVAILABLE) {
    48                                 z = zone_create(e820table[i].base_address, e820table[i].size & ~(FRAME_SIZE-1), 0);
    49                                 if (!z) {
    50                                         panic("Cannot allocate zone (%dB).\n", e820table[i].size & ~(FRAME_SIZE-1));
    51                                 }
    52                                 zone_attach(z);
     58                                zone_create_in_region(e820table[i].base_address,  e820table[i].size & ~(FRAME_SIZE-1));
    5359                        }
    5460                }
    55                
    56                 frame_not_free(0);
    57 
    58                 /* Reserve real mode bootstrap memory */
    59                 frame_region_not_free(BOOTSTRAP_OFFSET, BOOTSTRAP_OFFSET + hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size);
    6061        }
    6162}
  • arch/ia32/src/mm/page.c

    rd7ac642 r328f2934  
    4848
    4949        if (config.cpu_active == 1) {
    50                 dba = frame_alloc(FRAME_KA | FRAME_PANIC);
     50                dba = frame_alloc(FRAME_KA | FRAME_PANIC, 0);
    5151                memsetb(dba, PAGE_SIZE, 0);
    5252
     
    7070                 */
    7171
    72                 dba = frame_alloc(FRAME_KA | FRAME_PANIC);
     72                dba = frame_alloc(FRAME_KA | FRAME_PANIC, 0);
    7373                memcpy((void *)dba, (void *)bootstrap_dba , PAGE_SIZE);
    7474                write_cr3(KA2PA(dba));
  • arch/ia64/src/mm/frame.c

    rd7ac642 r328f2934  
    3434void frame_arch_init(void)
    3535{
    36         zone_t *z;
    37        
    38         z = zone_create(0, config.memory_size, 0);
    39         if (!z) {
    40                 panic("Can't allocate zone (%dB).\n", config.memory_size);
    41         }
    42         zone_attach(z);
     36        zone_create_in_region(0, config.memory_size & ~(FRAME_SIZE-1));
    4337}
  • arch/mips32/src/mm/frame.c

    rd7ac642 r328f2934  
    3333#include <config.h>
    3434#include <panic.h>
     35#include <print.h>
    3536
    3637void frame_arch_init(void)
    3738{
    38         zone_t *z;
    39        
    40         z = zone_create(0, config.memory_size, 0);
    41         if (!z) {
    42                 panic("Can't allocate zone (%dB).\n", config.memory_size);
    43         }
    44         zone_attach(z);
    45 
    4639        /* Disable Everything until load address */
    47         frame_region_not_free(0, KA2PA(KERNEL_LOAD_ADDRESS));
     40        frame_region_not_free(0, KA2PA(KERNEL_LOAD_ADDRESS) + FRAME_SIZE);
     41        zone_create_in_region(0, config.memory_size & ~(FRAME_SIZE-1));
    4842}
  • arch/mips32/src/mm/page.c

    rd7ac642 r328f2934  
    4040        __address ptl0;
    4141       
    42         ptl0 = frame_alloc(FRAME_KA | FRAME_PANIC);
     42        ptl0 = frame_alloc(FRAME_KA | FRAME_PANIC, 0);
    4343        memsetb(ptl0, FRAME_SIZE, 0);
    4444       
  • arch/ppc32/src/mm/frame.c

    rd7ac642 r328f2934  
    3434void frame_arch_init(void)
    3535{
    36         zone_t *z;
    37 
    38         z = zone_create(0, config.memory_size & ~(FRAME_SIZE-1), 0);
    39         if (!z) {
    40                 panic("Can't allocate zone (%dB).\n", config.memory_size & ~(FRAME_SIZE-1));
    41         }
    42         zone_attach(z);
     36        zone_create_in_region(0, config.memory_size & ~(FRAME_SIZE-1));
    4337}
  • generic/include/mm/buddy.h

    rd7ac642 r328f2934  
    4242        void (*set_order)(buddy_system_t *, link_t *, __u8);            /**< Set order of block passed as argument. */
    4343        __u8 (*get_order)(buddy_system_t *, link_t *);                  /**< Return order of block passed as argument. */
     44        void (*mark_busy)(buddy_system_t *, link_t *);                  /**< Mark block as busy */
    4445};
    4546
     
    5354extern buddy_system_t *buddy_system_create(__u8 max_order, buddy_system_operations_t *op, void *data);
    5455extern link_t *buddy_system_alloc(buddy_system_t *b, __u8 i);
     56extern bool buddy_system_can_alloc(buddy_system_t *b, __u8 order);
    5557extern void buddy_system_free(buddy_system_t *b, link_t *block);
    5658
  • generic/include/mm/frame.h

    rd7ac642 r328f2934  
    4343#define ADDR2FRAME(zone, addr)                  (&((zone)->frames[((addr) - (zone)->base) / FRAME_SIZE]))
    4444#define FRAME_INDEX(zone, frame)                ((count_t)((frame) - (zone)->frames))
    45 #define IS_BUDDY_LEFT_BLOCK(zone, frame)        ((FRAME_INDEX((zone), (frame)) % (1 >> ((frame)->buddy_order + 1))) == 0)
    46 #define IS_BUDDY_RIGHT_BLOCK(zone, frame)       ((FRAME_INDEX((zone), (frame)) % (1 >> ((frame)->buddy_order + 1))) == (1 >> (frame)->buddy_order))
     45#define FRAME_INDEX_VALID(zone, index)          (((index) >= 0) && ((index) < ((zone)->free_count + (zone)->busy_count)))
     46#define IS_BUDDY_LEFT_BLOCK(zone, frame)        ((FRAME_INDEX((zone), (frame)) % (1 << ((frame)->buddy_order + 1))) == 0)
     47#define IS_BUDDY_RIGHT_BLOCK(zone, frame)       ((FRAME_INDEX((zone), (frame)) % (1 << ((frame)->buddy_order + 1))) == (1 << (frame)->buddy_order))
    4748
    48 
     49#define ZONE_BLACKLIST_SIZE     3
    4950
    5051struct zone {
     
    6970};
    7071
     72struct region {
     73        __address base;
     74        size_t size;
     75};
     76
     77extern region_t zone_blacklist[];
     78extern count_t zone_blacklist_count;
     79extern void frame_region_not_free(__address base, size_t size);
     80extern void zone_create_in_region(__address base, size_t size);
     81
    7182extern spinlock_t zone_head_lock;       /**< this lock protects zone_head list */
    7283extern link_t zone_head;                /**< list of all zones in the system */
     
    7889extern void frame_init(void);
    7990extern void frame_initialize(frame_t *frame, zone_t *zone);
    80 __address frame_alloc(int flags);
     91__address frame_alloc(int flags, __u8 order);
    8192extern void frame_free(__address addr);
    82 extern void frame_not_free(__address addr);
    83 extern void frame_region_not_free(__address start, __address stop);
    8493zone_t * get_zone_by_frame(frame_t * frame);
    8594
     
    92101void zone_buddy_set_order(buddy_system_t *b, link_t * block, __u8 order);
    93102__u8 zone_buddy_get_order(buddy_system_t *b, link_t * block);
    94 
    95 __address zone_buddy_frame_alloc(int flags, __u8 order);
    96 void zone_buddy_frame_free(__address addr);
     103void zone_buddy_mark_busy(buddy_system_t *b, link_t * block);
    97104
    98105/*
  • generic/include/typedefs.h

    rd7ac642 r328f2934  
    6969typedef struct zone zone_t;
    7070typedef struct frame frame_t;
     71typedef struct region region_t;
    7172
    7273typedef enum vm_type vm_type_t;
  • generic/src/cpu/cpu.c

    rd7ac642 r328f2934  
    6161
    6262                for (i=0; i < config.cpu_count; i++) {
    63                         cpus[i].stack = (__u8 *) frame_alloc(FRAME_KA | FRAME_PANIC);
     63                        cpus[i].stack = (__u8 *) frame_alloc(FRAME_KA | FRAME_PANIC,0);
    6464                        if (!cpus[i].stack)
    6565                                panic("malloc/cpus[%d].stack\n", i);
  • generic/src/mm/buddy.c

    rd7ac642 r328f2934  
    3434#include <list.h>
    3535#include <debug.h>
     36#include <print.h>
    3637
    3738/** Create buddy system
     
    5758        ASSERT(op->bisect);
    5859        ASSERT(op->coalesce);
     60        ASSERT(op->mark_busy);
    5961
    6062        /*
     
    8486}
    8587
     88/** Check if buddy system can allocate block
     89 *
     90 * @param b Buddy system pointer
     91 * @param i Size of the block (2^i)
     92 *
     93 * @return True if block can be allocated
     94 */
     95bool buddy_system_can_alloc(buddy_system_t *b, __u8 i) {
     96        __u8 k;
     97       
     98        ASSERT(i < b->max_order);
     99       
     100        for (k=i; k < b->max_order; k++) {
     101                if (!list_empty(&b->order[k])) {
     102                        return true;
     103                }
     104        }
     105       
     106        return false;
     107       
     108}
     109
    86110/** Allocate block from buddy system.
    87111 *
     
    104128                res = b->order[i].next;
    105129                list_remove(res);
     130                b->op->mark_busy(b, res);
    106131                return res;
    107132        }
     
    137162        /*
    138163         * Return the other half to buddy system.
    139          */
     164         * PROBLEM!!!! FILL FIND OTHER PART AS BUDDY AND LINK TOGETHER
     165         */
     166        b->op->mark_busy(b, res);
    140167        buddy_system_free(b, hlp);
    141168       
     
    153180        link_t *buddy, *hlp;
    154181        __u8 i;
    155        
     182
    156183        /*
    157184         * Determine block's order.
     
    169196
    170197                        ASSERT(b->op->get_order(b, buddy) == i);
    171                
    172198                        /*
    173199                         * Remove buddy from the list of order i.
  • generic/src/mm/frame.c

    rd7ac642 r328f2934  
    3838#include <arch/asm.h>
    3939#include <arch.h>
     40#include <print.h>
    4041
    4142spinlock_t zone_head_lock;       /**< this lock protects zone_head list */
    4243link_t zone_head;                /**< list of all zones in the system */
     44
     45region_t zone_blacklist[ZONE_BLACKLIST_SIZE];
     46count_t zone_blacklist_count = 0;
    4347
    4448static struct buddy_system_operations  zone_buddy_system_operations = {
     
    4852        .set_order = zone_buddy_set_order,
    4953        .get_order = zone_buddy_get_order,
     54        .mark_busy = zone_buddy_mark_busy,
    5055};
    5156
     
    5863        if (config.cpu_active == 1) {
    5964                zone_init();
     65                frame_region_not_free(config.base, config.base + config.kernel_size + CONFIG_STACK_SIZE);
    6066        }
    6167
    6268        frame_arch_init();
    63        
    64         if (config.cpu_active == 1) {
    65                 frame_region_not_free(config.base, config.base + config.kernel_size + CONFIG_STACK_SIZE);
    66         }       
    6769}
    6870
     
    7577 * @return Allocated frame.
    7678 */
    77 __address frame_alloc(int flags)
     79__address frame_alloc(int flags, __u8 order)
    7880{
    7981        ipl_t ipl;
     
    8789        ipl = interrupts_disable();
    8890        spinlock_lock(&zone_head_lock);
    89        
     91
    9092        /*
    9193         * First, find suitable frame zone.
     
    9597               
    9698                spinlock_lock(&z->lock);
    97                 /*
    98                  * Check if the zone has any free frames.
    99                  */
    100                 if (z->free_count) {
     99
     100                /* Check if the zone has 2^order frames area available  */
     101                if (buddy_system_can_alloc(z->buddy_system, order)) {
    101102                        zone = z;
    102103                        break;
    103104                }
     105               
    104106                spinlock_unlock(&z->lock);
    105107        }
     
    119121        }
    120122               
    121         tmp = zone->free_head.next;
    122         frame = list_get_instance(tmp, frame_t, link);
    123 
    124         frame->refcount++;
    125         list_remove(tmp);                       /* remove frame from free_head */
    126         zone->free_count--;
    127         zone->busy_count++;
    128        
    129         //v = zone->base + (frame - zone->frames) * FRAME_SIZE;
     123
     124        /* Allocate frames from zone buddy system */
     125        cur = buddy_system_alloc(zone->buddy_system, order);
     126       
     127        /* frame will be actually a first frame of the block */
     128        frame = list_get_instance(cur, frame_t, buddy_link);
     129       
     130        /* get frame address */
    130131        v = FRAME2ADDR(zone, frame);
    131        
     132
    132133        if (flags & FRAME_KA)
    133134                v = PA2KA(v);
    134135       
    135136        spinlock_unlock(&zone->lock);
    136        
    137137        spinlock_unlock(&zone_head_lock);
    138138        interrupts_restore(ipl);
    139        
    140139        return v;
     140
    141141}
    142142
     
    156156        zone_t *zone = NULL;
    157157        frame_t *frame;
    158        
    159158        ASSERT(addr % FRAME_SIZE == 0);
    160159       
     
    186185       
    187186        frame = ADDR2FRAME(zone, addr);
    188         // frame = &zone->frames[(addr - zone->base)/FRAME_SIZE];
     187
    189188        ASSERT(frame->refcount);
    190189
    191190        if (!--frame->refcount) {
    192                 list_append(&frame->link, &zone->free_head);    /* append frame to free_head */
    193                 zone->free_count++;
    194                 zone->busy_count--;
     191                buddy_system_free(zone->buddy_system, &frame->buddy_link);
    195192        }
    196193       
     
    201198}
    202199
    203 /** Mark frame not free.
    204  *
    205  * Find respective frame structrue for supplied addr.
    206  * Increment frame reference count and remove the frame structure from free list.
    207  *
    208  * @param addr Address of the frame to be marked. It must be a multiple of FRAME_SIZE.
    209  */
    210 void frame_not_free(__address addr)
    211 {
    212         ipl_t ipl;
    213         link_t *cur;
    214         zone_t *z;
    215         zone_t *zone = NULL;
    216         frame_t *frame;
    217        
    218         ASSERT(addr % FRAME_SIZE == 0);
    219        
    220         ipl = interrupts_disable();
    221         spinlock_lock(&zone_head_lock);
    222        
    223         /*
    224          * First, find host frame zone for addr.
    225          */
    226         for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
    227                 z = list_get_instance(cur, zone_t, link);
    228                
    229                 spinlock_lock(&z->lock);
    230                
    231                 if (IS_KA(addr))
    232                         addr = KA2PA(addr);
    233                
    234                 /*
    235                  * Check if addr belongs to z.
    236                  */
    237                 if ((addr >= z->base) && (addr <= z->base + (z->free_count + z->busy_count) * FRAME_SIZE)) {
    238                         zone = z;
    239                         break;
    240                 }
    241                 spinlock_unlock(&z->lock);
    242         }
    243        
    244         ASSERT(zone != NULL);
    245        
    246         //frame = &zone->frames[(addr - zone->base)/FRAME_SIZE];
    247         frame = ADDR2FRAME(zone, addr);
    248 
    249         if (!frame->refcount) {
    250                 frame->refcount++;
    251 
    252                 list_remove(&frame->link);                      /* remove frame from free_head */
    253                 zone->free_count--;
    254                 zone->busy_count++;
    255         }
    256        
    257         spinlock_unlock(&zone->lock);   
    258        
    259         spinlock_unlock(&zone_head_lock);
    260         interrupts_restore(ipl);
    261 }
    262 
    263200/** Mark frame region not free.
    264201 *
     
    268205 * @param stop Last address.
    269206 */
    270 void frame_region_not_free(__address start, __address stop)
    271 {
    272         __address a;
    273 
    274         start /= FRAME_SIZE;
    275         stop /= FRAME_SIZE;
    276         for (a = start; a <= stop; a++)
    277                 frame_not_free(a * FRAME_SIZE);
     207void frame_region_not_free(__address base, size_t size)
     208{
     209        count_t index;
     210        index = zone_blacklist_count++;
     211        ASSERT(base % FRAME_SIZE == 0);
     212       
     213        if (size % FRAME_SIZE != 0) {
     214                size = size + (FRAME_SIZE - size % FRAME_SIZE);
     215        }
     216        ASSERT(size % FRAME_SIZE == 0);
     217        ASSERT(zone_blacklist_count <= ZONE_BLACKLIST_SIZE);
     218        zone_blacklist[index].base = base;
     219        zone_blacklist[index].size = size;
    278220}
    279221
     
    288230        list_initialize(&zone_head);
    289231}
     232
     233
     234void zone_create_in_region(__address base, size_t size) {
     235        int i;
     236        zone_t * z;
     237        __address s; size_t sz;
     238       
     239        ASSERT(base % FRAME_SIZE == 0);
     240        ASSERT(size % FRAME_SIZE == 0);
     241       
     242        if (!size) return;
     243       
     244        for (i = 0; i < zone_blacklist_count; i++) {
     245                if (zone_blacklist[i].base >= base && zone_blacklist[i].base < base + size) {
     246                        s = base; sz = zone_blacklist[i].base - base;
     247                        ASSERT(base != s || sz != size);
     248                        zone_create_in_region(s, sz);
     249                       
     250                        s = zone_blacklist[i].base + zone_blacklist[i].size;
     251                        sz = (base + size) - (zone_blacklist[i].base + zone_blacklist[i].size);
     252                        ASSERT(base != s || sz != size);
     253                        zone_create_in_region(s, sz);
     254                        return;
     255               
     256                }
     257        }
     258       
     259        z = zone_create(base, size, 0);
     260
     261        if (!z) {
     262                panic("Cannot allocate zone (%dB).\n", size);
     263        }
     264       
     265        zone_attach(z);
     266}
     267
     268
    290269
    291270/** Create frame zone
     
    299278 * @return Initialized zone.
    300279 */
    301 zone_t *zone_create(__address start, size_t size, int flags)
     280zone_t * zone_create(__address start, size_t size, int flags)
    302281{
    303282        zone_t *z;
     
    305284        int i;
    306285        __u8 max_order;
    307        
     286
     287        /* hack for bug #10 */
     288        // if (start == 0x100000) size -= (FRAME_SIZE * 256);
     289
     290        // printf("ZONE_CREATE()   %X - %X (%d kbytes)                  \n", start, start+size, size/1024);     
    308291        ASSERT(start % FRAME_SIZE == 0);
    309292        ASSERT(size % FRAME_SIZE == 0);
     
    340323                for (max_order = 0; cnt >> max_order; max_order++);
    341324                z->buddy_system = buddy_system_create(max_order, &zone_buddy_system_operations, (void *) z);
    342         }
    343        
     325               
     326                /* Stuffing frames */
     327                for (i = 0; i<cnt; i++) {
     328                        z->frames[i].refcount = 0;
     329                        buddy_system_free(z->buddy_system, &z->frames[i].buddy_link);   
     330                }
     331        }
    344332        return z;
    345333}
     
    373361void frame_initialize(frame_t *frame, zone_t *zone)
    374362{
    375         frame->refcount = 0;
     363        frame->refcount = 1;
     364        frame->buddy_order = 0;
    376365        link_initialize(&frame->link);
    377366}
    378367
    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 /** Guess zone by frame instance address
    511  *
    512  * @param frame Frame
    513  *
    514  * @return Zone of given frame
    515  */
    516 zone_t * get_zone_by_frame(frame_t * frame) {
    517         link_t * cur;
    518         zone_t * zone, *z;
    519 
    520         ASSERT(frame);
    521         /*
    522          * First, find host frame zone for addr.
    523          */
    524         for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
    525                 z = list_get_instance(cur, zone_t, link);
    526                
    527                 spinlock_lock(&z->lock);
    528                
    529                 /*
    530                  * Check if frame address belongs to z.
    531                  */
    532                 if ((frame >= z->frames) && (frame <= z->frames + (z->free_count + z->busy_count))) {
    533                         zone = z;
    534                         break;
    535                 }
    536                 spinlock_unlock(&z->lock);
    537         }
    538         ASSERT(zone);
    539        
    540         return zone;
    541 
    542 
    543 }
    544368
    545369/** Buddy system find_buddy implementation
     
    554378        zone_t * zone;
    555379        link_t * cur;
     380        count_t index;
    556381        bool is_left, is_right;
    557382
    558383        frame = list_get_instance(block, frame_t, buddy_link);
    559         zone = get_zone_by_frame(frame);
    560        
     384        zone = (zone_t *) b->data;
    561385       
    562386        /*
     
    564388         * (FRAME_INDEX % 2^(ORDER+1)) == 2^(ORDER) ===> RIGHT BUDDY
    565389         */
    566          
     390
    567391        is_left = IS_BUDDY_LEFT_BLOCK(zone, frame);
    568392        is_right = IS_BUDDY_RIGHT_BLOCK(zone, frame);
     
    570394        ASSERT((is_left || is_right) && (!is_left || !is_right));
    571395       
    572         for (cur = &zone->buddy_system->order[frame->buddy_order]; cur; cur = cur->next) {
    573                 f = list_get_instance(cur, frame_t, buddy_link);
    574                
    575                 ASSERT(f->buddy_order == frame->buddy_order);
    576                
    577                 /*
    578                  * if found frame is coherent with our frame from the left
    579                  */
    580                 if ((FRAME_INDEX(zone, f) + 1 >> frame->buddy_order == FRAME_INDEX(zone, frame)) && is_right) {
    581                         return cur;
    582                 }
    583                
    584                 /*
    585                  * if found frame is coherent with our frame from the right
    586                  */
    587                 if ((FRAME_INDEX(zone,f) - 1 >> frame->buddy_order == FRAME_INDEX(zone, frame)) && is_left) {
    588                         return cur;
    589                 }
    590                
     396        /*
     397         * test left buddy
     398         */
     399        if (is_left) {
     400                index = (FRAME_INDEX(zone, frame)) + (1 << frame->buddy_order);
     401        } else if (is_right) {
     402                index = (FRAME_INDEX(zone, frame)) - (1 << frame->buddy_order);
     403        }
     404       
     405        if (FRAME_INDEX_VALID(zone, index)) {
     406                if (    zone->frames[index].buddy_order == frame->buddy_order &&
     407                        zone->frames[index].refcount == 0) {
     408                        return &zone->frames[index].buddy_link;
     409                }
    591410        }
    592411       
    593412        return NULL;
    594        
    595413       
    596414}
     
    605423link_t * zone_buddy_bisect(buddy_system_t *b, link_t * block) {
    606424        frame_t * frame_l, * frame_r;
    607        
    608425        frame_l = list_get_instance(block, frame_t, buddy_link);
    609 
    610         frame_r = (frame_t *) (&frame_l + (1>>frame_l->buddy_order-1));
    611 
     426        frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
    612427        return &frame_r->buddy_link;
    613        
    614428}
    615429
     
    624438link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * block_1, link_t * block_2) {
    625439        frame_t * frame1, * frame2;
    626        
    627440        frame1 = list_get_instance(block_1, frame_t, buddy_link);
    628441        frame2 = list_get_instance(block_2, frame_t, buddy_link);
    629        
    630         return &frame1 < &frame2 ? block_1 : block_2;
     442        return frame1 < frame2 ? block_1 : block_2;
    631443}
    632444
     
    655467        return frame->buddy_order;
    656468}
     469
     470/** Buddy system mark_busy implementation
     471 *
     472 * @param b Buddy system
     473 * @param block Buddy system block
     474 *
     475 */
     476void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) {
     477        frame_t * frame;
     478        frame = list_get_instance(block, frame_t, buddy_link);
     479        frame->refcount = 1;
     480}
  • generic/src/mm/page.c

    rd7ac642 r328f2934  
    8080
    8181        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
    82                 newpt = frame_alloc(FRAME_KA);
     82                newpt = frame_alloc(FRAME_KA, 0);
    8383                memsetb(newpt, PAGE_SIZE, 0);
    8484                SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
     
    8989
    9090        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
    91                 newpt = frame_alloc(FRAME_KA);
     91                newpt = frame_alloc(FRAME_KA, 0);
    9292                memsetb(newpt, PAGE_SIZE, 0);
    9393                SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
     
    9898
    9999        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
    100                 newpt = frame_alloc(FRAME_KA);
     100                newpt = frame_alloc(FRAME_KA, 0);
    101101                memsetb(newpt, PAGE_SIZE, 0);
    102102                SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
  • generic/src/mm/vm.c

    rd7ac642 r328f2934  
    7070               
    7171                        src_ptl0 = (pte_t *) PA2KA((__address) GET_PTL0_ADDRESS());
    72                         dst_ptl0 = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC);
     72                        dst_ptl0 = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC, 0);
    7373
    7474//                      memsetb((__address) dst_ptl0, PAGE_SIZE, 0);
     
    116116               
    117117                for (i=0; i<size; i++)
    118                         a->mapping[i] = frame_alloc(0);
     118                        a->mapping[i] = frame_alloc(0,0);
    119119               
    120120                spinlock_initialize(&a->lock);
  • generic/src/proc/thread.c

    rd7ac642 r328f2934  
    176176                spinlock_initialize(&t->lock);
    177177       
    178                 frame_ks = frame_alloc(FRAME_KA);
     178                frame_ks = frame_alloc(FRAME_KA,0);
    179179                if (THREAD_USER_STACK & flags) {
    180                         frame_us = frame_alloc(FRAME_KA);
     180                        frame_us = frame_alloc(FRAME_KA,0);
    181181                }
    182182
Note: See TracChangeset for help on using the changeset viewer.