Changeset 84dd253 in mainline


Ignore:
Timestamp:
2005-09-21T13:37:50Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
aed4eca
Parents:
fcacfb7
Message:

Physical memory management work.
New frame allocator.
Some architectures need to have bigger heap.

Files:
1 added
10 edited

Legend:

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

    rfcacfb7 r84dd253  
    5353                 * PA2KA(identity) mapping for all frames.
    5454                 */
    55                 for (i = 0; i < frames; i++) {
     55                for (i = 0; i < config.memory_size/FRAME_SIZE; i++) {
    5656                        map_page_to_frame(PA2KA(i * PAGE_SIZE), i * PAGE_SIZE, PAGE_CACHEABLE | PAGE_EXEC, KA2PA(dba));
    5757                }
  • arch/ia32/src/mm/frame.c

    rfcacfb7 r84dd253  
    3333#include <arch/boot/boot.h>
    3434#include <arch/boot/memmap.h>
     35#include <panic.h>
    3536
    3637size_t hardcoded_unmapped_ktext_size = 0;
     
    3940void frame_arch_init(void)
    4041{
     42        zone_t *z;
    4143        __u8 i;
    4244       
    4345        if (config.cpu_active == 1) {
    44                 /* Reserve the NULL frame */
    45                 frame_not_free(0x0);
     46                for (i=e820counter;i>0;i--) {
     47                        if (e820table[i-1].type==MEMMAP_MEMORY_AVAILABLE) {
     48                                z = zone_create(e820table[i-1].base_address, e820table[i-1].size & ~(FRAME_SIZE-1), 0);
     49                                if (!z) {
     50                                        panic("Cannot allocate zone (%dB).\n", e820table[i-1].size & ~(FRAME_SIZE-1));
     51                                }
     52                                zone_attach(z);
     53                        }
     54                }
    4655               
    47                 /* Reserve well-known memory regions */
    48                 frame_region_not_free(0xa0000,0xff000);
    49                 frame_region_not_free(0xfec00000,0xffffffff);
    50                
     56                frame_not_free(0);
     57
    5158                /* Reserve real mode bootstrap memory */
    52                 frame_region_not_free(BOOTSTRAP_OFFSET, BOOTSTRAP_OFFSET + hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size);
    53                
    54                 for (i=e820counter;i>0;i--) {
    55                         if (e820table[i-1].type!=MEMMAP_MEMORY_AVAILABLE) {
    56                                         frame_region_not_free(e820table[i-1].base_address, e820table[i-1].base_address+e820table[i-1].size);
    57                                 }
    58                         }
     59                frame_region_not_free(BOOTSTRAP_OFFSET, BOOTSTRAP_OFFSET + hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size);
    5960        }
    6061}
  • arch/ia32/src/mm/page.c

    rfcacfb7 r84dd253  
    5656                 * PA2KA(identity) mapping for all frames.
    5757                 */
    58                 for (i = 0; i < frames; i++)
     58                for (i = 0; i < config.memory_size/PAGE_SIZE; i++)
    5959                        map_page_to_frame(PA2KA(i * PAGE_SIZE), i * PAGE_SIZE, PAGE_CACHEABLE, KA2PA(dba));
    6060
  • arch/ia32/src/smp/mps.c

    rfcacfb7 r84dd253  
    188188        printf("%P: MPS Floating Pointer Structure\n", fs);
    189189
    190         frame_not_free((__address) fs);
    191 
    192190        if (fs->config_type == 0 && fs->configuration_table) {
    193191                if (fs->mpfib2 >> 7) {
     
    197195
    198196                ct = (struct mps_ct *)PA2KA((__address)fs->configuration_table);
    199                 frame_not_free((__address) ct);
    200197                config.cpu_count = configure_via_ct();
    201198        }
  • arch/ia64/Makefile.inc

    rfcacfb7 r84dd253  
    3333        arch/ivt.S \
    3434        arch/interrupt_handler.c \
    35         arch/fmath.c
     35        arch/fmath.c \
     36        arch/mm/frame.c
  • arch/ia64/src/dummy.s

    rfcacfb7 r84dd253  
    4141.global cpu_priority_restore
    4242.global cpu_sleep
    43 .global frame_arch_init
    4443.global dummy
    4544.global fpu_enable
     
    5958cpu_priority_restore:
    6059cpu_sleep:
    61 frame_arch_init:
    6260fpu_init:
    6361fpu_enable:
  • arch/mips32/src/mm/frame.c

    rfcacfb7 r84dd253  
    3131#include <arch/asm/boot.h>
    3232#include <arch/mm/page.h>
     33#include <config.h>
     34#include <panic.h>
    3335
    3436void frame_arch_init(void)
    3537{
     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
    3646        /* Disable Everything until load address */
    3747        frame_region_not_free(0, KA2PA(KERNEL_LOAD_ADDRESS));
  • arch/ppc32/src/mm/frame.c

    rfcacfb7 r84dd253  
    2929#include <arch/mm/frame.h>
    3030#include <mm/frame.h>
     31#include <config.h>
     32#include <panic.h>
    3133
    3234void frame_arch_init(void)
    3335{
     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);
    3443}
  • include/mm/frame.h

    rfcacfb7 r84dd253  
    5252
    5353struct frame {
    54         zone_t *zone;           /**< host zone */
    5554        count_t refcount;       /**< when > 0, the frame is in busy list, otherwise the frame is in free list */
    5655        link_t link;            /**< link either to frame_zone free or busy list */
     
    6059extern link_t zone_head;                /**< list of all zones in the system */
    6160
    62 extern count_t frames;
    63 extern count_t frames_free;
    64 
    65 extern count_t kernel_frames;
    66 extern count_t kernel_frames_free;
    67 
    68 extern __u8 *frame_bitmap;
    69 extern count_t frame_bitmap_octets;
    70 
    71 extern __u8 *frame_kernel_bitmap;
     61extern void zone_init(void);
     62extern zone_t *zone_create(__address start, size_t size, int flags);
     63extern void zone_attach(zone_t *zone);
    7264
    7365extern void frame_init(void);
    74 
     66extern void frame_initialize(frame_t *frame, zone_t *zone);
    7567__address frame_alloc(int flags);
    7668extern void frame_free(__address addr);
     
    7870extern void frame_region_not_free(__address start, __address stop);
    7971
    80 extern void zone_init(void);
    81 extern zone_t *zone_create(__address start, size_t size, int flags);
    82 extern void zone_attach(zone_t *zone);
    83 
    84 extern void frame_initialize(frame_t *frame, zone_t *zone);
    85 extern __address frame_get_address(frame_t *frame);
    86 
    8772/*
    8873 * TODO: Implement the following functions.
    8974 */
    90 
    91 /*
    92 extern frame_t *frame_alloc(int flags);
    93 extern void frame_free(frame_t *frame);
    94 */
    9575extern frame_t *frame_reference(frame_t *frame);
    9676extern void frame_release(frame_t *frame);
  • src/mm/frame.c

    rfcacfb7 r84dd253  
    2727 */
    2828
     29#include <typedefs.h>
    2930#include <arch/types.h>
    30 #include <func.h>
    31 
    3231#include <mm/heap.h>
    3332#include <mm/frame.h>
    34 #include <mm/page.h>
    3533#include <mm/vm.h>
    36 #include <arch/mm/page.h>
    37 
    38 #include <config.h>
    39 #include <memstr.h>
    40 
    4134#include <panic.h>
    4235#include <debug.h>
    43 
     36#include <list.h>
    4437#include <synch/spinlock.h>
    45 
    4638#include <arch/asm.h>
    4739#include <arch.h>
    4840
    49 count_t frames = 0;
    50 count_t frames_free;
    51 
    52 __u8 *frame_bitmap;
    53 count_t frame_bitmap_octets;
    54 
    55 static spinlock_t framelock;
    56 
    5741spinlock_t zone_head_lock;       /**< this lock protects zone_head list */
    5842link_t zone_head;                /**< list of all zones in the system */
    5943
    60 
     44/** Initialize physical memory management
     45 *
     46 * Initialize physical memory managemnt.
     47 */
    6148void frame_init(void)
    6249{
    6350        if (config.cpu_active == 1) {
    6451                zone_init();
    65 
    66                 /*
    67                  * The bootstrap processor will allocate all necessary memory for frame allocation.
    68                  */
    69 
    70                 frames = config.memory_size / FRAME_SIZE;
    71                 frame_bitmap_octets = frames / 8 + (frames % 8 > 0);
    72                 frame_bitmap = (__u8 *) malloc(frame_bitmap_octets);
    73                 if (!frame_bitmap)
    74                         panic("malloc/frame_bitmap\n");
    75 
    76                 /*
    77                  * Mark all frames free.
    78                  */
    79                 memsetb((__address) frame_bitmap, frame_bitmap_octets, 0);
    80                 frames_free = frames;
    81         }
    82 
    83         /*
    84          * No frame allocations/reservations prior this point.
    85          */
     52        }
    8653
    8754        frame_arch_init();
    88 
     55       
    8956        if (config.cpu_active == 1) {
    90                 /*
    91                  * Create the memory address space map. Marked frames and frame
    92                  * regions cannot be used for allocation.
    93                  */
    94                 frame_region_not_free(config.base, config.base + config.kernel_size);
    95         }
    96 }
    97 
    98 /*
    99  * Allocate a frame.
     57                frame_region_not_free(config.base, config.base + config.kernel_size + CONFIG_STACK_SIZE);
     58        }       
     59}
     60
     61/** Allocate a frame
     62 *
     63 * Allocate a frame of physical memory.
     64 *
     65 * @param flags Flags for host zone selection and address processing.
     66 *
     67 * @return Allocated frame.
    10068 */
    10169__address frame_alloc(int flags)
    10270{
    103         int i;
    10471        pri_t pri;
     72        link_t *cur, *tmp;
     73        zone_t *z;
     74        zone_t *zone = NULL;
     75        frame_t *frame = NULL;
     76        __address v;
    10577       
    10678loop:
    10779        pri = cpu_priority_high();
    108         spinlock_lock(&framelock);
    109         if (frames_free) {
    110                 for (i=0; i < frames; i++) {
    111                         int m, n;
    112                
    113                         m = i / 8;
    114                         n = i % 8;
    115 
    116                         if ((frame_bitmap[m] & (1<<n)) == 0) {
    117                                 frame_bitmap[m] |= (1<<n);
    118                                 frames_free--;
    119                                 spinlock_unlock(&framelock);
    120                                 cpu_priority_restore(pri);
    121                                 if (flags & FRAME_KA) return PA2KA(i*FRAME_SIZE);
    122                                 return i*FRAME_SIZE;
    123                         }
    124                 }
    125                 panic("frames_free inconsistent (%d)\n", frames_free);
    126         }
    127         spinlock_unlock(&framelock);
     80        spinlock_lock(&zone_head_lock);
     81       
     82        /*
     83         * First, find suitable frame zone.
     84         */
     85        for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
     86                z = list_get_instance(cur, zone_t, link);
     87               
     88                spinlock_lock(&z->lock);
     89                /*
     90                 * Check if the zone has any free frames.
     91                 */
     92                if (z->free_count) {
     93                        zone = z;
     94                        break;
     95                }
     96                spinlock_unlock(&z->lock);
     97        }
     98       
     99        if (!zone) {
     100                if (flags & FRAME_PANIC)
     101                        panic("Can't allocate frame.\n");
     102               
     103                /*
     104                 * TODO: Sleep until frames are available again.
     105                 */
     106                spinlock_unlock(&zone_head_lock);
     107                cpu_priority_restore(pri);
     108
     109                panic("Sleep not implemented.\n");
     110                goto loop;
     111        }
     112               
     113        tmp = zone->free_head.next;
     114        frame = list_get_instance(tmp, frame_t, link);
     115
     116        frame->refcount++;
     117        list_remove(tmp);                       /* remove frame from free_head */
     118        list_append(tmp, &zone->busy_head);     /* append frame to busy_head */
     119        zone->free_count--;
     120        zone->busy_count++;
     121       
     122        v = zone->base + (frame - zone->frames) * FRAME_SIZE;
     123       
     124        if (flags & FRAME_KA)
     125                v = PA2KA(v);
     126       
     127        spinlock_unlock(&zone->lock);
     128       
     129        spinlock_unlock(&zone_head_lock);
    128130        cpu_priority_restore(pri);
    129 
    130         if (flags & FRAME_PANIC)
    131                 panic("unable to allocate frame\n");
    132                
    133         /* TODO: implement sleeping logic here */
    134         panic("sleep not supported\n");
    135        
    136         goto loop;
    137 }
    138 
    139 /*
    140  * Free a frame.
     131       
     132        return v;
     133}
     134
     135/** Free a frame.
     136 *
     137 * Find respective frame structrue for supplied addr.
     138 * Decrement frame reference count.
     139 * If it drops to zero, move the frame structure to free list.
     140 *
     141 * @param addr Address of the frame to be freed. It must be a multiple of FRAME_SIZE.
    141142 */
    142143void frame_free(__address addr)
    143144{
    144145        pri_t pri;
    145         __u32 frame;
    146 
     146        link_t *cur;
     147        zone_t *z;
     148        zone_t *zone = NULL;
     149        frame_t *frame;
     150       
     151        ASSERT(addr % FRAME_SIZE == 0);
     152       
    147153        pri = cpu_priority_high();
    148         spinlock_lock(&framelock);
    149        
    150         frame = IS_KA(addr) ? KA2PA(addr) : addr;
    151         frame /= FRAME_SIZE;
    152         if (frame < frames) {
    153                 int m, n;
    154        
    155                 m = frame / 8;
    156                 n = frame % 8;
    157        
    158                 if (frame_bitmap[m] & (1<<n)) {
    159                         frame_bitmap[m] &= ~(1<<n);
    160                         frames_free++;
    161                 }
    162                 else panic("frame already free\n");
    163         }
    164         else panic("frame number too big\n");
    165        
    166         spinlock_unlock(&framelock);
     154        spinlock_lock(&zone_head_lock);
     155       
     156        /*
     157         * First, find host frame zone for addr.
     158         */
     159        for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
     160                z = list_get_instance(cur, zone_t, link);
     161               
     162                spinlock_lock(&z->lock);
     163               
     164                if (IS_KA(addr))
     165                        addr = KA2PA(addr);
     166               
     167                /*
     168                 * Check if addr belongs to z.
     169                 */
     170                if ((addr >= z->base) && (addr <= z->base + (z->free_count + z->busy_count) * FRAME_SIZE)) {
     171                        zone = z;
     172                        break;
     173                }
     174                spinlock_unlock(&z->lock);
     175        }
     176       
     177        ASSERT(zone != NULL);
     178       
     179        frame = &zone->frames[(addr - zone->base)/FRAME_SIZE];
     180        ASSERT(frame->refcount);
     181
     182        if (!--frame->refcount) {
     183                list_remove(&frame->link);                      /* remove frame from busy_head */
     184                list_append(&frame->link, &zone->free_head);    /* append frame to free_head */
     185                zone->free_count++;
     186                zone->busy_count--;
     187        }
     188       
     189        spinlock_unlock(&zone->lock);   
     190       
     191        spinlock_unlock(&zone_head_lock);
    167192        cpu_priority_restore(pri);
    168193}
    169194
    170 /*
    171  * Don't use this function for normal allocation. Use frame_alloc() instead.
    172  * Use this function to declare that some special frame is not free.
     195/** Mark frame not free.
     196 *
     197 * Find respective frame structrue for supplied addr.
     198 * Increment frame reference count and move the frame structure to busy list.
     199 *
     200 * @param addr Address of the frame to be marked. It must be a multiple of FRAME_SIZE.
    173201 */
    174202void frame_not_free(__address addr)
    175203{
    176204        pri_t pri;
    177         __u32 frame;
     205        link_t *cur;
     206        zone_t *z;
     207        zone_t *zone = NULL;
     208        frame_t *frame;
     209       
     210        ASSERT(addr % FRAME_SIZE == 0);
    178211       
    179212        pri = cpu_priority_high();
    180         spinlock_lock(&framelock);
    181         frame = IS_KA(addr) ? KA2PA(addr) : addr;
    182         frame /= FRAME_SIZE;
    183         if (frame < frames) {
    184                 int m, n;
    185 
    186                 m = frame / 8;
    187                 n = frame % 8;
    188        
    189                 if ((frame_bitmap[m] & (1<<n)) == 0) { 
    190                         frame_bitmap[m] |= (1<<n);
    191                         frames_free--; 
    192                 }
    193         }
    194         spinlock_unlock(&framelock);
     213        spinlock_lock(&zone_head_lock);
     214       
     215        /*
     216         * First, find host frame zone for addr.
     217         */
     218        for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
     219                z = list_get_instance(cur, zone_t, link);
     220               
     221                spinlock_lock(&z->lock);
     222               
     223                if (IS_KA(addr))
     224                        addr = KA2PA(addr);
     225               
     226                /*
     227                 * Check if addr belongs to z.
     228                 */
     229                if ((addr >= z->base) && (addr <= z->base + (z->free_count + z->busy_count) * FRAME_SIZE)) {
     230                        zone = z;
     231                        break;
     232                }
     233                spinlock_unlock(&z->lock);
     234        }
     235       
     236        ASSERT(zone != NULL);
     237       
     238        frame = &zone->frames[(addr - zone->base)/FRAME_SIZE];
     239
     240        if (!frame->refcount) {
     241                frame->refcount++;
     242
     243                list_remove(&frame->link);                      /* remove frame from free_head */
     244                list_append(&frame->link, &zone->busy_head);    /* append frame to busy_head */
     245                zone->free_count--;
     246                zone->busy_count++;
     247        }
     248       
     249        spinlock_unlock(&zone->lock);   
     250       
     251        spinlock_unlock(&zone_head_lock);
    195252        cpu_priority_restore(pri);
    196253}
    197254
     255/** Mark frame region not free.
     256 *
     257 * Mark frame region not free.
     258 *
     259 * @param start First address.
     260 * @param stop Last address.
     261 */
    198262void frame_region_not_free(__address start, __address stop)
    199263{
    200         __address a;
    201 
    202         start /= FRAME_SIZE;
    203         stop /= FRAME_SIZE;
    204         for (a = start; a <= stop; a++)
    205                 frame_not_free(a * FRAME_SIZE);
    206 }
     264        __address a;
     265
     266        start /= FRAME_SIZE;
     267        stop /= FRAME_SIZE;
     268        for (a = start; a <= stop; a++)
     269                frame_not_free(a * FRAME_SIZE);
     270}
     271
    207272
    208273/** Initialize zonekeeping
     
    297362        frame->refcount = 0;
    298363        link_initialize(&frame->link);
    299         frame->zone = zone;
    300 }
    301 
    302 /** Get address of physical frame from its frame structure
    303  *
    304  * Get address of physical frame from its frame structure.
    305  *
    306  * @param frame Frame structure of the queried frame address.
    307  *
    308  * @return Address of frame associated with the argument.
    309  */
    310 __address frame_get_address(frame_t *frame)
    311 {
    312         __address v;
    313         zone_t *z;
    314         pri_t pri;
    315        
    316         z = frame->zone;
    317        
    318         pri = cpu_priority_high();
    319         spinlock_lock(&z->lock);
    320 
    321         v = z->base + (frame - z->frames) * FRAME_SIZE;
    322        
    323         if (z->flags & FRAME_KA)
    324                 v = PA2KA(v);
    325 
    326         spinlock_unlock(&z->lock);
    327         cpu_priority_restore(pri);
    328        
    329         return v;
    330 }
     364}
Note: See TracChangeset for help on using the changeset viewer.