Changeset 6e8b3c8 in mainline


Ignore:
Timestamp:
2005-11-11T18:50:41Z (19 years ago)
Author:
Sergey Bondari <bondari@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
30187eb
Parents:
8a0b3730
Message:

Buddy system implementation. Not functional yet - only framework prepeared.
Also added 2 macros FRAME2ADDR and ADDR2FRAME.

Location:
generic
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • generic/include/mm/frame.h

    r8a0b3730 r6e8b3c8  
    3434#include <list.h>
    3535#include <synch/spinlock.h>
     36#include <mm/buddy.h>
    3637
    3738#define FRAME_KA        1       /* skip frames conflicting with user address space */
    3839#define FRAME_PANIC     2       /* panic on failure */
     40
     41#define FRAME2ADDR(zone, frame)         ((zone)->base + ((frame) - (zone)->frames) * FRAME_SIZE)
     42#define ADDR2FRAME(zone, addr)          (&((zone)->frames[((addr) - (zone)->base) / FRAME_SIZE]))
    3943
    4044struct zone {
     
    4751        count_t free_count;     /**< number of frame_t structures in free list */
    4852        count_t busy_count;     /**< number of frame_t structures not in free list */
     53       
     54        buddy_system_t * buddy_system; /**< buddy system allocator for the zone */
    4955        int flags;
    5056};
     
    5359        count_t refcount;       /**< when == 0, the frame is in free list */
    5460        link_t link;            /**< link to zone free list when refcount == 0 */
     61        __u8 order;             /**< buddy system  block order */
     62        link_t buddy_link;      /**< link to the next free block inside one order*/
    5563};
    5664
     
    7078
    7179/*
     80 * Buddy system operations
     81 */
     82link_t * zone_buddy_find_buddy(link_t * buddy);
     83link_t * zone_buddy_bisect(link_t * block);
     84link_t * zone_buddy_coalesce(link_t * buddy_l, link_t * buddy_r);
     85void zone_buddy_set_order(link_t * block, __u8 order);
     86__u8 zone_buddy_get_order(link_t * block);
     87
     88__address zone_buddy_frame_alloc(int flags, __u8 order);
     89void zone_buddy_frame_free(__address addr);
     90
     91/*
    7292 * TODO: Implement the following functions.
    7393 */
  • generic/src/mm/frame.c

    r8a0b3730 r6e8b3c8  
    4242link_t zone_head;                /**< list of all zones in the system */
    4343
     44static struct buddy_system_operations  zone_buddy_system_operations = {
     45        .find_buddy = zone_buddy_find_buddy,
     46        .bisect = zone_buddy_bisect,
     47        .coalesce = zone_buddy_coalesce,
     48        .set_order = zone_buddy_set_order,
     49        .get_order = zone_buddy_get_order,
     50};
     51
    4452/** Initialize physical memory management
    4553 *
     
    119127        zone->busy_count++;
    120128       
    121         v = zone->base + (frame - zone->frames) * FRAME_SIZE;
     129        //v = zone->base + (frame - zone->frames) * FRAME_SIZE;
     130        v = FRAME2ADDR(zone, frame);
    122131       
    123132        if (flags & FRAME_KA)
     
    176185        ASSERT(zone != NULL);
    177186       
    178         frame = &zone->frames[(addr - zone->base)/FRAME_SIZE];
     187        frame = ADDR2FRAME(zone, addr);
     188        // frame = &zone->frames[(addr - zone->base)/FRAME_SIZE];
    179189        ASSERT(frame->refcount);
    180190
     
    234244        ASSERT(zone != NULL);
    235245       
    236         frame = &zone->frames[(addr - zone->base)/FRAME_SIZE];
     246        //frame = &zone->frames[(addr - zone->base)/FRAME_SIZE];
     247        frame = ADDR2FRAME(zone, addr);
    237248
    238249        if (!frame->refcount) {
     
    293304        count_t cnt;
    294305        int i;
     306        __u8 max_order;
    295307       
    296308        ASSERT(start % FRAME_SIZE == 0);
     
    323335                }
    324336               
     337                /*
     338                 * Create buddy system for the zone
     339                 */
     340                for (max_order = 0; cnt >> max_order; max_order++);
     341                z->buddy_system = buddy_system_create(max_order, &zone_buddy_system_operations);
    325342        }
    326343       
     
    359376        link_initialize(&frame->link);
    360377}
     378
     379
     380
     381/*
     382 * buddy system functions (under construction)
     383 *
     384 */
     385
     386
     387/** Allocate 2^order frames
     388 *
     389 */
     390__address zone_buddy_frame_alloc(int flags, __u8 order) {
     391        ipl_t ipl;
     392        link_t *cur, *tmp;
     393        zone_t *z;
     394        zone_t *zone = NULL;
     395        frame_t *frame = NULL;
     396        __address v;
     397       
     398loop:
     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 */
     460void zone_buddy_frame_free(__address addr)
     461{
     462        ipl_t ipl;
     463        link_t *cur;
     464        zone_t *z;
     465        zone_t *zone = NULL;
     466        frame_t *frame;
     467       
     468        ASSERT(addr % FRAME_SIZE == 0);
     469       
     470        ipl = interrupts_disable();
     471        spinlock_lock(&zone_head_lock);
     472       
     473        /*
     474         * First, find host frame zone for addr.
     475         */
     476        for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
     477                z = list_get_instance(cur, zone_t, link);
     478               
     479                spinlock_lock(&z->lock);
     480               
     481                if (IS_KA(addr))
     482                        addr = KA2PA(addr);
     483               
     484                /*
     485                 * Check if addr belongs to z.
     486                 */
     487                if ((addr >= z->base) && (addr <= z->base + (z->free_count + z->busy_count) * FRAME_SIZE)) {
     488                        zone = z;
     489                        break;
     490                }
     491                spinlock_unlock(&z->lock);
     492        }
     493       
     494        ASSERT(zone != NULL);
     495       
     496        frame = ADDR2FRAME(zone, addr);
     497
     498        ASSERT(frame->refcount);
     499
     500        if (!--frame->refcount) {
     501                buddy_system_free(zone->buddy_system, &frame->buddy_link);
     502        }
     503       
     504        spinlock_unlock(&zone->lock);   
     505       
     506        spinlock_unlock(&zone_head_lock);
     507        interrupts_restore(ipl);
     508}
     509
     510
     511/** Buddy system find_buddy implementation
     512 *
     513 */
     514link_t * zone_buddy_find_buddy(link_t * buddy) {
     515
     516}
     517
     518/** Buddy system bisect implementation
     519 *
     520 */
     521link_t * zone_buddy_bisect(link_t * block) {
     522
     523}
     524
     525/** Buddy system coalesce implementation
     526 *
     527 */
     528link_t * zone_buddy_coalesce(link_t * buddy_l, link_t * buddy_r) {
     529
     530}
     531
     532/** Buddy system set_order implementation
     533 *
     534 */
     535void zone_buddy_set_order(link_t * block, __u8 order) {
     536
     537}
     538
     539/** Buddy system get_order implementation
     540 *
     541 */
     542__u8 zone_buddy_get_order(link_t * block) {
     543
     544
     545}
Note: See TracChangeset for help on using the changeset viewer.