/kernel/trunk/test/mm/falloc1/test.c |
---|
29,7 → 29,7 |
#include <test.h> |
#include <mm/page.h> |
#include <mm/frame.h> |
#include <mm/heap.h> |
#include <mm/slab.h> |
#include <arch/mm/page.h> |
#include <arch/types.h> |
#include <debug.h> |
55,7 → 55,7 |
printf("Allocating %d frames blocks ... ", 1 << order); |
allocated = 0; |
for (i = 0; i < MAX_FRAMES >> order; i++) { |
frames[allocated] = frame_alloc_rc(order, FRAME_ATOMIC | FRAME_KA, &status); |
frames[allocated] = PA2KA(PFN2ADDR(frame_alloc_rc(order, FRAME_ATOMIC | FRAME_KA, &status))); |
if (ALIGN_UP(frames[allocated], FRAME_SIZE << order) != frames[allocated]) { |
panic("Test failed. Block at address %X (size %dK) is not aligned\n", frames[allocated], (FRAME_SIZE << order) >> 10); |
80,7 → 80,7 |
printf("Deallocating ... "); |
for (i = 0; i < allocated; i++) { |
frame_free(frames[i]); |
frame_free(ADDR2PFN(KA2PA(frames[i]))); |
} |
printf("done.\n"); |
} |
/kernel/trunk/test/mm/falloc2/test.c |
---|
29,7 → 29,7 |
#include <test.h> |
#include <mm/page.h> |
#include <mm/frame.h> |
#include <mm/heap.h> |
#include <mm/slab.h> |
#include <arch/mm/page.h> |
#include <arch/types.h> |
#include <arch/atomic.h> |
63,7 → 63,7 |
printf("Thread #%d (cpu%d): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order); |
allocated = 0; |
for (i = 0; i < (MAX_FRAMES >> order); i++) { |
frames[allocated] = frame_alloc_rc(order, FRAME_ATOMIC | FRAME_KA, &status); |
frames[allocated] = PA2KA(PFN2ADDR(frame_alloc_rc(order, FRAME_ATOMIC | FRAME_KA, &status))); |
if (status == 0) { |
memsetb(frames[allocated], FRAME_SIZE << order, val); |
allocated++; |
81,7 → 81,7 |
failed(); |
} |
} |
frame_free(frames[i]); |
frame_free(ADDR2PFN(KA2PA(frames[i]))); |
} |
printf("Thread #%d (cpu%d): Finished run.\n", THREAD->tid, CPU->id); |
} |
/kernel/trunk/contrib/conf/msim.conf |
---|
4,7 → 4,7 |
add dcpu mips1 |
add rwm firstmem 0x0 128k load "/dev/zero" |
add rwm firstmem 0x0 1M load "/dev/zero" |
add rwm mainmem 0x00100000 16M load "kernel.bin" |
add rom startmem 0x1fc00000 1k load "load.bin" |
add rwm init 0x20000000 1M load "init |
/kernel/trunk/genarch/src/mm/page_pt.c |
---|
65,7 → 65,7 |
ptl0 = (pte_t *) PA2KA((__address) as->page_table); |
if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) { |
newpt = frame_alloc(ONE_FRAME, FRAME_KA); |
newpt = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA))); |
memsetb(newpt, PAGE_SIZE, 0); |
SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt)); |
SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); |
74,7 → 74,7 |
ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page))); |
if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) { |
newpt = frame_alloc(ONE_FRAME, FRAME_KA); |
newpt = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA))); |
memsetb(newpt, PAGE_SIZE, 0); |
SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt)); |
SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); |
83,7 → 83,7 |
ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page))); |
if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) { |
newpt = frame_alloc(ONE_FRAME, FRAME_KA); |
newpt = PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA))); |
memsetb(newpt, PAGE_SIZE, 0); |
SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt)); |
SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); |
/kernel/trunk/genarch/src/mm/as_pt.c |
---|
56,7 → 56,7 |
pte_t *src_ptl0, *dst_ptl0; |
ipl_t ipl; |
dst_ptl0 = (pte_t *) frame_alloc(ONE_FRAME, FRAME_KA | FRAME_PANIC); |
dst_ptl0 = (pte_t *) PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA | FRAME_PANIC))); |
if (flags & FLAG_AS_KERNEL) { |
memsetb((__address) dst_ptl0, PAGE_SIZE, 0); |
/kernel/trunk/genarch/src/acpi/matd.c |
---|
36,7 → 36,7 |
#include <debug.h> |
#include <config.h> |
#include <print.h> |
#include <mm/heap.h> |
#include <mm/slab.h> |
#include <memstr.h> |
#include <sort.h> |
144,7 → 144,7 |
} |
/* create madt apic entries index array */ |
madt_entries_index = (struct madt_apic_header * *) early_malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *)); |
madt_entries_index = (struct madt_apic_header * *) malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *)); |
__u32 index = 0; |
/kernel/trunk/generic/include/proc/thread.h |
---|
111,7 → 111,6 |
ARCH_THREAD_DATA; /**< Architecture-specific data. */ |
__u8 *kstack; /**< Thread's kernel stack. */ |
__u8 *ustack; /**< Thread's user stack. */ |
}; |
/** Thread list lock. |
/kernel/trunk/generic/include/mm/heap.h |
---|
File deleted |
/kernel/trunk/generic/include/mm/frame.h |
---|
35,10 → 35,15 |
#include <adt/list.h> |
#include <synch/spinlock.h> |
#include <mm/buddy.h> |
#include <mm/slab.h> |
#include <arch/mm/page.h> |
#define ONE_FRAME 0 |
#define ZONES_MAX 16 /**< Maximum number of zones in system */ |
#define ZONE_JOIN 0x1 /**< If possible, merge with neighberhood zones */ |
#define FRAME_KA 0x1 /* skip frames conflicting with user address space */ |
#define FRAME_PANIC 0x2 /* panic on failure */ |
#define FRAME_ATOMIC 0x4 /* do not panic and do not sleep on failure */ |
48,92 → 53,61 |
#define FRAME_NO_MEMORY 1 /* frame_alloc return status */ |
#define FRAME_ERROR 2 /* frame_alloc return status */ |
#define FRAME2ADDR(zone, frame) ((zone)->base + (((frame) - (zone)->frames) << FRAME_WIDTH)) |
#define ADDR2FRAME(zone, addr) (&((zone)->frames[(((addr) - (zone)->base) >> FRAME_WIDTH)])) |
#define FRAME_INDEX(zone, frame) ((index_t)((frame) - (zone)->frames)) |
#define FRAME_INDEX_ABS(zone, frame) (((index_t)((frame) - (zone)->frames)) + (zone)->base_index) |
#define FRAME_INDEX_VALID(zone, index) (((index) >= 0) && ((index) < ((zone)->free_count + (zone)->busy_count))) |
/* Return true if the interlvals overlap */ |
static inline int overlaps(__address s1,__address e1, __address s2, __address e2) |
{ |
if (s1 >= s2 && s1 < e2) |
return 1; |
if (e1 >= s2 && e1 < e2) |
return 1; |
if ((s1 < s2) && (e1 >= e2)) |
return 1; |
return 0; |
} |
static inline __address PFN2ADDR(pfn_t frame) |
{ |
return (__address)(frame << PAGE_WIDTH); |
} |
static inline pfn_t ADDR2PFN(__address addr) |
{ |
return (pfn_t)(addr >> PAGE_WIDTH); |
} |
static inline pfn_t SIZE2PFN(__address size) |
{ |
if (!size) |
return 0; |
return (pfn_t)((size-1) >> PAGE_WIDTH)+1; |
} |
#define IS_BUDDY_ORDER_OK(index, order) ((~(((__native) -1) << (order)) & (index)) == 0) |
#define IS_BUDDY_LEFT_BLOCK(zone, frame) (((FRAME_INDEX((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0) |
#define IS_BUDDY_RIGHT_BLOCK(zone, frame) (((FRAME_INDEX((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1) |
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) (((FRAME_INDEX_ABS((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0) |
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) (((FRAME_INDEX_ABS((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1) |
#define IS_BUDDY_LEFT_BLOCK(zone, frame) (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0) |
#define IS_BUDDY_RIGHT_BLOCK(zone, frame) (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1) |
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0) |
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1) |
#define ZONE_BLACKLIST_SIZE 8 |
#define frame_alloc(order, flags) frame_alloc_generic(order, flags, NULL, NULL) |
#define frame_alloc_rc(order, flags, status) frame_alloc_generic(order, flags, status, NULL) |
#define frame_alloc_rc_zone(order, flags, status, zone) frame_alloc_generic(order, flags, status, zone) |
struct zone { |
link_t link; /**< link to previous and next zone */ |
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */ |
__address base; /**< physical address of the first frame in the frames array */ |
index_t base_index; /**< frame index offset of the zone base */ |
frame_t *frames; /**< array of frame_t structures in this zone */ |
count_t free_count; /**< number of free frame_t structures */ |
count_t busy_count; /**< number of busy frame_t structures */ |
buddy_system_t * buddy_system; /**< buddy system for the zone */ |
int flags; |
}; |
struct frame { |
count_t refcount; /**< tracking of shared frames */ |
__u8 buddy_order; /**< buddy system block order */ |
link_t buddy_link; /**< link to the next free block inside one order */ |
void *parent; /**< If allocated by slab, this points there */ |
}; |
struct region { |
__address base; |
size_t size; |
}; |
extern region_t zone_blacklist[]; |
extern count_t zone_blacklist_count; |
extern void frame_region_not_free(__address base, size_t size); |
extern void zone_create_in_region(__address base, size_t size); |
extern spinlock_t zone_head_lock; /**< this lock protects zone_head list */ |
extern link_t zone_head; /**< list of all zones in the system */ |
extern zone_t *zone_create(__address start, size_t size, int flags); |
extern void zone_attach(zone_t *zone); |
extern void frame_init(void); |
extern void frame_initialize(frame_t *frame, zone_t *zone); |
__address frame_alloc_generic(__u8 order, int flags, int * status, zone_t **pzone); |
__address frame_alloc_generic(__u8 order, int flags, int * status, int *pzone); |
extern void frame_free(__address addr); |
zone_t * get_zone_by_frame(frame_t * frame); |
extern void zone_create(pfn_t start, pfn_t count, pfn_t confframe, int flags); |
/* |
* Buddy system operations |
*/ |
link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * buddy); |
link_t * zone_buddy_bisect(buddy_system_t *b, link_t * block); |
link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * buddy_l, link_t * buddy_r); |
void zone_buddy_set_order(buddy_system_t *b, link_t * block, __u8 order); |
__u8 zone_buddy_get_order(buddy_system_t *b, link_t * block); |
void zone_buddy_mark_busy(buddy_system_t *b, link_t * block); |
extern frame_t * frame_addr2frame(__address addr); |
void * frame_get_parent(pfn_t frame, int hint); |
void frame_set_parent(pfn_t frame, void *data, int hint); |
void frame_mark_unavailable(pfn_t start, pfn_t count); |
__address zone_conf_size(pfn_t start, pfn_t count); |
/* |
* TODO: Implement the following functions. |
*/ |
extern frame_t *frame_reference(frame_t *frame); |
extern void frame_release(frame_t *frame); |
/* |
* Console functions |
*/ |
extern void zone_print_list(void); |
extern void zone_print_one(__address base); |
void zone_print_one(int znum); |
#endif |
/kernel/trunk/generic/include/mm/slab.h |
---|
32,6 → 32,7 |
#include <adt/list.h> |
#include <synch/spinlock.h> |
#include <arch/atomic.h> |
#include <mm/frame.h> |
/** Minimum size to be allocated by malloc */ |
#define SLAB_MIN_MALLOC_W 4 |
126,4 → 127,6 |
/* Malloc support */ |
extern void * kalloc(unsigned int size, int flags); |
extern void kfree(void *obj); |
#define malloc(x) kalloc(x, FRAME_ATOMIC) |
#define free(x) kfree(x) |
#endif |
/kernel/trunk/generic/include/mm/buddy.h |
---|
42,6 → 42,9 |
void (*set_order)(buddy_system_t *, link_t *, __u8); /**< Set order of block passed as argument. */ |
__u8 (*get_order)(buddy_system_t *, link_t *); /**< Return order of block passed as argument. */ |
void (*mark_busy)(buddy_system_t *, link_t *); /**< Mark block as busy */ |
void (*mark_available)(buddy_system_t *, link_t *); /**< Mark block as busy */ |
/** Find parent of block that has given order */ |
link_t *(* find_block)(buddy_system_t *, link_t *, __u8); |
}; |
struct buddy_system { |
51,10 → 54,14 |
void *data; /**< Pointer to be used by the implementation. */ |
}; |
extern buddy_system_t *buddy_system_create(__u8 max_order, buddy_system_operations_t *op, void *data); |
extern void buddy_system_create(buddy_system_t *b, |
__u8 max_order, |
buddy_system_operations_t *op, void *data); |
extern link_t *buddy_system_alloc(buddy_system_t *b, __u8 i); |
extern bool buddy_system_can_alloc(buddy_system_t *b, __u8 order); |
extern void buddy_system_free(buddy_system_t *b, link_t *block); |
extern void buddy_system_structure_print(buddy_system_t *b, size_t elem_size); |
extern size_t buddy_conf_size(int max_order); |
extern link_t *buddy_system_alloc_block(buddy_system_t *b, link_t *block); |
#endif |
/kernel/trunk/generic/include/typedefs.h |
---|
66,10 → 66,6 |
typedef struct buddy_system buddy_system_t; |
typedef struct buddy_system_operations buddy_system_operations_t; |
typedef struct zone zone_t; |
typedef struct frame frame_t; |
typedef struct region region_t; |
typedef enum as_area_type as_area_type_t; |
typedef struct as_area as_area_t; |
typedef struct as as_t; |
/kernel/trunk/generic/src/proc/scheduler.c |
---|
29,7 → 29,6 |
#include <proc/scheduler.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <mm/heap.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <mm/as.h> |
/kernel/trunk/generic/src/proc/task.c |
---|
29,7 → 29,7 |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <mm/as.h> |
#include <mm/heap.h> |
#include <mm/slab.h> |
#include <synch/spinlock.h> |
#include <arch.h> |
/kernel/trunk/generic/src/proc/thread.c |
---|
29,7 → 29,6 |
#include <proc/scheduler.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <mm/heap.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <arch/asm.h> |
95,6 → 94,7 |
static int thr_constructor(void *obj, int kmflags) |
{ |
thread_t *t = (thread_t *)obj; |
pfn_t pfn; |
spinlock_initialize(&t->lock, "thread_t_lock"); |
link_initialize(&t->rq_link); |
102,7 → 102,8 |
link_initialize(&t->th_link); |
link_initialize(&t->threads_link); |
t->kstack = (__u8 *)frame_alloc(ONE_FRAME, FRAME_KA | kmflags); |
pfn = frame_alloc(ONE_FRAME, FRAME_KA | kmflags); |
t->kstack = (__u8 *)PA2KA(PFN2ADDR(pfn)); |
if (!t->kstack) |
return -1; |
114,7 → 115,7 |
{ |
thread_t *t = (thread_t *)obj; |
frame_free((__address) t->kstack); |
frame_free(ADDR2PFN(KA2PA(t->kstack))); |
return 1; /* One page freed */ |
} |
193,9 → 194,6 |
t->cpu->fpu_owner=NULL; |
spinlock_unlock(&t->cpu->lock); |
if (t->ustack) |
frame_free((__address) t->ustack); |
/* |
* Detach from the containing task. |
*/ |
228,16 → 226,11 |
thread_t *thread_create(void (* func)(void *), void *arg, task_t *task, int flags) |
{ |
thread_t *t; |
__address frame_us = NULL; |
t = (thread_t *) slab_alloc(thread_slab, 0); |
if (t) { |
ipl_t ipl; |
if (THREAD_USER_STACK & flags) { |
frame_us = frame_alloc(ONE_FRAME, FRAME_KA); |
} |
/* Not needed, but good for debugging */ |
memsetb((__address)t->kstack, THREAD_STACK_SIZE, 0); |
247,8 → 240,6 |
spinlock_unlock(&tidlock); |
interrupts_restore(ipl); |
t->ustack = (__u8 *) frame_us; |
context_save(&t->saved_context); |
context_set(&t->saved_context, FADDR(cushion), (__address) t->kstack, THREAD_STACK_SIZE); |
/kernel/trunk/generic/src/main/main.c |
---|
43,7 → 43,6 |
#include <align.h> |
#include <interrupt.h> |
#include <arch/mm/memory_init.h> |
#include <mm/heap.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <genarch/mm/page_pt.h> |
103,6 → 102,8 |
*/ |
void main_bsp(void) |
{ |
__address stackaddr; |
config.cpu_count = 1; |
config.cpu_active = 1; |
111,19 → 112,22 |
config.init_addr = init_addr; |
config.init_size = init_size; |
if (init_size > 0) |
config.heap_addr = init_addr + init_size; |
else |
config.heap_addr = hardcoded_load_address + hardcoded_ktext_size + hardcoded_kdata_size; |
config.kernel_size = ALIGN_UP(hardcoded_ktext_size + hardcoded_kdata_size, PAGE_SIZE); |
stackaddr = config.base + config.kernel_size; |
/* Avoid placing kernel on top of init */ |
if (overlaps(stackaddr,stackaddr+CONFIG_STACK_SIZE, |
config.init_addr, config.init_addr+config.init_size)) { |
stackaddr = ALIGN_UP(config.init_addr+config.init_size, |
CONFIG_STACK_SIZE); |
config.init_size = ALIGN_UP(config.init_size,CONFIG_STACK_SIZE) + CONFIG_STACK_SIZE; |
} else { |
config.kernel_size += CONFIG_STACK_SIZE; |
} |
config.heap_size = CONFIG_HEAP_SIZE + (config.memory_size / FRAME_SIZE) * sizeof(frame_t); |
config.kernel_size = ALIGN_UP(config.heap_addr - hardcoded_load_address + config.heap_size, PAGE_SIZE); |
config.heap_delta = config.kernel_size - (config.heap_addr - hardcoded_load_address + config.heap_size); |
config.kernel_size = config.kernel_size + CONFIG_STACK_SIZE; |
context_save(&ctx); |
context_set(&ctx, FADDR(main_bsp_separated_stack), config.base + config.kernel_size - CONFIG_STACK_SIZE, CONFIG_STACK_SIZE); |
context_set(&ctx, FADDR(main_bsp_separated_stack), |
stackaddr, CONFIG_STACK_SIZE); |
context_restore(&ctx); |
/* not reached */ |
} |
140,7 → 144,6 |
thread_t *t; |
the_initialize(THE); |
/* |
* kconsole data structures must be initialized very early |
* because other subsystems will register their respective |
158,14 → 161,13 |
* Memory management subsystems initialization. |
*/ |
arch_pre_mm_init(); |
early_heap_init(config.heap_addr, config.heap_size + config.heap_delta); |
/* Initialize at least 1 memory segment big enough for slab to work */ |
frame_init(); |
slab_cache_init(); |
as_init(); |
page_init(); |
tlb_init(); |
arch_post_mm_init(); |
arch_post_mm_init(); |
version_print(); |
printf("%P: hardcoded_ktext_size=%dK, hardcoded_kdata_size=%dK\n", |
178,11 → 180,9 |
printf("config.memory_size=%dM\n", config.memory_size/(1024*1024)); |
printf("config.cpu_count=%d\n", config.cpu_count); |
cpu_init(); |
calibrate_delay_loop(); |
timeout_init(); |
scheduler_init(); |
task_init(); |
/kernel/trunk/generic/src/lib/sort.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <mm/heap.h> |
#include <mm/slab.h> |
#include <memstr.h> |
#include <sort.h> |
#include <panic.h> |
/kernel/trunk/generic/src/cpu/cpu.c |
---|
29,7 → 29,7 |
#include <cpu.h> |
#include <arch.h> |
#include <arch/cpu.h> |
#include <mm/heap.h> |
#include <mm/slab.h> |
#include <mm/page.h> |
#include <mm/frame.h> |
#include <arch/types.h> |
61,7 → 61,7 |
memsetb((__address) cpus, sizeof(cpu_t) * config.cpu_count, 0); |
for (i=0; i < config.cpu_count; i++) { |
cpus[i].stack = (__u8 *) frame_alloc(ONE_FRAME, FRAME_KA | FRAME_PANIC); |
cpus[i].stack = (__u8 *) PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA | FRAME_PANIC))); |
cpus[i].id = i; |
/kernel/trunk/generic/src/adt/hash_table.c |
---|
35,7 → 35,7 |
#include <typedefs.h> |
#include <arch/types.h> |
#include <debug.h> |
#include <mm/heap.h> |
#include <mm/slab.h> |
#include <memstr.h> |
/** Create chained hash table. |
/kernel/trunk/generic/src/mm/heap.c |
---|
File deleted |
/kernel/trunk/generic/src/mm/slab.c |
---|
96,7 → 96,6 |
#include <adt/list.h> |
#include <memstr.h> |
#include <align.h> |
#include <mm/heap.h> |
#include <mm/frame.h> |
#include <config.h> |
#include <print.h> |
154,11 → 153,12 |
slab_t *slab; |
size_t fsize; |
int i; |
zone_t *zone = NULL; |
int status; |
frame_t *frame; |
data = (void *)frame_alloc_rc_zone(cache->order, FRAME_KA | flags, &status, &zone); |
pfn_t pfn; |
int zone=0; |
pfn = frame_alloc_rc_zone(cache->order, FRAME_KA | flags, &status, &zone); |
data = (void *) PA2KA(PFN2ADDR(pfn)); |
if (status != FRAME_OK) { |
return NULL; |
} |
165,7 → 165,7 |
if (! (cache->flags & SLAB_CACHE_SLINSIDE)) { |
slab = slab_alloc(slab_extern_cache, flags); |
if (!slab) { |
frame_free((__address)data); |
frame_free(ADDR2PFN(KA2PA(data))); |
return NULL; |
} |
} else { |
174,11 → 174,8 |
} |
/* Fill in slab structures */ |
/* TODO: some better way of accessing the frame */ |
for (i=0; i < (1 << cache->order); i++) { |
frame = ADDR2FRAME(zone, KA2PA((__address)(data+i*PAGE_SIZE))); |
frame->parent = slab; |
} |
for (i=0; i < (1 << cache->order); i++) |
frame_set_parent(pfn+i, slab, zone); |
slab->start = data; |
slab->available = cache->objects; |
199,7 → 196,7 |
*/ |
static count_t slab_space_free(slab_cache_t *cache, slab_t *slab) |
{ |
frame_free((__address)slab->start); |
frame_free(ADDR2PFN(KA2PA(slab->start))); |
if (! (cache->flags & SLAB_CACHE_SLINSIDE)) |
slab_free(slab_extern_cache, slab); |
211,10 → 208,7 |
/** Map object to slab structure */ |
static slab_t * obj2slab(void *obj) |
{ |
frame_t *frame; |
frame = frame_addr2frame((__address)obj); |
return (slab_t *)frame->parent; |
return (slab_t *)frame_get_parent(ADDR2PFN(KA2PA(obj)), 0); |
} |
/**************************************/ |
725,8 → 719,9 |
/* Disable interrupts to avoid deadlocks with interrupt handlers */ |
ipl = interrupts_disable(); |
if (!(cache->flags & SLAB_CACHE_NOMAGAZINE)) |
if (!(cache->flags & SLAB_CACHE_NOMAGAZINE)) { |
result = magazine_obj_get(cache); |
} |
if (!result) |
result = slab_obj_create(cache, flags); |
/kernel/trunk/generic/src/mm/as.c |
---|
36,8 → 36,8 |
#include <arch/mm/as.h> |
#include <mm/page.h> |
#include <mm/frame.h> |
#include <mm/slab.h> |
#include <mm/tlb.h> |
#include <mm/heap.h> |
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <mm/asid.h> |
253,7 → 253,7 |
* do not forget to distinguish between |
* the different causes |
*/ |
frame = frame_alloc(ONE_FRAME, 0); |
frame = PFN2ADDR(frame_alloc(ONE_FRAME, 0)); |
memsetb(PA2KA(frame), FRAME_SIZE, 0); |
/* |
/kernel/trunk/generic/src/mm/buddy.c |
---|
28,7 → 28,6 |
#include <mm/buddy.h> |
#include <mm/frame.h> |
#include <mm/heap.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <adt/list.h> |
35,10 → 34,18 |
#include <debug.h> |
#include <print.h> |
/** Return size needed for the buddy configuration data */ |
size_t buddy_conf_size(int max_order) |
{ |
return sizeof(buddy_system_t) + (max_order + 1) * sizeof(link_t); |
} |
/** Create buddy system |
* |
* Allocate memory for and initialize new buddy system. |
* |
* @param b Preallocated buddy system control data |
* @param max_order The biggest allocable size will be 2^max_order. |
* @param op Operations for new buddy system. |
* @param data Pointer to be used by implementation. |
45,9 → 52,11 |
* |
* @return New buddy system. |
*/ |
buddy_system_t *buddy_system_create(__u8 max_order, buddy_system_operations_t *op, void *data) |
void buddy_system_create(buddy_system_t *b, |
__u8 max_order, |
buddy_system_operations_t *op, |
void *data) |
{ |
buddy_system_t *b; |
int i; |
ASSERT(max_order < BUDDY_SYSTEM_INNER_BLOCK); |
60,29 → 69,16 |
ASSERT(op->mark_busy); |
/* |
* Allocate memory for structure describing the whole buddy system. |
*/ |
b = (buddy_system_t *) early_malloc(sizeof(buddy_system_t)); |
* Use memory after our own structure |
*/ |
b->order = (link_t *) (&b[1]); |
if (b) { |
/* |
* Allocate memory for all orders this buddy system will work with. |
*/ |
b->order = (link_t *) early_malloc((max_order + 1) * sizeof(link_t)); |
if (!b->order) { |
early_free(b); |
return NULL; |
} |
for (i = 0; i <= max_order; i++) |
list_initialize(&b->order[i]); |
b->max_order = max_order; |
b->op = op; |
b->data = data; |
} |
return b; |
for (i = 0; i <= max_order; i++) |
list_initialize(&b->order[i]); |
b->max_order = max_order; |
b->op = op; |
b->data = data; |
} |
/** Check if buddy system can allocate block |
114,6 → 110,42 |
} |
/** Allocate PARTICULAR block from buddy system |
* |
* @ return Block of data or NULL if no such block was found |
*/ |
link_t *buddy_system_alloc_block(buddy_system_t *b, link_t *block) |
{ |
link_t *left,*right, *tmp; |
__u8 order; |
left = b->op->find_block(b, block, BUDDY_SYSTEM_INNER_BLOCK); |
ASSERT(left); |
list_remove(left); |
while (1) { |
if (! b->op->get_order(b,left)) { |
b->op->mark_busy(b, left); |
return left; |
} |
order = b->op->get_order(b, left); |
right = b->op->bisect(b, left); |
b->op->set_order(b, left, order-1); |
b->op->set_order(b, right, order-1); |
tmp = b->op->find_block(b, block, BUDDY_SYSTEM_INNER_BLOCK); |
if (tmp == right) { |
right = left; |
left = tmp; |
} |
b->op->mark_busy(b, left); |
buddy_system_free(b, right); |
b->op->mark_available(b, left); |
} |
} |
/** Allocate block from buddy system. |
* |
* @param b Buddy system pointer. |
137,7 → 169,6 |
b->op->mark_busy(b, res); |
return res; |
} |
/* |
* If order i is already the maximal order, |
* the request cannot be satisfied. |
167,8 → 198,8 |
b->op->set_order(b, hlp, i); |
/* |
* Return the other half to buddy system. |
* PROBLEM!!!! WILL FIND OTHER PART AS BUDDY AND LINK TOGETHER |
* Return the other half to buddy system. Mark the first part |
* full, so that it won't coalsce again. |
*/ |
b->op->mark_busy(b, res); |
buddy_system_free(b, hlp); |
/kernel/trunk/generic/src/mm/frame.c |
---|
27,9 → 27,18 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/* |
* Locking order |
* |
* In order to access particular zone, the process must first lock |
* the zones.lock, then lock the zone and then unlock the zones.lock. |
* This insures, that we can fiddle with the zones in runtime without |
* affecting the processes. |
* |
*/ |
#include <typedefs.h> |
#include <arch/types.h> |
#include <mm/heap.h> |
#include <mm/frame.h> |
#include <mm/as.h> |
#include <panic.h> |
40,439 → 49,210 |
#include <arch.h> |
#include <print.h> |
#include <align.h> |
#include <mm/slab.h> |
SPINLOCK_INITIALIZE(zone_head_lock); /**< this lock protects zone_head list */ |
LIST_INITIALIZE(zone_head); /**< list of all zones in the system */ |
typedef struct { |
count_t refcount; /**< tracking of shared frames */ |
__u8 buddy_order; /**< buddy system block order */ |
link_t buddy_link; /**< link to the next free block inside one order */ |
void *parent; /**< If allocated by slab, this points there */ |
}frame_t; |
/** Blacklist containing non-available areas of memory. |
* |
* This blacklist is used to exclude frames that cannot be allocated |
* (e.g. kernel memory) from available memory map. |
*/ |
region_t zone_blacklist[ZONE_BLACKLIST_SIZE]; |
count_t zone_blacklist_count = 0; |
typedef struct { |
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */ |
pfn_t base; /**< frame_no of the first frame in the frames array */ |
pfn_t count; /**< Size of zone */ |
static struct buddy_system_operations zone_buddy_system_operations = { |
.find_buddy = zone_buddy_find_buddy, |
.bisect = zone_buddy_bisect, |
.coalesce = zone_buddy_coalesce, |
.set_order = zone_buddy_set_order, |
.get_order = zone_buddy_get_order, |
.mark_busy = zone_buddy_mark_busy, |
}; |
frame_t *frames; /**< array of frame_t structures in this zone */ |
count_t free_count; /**< number of free frame_t structures */ |
count_t busy_count; /**< number of busy frame_t structures */ |
buddy_system_t * buddy_system; /**< buddy system for the zone */ |
int flags; |
}zone_t; |
/** Initialize physical memory management |
* |
* Initialize physical memory managemnt. |
/* |
* The zoneinfo.lock must be locked when accessing zoneinfo structure. |
* Some of the attributes in zone_t structures are 'read-only' |
*/ |
void frame_init(void) |
{ |
if (config.cpu_active == 1) { |
frame_region_not_free(KA2PA(config.base), config.kernel_size); |
if (config.init_size > 0) |
frame_region_not_free(KA2PA(config.init_addr), config.init_size); |
} |
frame_arch_init(); |
} |
struct { |
SPINLOCK_DECLARE(lock); |
int count; |
zone_t *info[ZONES_MAX]; |
}zones; |
/** |
* Find AND LOCK zone that can allocate order frames |
* |
* Assume zone_head_lock is locked. |
*/ |
static zone_t * find_free_zone(__u8 order) |
/*********************************/ |
/* Helper functions */ |
static inline index_t frame_index(zone_t *zone, frame_t *frame) |
{ |
link_t *cur; |
zone_t *z; |
for (cur = zone_head.next; cur != &zone_head;cur = cur->next) { |
z = list_get_instance(cur, zone_t, link); |
spinlock_lock(&z->lock); |
/* Check if the zone has 2^order frames area available */ |
if (buddy_system_can_alloc(z->buddy_system, order)) |
return z; |
spinlock_unlock(&z->lock); |
} |
return NULL; |
return (index_t)(frame - zone->frames); |
} |
/** Allocate power-of-two frames of physical memory. |
* |
* @param flags Flags for host zone selection and address processing. |
* @param order Allocate exactly 2^order frames. |
* @param pzone Pointer to preferred zone pointer, on output it changes |
* to the zone that the frame was really allocated to |
* |
* @return Allocated frame. |
*/ |
__address frame_alloc_generic(__u8 order, int flags, int * status, zone_t **pzone) |
static inline index_t frame_index_abs(zone_t *zone, frame_t *frame) |
{ |
ipl_t ipl; |
link_t *tmp; |
zone_t *zone = NULL; |
frame_t *frame = NULL; |
int freed; |
__address v; |
loop: |
ipl = interrupts_disable(); |
spinlock_lock(&zone_head_lock); |
/* |
* First, find suitable frame zone. |
*/ |
if (pzone && *pzone) { |
spinlock_lock(&(*pzone)->lock); |
if (!buddy_system_can_alloc((*pzone)->buddy_system, order)) |
spinlock_unlock(&(*pzone)->lock); |
else |
zone = *pzone; |
} |
if (!zone) { |
zone = find_free_zone(order); |
/* If no memory, reclaim some slab memory, |
if it does not help, reclaim all */ |
if (!zone && !(flags & FRAME_NO_RECLAIM)) { |
spinlock_unlock(&zone_head_lock); |
freed = slab_reclaim(0); |
spinlock_lock(&zone_head_lock); |
if (freed) |
zone = find_free_zone(order); |
if (!zone) { |
spinlock_unlock(&zone_head_lock); |
freed = slab_reclaim(SLAB_RECLAIM_ALL); |
spinlock_lock(&zone_head_lock); |
if (freed) |
zone = find_free_zone(order); |
} |
} |
} |
if (!zone) { |
if (flags & FRAME_PANIC) |
panic("Can't allocate frame.\n"); |
/* |
* TODO: Sleep until frames are available again. |
*/ |
spinlock_unlock(&zone_head_lock); |
interrupts_restore(ipl); |
if (flags & FRAME_ATOMIC) { |
ASSERT(status != NULL); |
*status = FRAME_NO_MEMORY; |
return NULL; |
} |
panic("Sleep not implemented.\n"); |
goto loop; |
} |
/* Allocate frames from zone buddy system */ |
tmp = buddy_system_alloc(zone->buddy_system, order); |
ASSERT(tmp); |
/* Update zone information. */ |
zone->free_count -= (1 << order); |
zone->busy_count += (1 << order); |
/* Frame will be actually a first frame of the block. */ |
frame = list_get_instance(tmp, frame_t, buddy_link); |
/* get frame address */ |
v = FRAME2ADDR(zone, frame); |
spinlock_unlock(&zone->lock); |
spinlock_unlock(&zone_head_lock); |
interrupts_restore(ipl); |
ASSERT(v == ALIGN_UP(v, FRAME_SIZE << order)); |
if (flags & FRAME_KA) |
v = PA2KA(v); |
if (status) |
*status = FRAME_OK; |
if (pzone) |
*pzone = zone; |
return v; |
return (index_t)(frame - zone->frames) + zone->base; |
} |
static inline int frame_index_valid(zone_t *zone, index_t index) |
{ |
return index >= 0 && index < zone->count; |
} |
/** Convert address to zone pointer |
* |
* Assume zone_head_lock is held |
* |
* @param addr Physical address |
* @param lock If true, lock the zone |
*/ |
static zone_t * addr2zone(__address addr, int lock) |
/** Compute pfn_t from frame_t pointer & zone pointer */ |
static pfn_t make_frame_index(zone_t *zone, frame_t *frame) |
{ |
link_t *cur; |
zone_t *z = NULL; |
for (cur = zone_head.next; cur != &zone_head; cur = cur->next) { |
z = list_get_instance(cur, zone_t, link); |
spinlock_lock(&z->lock); |
/* |
* Check if addr belongs to z. |
*/ |
if ((addr >= z->base) && (addr <= z->base + (z->free_count + z->busy_count) * FRAME_SIZE)) { |
if (!lock) |
spinlock_unlock(&z->lock); |
return z; |
} |
spinlock_unlock(&z->lock); |
} |
panic("Cannot find addr2zone: 0x%X", addr); |
return frame - zone->frames; |
} |
/** Return frame_t structure corresponding to address |
/** Initialize frame structure |
* |
* |
* Initialize frame structure. |
* |
* @param frame Frame structure to be initialized. |
*/ |
frame_t * frame_addr2frame(__address addr) |
static void frame_initialize(frame_t *frame) |
{ |
ipl_t ipl; |
frame_t *frame; |
zone_t *zone; |
if (IS_KA(addr)) |
addr = KA2PA(addr); |
/* Disable interrupts to avoid deadlocks with interrupt handlers */ |
ipl = interrupts_disable(); |
spinlock_lock(&zone_head_lock); |
zone = addr2zone(addr,0); |
frame = ADDR2FRAME(zone, addr); |
spinlock_unlock(&zone_head_lock); |
interrupts_restore(ipl); |
return frame; |
frame->refcount = 1; |
frame->buddy_order = 0; |
} |
/*************************************/ |
/* Zoneinfo functions */ |
/** Free a frame. |
* |
* Find respective frame structrue for supplied addr. |
* Decrement frame reference count. |
* If it drops to zero, move the frame structure to free list. |
* |
* @param addr Address of the frame to be freed. It must be a multiple of FRAME_SIZE. |
/** |
* Insert-sort zone into zones list |
*/ |
void frame_free(__address addr) |
static void zones_add_zone(zone_t *zone) |
{ |
ipl_t ipl; |
zone_t *zone; |
frame_t *frame; |
int order; |
ASSERT(addr % FRAME_SIZE == 0); |
if (IS_KA(addr)) |
addr = KA2PA(addr); |
int i; |
ipl = interrupts_disable(); |
spinlock_lock(&zone_head_lock); |
/* |
* First, find host frame zone for addr. |
*/ |
zone = addr2zone(addr, 1); /* This locks the zone automatically */ |
frame = ADDR2FRAME(zone, addr); |
/* remember frame order */ |
order = frame->buddy_order; |
spinlock_lock(&zones.lock); |
/* Try to merge */ |
if (zone->flags & ZONE_JOIN) { |
for (i=0; i < zones.count; i++) { |
spinlock_lock(&zones.info[i]->lock); |
/* Join forward, join backward */ |
panic("Not implemented"); |
ASSERT(frame->refcount); |
if (!--frame->refcount) { |
buddy_system_free(zone->buddy_system, &frame->buddy_link); |
spinlock_unlock(&zones.info[i]->lock); |
} |
spinlock_unlock(&zones.lock); |
} else { |
if (zones.count+1 == ZONES_MAX) |
panic("Maximum zone(%d) count exceeded.", ZONES_MAX); |
zones.info[zones.count++] = zone; |
} |
/* Update zone information. */ |
zone->free_count += (1 << order); |
zone->busy_count -= (1 << order); |
spinlock_unlock(&zone->lock); |
spinlock_unlock(&zone_head_lock); |
interrupts_restore(ipl); |
spinlock_unlock(&zones.lock); |
} |
/** Mark frame region not free. |
/** |
* Try to find a zone where can we find the frame |
* |
* Mark frame region not free. |
* @param hint Start searching in zone 'hint' |
* @param lock Lock zone if true |
* |
* @param base Base address of non-available region. |
* @param size Size of non-available region. |
* Assume interrupts disable |
*/ |
void frame_region_not_free(__address base, size_t size) |
static zone_t * find_zone_and_lock(pfn_t frame, int *pzone) |
{ |
index_t index; |
index = zone_blacklist_count++; |
/* Force base to the nearest lower address frame boundary. */ |
base = ALIGN_DOWN(base, FRAME_SIZE); |
/* Align size to frame boundary. */ |
size = ALIGN_UP(size, FRAME_SIZE); |
ASSERT(index < ZONE_BLACKLIST_SIZE); |
zone_blacklist[index].base = base; |
zone_blacklist[index].size = size; |
} |
/** Create frame zones in region of available memory. |
* |
* Avoid any black listed areas of non-available memory. |
* Assume that the black listed areas cannot overlap |
* one another or cross available memory region boundaries. |
* |
* @param base Base address of available memory region. |
* @param size Size of the region. |
*/ |
void zone_create_in_region(__address base, size_t size) { |
int i; |
zone_t * z; |
__address s; |
size_t sz; |
int hint = pzone ? *pzone : 0; |
zone_t *z; |
ASSERT(base % FRAME_SIZE == 0); |
ASSERT(size % FRAME_SIZE == 0); |
spinlock_lock(&zones.lock); |
if (hint >= zones.count || hint < 0) |
hint = 0; |
if (!size) |
return; |
for (i = 0; i < zone_blacklist_count; i++) { |
if (zone_blacklist[i].base >= base && zone_blacklist[i].base < base + size) { |
s = base; sz = zone_blacklist[i].base - base; |
ASSERT(base != s || sz != size); |
zone_create_in_region(s, sz); |
s = zone_blacklist[i].base + zone_blacklist[i].size; |
sz = (base + size) - (zone_blacklist[i].base + zone_blacklist[i].size); |
ASSERT(base != s || sz != size); |
zone_create_in_region(s, sz); |
return; |
i = hint; |
do { |
z = zones.info[i]; |
spinlock_lock(&z->lock); |
if (z->base <= frame && z->base + z->count > frame) { |
spinlock_unlock(&zones.lock); /* Unlock the global lock */ |
if (pzone) |
*pzone = i; |
return z; |
} |
} |
z = zone_create(base, size, 0); |
spinlock_unlock(&z->lock); |
if (!z) { |
panic("Cannot allocate zone (base=%P, size=%d).\n", base, size); |
} |
zone_attach(z); |
i++; |
if (i >= zones.count) |
i = 0; |
} while(i != hint); |
spinlock_unlock(&zones.lock); |
return NULL; |
} |
/** Create frame zone |
/** |
* Find AND LOCK zone that can allocate order frames |
* |
* Create new frame zone. |
* Assume interrupts are disabled!! |
* |
* @param start Physical address of the first frame within the zone. |
* @param size Size of the zone. Must be a multiple of FRAME_SIZE. |
* @param flags Zone flags. |
* |
* @return Initialized zone. |
* @param pzone Pointer to preferred zone or NULL, on return contains zone number |
*/ |
zone_t * zone_create(__address start, size_t size, int flags) |
static zone_t * find_free_zone_lock(__u8 order, int *pzone) |
{ |
int i; |
zone_t *z; |
count_t cnt; |
int i; |
__u8 max_order; |
ASSERT(start % FRAME_SIZE == 0); |
ASSERT(size % FRAME_SIZE == 0); |
int hint = pzone ? *pzone : 0; |
cnt = size / FRAME_SIZE; |
z = (zone_t *) early_malloc(sizeof(zone_t)); |
if (z) { |
link_initialize(&z->link); |
spinlock_initialize(&z->lock, "zone_lock"); |
z->base = start; |
z->base_index = start / FRAME_SIZE; |
spinlock_lock(&zones.lock); |
if (hint >= zones.count) |
hint = 0; |
i = hint; |
do { |
z = zones.info[i]; |
z->flags = flags; |
spinlock_lock(&z->lock); |
z->free_count = cnt; |
z->busy_count = 0; |
z->frames = (frame_t *) early_malloc(cnt * sizeof(frame_t)); |
if (!z->frames) { |
early_free(z); |
return NULL; |
/* Check if the zone has 2^order frames area available */ |
if (buddy_system_can_alloc(z->buddy_system, order)) { |
spinlock_unlock(&zones.lock); |
if (pzone) |
*pzone = i; |
return z; |
} |
for (i = 0; i<cnt; i++) { |
frame_initialize(&z->frames[i], z); |
} |
/* |
* Create buddy system for the zone |
*/ |
for (max_order = 0; cnt >> max_order; max_order++) |
; |
z->buddy_system = buddy_system_create(max_order, &zone_buddy_system_operations, (void *) z); |
/* Stuffing frames */ |
for (i = 0; i<cnt; i++) { |
z->frames[i].refcount = 0; |
buddy_system_free(z->buddy_system, &z->frames[i].buddy_link); |
} |
} |
return z; |
spinlock_unlock(&z->lock); |
if (++i >= zones.count) |
i = 0; |
} while(i != hint); |
spinlock_unlock(&zones.lock); |
return NULL; |
} |
/** Attach frame zone |
/********************************************/ |
/* Buddy system functions */ |
/** Buddy system find_block implementation |
* |
* Attach frame zone to zone list. |
* Find block that is parent of current list. |
* That means go to lower addresses, until such block is found |
* |
* @param zone Zone to be attached. |
* @param order - Order of parent must be different then this parameter!! |
*/ |
void zone_attach(zone_t *zone) |
static link_t *zone_buddy_find_block(buddy_system_t *b, link_t *child, |
__u8 order) |
{ |
ipl_t ipl; |
frame_t * frame; |
zone_t * zone; |
index_t index; |
ipl = interrupts_disable(); |
spinlock_lock(&zone_head_lock); |
list_append(&zone->link, &zone_head); |
spinlock_unlock(&zone_head_lock); |
interrupts_restore(ipl); |
} |
frame = list_get_instance(child, frame_t, buddy_link); |
zone = (zone_t *) b->data; |
/** Initialize frame structure |
* |
* Initialize frame structure. |
* |
* @param frame Frame structure to be initialized. |
* @param zone Host frame zone. |
*/ |
void frame_initialize(frame_t *frame, zone_t *zone) |
{ |
frame->refcount = 1; |
frame->buddy_order = 0; |
index = frame_index(zone, frame); |
do { |
if (zone->frames[index].buddy_order != order) { |
return &zone->frames[index].buddy_link; |
} |
} while(index-- > 0); |
return NULL; |
} |
/** Buddy system find_buddy implementation |
* |
481,7 → 261,8 |
* |
* @return Buddy for given block if found |
*/ |
link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * block) { |
static link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * block) |
{ |
frame_t * frame; |
zone_t * zone; |
index_t index; |
489,27 → 270,26 |
frame = list_get_instance(block, frame_t, buddy_link); |
zone = (zone_t *) b->data; |
ASSERT(IS_BUDDY_ORDER_OK(FRAME_INDEX_ABS(zone, frame), frame->buddy_order)); |
ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame), frame->buddy_order)); |
is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame); |
is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame); |
ASSERT(is_left ^ is_right); |
if (is_left) { |
index = (FRAME_INDEX(zone, frame)) + (1 << frame->buddy_order); |
index = (frame_index(zone, frame)) + (1 << frame->buddy_order); |
} else { // if (is_right) |
index = (FRAME_INDEX(zone, frame)) - (1 << frame->buddy_order); |
index = (frame_index(zone, frame)) - (1 << frame->buddy_order); |
} |
if (FRAME_INDEX_VALID(zone, index)) { |
if ( zone->frames[index].buddy_order == frame->buddy_order && |
zone->frames[index].refcount == 0) { |
if (frame_index_valid(zone, index)) { |
if (zone->frames[index].buddy_order == frame->buddy_order && |
zone->frames[index].refcount == 0) { |
return &zone->frames[index].buddy_link; |
} |
} |
return NULL; |
} |
520,7 → 300,7 |
* |
* @return right block |
*/ |
link_t * zone_buddy_bisect(buddy_system_t *b, link_t * block) { |
static link_t * zone_buddy_bisect(buddy_system_t *b, link_t * block) { |
frame_t * frame_l, * frame_r; |
frame_l = list_get_instance(block, frame_t, buddy_link); |
537,8 → 317,9 |
* |
* @return Coalesced block (actually block that represents lower address) |
*/ |
link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * block_1, link_t * block_2) { |
frame_t * frame1, * frame2; |
static link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * block_1, |
link_t * block_2) { |
frame_t *frame1, *frame2; |
frame1 = list_get_instance(block_1, frame_t, buddy_link); |
frame2 = list_get_instance(block_2, frame_t, buddy_link); |
552,7 → 333,7 |
* @param block Buddy system block |
* @param order Order to set |
*/ |
void zone_buddy_set_order(buddy_system_t *b, link_t * block, __u8 order) { |
static void zone_buddy_set_order(buddy_system_t *b, link_t * block, __u8 order) { |
frame_t * frame; |
frame = list_get_instance(block, frame_t, buddy_link); |
frame->buddy_order = order; |
565,7 → 346,7 |
* |
* @return Order of block |
*/ |
__u8 zone_buddy_get_order(buddy_system_t *b, link_t * block) { |
static __u8 zone_buddy_get_order(buddy_system_t *b, link_t * block) { |
frame_t * frame; |
frame = list_get_instance(block, frame_t, buddy_link); |
return frame->buddy_order; |
577,31 → 358,406 |
* @param block Buddy system block |
* |
*/ |
void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) { |
static void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) { |
frame_t * frame; |
frame = list_get_instance(block, frame_t, buddy_link); |
frame->refcount = 1; |
} |
/** Buddy system mark_available implementation |
* |
* @param b Buddy system |
* @param block Buddy system block |
* |
*/ |
static void zone_buddy_mark_available(buddy_system_t *b, link_t * block) { |
frame_t * frame; |
frame = list_get_instance(block, frame_t, buddy_link); |
frame->refcount = 0; |
} |
static struct buddy_system_operations zone_buddy_system_operations = { |
.find_buddy = zone_buddy_find_buddy, |
.bisect = zone_buddy_bisect, |
.coalesce = zone_buddy_coalesce, |
.set_order = zone_buddy_set_order, |
.get_order = zone_buddy_get_order, |
.mark_busy = zone_buddy_mark_busy, |
.mark_available = zone_buddy_mark_available, |
.find_block = zone_buddy_find_block |
}; |
/*************************************/ |
/* Zone functions */ |
/** Allocate frame in particular zone |
* |
* Assume zone is locked |
* |
* @return Frame index in zone |
*/ |
static pfn_t zone_frame_alloc(zone_t *zone,__u8 order, int flags, int *status) |
{ |
pfn_t v; |
link_t *tmp; |
frame_t *frame; |
/* Allocate frames from zone buddy system */ |
tmp = buddy_system_alloc(zone->buddy_system, order); |
ASSERT(tmp); |
/* Update zone information. */ |
zone->free_count -= (1 << order); |
zone->busy_count += (1 << order); |
/* Frame will be actually a first frame of the block. */ |
frame = list_get_instance(tmp, frame_t, buddy_link); |
/* get frame address */ |
v = make_frame_index(zone, frame); |
return v; |
} |
/** Free frame from zone |
* |
* Assume zone is locked |
*/ |
static void zone_frame_free(zone_t *zone, pfn_t frame_idx) |
{ |
frame_t *frame; |
__u8 order; |
frame = &zone->frames[frame_idx]; |
/* remember frame order */ |
order = frame->buddy_order; |
ASSERT(frame->refcount); |
if (!--frame->refcount) { |
buddy_system_free(zone->buddy_system, &frame->buddy_link); |
} |
/* Update zone information. */ |
zone->free_count += (1 << order); |
zone->busy_count -= (1 << order); |
} |
/** Return frame from zone */ |
static frame_t * zone_get_frame(zone_t *zone, pfn_t frame_idx) |
{ |
ASSERT(frame_idx < zone->count); |
return &zone->frames[frame_idx]; |
} |
/** Mark frame in zone unavailable to allocation */ |
static void zone_mark_unavailable(zone_t *zone, pfn_t frame_idx) |
{ |
frame_t *frame; |
link_t *link; |
frame = zone_get_frame(zone, frame_idx); |
link = buddy_system_alloc_block(zone->buddy_system, |
&frame->buddy_link); |
ASSERT(link); |
zone->free_count--; |
} |
/** Create frame zone |
* |
* Create new frame zone. |
* |
* @param start Physical address of the first frame within the zone. |
* @param size Size of the zone. Must be a multiple of FRAME_SIZE. |
* @param conffram Address of configuration frame |
* @param flags Zone flags. |
* |
* @return Initialized zone. |
*/ |
static zone_t * zone_construct(pfn_t start, pfn_t count, |
zone_t *z, int flags) |
{ |
int i; |
__u8 max_order; |
spinlock_initialize(&z->lock, "zone_lock"); |
z->base = start; |
z->count = count; |
z->flags = flags; |
z->free_count = count; |
z->busy_count = 0; |
/* |
* Compute order for buddy system, initialize |
*/ |
for (max_order = 0; count >> max_order; max_order++) |
; |
z->buddy_system = (buddy_system_t *)&z[1]; |
buddy_system_create(z->buddy_system, max_order, |
&zone_buddy_system_operations, |
(void *) z); |
/* Allocate frames _after_ the conframe */ |
/* Check sizes */ |
z->frames = (frame_t *)((void *)z->buddy_system+buddy_conf_size(max_order)); |
for (i = 0; i<count; i++) { |
frame_initialize(&z->frames[i]); |
} |
/* Stuffing frames */ |
for (i = 0; i < count; i++) { |
z->frames[i].refcount = 0; |
buddy_system_free(z->buddy_system, &z->frames[i].buddy_link); |
} |
return z; |
} |
/** Compute configuration data size for zone */ |
__address zone_conf_size(pfn_t start, pfn_t count) |
{ |
int size = sizeof(zone_t) + count*sizeof(frame_t); |
int max_order; |
for (max_order = 0; count >> max_order; max_order++) |
; |
size += buddy_conf_size(max_order); |
return size; |
} |
/** Create and add zone to system |
* |
* @param confframe Where configuration frame is supposed to be. |
* Always check, that we will not disturb kernel pages |
* the kernel and possibly init. |
* If confframe is given _outside_ this zone, it is expected, |
* that the area is already marked BUSY and big enough |
* to contain zone_conf_size() amount of data |
*/ |
void zone_create(pfn_t start, pfn_t count, pfn_t confframe, int flags) |
{ |
zone_t *z; |
__address addr,endaddr; |
pfn_t confcount; |
int i; |
/* Theoretically we could have here 0, practically make sure |
* nobody tries to do that. If some platform requires, remove |
* the assert |
*/ |
ASSERT(confframe); |
/* If conframe is supposed to be inside our zone, then make sure |
* it does not span kernel & init |
*/ |
confcount = SIZE2PFN(zone_conf_size(start,count)); |
if (confframe >= start && confframe < start+count) { |
for (;confframe < start+count;confframe++) { |
addr = PFN2ADDR(confframe); |
endaddr = PFN2ADDR (confframe + confcount); |
if (overlaps(addr, endaddr, KA2PA(config.base), |
KA2PA(config.base+config.kernel_size))) |
continue; |
if (config.init_addr) |
if (overlaps(addr,endaddr, |
KA2PA(config.init_addr), |
KA2PA(config.init_addr+config.init_size))) |
continue; |
break; |
} |
if (confframe >= start+count) |
panic("Cannot find configuration data for zone."); |
} |
z = zone_construct(start, count, (zone_t *)PA2KA(PFN2ADDR(confframe)), flags); |
zones_add_zone(z); |
/* If confdata in zone, mark as unavailable */ |
if (confframe >= start && confframe < start+count) |
for (i=confframe; i<confframe+confcount; i++) { |
zone_mark_unavailable(z, i - z->base); |
} |
} |
/***************************************/ |
/* Frame functions */ |
/** Set parent of frame */ |
void frame_set_parent(pfn_t pfn, void *data, int hint) |
{ |
zone_t *zone = find_zone_and_lock(pfn, &hint); |
ASSERT(zone); |
zone_get_frame(zone, pfn-zone->base)->parent = data; |
spinlock_unlock(&zone->lock); |
} |
void * frame_get_parent(pfn_t pfn, int hint) |
{ |
zone_t *zone = find_zone_and_lock(pfn, &hint); |
void *res; |
ASSERT(zone); |
res = zone_get_frame(zone, pfn - zone->base)->parent; |
spinlock_unlock(&zone->lock); |
return res; |
} |
/** Allocate power-of-two frames of physical memory. |
* |
* @param flags Flags for host zone selection and address processing. |
* @param order Allocate exactly 2^order frames. |
* @param pzone Preferred zone |
* |
* @return Allocated frame. |
*/ |
pfn_t frame_alloc_generic(__u8 order, int flags, int * status, int *pzone) |
{ |
ipl_t ipl; |
int freed; |
pfn_t v; |
zone_t *zone; |
loop: |
ipl = interrupts_disable(); |
/* |
* First, find suitable frame zone. |
*/ |
zone = find_free_zone_lock(order,pzone); |
/* If no memory, reclaim some slab memory, |
if it does not help, reclaim all */ |
if (!zone && !(flags & FRAME_NO_RECLAIM)) { |
freed = slab_reclaim(0); |
if (freed) |
zone = find_free_zone_lock(order,pzone); |
if (!zone) { |
freed = slab_reclaim(SLAB_RECLAIM_ALL); |
if (freed) |
zone = find_free_zone_lock(order,pzone); |
} |
} |
if (!zone) { |
if (flags & FRAME_PANIC) |
panic("Can't allocate frame.\n"); |
/* |
* TODO: Sleep until frames are available again. |
*/ |
interrupts_restore(ipl); |
if (flags & FRAME_ATOMIC) { |
ASSERT(status != NULL); |
if (status) |
*status = FRAME_NO_MEMORY; |
return NULL; |
} |
panic("Sleep not implemented.\n"); |
goto loop; |
} |
v = zone_frame_alloc(zone,order,flags,status); |
v += zone->base; |
spinlock_unlock(&zone->lock); |
interrupts_restore(ipl); |
if (status) |
*status = FRAME_OK; |
return v; |
} |
/** Free a frame. |
* |
* Find respective frame structrue for supplied addr. |
* Decrement frame reference count. |
* If it drops to zero, move the frame structure to free list. |
* |
* @param frame Frame no to be freed. |
*/ |
void frame_free(pfn_t pfn) |
{ |
ipl_t ipl; |
zone_t *zone; |
ipl = interrupts_disable(); |
/* |
* First, find host frame zone for addr. |
*/ |
zone = find_zone_and_lock(pfn,NULL); |
ASSERT(zone); |
zone_frame_free(zone, pfn-zone->base); |
spinlock_unlock(&zone->lock); |
interrupts_restore(ipl); |
} |
/** Mark given range unavailable in frame zones */ |
void frame_mark_unavailable(pfn_t start, pfn_t count) |
{ |
int i; |
zone_t *zone; |
int prefzone = 0; |
for (i=0; i<count; i++) { |
zone = find_zone_and_lock(start+i,&prefzone); |
if (!zone) /* PFN not found */ |
continue; |
zone_mark_unavailable(zone, start+i-zone->base); |
spinlock_unlock(&zone->lock); |
} |
} |
/** Initialize physical memory management |
* |
* Initialize physical memory managemnt. |
*/ |
void frame_init(void) |
{ |
if (config.cpu_active == 1) { |
zones.count = 0; |
spinlock_initialize(&zones.lock,"zones_glob_lock"); |
} |
/* Tell the architecture to create some memory */ |
frame_arch_init(); |
if (config.cpu_active == 1) { |
frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)), |
SIZE2PFN(config.kernel_size)); |
if (config.init_size > 0) |
frame_mark_unavailable(ADDR2PFN(KA2PA(config.init_addr)), |
SIZE2PFN(config.init_size)); |
} |
} |
/** Prints list of zones |
* |
*/ |
void zone_print_list(void) { |
zone_t *zone = NULL; |
link_t *cur; |
int i; |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&zone_head_lock); |
spinlock_lock(&zones.lock); |
printf("Base address\tFree Frames\tBusy Frames\n"); |
printf("------------\t-----------\t-----------\n"); |
for (cur = zone_head.next; cur != &zone_head; cur = cur->next) { |
zone = list_get_instance(cur, zone_t, link); |
for (i=0;i<zones.count;i++) { |
zone = zones.info[i]; |
spinlock_lock(&zone->lock); |
printf("%L\t%d\t\t%d\n",zone->base, zone->free_count, zone->busy_count); |
printf("%L\t%d\t\t%d\n",PFN2ADDR(zone->base), |
zone->free_count, zone->busy_count); |
spinlock_unlock(&zone->lock); |
} |
spinlock_unlock(&zone_head_lock); |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
} |
609,33 → 765,26 |
* |
* @param base Zone base address |
*/ |
void zone_print_one(__address base) { |
zone_t *zone = NULL, *z ; |
link_t *cur; |
void zone_print_one(int znum) { |
zone_t *zone = NULL; |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&zone_head_lock); |
spinlock_lock(&zones.lock); |
for (cur = zone_head.next; cur != &zone_head; cur = cur->next) { |
z = list_get_instance(cur, zone_t, link); |
if (base == z->base) { |
zone = z; |
break; |
} |
} |
if (!zone) { |
spinlock_unlock(&zone_head_lock); |
if (znum >= zones.count || znum < 0) { |
printf("Zone number out of bounds.\n"); |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
printf("No zone with address %X\n", base); |
return; |
} |
zone = zones.info[znum]; |
spinlock_lock(&zone->lock); |
printf("Memory zone information\n\n"); |
printf("Zone base address: %P\n", zone->base); |
printf("Zone size: %d frames (%dK)\n", zone->free_count + zone->busy_count, ((zone->free_count + zone->busy_count) * FRAME_SIZE) >> 10); |
printf("Zone base address: %P\n", PFN2ADDR(zone->base)); |
printf("Zone size: %d frames (%dK)\n", zone->count, ((zone->count) * FRAME_SIZE) >> 10); |
printf("Allocated space: %d frames (%dK)\n", zone->busy_count, (zone->busy_count * FRAME_SIZE) >> 10); |
printf("Available space: %d (%dK)\n", zone->free_count, (zone->free_count * FRAME_SIZE) >> 10); |
643,7 → 792,7 |
buddy_system_structure_print(zone->buddy_system, FRAME_SIZE); |
spinlock_unlock(&zone->lock); |
spinlock_unlock(&zone_head_lock); |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
} |
/kernel/trunk/Makefile |
---|
112,7 → 112,6 |
generic/src/proc/the.c \ |
generic/src/syscall/syscall.c \ |
generic/src/mm/buddy.c \ |
generic/src/mm/heap.c \ |
generic/src/mm/frame.c \ |
generic/src/mm/page.c \ |
generic/src/mm/tlb.c \ |
/kernel/trunk/arch/amd64/include/types.h |
---|
39,6 → 39,7 |
typedef unsigned long long __u64; |
typedef __u64 __address; |
typedef __u64 pfn_t; |
/* Flags of processor (return value of interrupts_disable()) */ |
typedef __u64 ipl_t; |
/kernel/trunk/arch/amd64/src/pm.c |
---|
37,7 → 37,7 |
#include <config.h> |
#include <memstr.h> |
#include <mm/heap.h> |
#include <mm/slab.h> |
#include <debug.h> |
/* |
/kernel/trunk/arch/amd64/src/mm/page.c |
---|
44,7 → 44,7 |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
/* |
* PA2KA(identity) mapping for all frames. |
*/ |
51,7 → 51,6 |
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, PAGE_CACHEABLE | PAGE_EXEC); |
} |
exc_register(14, "page_fault", (iroutine)page_fault); |
write_cr3((__address) AS_KERNEL->page_table); |
} |
/kernel/trunk/arch/mips32/include/types.h |
---|
51,4 → 51,6 |
typedef union pte pte_t; |
typedef __u32 pfn_t; |
#endif |
/kernel/trunk/arch/mips32/Makefile.inc |
---|
73,6 → 73,8 |
TOOLCHAIN_DIR = /usr/local/mips/bin |
KERNEL_LOAD_ADDRESS = 0x88002000 |
CFLAGS += -EB -DBIG_ENDIAN -DHAVE_FPU -march=r4600 |
INIT_ADDRESS = 0 |
INIT_SIZE = 0 |
endif |
ifeq ($(MIPS_MACHINE),lgxemul) |
BFD_NAME=elf32-tradlittlemips |
/kernel/trunk/arch/mips32/src/mm/frame.c |
---|
43,12 → 43,9 |
*/ |
void frame_arch_init(void) |
{ |
/* Blacklist first 4KB, exception vector */ |
frame_region_not_free(0, FRAME_SIZE); |
if (arc_enabled()) |
arc_frame_init(); |
else |
zone_create_in_region(KA2PA(KERNEL_LOAD_ADDRESS), |
(config.memory_size & ~(FRAME_SIZE-1))); |
else { |
zone_create(1, (config.memory_size >> PAGE_WIDTH)-1,1,0); |
} |
} |
/kernel/trunk/arch/mips32/src/drivers/arc.c |
---|
303,7 → 303,10 |
basesize = ALIGN_DOWN(basesize, FRAME_SIZE); |
total += basesize; |
zone_create_in_region(base, basesize); |
zone_create(ADDR2PFN(base), |
SIZE2PFN(ALIGN_DOWN(basesize,FRAME_SIZE)), |
ADDR2PFN(base),0); |
} |
desc = arc_entry->getmemorydescriptor(desc); |
} |
/kernel/trunk/arch/mips32/src/mips32.c |
---|
95,13 → 95,13 |
debugger_init(); |
arc_print_memory_map(); |
arc_print_devices(); |
/* Setup usermode...*/ |
// config.init_addr = INIT_ADDRESS; |
// config.init_size = INIT_SIZE; |
} |
void arch_post_mm_init(void) |
{ |
/* Setup usermode...*/ |
config.init_addr = INIT_ADDRESS; |
config.init_size = INIT_SIZE; |
} |
void arch_pre_smp_init(void) |
/kernel/trunk/arch/ia32/include/types.h |
---|
39,6 → 39,7 |
typedef long long __u64; |
typedef __u32 __address; |
typedef __u32 pfn_t; |
typedef __u32 ipl_t; |
/kernel/trunk/arch/ia32/src/pm.c |
---|
35,7 → 35,7 |
#include <arch/context.h> |
#include <panic.h> |
#include <arch/mm/page.h> |
#include <mm/heap.h> |
#include <mm/slab.h> |
#include <memstr.h> |
#include <arch/boot/boot.h> |
#include <interrupt.h> |
/kernel/trunk/arch/ia32/src/smp/smp.c |
---|
43,7 → 43,7 |
#include <arch/asm.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <mm/heap.h> |
#include <mm/slab.h> |
#include <mm/as.h> |
#include <print.h> |
#include <memstr.h> |
/kernel/trunk/arch/ia32/src/mm/frame.c |
---|
35,39 → 35,101 |
#include <panic.h> |
#include <debug.h> |
#include <align.h> |
#include <macros.h> |
#include <print.h> |
#include <console/cmd.h> |
#include <console/kconsole.h> |
size_t hardcoded_unmapped_ktext_size = 0; |
size_t hardcoded_unmapped_kdata_size = 0; |
__address last_frame = 0; |
static void init_e820_memory(pfn_t minconf) |
{ |
int i; |
pfn_t start, size,conf; |
for (i = 0; i < e820counter; i++) { |
if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { |
start = ADDR2PFN(ALIGN_UP(e820table[i].base_address, |
FRAME_SIZE)); |
size = SIZE2PFN(ALIGN_DOWN(e820table[i].size, |
FRAME_SIZE)); |
if (minconf < start || minconf >= start+size) |
conf = start; |
else |
conf = minconf; |
zone_create(start,size, conf, 0); |
if (last_frame < ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE)) |
last_frame = ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE); |
} |
} |
} |
static int cmd_e820mem(cmd_arg_t *argv); |
static cmd_info_t e820_info = { |
.name = "e820list", |
.description = "List e820 memory.", |
.func = cmd_e820mem, |
.argc = 0 |
}; |
static char *e820names[] = { "invalid", "available", "reserved", |
"acpi", "nvs", "unusable" }; |
static int cmd_e820mem(cmd_arg_t *argv) |
{ |
int i; |
char *name; |
for (i = 0; i < e820counter; i++) { |
if (e820table[i].type <= MEMMAP_MEMORY_UNUSABLE) |
name = e820names[e820table[i].type]; |
else |
name = "invalid"; |
printf("%P %dB %s\n", e820table[i].base_address, |
e820table[i].size, |
name); |
} |
return 0; |
} |
void frame_arch_init(void) |
{ |
__u8 i; |
static pfn_t minconf; |
if (config.cpu_active == 1) { |
cmd_initialize(&e820_info); |
cmd_register(&e820_info); |
minconf = 1; |
#ifdef CONFIG_SMP |
minconf = max(minconf, |
ADDR2PFN(AP_BOOT_OFFSET+hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size)); |
#endif |
#ifdef CONFIG_SIMICS_FIX |
minconf = max(minconf, ADDR2PFN(0x10000)); |
#endif |
init_e820_memory(minconf); |
/* Reserve frame 0 (BIOS data) */ |
frame_region_not_free(0, FRAME_SIZE); |
frame_mark_unavailable(0, 1); |
#ifdef CONFIG_SMP |
/* Reserve AP real mode bootstrap memory */ |
frame_region_not_free(AP_BOOT_OFFSET, hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size); |
frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH, |
(hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size) >> FRAME_WIDTH); |
#ifdef CONFIG_SIMICS_FIX |
/* Don't know why, but this addresses help */ |
frame_region_not_free(0xf000,FRAME_SIZE); |
frame_region_not_free(0xe000,FRAME_SIZE); |
frame_region_not_free(0xd000,FRAME_SIZE); |
frame_mark_unavailable(0xd000 >> FRAME_WIDTH,3); |
#endif |
#endif |
for (i = 0; i < e820counter; i++) { |
if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { |
zone_create_in_region(e820table[i].base_address, e820table[i].size & ~(FRAME_SIZE-1)); |
if (last_frame < ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE)) |
last_frame = ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE); |
} |
} |
} |
} |