Changeset 085d973 in mainline


Ignore:
Timestamp:
2006-02-08T12:34:05Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5e3757d
Parents:
eb1b8b6
Message:

Cleanup o frame allocator.
Removed early_malloc & initial heap.
Will break ia64, ppc & sparc.
Added e820 table print.

Files:
2 deleted
35 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    reb1b8b6 r085d973  
    113113        generic/src/syscall/syscall.c \
    114114        generic/src/mm/buddy.c \
    115         generic/src/mm/heap.c \
    116115        generic/src/mm/frame.c \
    117116        generic/src/mm/page.c \
  • arch/amd64/include/types.h

    reb1b8b6 r085d973  
    4040
    4141typedef __u64 __address;
     42typedef __u64 pfn_t;
    4243
    4344/* Flags of processor (return value of interrupts_disable()) */
  • arch/amd64/src/mm/page.c

    reb1b8b6 r085d973  
    4545        if (config.cpu_active == 1) {
    4646                page_mapping_operations = &pt_mapping_operations;
    47        
     47               
    4848                /*
    4949                 * PA2KA(identity) mapping for all frames.
     
    5252                        page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, PAGE_CACHEABLE | PAGE_EXEC);
    5353                }
    54 
    5554                exc_register(14, "page_fault", (iroutine)page_fault);
    5655                write_cr3((__address) AS_KERNEL->page_table);
  • arch/amd64/src/pm.c

    reb1b8b6 r085d973  
    3838
    3939#include <memstr.h>
    40 #include <mm/heap.h>
     40#include <mm/slab.h>
    4141#include <debug.h>
    4242
  • arch/ia32/include/types.h

    reb1b8b6 r085d973  
    4040
    4141typedef __u32 __address;
     42typedef __u32 pfn_t;
    4243
    4344typedef __u32 ipl_t;
  • arch/ia32/src/mm/frame.c

    reb1b8b6 r085d973  
    3636#include <debug.h>
    3737#include <align.h>
     38#include <macros.h>
     39
     40#include <print.h>
     41#include <console/cmd.h>
     42#include <console/kconsole.h>
     43
    3844
    3945size_t hardcoded_unmapped_ktext_size = 0;
     
    4248__address last_frame = 0;
    4349
     50static void init_e820_memory(pfn_t minconf)
     51{
     52        int i;
     53        pfn_t start, size,conf;
     54
     55        for (i = 0; i < e820counter; i++) {
     56                if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) {
     57                        start = ADDR2PFN(ALIGN_UP(e820table[i].base_address,
     58                                                  FRAME_SIZE));
     59                        size = SIZE2PFN(ALIGN_DOWN(e820table[i].size,
     60                                                   FRAME_SIZE));
     61                        if (minconf < start || minconf >= start+size)
     62                                conf = start;
     63                        else
     64                                conf = minconf;
     65                        zone_create(start,size, conf, 0);
     66                        if (last_frame < ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE))
     67                                last_frame = ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE);
     68                }                       
     69        }
     70}
     71
     72static int cmd_e820mem(cmd_arg_t *argv);
     73static cmd_info_t e820_info = {
     74        .name = "e820list",
     75        .description = "List e820 memory.",
     76        .func = cmd_e820mem,
     77        .argc = 0
     78};
     79
     80static char *e820names[] = { "invalid", "available", "reserved",
     81                             "acpi", "nvs", "unusable" };
     82
     83
     84static int cmd_e820mem(cmd_arg_t *argv)
     85{
     86        int i;
     87        char *name;
     88
     89        for (i = 0; i < e820counter; i++) {
     90                if (e820table[i].type <= MEMMAP_MEMORY_UNUSABLE)
     91                        name = e820names[e820table[i].type];
     92                else
     93                        name = "invalid";
     94                printf("%P %dB %s\n", e820table[i].base_address,
     95                       e820table[i].size,
     96                       name);
     97        }                       
     98        return 0;
     99}
     100
     101
    44102void frame_arch_init(void)
    45103{
    46         __u8 i;
    47        
     104        static pfn_t minconf;
     105
    48106        if (config.cpu_active == 1) {
     107                cmd_initialize(&e820_info);
     108                cmd_register(&e820_info);
     109
     110
     111                minconf = 1;
     112#ifdef CONFIG_SMP
     113                minconf = max(minconf,
     114                              ADDR2PFN(AP_BOOT_OFFSET+hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size));
     115#endif
     116#ifdef CONFIG_SIMICS_FIX
     117                minconf = max(minconf, ADDR2PFN(0x10000));
     118#endif
     119                init_e820_memory(minconf);
    49120
    50121                /* Reserve frame 0 (BIOS data) */
    51                 frame_region_not_free(0, FRAME_SIZE);
     122                frame_mark_unavailable(0, 1);
    52123               
    53124#ifdef CONFIG_SMP
    54125                /* Reserve AP real mode bootstrap memory */
    55                 frame_region_not_free(AP_BOOT_OFFSET, hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size);
     126                frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH,
     127                                       (hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size) >> FRAME_WIDTH);
    56128               
    57129#ifdef CONFIG_SIMICS_FIX
    58130                /* Don't know why, but this addresses help */
    59                 frame_region_not_free(0xf000,FRAME_SIZE);
    60                 frame_region_not_free(0xe000,FRAME_SIZE);
    61                 frame_region_not_free(0xd000,FRAME_SIZE);
     131                frame_mark_unavailable(0xd000 >> FRAME_WIDTH,3);
    62132#endif
    63133#endif
    64                
    65                 for (i = 0; i < e820counter; i++) {
    66                         if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) {
    67                                 zone_create_in_region(e820table[i].base_address, e820table[i].size & ~(FRAME_SIZE-1));
    68                                 if (last_frame < ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE))
    69                                         last_frame = ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE);
    70                         }                       
    71                 }
    72134        }
    73135}
  • arch/ia32/src/pm.c

    reb1b8b6 r085d973  
    3636#include <panic.h>
    3737#include <arch/mm/page.h>
    38 #include <mm/heap.h>
     38#include <mm/slab.h>
    3939#include <memstr.h>
    4040#include <arch/boot/boot.h>
  • arch/ia32/src/smp/smp.c

    reb1b8b6 r085d973  
    4444#include <mm/frame.h>
    4545#include <mm/page.h>
    46 #include <mm/heap.h>
     46#include <mm/slab.h>
    4747#include <mm/as.h>
    4848#include <print.h>
  • arch/mips32/Makefile.inc

    reb1b8b6 r085d973  
    7474        KERNEL_LOAD_ADDRESS = 0x88002000
    7575        CFLAGS += -EB -DBIG_ENDIAN -DHAVE_FPU -march=r4600
     76        INIT_ADDRESS = 0
     77        INIT_SIZE = 0
    7678endif
    7779ifeq ($(MIPS_MACHINE),lgxemul)
  • arch/mips32/include/types.h

    reb1b8b6 r085d973  
    5252typedef union pte pte_t;
    5353
     54typedef __u32 pfn_t;
     55
    5456#endif
  • arch/mips32/src/drivers/arc.c

    reb1b8b6 r085d973  
    304304
    305305                        total += basesize;
    306                         zone_create_in_region(base, basesize);
     306                       
     307                        zone_create(ADDR2PFN(base),
     308                                    SIZE2PFN(ALIGN_DOWN(basesize,FRAME_SIZE)),
     309                                    ADDR2PFN(base),0);
    307310                }
    308311                desc = arc_entry->getmemorydescriptor(desc);
  • arch/mips32/src/mips32.c

    reb1b8b6 r085d973  
    9696        arc_print_memory_map();
    9797        arc_print_devices();
     98        /* Setup usermode...*/
     99//      config.init_addr = INIT_ADDRESS;
     100//      config.init_size = INIT_SIZE;
    98101}
    99102
    100103void arch_post_mm_init(void)
    101104{
    102         /* Setup usermode...*/
    103         config.init_addr = INIT_ADDRESS;
    104         config.init_size = INIT_SIZE;
    105105}
    106106
  • arch/mips32/src/mm/frame.c

    reb1b8b6 r085d973  
    4444void frame_arch_init(void)
    4545{
    46         /* Blacklist first 4KB, exception vector */
    47         frame_region_not_free(0, FRAME_SIZE);
    48 
    4946        if (arc_enabled())
    5047                arc_frame_init();
    51         else
    52                 zone_create_in_region(KA2PA(KERNEL_LOAD_ADDRESS),
    53                                       (config.memory_size & ~(FRAME_SIZE-1)));
     48        else {
     49                zone_create(1, (config.memory_size >> PAGE_WIDTH)-1,1,0);
     50        }
    5451}
  • contrib/conf/msim.conf

    reb1b8b6 r085d973  
    55add dcpu mips1
    66
    7 add rwm firstmem        0x0             128k    load "/dev/zero"
     7add rwm firstmem        0x0             1M      load "/dev/zero"
    88add rwm mainmem         0x00100000      16M     load "kernel.bin"
    99add rom startmem        0x1fc00000      1k      load "load.bin"
  • genarch/src/acpi/matd.c

    reb1b8b6 r085d973  
    3737#include <config.h>
    3838#include <print.h>
    39 #include <mm/heap.h>
     39#include <mm/slab.h>
    4040#include <memstr.h>
    4141#include <sort.h>
     
    145145
    146146        /* create madt apic entries index array */
    147         madt_entries_index = (struct madt_apic_header * *) early_malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *));
     147        madt_entries_index = (struct madt_apic_header * *) malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *));
    148148
    149149        __u32 index = 0;
  • genarch/src/mm/as_pt.c

    reb1b8b6 r085d973  
    5757        ipl_t ipl;
    5858
    59         dst_ptl0 = (pte_t *) frame_alloc(ONE_FRAME, FRAME_KA | FRAME_PANIC);
     59        dst_ptl0 = (pte_t *) PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA | FRAME_PANIC)));
    6060
    6161        if (flags & FLAG_AS_KERNEL) {
  • genarch/src/mm/page_pt.c

    reb1b8b6 r085d973  
    6666
    6767        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
    68                 newpt = frame_alloc(ONE_FRAME, FRAME_KA);
     68                newpt = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA)));
    6969                memsetb(newpt, PAGE_SIZE, 0);
    7070                SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
     
    7575
    7676        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
    77                 newpt = frame_alloc(ONE_FRAME, FRAME_KA);
     77                newpt = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA)));
    7878                memsetb(newpt, PAGE_SIZE, 0);
    7979                SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
     
    8484
    8585        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
    86                 newpt = frame_alloc(ONE_FRAME, FRAME_KA);
     86                newpt = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA)));
    8787                memsetb(newpt, PAGE_SIZE, 0);
    8888                SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
  • generic/include/mm/buddy.h

    reb1b8b6 r085d973  
    4343        __u8 (*get_order)(buddy_system_t *, link_t *);                  /**< Return order of block passed as argument. */
    4444        void (*mark_busy)(buddy_system_t *, link_t *);                  /**< Mark block as busy */
     45        void (*mark_available)(buddy_system_t *, link_t *);                     /**< Mark block as busy */
     46        /** Find parent of block that has given order  */
     47        link_t *(* find_block)(buddy_system_t *, link_t *, __u8);
    4548};
    4649
     
    5255};
    5356
    54 extern buddy_system_t *buddy_system_create(__u8 max_order, buddy_system_operations_t *op, void *data);
     57extern void buddy_system_create(buddy_system_t *b,
     58                                __u8 max_order,
     59                                buddy_system_operations_t *op, void *data);
    5560extern link_t *buddy_system_alloc(buddy_system_t *b, __u8 i);
    5661extern bool buddy_system_can_alloc(buddy_system_t *b, __u8 order);
    5762extern void buddy_system_free(buddy_system_t *b, link_t *block);
    5863extern void buddy_system_structure_print(buddy_system_t *b, size_t elem_size);
     64extern size_t buddy_conf_size(int max_order);
     65extern link_t *buddy_system_alloc_block(buddy_system_t *b, link_t *block);
    5966
    6067#endif
  • generic/include/mm/frame.h

    reb1b8b6 r085d973  
    3636#include <synch/spinlock.h>
    3737#include <mm/buddy.h>
    38 #include <mm/slab.h>
     38#include <arch/mm/page.h>
    3939
    4040#define ONE_FRAME       0
     41
     42#define ZONES_MAX       16      /**< Maximum number of zones in system */
     43
     44#define ZONE_JOIN       0x1  /**< If possible, merge with neighberhood zones */
     45
    4146
    4247#define FRAME_KA                0x1     /* skip frames conflicting with user address space */
     
    4954#define FRAME_ERROR             2       /* frame_alloc return status */
    5055
    51 #define FRAME2ADDR(zone, frame)                 ((zone)->base + (((frame) - (zone)->frames) << FRAME_WIDTH))
    52 #define ADDR2FRAME(zone, addr)                  (&((zone)->frames[(((addr) - (zone)->base) >> FRAME_WIDTH)]))
    53 #define FRAME_INDEX(zone, frame)                ((index_t)((frame) - (zone)->frames))
    54 #define FRAME_INDEX_ABS(zone, frame)            (((index_t)((frame) - (zone)->frames)) + (zone)->base_index)
    55 #define FRAME_INDEX_VALID(zone, index)          (((index) >= 0) && ((index) < ((zone)->free_count + (zone)->busy_count)))
     56/* Return true if the interlvals overlap */
     57static inline int overlaps(__address s1,__address e1, __address s2, __address e2)
     58{
     59        if (s1 >= s2 && s1 < e2)
     60                return 1;
     61        if (e1 >= s2 && e1 < e2)
     62                return 1;
     63        if ((s1 < s2) && (e1 >= e2))
     64                return 1;
     65        return 0;
     66}
     67
     68static inline __address PFN2ADDR(pfn_t frame)
     69{
     70        return (__address)(frame << PAGE_WIDTH);
     71}
     72
     73static inline pfn_t ADDR2PFN(__address addr)
     74{
     75        return (pfn_t)(addr >> PAGE_WIDTH);
     76}
     77
     78static inline pfn_t SIZE2PFN(__address size)
     79{
     80        if (!size)
     81                return 0;
     82        return (pfn_t)((size-1) >> PAGE_WIDTH)+1;
     83}
     84
    5685#define IS_BUDDY_ORDER_OK(index, order)         ((~(((__native) -1) << (order)) & (index)) == 0)
    57 #define IS_BUDDY_LEFT_BLOCK(zone, frame)        (((FRAME_INDEX((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
    58 #define IS_BUDDY_RIGHT_BLOCK(zone, frame)       (((FRAME_INDEX((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
    59 #define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame)    (((FRAME_INDEX_ABS((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
    60 #define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame)   (((FRAME_INDEX_ABS((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
     86#define IS_BUDDY_LEFT_BLOCK(zone, frame)        (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
     87#define IS_BUDDY_RIGHT_BLOCK(zone, frame)       (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
     88#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame)    (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
     89#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame)   (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
    6190
    62 #define ZONE_BLACKLIST_SIZE     8
    6391
    6492#define frame_alloc(order, flags)                               frame_alloc_generic(order, flags, NULL, NULL)
     
    6694#define frame_alloc_rc_zone(order, flags, status, zone)         frame_alloc_generic(order, flags, status, zone)
    6795
    68 struct zone {
    69         link_t link;            /**< link to previous and next zone */
    70 
    71         SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
    72         __address base;         /**< physical address of the first frame in the frames array */
    73         index_t base_index;     /**< frame index offset of the zone base */
    74         frame_t *frames;        /**< array of frame_t structures in this zone */
    75         count_t free_count;     /**< number of free frame_t structures */
    76         count_t busy_count;     /**< number of busy frame_t structures */
    77        
    78         buddy_system_t * buddy_system; /**< buddy system for the zone */
    79         int flags;
    80 };
    81 
    82 struct frame {
    83         count_t refcount;       /**< tracking of shared frames  */
    84         __u8 buddy_order;       /**< buddy system block order */
    85         link_t buddy_link;      /**< link to the next free block inside one order */
    86         void *parent;           /**< If allocated by slab, this points there */
    87 };
    88 
    89 struct region {
    90         __address base;
    91         size_t size;
    92 };
    93 
    94 extern region_t zone_blacklist[];
    95 extern count_t zone_blacklist_count;
    96 extern void frame_region_not_free(__address base, size_t size);
    97 extern void zone_create_in_region(__address base, size_t size);
    98 
    99 extern spinlock_t zone_head_lock;       /**< this lock protects zone_head list */
    100 extern link_t zone_head;                /**< list of all zones in the system */
    101 
    102 extern zone_t *zone_create(__address start, size_t size, int flags);
    103 extern void zone_attach(zone_t *zone);
    104 
    10596extern void frame_init(void);
    106 extern void frame_initialize(frame_t *frame, zone_t *zone);
    107 
    108 __address frame_alloc_generic(__u8 order, int flags, int * status, zone_t **pzone);
    109 
    110 
     97__address frame_alloc_generic(__u8 order, int flags, int * status, int *pzone);
    11198extern void frame_free(__address addr);
    11299
    113 zone_t * get_zone_by_frame(frame_t * frame);
     100extern void zone_create(pfn_t start, pfn_t count, pfn_t confframe, int flags);
    114101
    115 /*
    116  * Buddy system operations
    117  */
    118 link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * buddy);
    119 link_t * zone_buddy_bisect(buddy_system_t *b, link_t * block);
    120 link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * buddy_l, link_t * buddy_r);
    121 void zone_buddy_set_order(buddy_system_t *b, link_t * block, __u8 order);
    122 __u8 zone_buddy_get_order(buddy_system_t *b, link_t * block);
    123 void zone_buddy_mark_busy(buddy_system_t *b, link_t * block);
    124 extern frame_t * frame_addr2frame(__address addr);
    125 
    126 /*
    127  * TODO: Implement the following functions.
    128  */
    129 extern frame_t *frame_reference(frame_t *frame);
    130 extern void frame_release(frame_t *frame);
    131 
     102void * frame_get_parent(pfn_t frame, int hint);
     103void frame_set_parent(pfn_t frame, void *data, int hint);
     104void frame_mark_unavailable(pfn_t start, pfn_t count);
     105__address zone_conf_size(pfn_t start, pfn_t count);
    132106
    133107/*
     
    135109 */
    136110extern void zone_print_list(void);
    137 extern void zone_print_one(__address base);
     111void zone_print_one(int znum);
    138112
    139113#endif
  • generic/include/mm/slab.h

    reb1b8b6 r085d973  
    3333#include <synch/spinlock.h>
    3434#include <arch/atomic.h>
     35#include <mm/frame.h>
    3536
    3637/** Minimum size to be allocated by malloc */
     
    127128extern void * kalloc(unsigned int size, int flags);
    128129extern void kfree(void *obj);
     130#define malloc(x)  kalloc(x, FRAME_ATOMIC)
     131#define free(x)    kfree(x)
    129132#endif
  • generic/include/proc/thread.h

    reb1b8b6 r085d973  
    112112
    113113        __u8 *kstack;                           /**< Thread's kernel stack. */
    114         __u8 *ustack;                           /**< Thread's user stack. */
    115114};
    116115
  • generic/include/typedefs.h

    reb1b8b6 r085d973  
    6767typedef struct buddy_system_operations buddy_system_operations_t;
    6868
    69 typedef struct zone zone_t;
    70 typedef struct frame frame_t;
    71 typedef struct region region_t;
    72 
    7369typedef enum as_area_type as_area_type_t;
    7470typedef struct as_area as_area_t;
  • generic/src/adt/hash_table.c

    reb1b8b6 r085d973  
    3636#include <arch/types.h>
    3737#include <debug.h>
    38 #include <mm/heap.h>
     38#include <mm/slab.h>
    3939#include <memstr.h>
    4040
  • generic/src/cpu/cpu.c

    reb1b8b6 r085d973  
    3030#include <arch.h>
    3131#include <arch/cpu.h>
    32 #include <mm/heap.h>
     32#include <mm/slab.h>
    3333#include <mm/page.h>
    3434#include <mm/frame.h>
     
    6262
    6363                for (i=0; i < config.cpu_count; i++) {
    64                         cpus[i].stack = (__u8 *) frame_alloc(ONE_FRAME, FRAME_KA | FRAME_PANIC);
     64                        cpus[i].stack = (__u8 *) PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA | FRAME_PANIC)));
    6565                       
    6666                        cpus[i].id = i;
  • generic/src/lib/sort.c

    reb1b8b6 r085d973  
    2727 */
    2828
    29 #include <mm/heap.h>
     29#include <mm/slab.h>
    3030#include <memstr.h>
    3131#include <sort.h>
  • generic/src/main/main.c

    reb1b8b6 r085d973  
    4444#include <interrupt.h>
    4545#include <arch/mm/memory_init.h>
    46 #include <mm/heap.h>
    4746#include <mm/frame.h>
    4847#include <mm/page.h>
     
    104103void main_bsp(void)
    105104{
     105        __address stackaddr;
     106
    106107        config.cpu_count = 1;
    107108        config.cpu_active = 1;
     
    112113        config.init_size = init_size;
    113114       
    114         if (init_size > 0)
    115                 config.heap_addr = init_addr + init_size;
    116         else
    117                 config.heap_addr = hardcoded_load_address + hardcoded_ktext_size + hardcoded_kdata_size;
    118        
    119         config.heap_size = CONFIG_HEAP_SIZE + (config.memory_size / FRAME_SIZE) * sizeof(frame_t);
    120        
    121         config.kernel_size = ALIGN_UP(config.heap_addr - hardcoded_load_address + config.heap_size, PAGE_SIZE);
    122         config.heap_delta = config.kernel_size - (config.heap_addr - hardcoded_load_address + config.heap_size);
    123         config.kernel_size = config.kernel_size + CONFIG_STACK_SIZE;
     115        config.kernel_size = ALIGN_UP(hardcoded_ktext_size + hardcoded_kdata_size, PAGE_SIZE);
     116        stackaddr = config.base + config.kernel_size;
     117        /* Avoid placing kernel on top of init */
     118        if (overlaps(stackaddr,stackaddr+CONFIG_STACK_SIZE,
     119                     config.init_addr, config.init_addr+config.init_size)) {
     120               
     121                stackaddr = ALIGN_UP(config.init_addr+config.init_size,
     122                                     CONFIG_STACK_SIZE);
     123                config.init_size = ALIGN_UP(config.init_size,CONFIG_STACK_SIZE) + CONFIG_STACK_SIZE;
     124        } else {
     125                config.kernel_size += CONFIG_STACK_SIZE;
     126        }
    124127       
    125128        context_save(&ctx);
    126         context_set(&ctx, FADDR(main_bsp_separated_stack), config.base + config.kernel_size - CONFIG_STACK_SIZE, CONFIG_STACK_SIZE);
     129        context_set(&ctx, FADDR(main_bsp_separated_stack),
     130                    stackaddr, CONFIG_STACK_SIZE);
    127131        context_restore(&ctx);
    128132        /* not reached */
     
    141145       
    142146        the_initialize(THE);
    143        
    144147        /*
    145148         * kconsole data structures must be initialized very early
     
    159162         */     
    160163        arch_pre_mm_init();
    161         early_heap_init(config.heap_addr, config.heap_size + config.heap_delta);
     164        /* Initialize at least 1 memory segment big enough for slab to work */
    162165        frame_init();
    163166        slab_cache_init();
     
    165168        page_init();
    166169        tlb_init();
    167         arch_post_mm_init();
    168 
     170        arch_post_mm_init();   
    169171        version_print();
    170172
     
    179181        printf("config.memory_size=%dM\n", config.memory_size/(1024*1024));
    180182        printf("config.cpu_count=%d\n", config.cpu_count);
    181 
    182183        cpu_init();
    183184
    184185        calibrate_delay_loop();
    185 
    186186        timeout_init();
    187187        scheduler_init();
  • generic/src/mm/as.c

    reb1b8b6 r085d973  
    3737#include <mm/page.h>
    3838#include <mm/frame.h>
     39#include <mm/slab.h>
    3940#include <mm/tlb.h>
    40 #include <mm/heap.h>
    4141#include <arch/mm/page.h>
    4242#include <genarch/mm/page_pt.h>
     
    254254         *   the different causes
    255255         */
    256         frame = frame_alloc(ONE_FRAME, 0);
     256        frame = PFN2ADDR(frame_alloc(ONE_FRAME, 0));
    257257        memsetb(PA2KA(frame), FRAME_SIZE, 0);
    258258       
  • generic/src/mm/buddy.c

    reb1b8b6 r085d973  
    2929#include <mm/buddy.h>
    3030#include <mm/frame.h>
    31 #include <mm/heap.h>
    3231#include <arch/types.h>
    3332#include <typedefs.h>
     
    3635#include <print.h>
    3736
     37/** Return size needed for the buddy configuration data */
     38size_t buddy_conf_size(int max_order)
     39{
     40        return sizeof(buddy_system_t) + (max_order + 1) * sizeof(link_t);
     41}
     42
     43
    3844/** Create buddy system
    3945 *
    4046 * Allocate memory for and initialize new buddy system.
    4147 *
     48 * @param b Preallocated buddy system control data
    4249 * @param max_order The biggest allocable size will be 2^max_order.
    4350 * @param op Operations for new buddy system.
     
    4653 * @return New buddy system.
    4754 */
    48 buddy_system_t *buddy_system_create(__u8 max_order, buddy_system_operations_t *op, void *data)
    49 {
    50         buddy_system_t *b;
     55void buddy_system_create(buddy_system_t *b,
     56                         __u8 max_order,
     57                         buddy_system_operations_t *op,
     58                         void *data)
     59{
    5160        int i;
    5261
     
    6170
    6271        /*
    63          * Allocate memory for structure describing the whole buddy system.
    64          */     
    65         b = (buddy_system_t *) early_malloc(sizeof(buddy_system_t));
    66        
    67         if (b) {
    68                 /*
    69                  * Allocate memory for all orders this buddy system will work with.
    70                  */
    71                 b->order = (link_t *) early_malloc((max_order + 1) * sizeof(link_t));
    72                 if (!b->order) {
    73                         early_free(b);
    74                         return NULL;
    75                 }
    76        
    77                 for (i = 0; i <= max_order; i++)
    78                         list_initialize(&b->order[i]);
    79        
    80                 b->max_order = max_order;
    81                 b->op = op;
    82                 b->data = data;
    83         }
    84        
    85         return b;
     72         * Use memory after our own structure
     73         */
     74        b->order = (link_t *) (&b[1]);
     75       
     76        for (i = 0; i <= max_order; i++)
     77                list_initialize(&b->order[i]);
     78
     79        b->max_order = max_order;
     80        b->op = op;
     81        b->data = data;
    8682}
    8783
     
    113109        return false;
    114110       
     111}
     112
     113/** Allocate PARTICULAR block from buddy system
     114 *
     115 * @ return Block of data or NULL if no such block was found
     116 */
     117link_t *buddy_system_alloc_block(buddy_system_t *b, link_t *block)
     118{
     119        link_t *left,*right, *tmp;
     120        __u8 order;
     121
     122        left = b->op->find_block(b, block, BUDDY_SYSTEM_INNER_BLOCK);
     123        ASSERT(left);
     124        list_remove(left);
     125        while (1) {
     126                if (! b->op->get_order(b,left)) {
     127                        b->op->mark_busy(b, left);
     128                        return left;
     129                }
     130               
     131                order = b->op->get_order(b, left);
     132
     133                right = b->op->bisect(b, left);
     134                b->op->set_order(b, left, order-1);
     135                b->op->set_order(b, right, order-1);
     136
     137                tmp = b->op->find_block(b, block, BUDDY_SYSTEM_INNER_BLOCK);
     138
     139                if (tmp == right) {
     140                        right = left;
     141                        left = tmp;
     142                }
     143                b->op->mark_busy(b, left);
     144                buddy_system_free(b, right);
     145                b->op->mark_available(b, left);
     146        }
    115147}
    116148
     
    138170                return res;
    139171        }
    140        
    141172        /*
    142173         * If order i is already the maximal order,
     
    168199       
    169200        /*
    170          * Return the other half to buddy system.
    171          * PROBLEM!!!! WILL FIND OTHER PART AS BUDDY AND LINK TOGETHER
     201         * Return the other half to buddy system. Mark the first part
     202         * full, so that it won't coalsce again.
    172203         */
    173204        b->op->mark_busy(b, res);
  • generic/src/mm/frame.c

    reb1b8b6 r085d973  
    2828 */
    2929
     30/*
     31 * Locking order
     32 *
     33 * In order to access particular zone, the process must first lock
     34 * the zones.lock, then lock the zone and then unlock the zones.lock.
     35 * This insures, that we can fiddle with the zones in runtime without
     36 * affecting the processes.
     37 *
     38 */
     39
    3040#include <typedefs.h>
    3141#include <arch/types.h>
    32 #include <mm/heap.h>
    3342#include <mm/frame.h>
    3443#include <mm/as.h>
     
    4150#include <print.h>
    4251#include <align.h>
    43 
    44 SPINLOCK_INITIALIZE(zone_head_lock);    /**< this lock protects zone_head list */
    45 LIST_INITIALIZE(zone_head);             /**< list of all zones in the system */
    46 
    47 /** Blacklist containing non-available areas of memory.
    48  *
    49  * This blacklist is used to exclude frames that cannot be allocated
    50  * (e.g. kernel memory) from available memory map.
    51  */
    52 region_t zone_blacklist[ZONE_BLACKLIST_SIZE];
    53 count_t zone_blacklist_count = 0;
     52#include <mm/slab.h>
     53
     54typedef struct {
     55        count_t refcount;       /**< tracking of shared frames  */
     56        __u8 buddy_order;       /**< buddy system block order */
     57        link_t buddy_link;      /**< link to the next free block inside one order */
     58        void *parent;           /**< If allocated by slab, this points there */
     59}frame_t;
     60
     61typedef struct {
     62        SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
     63        pfn_t base;     /**< frame_no of the first frame in the frames array */
     64        pfn_t count;          /**< Size of zone */
     65
     66        frame_t *frames;        /**< array of frame_t structures in this zone */
     67        count_t free_count;     /**< number of free frame_t structures */
     68        count_t busy_count;     /**< number of busy frame_t structures */
     69       
     70        buddy_system_t * buddy_system; /**< buddy system for the zone */
     71        int flags;
     72}zone_t;
     73
     74/*
     75 * The zoneinfo.lock must be locked when accessing zoneinfo structure.
     76 * Some of the attributes in zone_t structures are 'read-only'
     77 */
     78
     79struct {
     80        SPINLOCK_DECLARE(lock);
     81        int count;
     82        zone_t *info[ZONES_MAX];
     83}zones;
     84
     85
     86/*********************************/
     87/* Helper functions */
     88static inline index_t frame_index(zone_t *zone, frame_t *frame)
     89{
     90        return (index_t)(frame - zone->frames);
     91}
     92static inline index_t frame_index_abs(zone_t *zone, frame_t *frame)
     93{
     94        return (index_t)(frame - zone->frames) + zone->base;
     95}
     96static inline int frame_index_valid(zone_t *zone, index_t index)
     97{
     98        return index >= 0 && index < zone->count;
     99}
     100
     101/** Compute pfn_t from frame_t pointer & zone pointer */
     102static pfn_t make_frame_index(zone_t *zone, frame_t *frame)
     103{
     104        return frame - zone->frames;
     105}
     106
     107/** Initialize frame structure
     108 *
     109 * Initialize frame structure.
     110 *
     111 * @param frame Frame structure to be initialized.
     112 */
     113static void frame_initialize(frame_t *frame)
     114{
     115        frame->refcount = 1;
     116        frame->buddy_order = 0;
     117}
     118
     119/*************************************/
     120/* Zoneinfo functions */
     121
     122/**
     123 * Insert-sort zone into zones list
     124 */
     125static void zones_add_zone(zone_t *zone)
     126{
     127        int i;
     128
     129        spinlock_lock(&zones.lock);
     130        /* Try to merge */
     131        if (zone->flags & ZONE_JOIN) {
     132                for (i=0; i < zones.count; i++) {
     133                        spinlock_lock(&zones.info[i]->lock);
     134                       
     135                        /* Join forward, join backward */
     136                        panic("Not implemented");
     137
     138                        spinlock_unlock(&zones.info[i]->lock);
     139                }
     140                spinlock_unlock(&zones.lock);
     141        } else {
     142                if (zones.count+1 == ZONES_MAX)
     143                        panic("Maximum zone(%d) count exceeded.", ZONES_MAX);
     144                zones.info[zones.count++] = zone;
     145        }
     146        spinlock_unlock(&zones.lock);
     147}
     148
     149/**
     150 * Try to find a zone where can we find the frame
     151 *
     152 * @param hint Start searching in zone 'hint'
     153 * @param lock Lock zone if true
     154 *
     155 * Assume interrupts disable
     156 */
     157static zone_t * find_zone_and_lock(pfn_t frame, int *pzone)
     158{
     159        int i;
     160        int hint = pzone ? *pzone : 0;
     161        zone_t *z;
     162       
     163        spinlock_lock(&zones.lock);
     164
     165        if (hint >= zones.count || hint < 0)
     166                hint = 0;
     167       
     168        i = hint;
     169        do {
     170                z = zones.info[i];
     171                spinlock_lock(&z->lock);
     172                if (z->base <= frame && z->base + z->count > frame) {
     173                        spinlock_unlock(&zones.lock); /* Unlock the global lock */
     174                        if (pzone)
     175                                *pzone = i;
     176                        return z;
     177                }
     178                spinlock_unlock(&z->lock);
     179
     180                i++;
     181                if (i >= zones.count)
     182                        i = 0;
     183        } while(i != hint);
     184
     185        spinlock_unlock(&zones.lock);
     186        return NULL;
     187}
     188
     189/**
     190 * Find AND LOCK zone that can allocate order frames
     191 *
     192 * Assume interrupts are disabled!!
     193 *
     194 * @param pzone Pointer to preferred zone or NULL, on return contains zone number
     195 */
     196static zone_t * find_free_zone_lock(__u8 order, int *pzone)
     197{
     198        int i;
     199        zone_t *z;
     200        int hint = pzone ? *pzone : 0;
     201       
     202        spinlock_lock(&zones.lock);
     203        if (hint >= zones.count)
     204                hint = 0;
     205        i = hint;
     206        do {
     207                z = zones.info[i];
     208               
     209                spinlock_lock(&z->lock);
     210
     211                /* Check if the zone has 2^order frames area available  */
     212                if (buddy_system_can_alloc(z->buddy_system, order)) {
     213                        spinlock_unlock(&zones.lock);
     214                        if (pzone)
     215                                *pzone = i;
     216                        return z;
     217                }
     218                spinlock_unlock(&z->lock);
     219                if (++i >= zones.count)
     220                        i = 0;
     221        } while(i != hint);
     222        spinlock_unlock(&zones.lock);
     223        return NULL;
     224}
     225
     226/********************************************/
     227/* Buddy system functions */
     228
     229/** Buddy system find_block implementation
     230 *
     231 * Find block that is parent of current list.
     232 * That means go to lower addresses, until such block is found
     233 *
     234 * @param order - Order of parent must be different then this parameter!!
     235 */
     236static link_t *zone_buddy_find_block(buddy_system_t *b, link_t *child,
     237                                     __u8 order)
     238{
     239        frame_t * frame;
     240        zone_t * zone;
     241        index_t index;
     242       
     243        frame = list_get_instance(child, frame_t, buddy_link);
     244        zone = (zone_t *) b->data;
     245
     246        index = frame_index(zone, frame);
     247        do {
     248                if (zone->frames[index].buddy_order != order) {
     249                        return &zone->frames[index].buddy_link;
     250                }
     251        } while(index-- > 0);
     252        return NULL;
     253}
     254
     255                                     
     256
     257/** Buddy system find_buddy implementation
     258 *
     259 * @param b Buddy system.
     260 * @param block Block for which buddy should be found
     261 *
     262 * @return Buddy for given block if found
     263 */
     264static link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * block)
     265{
     266        frame_t * frame;
     267        zone_t * zone;
     268        index_t index;
     269        bool is_left, is_right;
     270
     271        frame = list_get_instance(block, frame_t, buddy_link);
     272        zone = (zone_t *) b->data;
     273        ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame), frame->buddy_order));
     274       
     275        is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
     276        is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame);
     277
     278        ASSERT(is_left ^ is_right);
     279        if (is_left) {
     280                index = (frame_index(zone, frame)) + (1 << frame->buddy_order);
     281        } else { // if (is_right)
     282                index = (frame_index(zone, frame)) - (1 << frame->buddy_order);
     283        }
     284       
     285
     286        if (frame_index_valid(zone, index)) {
     287                if (zone->frames[index].buddy_order == frame->buddy_order &&
     288                    zone->frames[index].refcount == 0) {
     289                        return &zone->frames[index].buddy_link;
     290                }
     291        }
     292
     293        return NULL;   
     294}
     295
     296/** Buddy system bisect implementation
     297 *
     298 * @param b Buddy system.
     299 * @param block Block to bisect
     300 *
     301 * @return right block
     302 */
     303static link_t * zone_buddy_bisect(buddy_system_t *b, link_t * block) {
     304        frame_t * frame_l, * frame_r;
     305
     306        frame_l = list_get_instance(block, frame_t, buddy_link);
     307        frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
     308       
     309        return &frame_r->buddy_link;
     310}
     311
     312/** Buddy system coalesce implementation
     313 *
     314 * @param b Buddy system.
     315 * @param block_1 First block
     316 * @param block_2 First block's buddy
     317 *
     318 * @return Coalesced block (actually block that represents lower address)
     319 */
     320static link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * block_1,
     321                                    link_t * block_2) {
     322        frame_t *frame1, *frame2;
     323       
     324        frame1 = list_get_instance(block_1, frame_t, buddy_link);
     325        frame2 = list_get_instance(block_2, frame_t, buddy_link);
     326       
     327        return frame1 < frame2 ? block_1 : block_2;
     328}
     329
     330/** Buddy system set_order implementation
     331 *
     332 * @param b Buddy system.
     333 * @param block Buddy system block
     334 * @param order Order to set
     335 */
     336static void zone_buddy_set_order(buddy_system_t *b, link_t * block, __u8 order) {
     337        frame_t * frame;
     338        frame = list_get_instance(block, frame_t, buddy_link);
     339        frame->buddy_order = order;
     340}
     341
     342/** Buddy system get_order implementation
     343 *
     344 * @param b Buddy system.
     345 * @param block Buddy system block
     346 *
     347 * @return Order of block
     348 */
     349static __u8 zone_buddy_get_order(buddy_system_t *b, link_t * block) {
     350        frame_t * frame;
     351        frame = list_get_instance(block, frame_t, buddy_link);
     352        return frame->buddy_order;
     353}
     354
     355/** Buddy system mark_busy implementation
     356 *
     357 * @param b Buddy system
     358 * @param block Buddy system block
     359 *
     360 */
     361static void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) {
     362        frame_t * frame;
     363        frame = list_get_instance(block, frame_t, buddy_link);
     364        frame->refcount = 1;
     365}
     366
     367/** Buddy system mark_available implementation
     368 *
     369 * @param b Buddy system
     370 * @param block Buddy system block
     371 *
     372 */
     373static void zone_buddy_mark_available(buddy_system_t *b, link_t * block) {
     374        frame_t * frame;
     375        frame = list_get_instance(block, frame_t, buddy_link);
     376        frame->refcount = 0;
     377}
    54378
    55379static struct buddy_system_operations  zone_buddy_system_operations = {
     
    60384        .get_order = zone_buddy_get_order,
    61385        .mark_busy = zone_buddy_mark_busy,
     386        .mark_available = zone_buddy_mark_available,
     387        .find_block = zone_buddy_find_block
    62388};
    63389
    64 /** Initialize physical memory management
    65  *
    66  * Initialize physical memory managemnt.
    67  */
    68 void frame_init(void)
    69 {
    70         if (config.cpu_active == 1) {
    71                 frame_region_not_free(KA2PA(config.base), config.kernel_size);
    72                 if (config.init_size > 0)
    73                         frame_region_not_free(KA2PA(config.init_addr), config.init_size);
    74         }
    75 
    76         frame_arch_init();
    77 }
    78 
    79 /**
    80  * Find AND LOCK zone that can allocate order frames
    81  *
    82  * Assume zone_head_lock is locked.
    83  */
    84 static zone_t * find_free_zone(__u8 order)
    85 {
    86         link_t *cur;
     390/*************************************/
     391/* Zone functions */
     392
     393/** Allocate frame in particular zone
     394 *
     395 * Assume zone is locked
     396 *
     397 * @return Frame index in zone
     398 */
     399static pfn_t zone_frame_alloc(zone_t *zone,__u8 order, int flags, int *status)
     400{
     401        pfn_t v;
     402        link_t *tmp;
     403        frame_t *frame;
     404
     405        /* Allocate frames from zone buddy system */
     406        tmp = buddy_system_alloc(zone->buddy_system, order);
     407       
     408        ASSERT(tmp);
     409       
     410        /* Update zone information. */
     411        zone->free_count -= (1 << order);
     412        zone->busy_count += (1 << order);
     413
     414        /* Frame will be actually a first frame of the block. */
     415        frame = list_get_instance(tmp, frame_t, buddy_link);
     416       
     417        /* get frame address */
     418        v = make_frame_index(zone, frame);
     419        return v;
     420}
     421
     422/** Free frame from zone
     423 *
     424 * Assume zone is locked
     425 */
     426static void zone_frame_free(zone_t *zone, pfn_t frame_idx)
     427{
     428        frame_t *frame;
     429        __u8 order;
     430
     431        frame = &zone->frames[frame_idx];
     432       
     433        /* remember frame order */
     434        order = frame->buddy_order;
     435
     436        ASSERT(frame->refcount);
     437
     438        if (!--frame->refcount) {
     439                buddy_system_free(zone->buddy_system, &frame->buddy_link);
     440        }
     441
     442        /* Update zone information. */
     443        zone->free_count += (1 << order);
     444        zone->busy_count -= (1 << order);
     445}
     446
     447/** Return frame from zone */
     448static frame_t * zone_get_frame(zone_t *zone, pfn_t frame_idx)
     449{
     450        ASSERT(frame_idx < zone->count);
     451        return &zone->frames[frame_idx];
     452}
     453
     454/** Mark frame in zone unavailable to allocation */
     455static void zone_mark_unavailable(zone_t *zone, pfn_t frame_idx)
     456{
     457        frame_t *frame;
     458        link_t *link;
     459
     460        frame = zone_get_frame(zone, frame_idx);
     461        link = buddy_system_alloc_block(zone->buddy_system,
     462                                        &frame->buddy_link);
     463        ASSERT(link);
     464        zone->free_count--;
     465}
     466
     467/** Create frame zone
     468 *
     469 * Create new frame zone.
     470 *
     471 * @param start Physical address of the first frame within the zone.
     472 * @param size Size of the zone. Must be a multiple of FRAME_SIZE.
     473 * @param conffram Address of configuration frame
     474 * @param flags Zone flags.
     475 *
     476 * @return Initialized zone.
     477 */
     478static zone_t * zone_construct(pfn_t start, pfn_t count,
     479                               zone_t *z, int flags)
     480{
     481        int i;
     482        __u8 max_order;
     483
     484        spinlock_initialize(&z->lock, "zone_lock");
     485        z->base = start;
     486        z->count = count;
     487        z->flags = flags;
     488        z->free_count = count;
     489        z->busy_count = 0;
     490
     491        /*
     492         * Compute order for buddy system, initialize
     493         */
     494        for (max_order = 0; count >> max_order; max_order++)
     495                ;
     496        z->buddy_system = (buddy_system_t *)&z[1];
     497       
     498        buddy_system_create(z->buddy_system, max_order,
     499                            &zone_buddy_system_operations,
     500                            (void *) z);
     501       
     502        /* Allocate frames _after_ the conframe */
     503        /* Check sizes */
     504        z->frames = (frame_t *)((void *)z->buddy_system+buddy_conf_size(max_order));
     505
     506        for (i = 0; i<count; i++) {
     507                frame_initialize(&z->frames[i]);
     508        }
     509        /* Stuffing frames */
     510        for (i = 0; i < count; i++) {
     511                z->frames[i].refcount = 0;
     512                buddy_system_free(z->buddy_system, &z->frames[i].buddy_link);
     513        }
     514        return z;
     515}
     516
     517
     518/** Compute configuration data size for zone */
     519__address zone_conf_size(pfn_t start, pfn_t count)
     520{
     521        int size = sizeof(zone_t) + count*sizeof(frame_t);
     522        int max_order;
     523
     524        for (max_order = 0; count >> max_order; max_order++)
     525                ;
     526        size += buddy_conf_size(max_order);
     527        return size;
     528}
     529
     530/** Create and add zone to system
     531 *
     532 * @param confframe Where configuration frame is supposed to be.
     533 *                  Always check, that we will not disturb kernel pages
     534 *                  the kernel and possibly init.
     535 *                  If confframe is given _outside_ this zone, it is expected,
     536 *                  that the area is already marked BUSY and big enough
     537 *                  to contain zone_conf_size() amount of data
     538 */
     539void zone_create(pfn_t start, pfn_t count, pfn_t confframe, int flags)
     540{
    87541        zone_t *z;
    88 
    89         for (cur = zone_head.next; cur != &zone_head;cur = cur->next) {
    90                 z = list_get_instance(cur, zone_t, link);
    91                
    92                 spinlock_lock(&z->lock);
    93                
    94                 /* Check if the zone has 2^order frames area available  */
    95                 if (buddy_system_can_alloc(z->buddy_system, order))
    96                         return z;
    97                
    98                 spinlock_unlock(&z->lock);
    99         }
    100         return NULL;
     542        __address addr,endaddr;
     543        pfn_t confcount;
     544        int i;
     545
     546        /* Theoretically we could have here 0, practically make sure
     547         * nobody tries to do that. If some platform requires, remove
     548         * the assert
     549         */
     550        ASSERT(confframe);
     551        /* If conframe is supposed to be inside our zone, then make sure
     552         * it does not span kernel & init
     553         */
     554        confcount = SIZE2PFN(zone_conf_size(start,count));
     555        if (confframe >= start && confframe < start+count) {
     556                for (;confframe < start+count;confframe++) {
     557                        addr = PFN2ADDR(confframe);
     558                        endaddr =  PFN2ADDR (confframe + confcount);
     559                        if (overlaps(addr, endaddr, KA2PA(config.base),
     560                                     KA2PA(config.base+config.kernel_size)))
     561                                continue;
     562                        if (config.init_addr)
     563                                if (overlaps(addr,endaddr,
     564                                             KA2PA(config.init_addr),
     565                                             KA2PA(config.init_addr+config.init_size)))
     566                                        continue;
     567                        break;
     568                }
     569                if (confframe >= start+count)
     570                        panic("Cannot find configuration data for zone.");
     571        }
     572
     573        z = zone_construct(start, count, (zone_t *)PA2KA(PFN2ADDR(confframe)), flags);
     574        zones_add_zone(z);
     575       
     576        /* If confdata in zone, mark as unavailable */
     577        if (confframe >= start && confframe < start+count)
     578                for (i=confframe; i<confframe+confcount; i++) {
     579                        zone_mark_unavailable(z, i - z->base);
     580                }
     581}
     582
     583/***************************************/
     584/* Frame functions */
     585
     586/** Set parent of frame */
     587void frame_set_parent(pfn_t pfn, void *data, int hint)
     588{
     589        zone_t *zone = find_zone_and_lock(pfn, &hint);
     590
     591        ASSERT(zone);
     592
     593        zone_get_frame(zone, pfn-zone->base)->parent = data;
     594        spinlock_unlock(&zone->lock);
     595}
     596
     597void * frame_get_parent(pfn_t pfn, int hint)
     598{
     599        zone_t *zone = find_zone_and_lock(pfn, &hint);
     600        void *res;
     601
     602        ASSERT(zone);
     603        res = zone_get_frame(zone, pfn - zone->base)->parent;
     604       
     605        spinlock_unlock(&zone->lock);
     606        return res;
    101607}
    102608
     
    105611 * @param flags Flags for host zone selection and address processing.
    106612 * @param order Allocate exactly 2^order frames.
    107  * @param pzone Pointer to preferred zone pointer, on output it changes
    108  *              to the zone that the frame was really allocated to
     613 * @param pzone Preferred zone
    109614 *
    110615 * @return Allocated frame.
    111616 */
    112 __address frame_alloc_generic(__u8 order, int flags, int * status, zone_t **pzone)
     617pfn_t frame_alloc_generic(__u8 order, int flags, int * status, int *pzone)
    113618{
    114619        ipl_t ipl;
    115         link_t *tmp;
    116         zone_t *zone = NULL;
    117         frame_t *frame = NULL;
    118620        int freed;
    119         __address v;
     621        pfn_t v;
     622        zone_t *zone;
    120623       
    121624loop:
    122625        ipl = interrupts_disable();
    123         spinlock_lock(&zone_head_lock);
    124 
    125626        /*
    126627         * First, find suitable frame zone.
    127628         */
    128         if (pzone && *pzone) {
    129                 spinlock_lock(&(*pzone)->lock);
    130                 if (!buddy_system_can_alloc((*pzone)->buddy_system, order))
    131                         spinlock_unlock(&(*pzone)->lock);
    132                 else
    133                         zone = *pzone;
    134         }
    135         if (!zone) {
    136                 zone = find_free_zone(order);
    137                 /* If no memory, reclaim some slab memory,
    138                    if it does not help, reclaim all */
    139                 if (!zone && !(flags & FRAME_NO_RECLAIM)) {
    140                         spinlock_unlock(&zone_head_lock);
    141                         freed = slab_reclaim(0);
    142                         spinlock_lock(&zone_head_lock);
     629        zone = find_free_zone_lock(order,pzone);
     630        /* If no memory, reclaim some slab memory,
     631           if it does not help, reclaim all */
     632        if (!zone && !(flags & FRAME_NO_RECLAIM)) {
     633                freed = slab_reclaim(0);
     634                if (freed)
     635                        zone = find_free_zone_lock(order,pzone);
     636                if (!zone) {
     637                        freed = slab_reclaim(SLAB_RECLAIM_ALL);
    143638                        if (freed)
    144                                 zone = find_free_zone(order);
    145                         if (!zone) {
    146                                 spinlock_unlock(&zone_head_lock);
    147                                 freed = slab_reclaim(SLAB_RECLAIM_ALL);
    148                                 spinlock_lock(&zone_head_lock);
    149                                 if (freed)
    150                                         zone = find_free_zone(order);
    151                         }
    152                 }
    153         }
    154 
     639                                zone = find_free_zone_lock(order,pzone);
     640                }
     641        }
    155642        if (!zone) {
    156643                if (flags & FRAME_PANIC)
     
    160647                 * TODO: Sleep until frames are available again.
    161648                 */
    162                 spinlock_unlock(&zone_head_lock);
    163649                interrupts_restore(ipl);
    164650
    165651                if (flags & FRAME_ATOMIC) {
    166652                        ASSERT(status != NULL);
    167                         *status = FRAME_NO_MEMORY;
     653                        if (status)
     654                                *status = FRAME_NO_MEMORY;
    168655                        return NULL;
    169656                }
     
    172659                goto loop;
    173660        }
    174                
    175         /* Allocate frames from zone buddy system */
    176         tmp = buddy_system_alloc(zone->buddy_system, order);
    177        
    178         ASSERT(tmp);
    179        
    180         /* Update zone information. */
    181         zone->free_count -= (1 << order);
    182         zone->busy_count += (1 << order);
    183 
    184         /* Frame will be actually a first frame of the block. */
    185         frame = list_get_instance(tmp, frame_t, buddy_link);
    186        
    187         /* get frame address */
    188         v = FRAME2ADDR(zone, frame);
     661        v = zone_frame_alloc(zone,order,flags,status);
     662        v += zone->base;
    189663
    190664        spinlock_unlock(&zone->lock);
    191         spinlock_unlock(&zone_head_lock);
    192665        interrupts_restore(ipl);
    193666
    194         ASSERT(v == ALIGN_UP(v, FRAME_SIZE << order));
    195 
    196         if (flags & FRAME_KA)
    197                 v = PA2KA(v);
    198        
    199667        if (status)
    200668                *status = FRAME_OK;
    201 
    202         if (pzone)
    203                 *pzone = zone;
    204669        return v;
    205670}
    206 
    207 /** Convert address to zone pointer
    208  *
    209  * Assume zone_head_lock is held
    210  *
    211  * @param addr Physical address
    212  * @param lock If true, lock the zone
    213  */
    214 static zone_t * addr2zone(__address addr, int lock)
    215 {
    216         link_t *cur;
    217         zone_t *z = NULL;
    218 
    219         for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
    220                 z = list_get_instance(cur, zone_t, link);
    221                
    222                 spinlock_lock(&z->lock);
    223                
    224                 /*
    225                  * Check if addr belongs to z.
    226                  */
    227                 if ((addr >= z->base) && (addr <= z->base + (z->free_count + z->busy_count) * FRAME_SIZE)) {
    228                         if (!lock)
    229                                 spinlock_unlock(&z->lock);
    230                         return z;
    231                 }
    232 
    233                 spinlock_unlock(&z->lock);
    234         }
    235 
    236         panic("Cannot find addr2zone: 0x%X", addr);
    237 }
    238 
    239 /** Return frame_t structure corresponding to address
    240  *
    241  *
    242  */
    243 frame_t * frame_addr2frame(__address addr)
    244 {
    245         ipl_t ipl;
    246         frame_t *frame;
    247         zone_t *zone;
    248 
    249         if (IS_KA(addr))
    250                 addr = KA2PA(addr);
    251 
    252         /* Disable interrupts to avoid deadlocks with interrupt handlers */
    253         ipl = interrupts_disable();
    254         spinlock_lock(&zone_head_lock);
    255        
    256         zone = addr2zone(addr,0);
    257         frame = ADDR2FRAME(zone, addr);
    258 
    259         spinlock_unlock(&zone_head_lock);
    260         interrupts_restore(ipl);
    261 
    262         return frame;
    263 }
    264 
    265671
    266672/** Free a frame.
     
    270676 * If it drops to zero, move the frame structure to free list.
    271677 *
    272  * @param addr Address of the frame to be freed. It must be a multiple of FRAME_SIZE.
    273  */
    274 void frame_free(__address addr)
     678 * @param frame Frame no to be freed.
     679 */
     680void frame_free(pfn_t pfn)
    275681{
    276682        ipl_t ipl;
    277683        zone_t *zone;
    278         frame_t *frame;
    279         int order;
    280        
    281         ASSERT(addr % FRAME_SIZE == 0);
    282        
    283         if (IS_KA(addr))
    284                 addr = KA2PA(addr);
    285684
    286685        ipl = interrupts_disable();
    287         spinlock_lock(&zone_head_lock);
    288686       
    289687        /*
    290688         * First, find host frame zone for addr.
    291689         */
    292         zone = addr2zone(addr, 1); /* This locks the zone automatically */
    293        
    294         frame = ADDR2FRAME(zone, addr);
    295        
    296         /* remember frame order */
    297         order = frame->buddy_order;
    298 
    299         ASSERT(frame->refcount);
    300 
    301         if (!--frame->refcount) {
    302                 buddy_system_free(zone->buddy_system, &frame->buddy_link);
    303         }
    304 
    305         /* Update zone information. */
    306         zone->free_count += (1 << order);
    307         zone->busy_count -= (1 << order);
     690        zone = find_zone_and_lock(pfn,NULL);
     691        ASSERT(zone);
     692       
     693        zone_frame_free(zone, pfn-zone->base);
    308694       
    309695        spinlock_unlock(&zone->lock);
    310         spinlock_unlock(&zone_head_lock);
    311696        interrupts_restore(ipl);
    312697}
    313698
    314 /** Mark frame region not free.
    315  *
    316  * Mark frame region not free.
    317  *
    318  * @param base Base address of non-available region.
    319  * @param size Size of non-available region.
    320  */
    321 void frame_region_not_free(__address base, size_t size)
    322 {
    323         index_t index;
    324         index = zone_blacklist_count++;
    325 
    326         /* Force base to the nearest lower address frame boundary. */
    327         base = ALIGN_DOWN(base, FRAME_SIZE);
    328         /* Align size to frame boundary. */
    329         size = ALIGN_UP(size, FRAME_SIZE);
    330 
    331         ASSERT(index < ZONE_BLACKLIST_SIZE);
    332         zone_blacklist[index].base = base;
    333         zone_blacklist[index].size = size;
    334 }
    335 
    336 /** Create frame zones in region of available memory.
    337  *
    338  * Avoid any black listed areas of non-available memory.
    339  * Assume that the black listed areas cannot overlap
    340  * one another or cross available memory region boundaries.
    341  *
    342  * @param base Base address of available memory region.
    343  * @param size Size of the region.
    344  */
    345 void zone_create_in_region(__address base, size_t size) {
     699
     700
     701/** Mark given range unavailable in frame zones */
     702void frame_mark_unavailable(pfn_t start, pfn_t count)
     703{
    346704        int i;
    347         zone_t * z;
    348         __address s;
    349         size_t sz;
    350        
    351         ASSERT(base % FRAME_SIZE == 0);
    352         ASSERT(size % FRAME_SIZE == 0);
    353        
    354         if (!size)
    355                 return;
    356 
    357         for (i = 0; i < zone_blacklist_count; i++) {
    358                 if (zone_blacklist[i].base >= base && zone_blacklist[i].base < base + size) {
    359                         s = base; sz = zone_blacklist[i].base - base;
    360                         ASSERT(base != s || sz != size);
    361                         zone_create_in_region(s, sz);
    362                        
    363                         s = zone_blacklist[i].base + zone_blacklist[i].size;
    364                         sz = (base + size) - (zone_blacklist[i].base + zone_blacklist[i].size);
    365                         ASSERT(base != s || sz != size);
    366                         zone_create_in_region(s, sz);
    367                         return;
    368                
    369                 }
    370         }
    371        
    372         z = zone_create(base, size, 0);
    373 
    374         if (!z) {
    375                 panic("Cannot allocate zone (base=%P, size=%d).\n", base, size);
    376         }
    377        
    378         zone_attach(z);
    379 }
    380 
    381 
    382 /** Create frame zone
    383  *
    384  * Create new frame zone.
    385  *
    386  * @param start Physical address of the first frame within the zone.
    387  * @param size Size of the zone. Must be a multiple of FRAME_SIZE.
    388  * @param flags Zone flags.
    389  *
    390  * @return Initialized zone.
    391  */
    392 zone_t * zone_create(__address start, size_t size, int flags)
    393 {
    394         zone_t *z;
    395         count_t cnt;
    396         int i;
    397         __u8 max_order;
    398 
    399         ASSERT(start % FRAME_SIZE == 0);
    400         ASSERT(size % FRAME_SIZE == 0);
    401        
    402         cnt = size / FRAME_SIZE;
    403        
    404         z = (zone_t *) early_malloc(sizeof(zone_t));
    405         if (z) {
    406                 link_initialize(&z->link);
    407                 spinlock_initialize(&z->lock, "zone_lock");
    408        
    409                 z->base = start;
    410                 z->base_index = start / FRAME_SIZE;
    411                
    412                 z->flags = flags;
    413 
    414                 z->free_count = cnt;
    415                 z->busy_count = 0;
    416                
    417                 z->frames = (frame_t *) early_malloc(cnt * sizeof(frame_t));
    418                 if (!z->frames) {
    419                         early_free(z);
    420                         return NULL;
    421                 }
    422                
    423                 for (i = 0; i<cnt; i++) {
    424                         frame_initialize(&z->frames[i], z);
    425                 }
    426                
    427                 /*
    428                  * Create buddy system for the zone
    429                  */
    430                 for (max_order = 0; cnt >> max_order; max_order++)
    431                         ;
    432                 z->buddy_system = buddy_system_create(max_order, &zone_buddy_system_operations, (void *) z);
    433                
    434                 /* Stuffing frames */
    435                 for (i = 0; i<cnt; i++) {
    436                         z->frames[i].refcount = 0;
    437                         buddy_system_free(z->buddy_system, &z->frames[i].buddy_link);   
    438                 }
    439                
    440         }
    441         return z;
    442 }
    443 
    444 /** Attach frame zone
    445  *
    446  * Attach frame zone to zone list.
    447  *
    448  * @param zone Zone to be attached.
    449  */
    450 void zone_attach(zone_t *zone)
    451 {
    452         ipl_t ipl;
    453        
    454         ipl = interrupts_disable();
    455         spinlock_lock(&zone_head_lock);
    456        
    457         list_append(&zone->link, &zone_head);
    458        
    459         spinlock_unlock(&zone_head_lock);
    460         interrupts_restore(ipl);
    461 }
    462 
    463 /** Initialize frame structure
    464  *
    465  * Initialize frame structure.
    466  *
    467  * @param frame Frame structure to be initialized.
    468  * @param zone Host frame zone.
    469  */
    470 void frame_initialize(frame_t *frame, zone_t *zone)
    471 {
    472         frame->refcount = 1;
    473         frame->buddy_order = 0;
    474 }
    475 
    476 
    477 /** Buddy system find_buddy implementation
    478  *
    479  * @param b Buddy system.
    480  * @param block Block for which buddy should be found
    481  *
    482  * @return Buddy for given block if found
    483  */
    484 link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * block) {
    485         frame_t * frame;
    486         zone_t * zone;
    487         index_t index;
    488         bool is_left, is_right;
    489 
    490         frame = list_get_instance(block, frame_t, buddy_link);
    491         zone = (zone_t *) b->data;
    492         ASSERT(IS_BUDDY_ORDER_OK(FRAME_INDEX_ABS(zone, frame), frame->buddy_order));
    493        
    494        
    495         is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
    496         is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame);
    497        
    498         ASSERT(is_left ^ is_right);
    499        
    500         if (is_left) {
    501                 index = (FRAME_INDEX(zone, frame)) + (1 << frame->buddy_order);
    502         } else { // if (is_right)
    503                 index = (FRAME_INDEX(zone, frame)) - (1 << frame->buddy_order);
    504         }
    505        
    506         if (FRAME_INDEX_VALID(zone, index)) {
    507                 if (    zone->frames[index].buddy_order == frame->buddy_order &&
    508                         zone->frames[index].refcount == 0) {
    509                         return &zone->frames[index].buddy_link;
    510                 }
    511         }
    512        
    513         return NULL;   
    514 }
    515 
    516 /** Buddy system bisect implementation
    517  *
    518  * @param b Buddy system.
    519  * @param block Block to bisect
    520  *
    521  * @return right block
    522  */
    523 link_t * zone_buddy_bisect(buddy_system_t *b, link_t * block) {
    524         frame_t * frame_l, * frame_r;
    525 
    526         frame_l = list_get_instance(block, frame_t, buddy_link);
    527         frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
    528        
    529         return &frame_r->buddy_link;
    530 }
    531 
    532 /** Buddy system coalesce implementation
    533  *
    534  * @param b Buddy system.
    535  * @param block_1 First block
    536  * @param block_2 First block's buddy
    537  *
    538  * @return Coalesced block (actually block that represents lower address)
    539  */
    540 link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * block_1, link_t * block_2) {
    541         frame_t * frame1, * frame2;
    542        
    543         frame1 = list_get_instance(block_1, frame_t, buddy_link);
    544         frame2 = list_get_instance(block_2, frame_t, buddy_link);
    545        
    546         return frame1 < frame2 ? block_1 : block_2;
    547 }
    548 
    549 /** Buddy system set_order implementation
    550  *
    551  * @param b Buddy system.
    552  * @param block Buddy system block
    553  * @param order Order to set
    554  */
    555 void zone_buddy_set_order(buddy_system_t *b, link_t * block, __u8 order) {
    556         frame_t * frame;
    557         frame = list_get_instance(block, frame_t, buddy_link);
    558         frame->buddy_order = order;
    559 }
    560 
    561 /** Buddy system get_order implementation
    562  *
    563  * @param b Buddy system.
    564  * @param block Buddy system block
    565  *
    566  * @return Order of block
    567  */
    568 __u8 zone_buddy_get_order(buddy_system_t *b, link_t * block) {
    569         frame_t * frame;
    570         frame = list_get_instance(block, frame_t, buddy_link);
    571         return frame->buddy_order;
    572 }
    573 
    574 /** Buddy system mark_busy implementation
    575  *
    576  * @param b Buddy system
    577  * @param block Buddy system block
    578  *
    579  */
    580 void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) {
    581         frame_t * frame;
    582         frame = list_get_instance(block, frame_t, buddy_link);
    583         frame->refcount = 1;
    584 }
     705        zone_t *zone;
     706        int prefzone = 0;
     707
     708        for (i=0; i<count; i++) {
     709                zone = find_zone_and_lock(start+i,&prefzone);
     710                if (!zone) /* PFN not found */
     711                        continue;
     712                zone_mark_unavailable(zone, start+i-zone->base);
     713
     714                spinlock_unlock(&zone->lock);
     715        }
     716}
     717
     718/** Initialize physical memory management
     719 *
     720 * Initialize physical memory managemnt.
     721 */
     722void frame_init(void)
     723{
     724        if (config.cpu_active == 1) {
     725                zones.count = 0;
     726                spinlock_initialize(&zones.lock,"zones_glob_lock");
     727        }
     728        /* Tell the architecture to create some memory */
     729        frame_arch_init();
     730        if (config.cpu_active == 1) {
     731                frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)),
     732                                       SIZE2PFN(config.kernel_size));
     733                if (config.init_size > 0)
     734                        frame_mark_unavailable(ADDR2PFN(KA2PA(config.init_addr)),
     735                                               SIZE2PFN(config.init_size));
     736        }
     737}
     738
     739
    585740
    586741/** Prints list of zones
     
    589744void zone_print_list(void) {
    590745        zone_t *zone = NULL;
    591         link_t *cur;
     746        int i;
    592747        ipl_t ipl;
    593748
    594749        ipl = interrupts_disable();
    595         spinlock_lock(&zone_head_lock);
     750        spinlock_lock(&zones.lock);
    596751        printf("Base address\tFree Frames\tBusy Frames\n");
    597752        printf("------------\t-----------\t-----------\n");
    598         for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
    599                 zone = list_get_instance(cur, zone_t, link);
     753        for (i=0;i<zones.count;i++) {
     754                zone = zones.info[i];
    600755                spinlock_lock(&zone->lock);
    601                 printf("%L\t%d\t\t%d\n",zone->base, zone->free_count, zone->busy_count);
     756                printf("%L\t%d\t\t%d\n",PFN2ADDR(zone->base),
     757                       zone->free_count, zone->busy_count);
    602758                spinlock_unlock(&zone->lock);
    603759        }
    604         spinlock_unlock(&zone_head_lock);
     760        spinlock_unlock(&zones.lock);
    605761        interrupts_restore(ipl);
    606762}
     
    610766 * @param base Zone base address
    611767 */
    612 void zone_print_one(__address base) {
    613         zone_t *zone = NULL, *z ;
    614         link_t *cur;
     768void zone_print_one(int znum) {
     769        zone_t *zone = NULL;
    615770        ipl_t ipl;
    616771
    617772        ipl = interrupts_disable();
    618         spinlock_lock(&zone_head_lock);
    619        
    620         for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
    621                 z = list_get_instance(cur, zone_t, link);
    622                 if (base == z->base) {
    623                         zone = z;
    624                         break;
    625                 }
    626         }
    627        
    628         if (!zone) {
    629                 spinlock_unlock(&zone_head_lock);
     773        spinlock_lock(&zones.lock);
     774       
     775        if (znum >= zones.count || znum < 0) {
     776                printf("Zone number out of bounds.\n");
     777                spinlock_unlock(&zones.lock);
    630778                interrupts_restore(ipl);
    631                 printf("No zone with address %X\n", base);
    632779                return;
    633780        }
     781       
     782        zone = zones.info[znum];
    634783       
    635784        spinlock_lock(&zone->lock);
    636785        printf("Memory zone information\n\n");
    637         printf("Zone base address: %P\n", zone->base);
    638         printf("Zone size: %d frames (%dK)\n", zone->free_count + zone->busy_count, ((zone->free_count + zone->busy_count) * FRAME_SIZE) >> 10);
     786        printf("Zone base address: %P\n", PFN2ADDR(zone->base));
     787        printf("Zone size: %d frames (%dK)\n", zone->count, ((zone->count) * FRAME_SIZE) >> 10);
    639788        printf("Allocated space: %d frames (%dK)\n", zone->busy_count, (zone->busy_count * FRAME_SIZE) >> 10);
    640789        printf("Available space: %d (%dK)\n", zone->free_count, (zone->free_count * FRAME_SIZE) >> 10);
     
    644793       
    645794        spinlock_unlock(&zone->lock);
    646         spinlock_unlock(&zone_head_lock);
     795        spinlock_unlock(&zones.lock);
    647796        interrupts_restore(ipl);
    648797}
  • generic/src/mm/slab.c

    reb1b8b6 r085d973  
    9797#include <memstr.h>
    9898#include <align.h>
    99 #include <mm/heap.h>
    10099#include <mm/frame.h>
    101100#include <config.h>
     
    155154        size_t fsize;
    156155        int i;
    157         zone_t *zone = NULL;
    158156        int status;
    159         frame_t *frame;
    160 
    161         data = (void *)frame_alloc_rc_zone(cache->order, FRAME_KA | flags, &status, &zone);
     157        pfn_t pfn;
     158        int zone=0;
     159       
     160        pfn = frame_alloc_rc_zone(cache->order, FRAME_KA | flags, &status, &zone);
     161        data = (void *) PA2KA(PFN2ADDR(pfn));
    162162        if (status != FRAME_OK) {
    163163                return NULL;
     
    166166                slab = slab_alloc(slab_extern_cache, flags);
    167167                if (!slab) {
    168                         frame_free((__address)data);
     168                        frame_free(ADDR2PFN(KA2PA(data)));
    169169                        return NULL;
    170170                }
     
    175175               
    176176        /* Fill in slab structures */
    177         /* TODO: some better way of accessing the frame */
    178         for (i=0; i < (1 << cache->order); i++) {
    179                 frame = ADDR2FRAME(zone, KA2PA((__address)(data+i*PAGE_SIZE)));
    180                 frame->parent = slab;
    181         }
     177        for (i=0; i < (1 << cache->order); i++)
     178                frame_set_parent(pfn+i, slab, zone);
    182179
    183180        slab->start = data;
     
    200197static count_t slab_space_free(slab_cache_t *cache, slab_t *slab)
    201198{
    202         frame_free((__address)slab->start);
     199        frame_free(ADDR2PFN(KA2PA(slab->start)));
    203200        if (! (cache->flags & SLAB_CACHE_SLINSIDE))
    204201                slab_free(slab_extern_cache, slab);
     
    212209static slab_t * obj2slab(void *obj)
    213210{
    214         frame_t *frame;
    215 
    216         frame = frame_addr2frame((__address)obj);
    217         return (slab_t *)frame->parent;
     211        return (slab_t *)frame_get_parent(ADDR2PFN(KA2PA(obj)), 0);
    218212}
    219213
     
    726720        ipl = interrupts_disable();
    727721
    728         if (!(cache->flags & SLAB_CACHE_NOMAGAZINE))
     722        if (!(cache->flags & SLAB_CACHE_NOMAGAZINE)) {
    729723                result = magazine_obj_get(cache);
     724        }
    730725        if (!result)
    731726                result = slab_obj_create(cache, flags);
  • generic/src/proc/scheduler.c

    reb1b8b6 r085d973  
    3030#include <proc/thread.h>
    3131#include <proc/task.h>
    32 #include <mm/heap.h>
    3332#include <mm/frame.h>
    3433#include <mm/page.h>
  • generic/src/proc/task.c

    reb1b8b6 r085d973  
    3030#include <proc/task.h>
    3131#include <mm/as.h>
    32 #include <mm/heap.h>
     32#include <mm/slab.h>
    3333
    3434#include <synch/spinlock.h>
  • generic/src/proc/thread.c

    reb1b8b6 r085d973  
    3030#include <proc/thread.h>
    3131#include <proc/task.h>
    32 #include <mm/heap.h>
    3332#include <mm/frame.h>
    3433#include <mm/page.h>
     
    9695{
    9796        thread_t *t = (thread_t *)obj;
     97        pfn_t pfn;
    9898
    9999        spinlock_initialize(&t->lock, "thread_t_lock");
     
    103103        link_initialize(&t->threads_link);
    104104       
    105         t->kstack = (__u8 *)frame_alloc(ONE_FRAME, FRAME_KA | kmflags);
     105        pfn = frame_alloc(ONE_FRAME, FRAME_KA | kmflags);
     106        t->kstack = (__u8 *)PA2KA(PFN2ADDR(pfn));
    106107        if (!t->kstack)
    107108                return -1;
     
    115116        thread_t *t = (thread_t *)obj;
    116117
    117         frame_free((__address) t->kstack);
     118        frame_free(ADDR2PFN(KA2PA(t->kstack)));
    118119        return 1; /* One page freed */
    119120}
     
    194195        spinlock_unlock(&t->cpu->lock);
    195196
    196         if (t->ustack)
    197                 frame_free((__address) t->ustack);
    198        
    199197        /*
    200198         * Detach from the containing task.
     
    229227{
    230228        thread_t *t;
    231         __address frame_us = NULL;
    232229
    233230        t = (thread_t *) slab_alloc(thread_slab, 0);
     
    235232                ipl_t ipl;
    236233       
    237                 if (THREAD_USER_STACK & flags) {
    238                         frame_us = frame_alloc(ONE_FRAME, FRAME_KA);
    239                 }
    240 
    241234                /* Not needed, but good for debugging */
    242235                memsetb((__address)t->kstack, THREAD_STACK_SIZE, 0);
     
    247240                spinlock_unlock(&tidlock);
    248241                interrupts_restore(ipl);
    249                
    250                 t->ustack = (__u8 *) frame_us;
    251242               
    252243                context_save(&t->saved_context);
  • test/mm/falloc1/test.c

    reb1b8b6 r085d973  
    3030#include <mm/page.h>
    3131#include <mm/frame.h>
    32 #include <mm/heap.h>
     32#include <mm/slab.h>
    3333#include <arch/mm/page.h>
    3434#include <arch/types.h>
     
    5656                        allocated = 0;
    5757                        for (i = 0; i < MAX_FRAMES >> order; i++) {
    58                                 frames[allocated] = frame_alloc_rc(order, FRAME_ATOMIC | FRAME_KA, &status);
     58                                frames[allocated] = PA2KA(PFN2ADDR(frame_alloc_rc(order, FRAME_ATOMIC | FRAME_KA, &status)));
    5959                               
    6060                                if (ALIGN_UP(frames[allocated], FRAME_SIZE << order) != frames[allocated]) {
     
    8181                        printf("Deallocating ... ");
    8282                        for (i = 0; i < allocated; i++) {
    83                                 frame_free(frames[i]);
     83                                frame_free(ADDR2PFN(KA2PA(frames[i])));
    8484                        }
    8585                        printf("done.\n");
  • test/mm/falloc2/test.c

    reb1b8b6 r085d973  
    3030#include <mm/page.h>
    3131#include <mm/frame.h>
    32 #include <mm/heap.h>
     32#include <mm/slab.h>
    3333#include <arch/mm/page.h>
    3434#include <arch/types.h>
     
    6464                        allocated = 0;
    6565                        for (i = 0; i < (MAX_FRAMES >> order); i++) {
    66                                 frames[allocated] = frame_alloc_rc(order, FRAME_ATOMIC | FRAME_KA, &status);
     66                                frames[allocated] = PA2KA(PFN2ADDR(frame_alloc_rc(order, FRAME_ATOMIC | FRAME_KA, &status)));
    6767                                if (status == 0) {
    6868                                        memsetb(frames[allocated], FRAME_SIZE << order, val);
     
    8282                                        }
    8383                                }
    84                                 frame_free(frames[i]);
     84                                frame_free(ADDR2PFN(KA2PA(frames[i])));
    8585                        }
    8686                        printf("Thread #%d (cpu%d): Finished run.\n", THREAD->tid, CPU->id);
Note: See TracChangeset for help on using the changeset viewer.