bios: Fix lowmem check
[syslinux.git] / core / mem / init.c
blobd6a5f18987c0491af66588bfd698387e4805fecd
1 #include <stdlib.h>
2 #include <errno.h>
3 #include <string.h>
4 #include "malloc.h"
5 #include "core.h"
6 #include <syslinux/memscan.h>
8 struct free_arena_header __core_malloc_head[NHEAP];
10 //static __hugebss char main_heap[128 << 10];
11 extern char __lowmem_heap[];
12 extern char free_high_memory[];
14 #define E820_MEM_MAX 0xfff00000 /* 4 GB - 1 MB */
15 int scan_highmem_area(void *data, addr_t start, addr_t len, bool is_ram)
17 struct free_arena_header *fp;
19 (void)data;
21 dprintf("start = %x, len = %x, is_ram = %d", start, len, is_ram);
23 if (start < 0x100000 || start > E820_MEM_MAX
24 || !is_ram)
25 return 0;
27 if (start < __com32.cs_memsize) {
28 len -= __com32.cs_memsize - start;
29 start = __com32.cs_memsize;
31 if (len > E820_MEM_MAX - start)
32 len = E820_MEM_MAX - start;
34 if (len >= 2 * sizeof(struct arena_header)) {
35 fp = (struct free_arena_header *)start;
36 fp->a.attrs = ARENA_TYPE_USED | (HEAP_MAIN << ARENA_HEAP_POS);
37 #ifdef DEBUG_MALLOC
38 fp->a.magic = ARENA_MAGIC;
39 #endif
40 ARENA_SIZE_SET(fp->a.attrs, len);
41 dprintf("will inject a block start:0x%x size 0x%x", start, len);
42 __inject_free_block(fp);
45 __com32.cs_memsize = start + len; /* update the HighMemSize */
46 return 0;
49 #if 0
50 static void mpool_dump(enum heap heap)
52 struct free_arena_header *head = &__core_malloc_head[heap];
53 struct free_arena_header *fp;
54 int size, type, i = 0;
55 addr_t start, end;
57 fp = head->next_free;
58 while (fp != head) {
59 size = ARENA_SIZE_GET(fp->a.attrs);
60 type = ARENA_TYPE_GET(fp->a.attrs);
61 start = (addr_t)fp;
62 end = start + size;
63 printf("area[%d]: start = 0x%08x, end = 0x%08x, type = %d\n",
64 i++, start, end, type);
65 fp = fp->next_free;
68 #endif
70 void mem_init(void)
72 struct free_arena_header *fp;
73 int i;
74 uint16_t *bios_free_mem = (uint16_t *)0x413;
76 //dprintf("enter");
78 /* Initialize the head nodes */
79 fp = &__core_malloc_head[0];
80 for (i = 0 ; i < NHEAP ; i++) {
81 fp->a.next = fp->a.prev = fp->next_free = fp->prev_free = fp;
82 fp->a.attrs = ARENA_TYPE_HEAD | (i << ARENA_HEAP_POS);
83 fp->a.tag = MALLOC_HEAD;
84 fp++;
87 //dprintf("__lowmem_heap = 0x%p bios_free = 0x%p",
88 // __lowmem_heap, *bios_free_mem);
90 /* Initialize the lowmem heap */
91 fp = (struct free_arena_header *)__lowmem_heap;
92 fp->a.attrs = ARENA_TYPE_USED | (HEAP_LOWMEM << ARENA_HEAP_POS);
93 ARENA_SIZE_SET(fp->a.attrs, (*bios_free_mem << 10) - (uintptr_t)fp);
94 #ifdef DEBUG_MALLOC
95 fp->a.magic = ARENA_MAGIC;
96 #endif
97 __inject_free_block(fp);
99 /* Initialize the main heap */
100 __com32.cs_memsize = (size_t)free_high_memory;
101 syslinux_scan_memory(scan_highmem_area, NULL);