dm: Split the simple malloc() implementation into its own file

The simple malloc() implementation is used when memory is tight. It provides
a simple buffer with an incrementing pointer.

At present the implementation is inside dlmalloc. Move it into its own file
so that it is easier to find.

Rather than using relocation as a signal that the full malloc() is
available, add a special GD_FLG_FULL_MALLOC_INIT flag. This signals that the
simple malloc() should no longer be used.

In some cases, such as SPL, even the code space used by the full malloc() is
wasteful. Add a CONFIG_SYS_MALLOC_SIMPLE option to provide only the simple
malloc. In this case the full malloc is not available at all. It saves about
1KB of code space and about 0.5KB of data on Thumb 2.

Acked-by: Tom Rini <trini@ti.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
master
Simon Glass 10 years ago
parent 9dacbb2772
commit c9356be307
  1. 3
      common/Makefile
  2. 3
      common/board_r.c
  3. 19
      common/dlmalloc.c
  4. 39
      common/malloc_simple.c
  5. 1
      include/asm-generic/global_data.h
  6. 60
      include/malloc.h

@ -251,6 +251,9 @@ obj-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o
obj-y += console.o obj-y += console.o
obj-$(CONFIG_CROS_EC) += cros_ec.o obj-$(CONFIG_CROS_EC) += cros_ec.o
obj-y += dlmalloc.o obj-y += dlmalloc.o
ifdef CONFIG_SYS_MALLOC_F_LEN
obj-y += malloc_simple.o
endif
obj-y += image.o obj-y += image.o
obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
obj-$(CONFIG_OF_LIBFDT) += image-fdt.o obj-$(CONFIG_OF_LIBFDT) += image-fdt.o

@ -99,7 +99,8 @@ static int initr_trace(void)
static int initr_reloc(void) static int initr_reloc(void)
{ {
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ /* tell others: relocation done */
gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT;
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
return 0; return 0;

@ -2184,17 +2184,8 @@ Void_t* mALLOc(bytes) size_t bytes;
INTERNAL_SIZE_T nb; INTERNAL_SIZE_T nb;
#ifdef CONFIG_SYS_MALLOC_F_LEN #ifdef CONFIG_SYS_MALLOC_F_LEN
if (gd && !(gd->flags & GD_FLG_RELOC)) { if (gd && !(gd->flags & GD_FLG_FULL_MALLOC_INIT))
ulong new_ptr; return malloc_simple(bytes);
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 #endif
/* check if mem_malloc_init() was run */ /* check if mem_malloc_init() was run */
@ -2462,7 +2453,7 @@ void fREe(mem) Void_t* mem;
#ifdef CONFIG_SYS_MALLOC_F_LEN #ifdef CONFIG_SYS_MALLOC_F_LEN
/* free() is a no-op - all the memory will be freed on relocation */ /* free() is a no-op - all the memory will be freed on relocation */
if (!(gd->flags & GD_FLG_RELOC)) if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
return; return;
#endif #endif
@ -2618,7 +2609,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
if (oldmem == NULL) return mALLOc(bytes); if (oldmem == NULL) return mALLOc(bytes);
#ifdef CONFIG_SYS_MALLOC_F_LEN #ifdef CONFIG_SYS_MALLOC_F_LEN
if (!(gd->flags & GD_FLG_RELOC)) { if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
/* This is harder to support and should not be needed */ /* This is harder to support and should not be needed */
panic("pre-reloc realloc() is not supported"); panic("pre-reloc realloc() is not supported");
} }
@ -2970,7 +2961,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
else else
{ {
#ifdef CONFIG_SYS_MALLOC_F_LEN #ifdef CONFIG_SYS_MALLOC_F_LEN
if (!(gd->flags & GD_FLG_RELOC)) { if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
MALLOC_ZERO(mem, sz); MALLOC_ZERO(mem, sz);
return mem; return mem;
} }

@ -0,0 +1,39 @@
/*
* Simple malloc implementation
*
* Copyright (c) 2014 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <malloc.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
void *malloc_simple(size_t bytes)
{
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;
}
#ifdef CONFIG_SYS_MALLOC_SIMPLE
void *calloc(size_t nmemb, size_t elem_size)
{
size_t size = nmemb * elem_size;
void *ptr;
ptr = malloc(size);
memset(ptr, '\0', size);
return ptr;
}
#endif

@ -107,5 +107,6 @@ typedef struct global_data {
#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */ #define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */
#define GD_FLG_ENV_READY 0x00080 /* Env. imported into hash table */ #define GD_FLG_ENV_READY 0x00080 /* Env. imported into hash table */
#define GD_FLG_SERIAL_READY 0x00100 /* Pre-reloc serial console ready */ #define GD_FLG_SERIAL_READY 0x00100 /* Pre-reloc serial console ready */
#define GD_FLG_FULL_MALLOC_INIT 0x00200 /* Full malloc() is ready */
#endif /* __ASM_GENERIC_GBL_DATA_H */ #endif /* __ASM_GENERIC_GBL_DATA_H */

@ -872,33 +872,46 @@ extern Void_t* sbrk();
#else #else
#ifdef USE_DL_PREFIX #ifdef CONFIG_SYS_MALLOC_SIMPLE
#define cALLOc dlcalloc #define malloc malloc_simple
#define fREe dlfree #define realloc realloc_simple
#define mALLOc dlmalloc #define memalign memalign_simple
#define mEMALIGn dlmemalign static inline void free(void *ptr) {}
#define rEALLOc dlrealloc void *calloc(size_t nmemb, size_t size);
#define vALLOc dlvalloc void *memalign_simple(size_t alignment, size_t bytes);
#define pvALLOc dlpvalloc void *realloc_simple(void *ptr, size_t size);
#define mALLINFo dlmallinfo #else
#define mALLOPt dlmallopt
#else /* USE_DL_PREFIX */ # ifdef USE_DL_PREFIX
#define cALLOc calloc # define cALLOc dlcalloc
#define fREe free # define fREe dlfree
#define mALLOc malloc # define mALLOc dlmalloc
#define mEMALIGn memalign # define mEMALIGn dlmemalign
#define rEALLOc realloc # define rEALLOc dlrealloc
#define vALLOc valloc # define vALLOc dlvalloc
#define pvALLOc pvalloc # define pvALLOc dlpvalloc
#define mALLINFo mallinfo # define mALLINFo dlmallinfo
#define mALLOPt mallopt # define mALLOPt dlmallopt
#endif /* USE_DL_PREFIX */ # else /* USE_DL_PREFIX */
# define cALLOc calloc
# define fREe free
# define mALLOc malloc
# define mEMALIGn memalign
# define rEALLOc realloc
# define vALLOc valloc
# define pvALLOc pvalloc
# define mALLINFo mallinfo
# define mALLOPt mallopt
# endif /* USE_DL_PREFIX */
#endif #endif
/* Public routines */ /* Public routines */
#if __STD_C /* Simple versions which can be used when space is tight */
void *malloc_simple(size_t size);
# if __STD_C
Void_t* mALLOc(size_t); Void_t* mALLOc(size_t);
void fREe(Void_t*); void fREe(Void_t*);
@ -913,7 +926,7 @@ size_t malloc_usable_size(Void_t*);
void malloc_stats(void); void malloc_stats(void);
int mALLOPt(int, int); int mALLOPt(int, int);
struct mallinfo mALLINFo(void); struct mallinfo mALLINFo(void);
#else # else
Void_t* mALLOc(); Void_t* mALLOc();
void fREe(); void fREe();
Void_t* rEALLOc(); Void_t* rEALLOc();
@ -927,6 +940,7 @@ size_t malloc_usable_size();
void malloc_stats(); void malloc_stats();
int mALLOPt(); int mALLOPt();
struct mallinfo mALLINFo(); struct mallinfo mALLINFo();
# endif
#endif #endif
/* /*

Loading…
Cancel
Save