diff options
Diffstat (limited to 'core/mem/init.c')
-rw-r--r-- | core/mem/init.c | 106 |
1 files changed, 85 insertions, 21 deletions
diff --git a/core/mem/init.c b/core/mem/init.c index 487bbb3f..d6a5f189 100644 --- a/core/mem/init.c +++ b/core/mem/init.c @@ -2,37 +2,101 @@ #include <errno.h> #include <string.h> #include "malloc.h" +#include "core.h" +#include <syslinux/memscan.h> -struct free_arena_header __malloc_head[NHEAP]; +struct free_arena_header __core_malloc_head[NHEAP]; -static __hugebss char main_heap[128 << 10]; +//static __hugebss char main_heap[128 << 10]; extern char __lowmem_heap[]; +extern char free_high_memory[]; + +#define E820_MEM_MAX 0xfff00000 /* 4 GB - 1 MB */ +int scan_highmem_area(void *data, addr_t start, addr_t len, bool is_ram) +{ + struct free_arena_header *fp; + + (void)data; + + dprintf("start = %x, len = %x, is_ram = %d", start, len, is_ram); + + if (start < 0x100000 || start > E820_MEM_MAX + || !is_ram) + return 0; + + if (start < __com32.cs_memsize) { + len -= __com32.cs_memsize - start; + start = __com32.cs_memsize; + } + if (len > E820_MEM_MAX - start) + len = E820_MEM_MAX - start; + + if (len >= 2 * sizeof(struct arena_header)) { + fp = (struct free_arena_header *)start; + fp->a.attrs = ARENA_TYPE_USED | (HEAP_MAIN << ARENA_HEAP_POS); +#ifdef DEBUG_MALLOC + fp->a.magic = ARENA_MAGIC; +#endif + ARENA_SIZE_SET(fp->a.attrs, len); + dprintf("will inject a block start:0x%x size 0x%x", start, len); + __inject_free_block(fp); + } + + __com32.cs_memsize = start + len; /* update the HighMemSize */ + return 0; +} + +#if 0 +static void mpool_dump(enum heap heap) +{ + struct free_arena_header *head = &__core_malloc_head[heap]; + struct free_arena_header *fp; + int size, type, i = 0; + addr_t start, end; + + fp = head->next_free; + while (fp != head) { + size = ARENA_SIZE_GET(fp->a.attrs); + type = ARENA_TYPE_GET(fp->a.attrs); + start = (addr_t)fp; + end = start + size; + printf("area[%d]: start = 0x%08x, end = 0x%08x, type = %d\n", + i++, start, end, type); + fp = fp->next_free; + } +} +#endif void mem_init(void) { - struct free_arena_header *fp; - int i; - uint16_t *bios_free_mem = (uint16_t *)0x413; + struct free_arena_header *fp; + int i; + uint16_t *bios_free_mem = (uint16_t *)0x413; - /* Initialize the head nodes */ + //dprintf("enter"); - fp = &__malloc_head[0]; - for (i = 0 ; i < NHEAP ; i++) { + /* Initialize the head nodes */ + fp = &__core_malloc_head[0]; + for (i = 0 ; i < NHEAP ; i++) { fp->a.next = fp->a.prev = fp->next_free = fp->prev_free = fp; fp->a.attrs = ARENA_TYPE_HEAD | (i << ARENA_HEAP_POS); fp->a.tag = MALLOC_HEAD; fp++; - } - - /* Initialize the main heap */ - fp = (struct free_arena_header *)main_heap; - fp->a.attrs = ARENA_TYPE_USED | (HEAP_MAIN << ARENA_HEAP_POS); - ARENA_SIZE_SET(fp->a.attrs, sizeof main_heap); - __inject_free_block(fp); - - /* Initialize the lowmem heap */ - fp = (struct free_arena_header *)__lowmem_heap; - fp->a.attrs = ARENA_TYPE_USED | (HEAP_LOWMEM << ARENA_HEAP_POS); - ARENA_SIZE_SET(fp->a.attrs, (*bios_free_mem << 10) - (uintptr_t)fp); - __inject_free_block(fp); + } + + //dprintf("__lowmem_heap = 0x%p bios_free = 0x%p", + // __lowmem_heap, *bios_free_mem); + + /* Initialize the lowmem heap */ + fp = (struct free_arena_header *)__lowmem_heap; + fp->a.attrs = ARENA_TYPE_USED | (HEAP_LOWMEM << ARENA_HEAP_POS); + ARENA_SIZE_SET(fp->a.attrs, (*bios_free_mem << 10) - (uintptr_t)fp); +#ifdef DEBUG_MALLOC + fp->a.magic = ARENA_MAGIC; +#endif + __inject_free_block(fp); + + /* Initialize the main heap */ + __com32.cs_memsize = (size_t)free_high_memory; + syslinux_scan_memory(scan_highmem_area, NULL); } |