summaryrefslogtreecommitdiff
path: root/common/dlmalloc.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2014-07-10 22:23:28 -0600
committerSimon Glass <sjg@chromium.org>2014-07-23 14:05:40 +0100
commitd59476b6446799c21e64147d86483140154c1886 (patch)
tree4776a03340adc8f85434c91d4cb0d060cf36c013 /common/dlmalloc.c
parent4d94dfa0594260245813ea150e276908cc677199 (diff)
downloadu-boot-imx-d59476b6446799c21e64147d86483140154c1886.zip
u-boot-imx-d59476b6446799c21e64147d86483140154c1886.tar.gz
u-boot-imx-d59476b6446799c21e64147d86483140154c1886.tar.bz2
Add a simple malloc() implementation for pre-relocation
If we are to have driver model before relocation we need to support some way of calling memory allocation routines. The standard malloc() is pretty complicated: 1. It uses some BSS memory for its state, and BSS is not available before relocation 2. It supports algorithms for reducing memory fragmentation and improving performace of free(). Before relocation we could happily just not support free(). 3. It includes about 4KB of code (Thumb 2) and 1KB of data. However since this has been loaded anyway this is not really a problem. The simplest way to support pre-relocation malloc() is to reserve an area of memory and allocate it in increasing blocks as needed. This implementation does this. To enable it, you need to define the size of the malloc() pool as described in the README. It will be located above the pre-relocation stack on supported architectures. Note that this implementation is only useful on machines which have some memory available before dram_init() is called - this includes those that do no DRAM init (like tegra) and those that do it in SPL (quite a few boards). Enabling driver model preior to relocation for the rest of the boards is left for a later exercise. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'common/dlmalloc.c')
-rw-r--r--common/dlmalloc.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index d1cd561..26ba8fd 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -930,6 +930,8 @@ struct mallinfo mALLINFo();
#endif /* 0 */ /* Moved to malloc.h */
#include <malloc.h>
+#include <asm/io.h>
+
#ifdef DEBUG
#if __STD_C
static void malloc_update_mallinfo (void);
@@ -2174,6 +2176,20 @@ Void_t* mALLOc(bytes) size_t bytes;
INTERNAL_SIZE_T nb;
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+ if (!(gd->flags & GD_FLG_RELOC)) {
+ ulong new_ptr;
+ void *ptr;
+
+ new_ptr = gd->malloc_ptr + bytes;
+ if (new_ptr > gd->malloc_limit)
+ panic("Out of pre-reloc memory");
+ ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes);
+ gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr));
+ return ptr;
+ }
+#endif
+
/* check if mem_malloc_init() was run */
if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) {
/* not initialized yet */
@@ -2437,6 +2453,12 @@ void fREe(mem) Void_t* mem;
mchunkptr fwd; /* misc temp for linking */
int islr; /* track whether merging with last_remainder */
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+ /* free() is a no-op - all the memory will be freed on relocation */
+ if (!(gd->flags & GD_FLG_RELOC))
+ return;
+#endif
+
if (mem == NULL) /* free(0) has no effect */
return;
@@ -2588,6 +2610,13 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
/* realloc of null is supposed to be same as malloc */
if (oldmem == NULL) return mALLOc(bytes);
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+ if (!(gd->flags & GD_FLG_RELOC)) {
+ /* This is harder to support and should not be needed */
+ panic("pre-reloc realloc() is not supported");
+ }
+#endif
+
newp = oldp = mem2chunk(oldmem);
newsize = oldsize = chunksize(oldp);
@@ -2933,6 +2962,12 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
return NULL;
else
{
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+ if (!(gd->flags & GD_FLG_RELOC)) {
+ MALLOC_ZERO(mem, sz);
+ return mem;
+ }
+#endif
p = mem2chunk(mem);
/* Two optional cases in which clearing not necessary */