diff options
| author | H. Peter Anvin <hpa@linux.intel.com> | 2009-04-03 15:02:37 -0700 |
|---|---|---|
| committer | H. Peter Anvin <hpa@linux.intel.com> | 2009-04-03 15:02:37 -0700 |
| commit | 4bb348e620229225e01adb7c0e7eca61d749d2a5 (patch) | |
| tree | 6593150387e72dc6ee65bc16dd783731590cca99 /com32/lib/malloc.c | |
| parent | 4cfcede66002a1c0caf1fdc2d4123a3096f6233f (diff) | |
| download | syslinux-4bb348e620229225e01adb7c0e7eca61d749d2a5.tar.gz | |
com32: merge all memory map discovery to one file
Merge the memory map discovery for malloc and the memory map discovery
for memmap into one file that scans memory and invokes a callback.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'com32/lib/malloc.c')
| -rw-r--r-- | com32/lib/malloc.c | 98 |
1 files changed, 35 insertions, 63 deletions
diff --git a/com32/lib/malloc.c b/com32/lib/malloc.c index 6ba80672..40e88b49 100644 --- a/com32/lib/malloc.c +++ b/com32/lib/malloc.c @@ -7,6 +7,7 @@ #include <stdlib.h> #include <string.h> #include <com32.h> +#include <syslinux/memscan.h> #include "init.h" #include "malloc.h" @@ -33,22 +34,43 @@ static inline size_t sp(void) return sp; } -struct e820_entry { - uint64_t start; - uint64_t len; - uint32_t type; - uint32_t extattr; -}; - #define E820_MEM_MAX 0xfff00000 /* 4 GB - 1 MB */ +static int consider_memory_area(void *dummy, addr_t start, + addr_t len, bool valid) +{ + struct free_arena_header *fp; + addr_t end; + + (void)dummy; + + if (valid && start < E820_MEM_MAX) { + if (len > E820_MEM_MAX - start) + len = E820_MEM_MAX - start; + + end = start + len; + + if (end > __com32.cs_memsize) { + if (start <= __com32.cs_memsize) { + start = __com32.cs_memsize; + len = end - start; + } + + if (len >= 2*sizeof(struct arena_header)) { + fp = (struct free_arena_header *)start; + fp->a.size = len; + __inject_free_block(fp); + } + } + } + + return 0; +} + static void __constructor init_memory_arena(void) { - struct free_arena_header *fp, *fx; + struct free_arena_header *fp; size_t start, total_space; - static com32sys_t ireg; - com32sys_t oreg; - struct e820_entry *e820buf; start = (size_t)ARENA_ALIGN_UP(__mem_end); total_space = sp() - start; @@ -64,61 +86,11 @@ static void __constructor init_memory_arena(void) __inject_free_block(fp); - /* Scan E820 to see if there are any other suitable blocks */ + /* Scan the memory map to look for other suitable regions */ if (!__com32.cs_memsize) return; /* Old Syslinux core, can't do this... */ - e820buf = __com32.cs_bounce; - ireg.eax.w[0] = 0xe820; - ireg.edx.l = 0x534d4150; - /* ireg.ebx.l = 0; */ - ireg.ecx.b[0] = sizeof(*e820buf); - ireg.es = SEG(e820buf); - ireg.edi.w[0] = OFFS(e820buf); - memset(e820buf, 0, sizeof *e820buf); - /* Set this in case the BIOS doesn't, but doesn't change %ecx to match. */ - e820buf->extattr = 1; - - do { - size_t start, end, len; - - __intcall(0x15, &ireg, &oreg); - - if ((oreg.eflags.l & EFLAGS_CF) || - (oreg.eax.l != 0x534d4150) || - (oreg.ecx.l < 20)) - break; - - if (oreg.ecx.l > 20 && !(e820buf->extattr & 1)) - continue; - if (e820buf->type != 1) - continue; - - /* Careful... these may be truncated values */ - start = e820buf->start; - len = e820buf->len; - - if (e820buf->start >= E820_MEM_MAX) - continue; - if (e820buf->len > E820_MEM_MAX - start) - len = E820_MEM_MAX - start; - - /* Now all the values should be within range */ - end = start + len; - - if (end <= __com32.cs_memsize) - continue; - if (start <= __com32.cs_memsize) { - start = __com32.cs_memsize; - len = end - start; - } - - if (len >= 2*sizeof(struct arena_header)) { - fp = (struct free_arena_header *)start; - fp->a.size = len; - __inject_free_block(fp); - } - } while ((ireg.ebx.l = oreg.ebx.l) != 0); + syslinux_scan_memory(consider_memory_area, NULL); } static void *__malloc_from_block(struct free_arena_header *fp, size_t size) |
