Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/23583
Change subject: libpayload/x86/malloc: Add methods to allocate low memory ......................................................................
libpayload/x86/malloc: Add methods to allocate low memory
Add implementation of low_malloc to allocate heap below 1MiB.
Change-Id: I5b303863a4a41a07f3b7c01e3e85706ae105ec87 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M payloads/libpayload/arch/x86/main.c M payloads/libpayload/arch/x86/sysinfo.c M payloads/libpayload/include/stdlib.h M payloads/libpayload/libc/malloc.c 4 files changed, 80 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/83/23583/1
diff --git a/payloads/libpayload/arch/x86/main.c b/payloads/libpayload/arch/x86/main.c index 5f7f505..e5534b8 100644 --- a/payloads/libpayload/arch/x86/main.c +++ b/payloads/libpayload/arch/x86/main.c @@ -57,6 +57,8 @@
exception_init();
+ init_low_memory(); + /* * Any other system init that has to happen before the * user gets control goes here. diff --git a/payloads/libpayload/arch/x86/sysinfo.c b/payloads/libpayload/arch/x86/sysinfo.c index ddd6550..45b30ff 100644 --- a/payloads/libpayload/arch/x86/sysinfo.c +++ b/payloads/libpayload/arch/x86/sysinfo.c @@ -81,3 +81,10 @@
return ret; } + +void lib_sysinfo_get_memranges(struct memrange **ranges, + uint64_t *nranges) +{ + *ranges = &lib_sysinfo.memrange[0]; + *nranges = lib_sysinfo.n_memranges; +} diff --git a/payloads/libpayload/include/stdlib.h b/payloads/libpayload/include/stdlib.h index 658fe61..f9563c7 100644 --- a/payloads/libpayload/include/stdlib.h +++ b/payloads/libpayload/include/stdlib.h @@ -150,10 +150,13 @@ void *memalign(size_t align, size_t size); void *dma_malloc(size_t size); void *dma_memalign(size_t align, size_t size); +void *low_malloc(size_t size); +void *low_memalign(size_t align, size_t size); #endif void init_dma_memory(void *start, u32 size); int dma_initialized(void); int dma_coherent(void *ptr); +int init_low_memory(void);
static inline void *xmalloc_work(size_t size, const char *file, const char *func, int line) diff --git a/payloads/libpayload/libc/malloc.c b/payloads/libpayload/libc/malloc.c index 595af63..84b310c 100644 --- a/payloads/libpayload/libc/malloc.c +++ b/payloads/libpayload/libc/malloc.c @@ -64,6 +64,7 @@ }; static struct memory_type *const heap = &default_type; static struct memory_type *dma = &default_type; +static struct memory_type *low_mem = NULL;
typedef u64 hdrtype_t; #define HDRSIZE (sizeof(hdrtype_t)) @@ -124,6 +125,57 @@ return !dma_initialized() || (dma->start <= ptr && dma->end > ptr); }
+int init_low_memory(void) +{ + uint64_t nranges; + struct memrange *ranges; + unsigned long long start; + unsigned long long size; + + if (low_mem) { + printf("ERROR: %s called twice!\n", __func__); + return 0; + } + + lib_sysinfo_get_memranges(&ranges, &nranges); + if (!nranges) + return 1; + + start = 0x100000ULL; + size = 0; + for (size_t i = 0; i < nranges; i++) { + if (ranges[i].type != CB_MEM_RAM) + continue; + if (ranges[i].base > start) + continue; + if (ranges[i].size < size) + continue; + + size = ranges[i].size; + start = ranges[i].base; + } + + if (!size) + return 1; + + low_mem = malloc(sizeof(*low_mem)); + if (!low_mem) + return 1; + + low_mem->start = (void *)(uintptr_t)start; + low_mem->end = (void *)(uintptr_t)(start + size); + low_mem->align_regions = NULL; + +#if IS_ENABLED(CONFIG_LP_DEBUG_MALLOC) + low_mem->minimal_free = 0; + low_mem->magic_initialized = 0; + low_mem->name = "LOW"; + + printf("Initialized low memory at [%p:%p]\n", start, start + size); +#endif + return 0; +} + static void *alloc(int len, struct memory_type *type) { hdrtype_t header; @@ -259,6 +311,14 @@ return alloc(size, heap); }
+void *low_malloc(size_t size) +{ + if (!low_mem) + return NULL; + + return alloc(size, low_mem); +} + void *dma_malloc(size_t size) { return alloc(size, dma); @@ -533,6 +593,14 @@ return alloc_aligned(align, size, heap); }
+void *low_memalign(size_t align, size_t size) +{ + if (!low_mem) + return NULL; + + return alloc_aligned(align, size, low_mem); +} + void *dma_memalign(size_t align, size_t size) { return alloc_aligned(align, size, dma);