[U-Boot] [PATCHv4] [RFC] DM: early_malloc for DM added.

Tomas Hlavacek tmshlvck at gmail.com
Tue Sep 18 09:13:56 CEST 2012


early_malloc for DM with support for more heaps and lightweight
first heap on stack.

Adaptation layer for seamless calling of early_malloc or dlmalloc from
DM based on init stage added (dmmalloc() and related functions).

Signed-off-by: Tomas Hlavacek <tmshlvck at gmail.com>
---
 arch/arm/include/asm/config.h             |    3 +
 arch/arm/include/asm/global_data.h        |    1 +
 arch/arm/lib/board.c                      |    7 ++
 arch/avr32/include/asm/global_data.h      |    1 +
 arch/avr32/lib/board.c                    |    6 ++
 arch/blackfin/include/asm/global_data.h   |    1 +
 arch/blackfin/lib/board.c                 |    7 ++
 arch/m68k/include/asm/global_data.h       |    1 +
 arch/m68k/lib/board.c                     |    7 ++
 arch/microblaze/include/asm/global_data.h |    1 +
 arch/microblaze/lib/board.c               |    8 ++
 arch/mips/include/asm/global_data.h       |    1 +
 arch/mips/lib/board.c                     |    7 ++
 arch/nds32/include/asm/global_data.h      |    1 +
 arch/nds32/lib/board.c                    |    6 ++
 arch/nios2/include/asm/global_data.h      |    1 +
 arch/nios2/lib/board.c                    |    6 ++
 arch/openrisc/include/asm/global_data.h   |    1 +
 arch/openrisc/lib/board.c                 |    6 ++
 arch/powerpc/include/asm/global_data.h    |    1 +
 arch/powerpc/lib/board.c                  |    6 ++
 arch/sandbox/include/asm/global_data.h    |    1 +
 arch/sandbox/lib/board.c                  |    6 ++
 arch/sh/include/asm/global_data.h         |    1 +
 arch/sh/lib/board.c                       |    6 ++
 arch/sparc/include/asm/global_data.h      |    1 +
 arch/sparc/lib/board.c                    |    6 ++
 arch/x86/include/asm/global_data.h        |    1 +
 arch/x86/lib/board.c                      |   14 ++++
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |  128 +++++++++++++++++++++++++++++
 include/configs/zipitz2.h                 |   12 ++-
 include/dmmalloc.h                        |   51 ++++++++++++
 33 files changed, 306 insertions(+), 1 deletion(-)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h

diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h
index c60dba2..8e2f67b 100644
--- a/arch/arm/include/asm/config.h
+++ b/arch/arm/include/asm/config.h
@@ -23,4 +23,7 @@
 
 #define CONFIG_LMB
 #define CONFIG_SYS_BOOT_RAMDISK_HIGH
+
+#define CONFIG_SYS_EARLY_MALLOC
 #endif
+
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index c3ff789..8563d49 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -84,6 +84,7 @@ typedef	struct	global_data {
 	unsigned long	post_log_res; /* success of POST test */
 	unsigned long	post_init_f_time; /* When post_init_f started */
 #endif
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 /*
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 500e216..33e74da 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -52,6 +52,7 @@
 #include <fdtdec.h>
 #include <post.h>
 #include <logbuff.h>
+#include <dmmalloc.h>
 
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
@@ -273,6 +274,12 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	gd->mon_len = _bss_end_ofs;
 #ifdef CONFIG_OF_EMBED
 	/* Get a pointer to the FDT */
diff --git a/arch/avr32/include/asm/global_data.h b/arch/avr32/include/asm/global_data.h
index 5c654bd..9ae7c5e 100644
--- a/arch/avr32/include/asm/global_data.h
+++ b/arch/avr32/include/asm/global_data.h
@@ -50,6 +50,7 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 /*
diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c
index 63fe297..6c97ef7 100644
--- a/arch/avr32/lib/board.c
+++ b/arch/avr32/lib/board.c
@@ -25,6 +25,7 @@
 #include <stdio_dev.h>
 #include <version.h>
 #include <net.h>
+#include <dmmalloc.h>
 
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
@@ -149,6 +150,11 @@ void board_init_f(ulong board_type)
 	memset(&gd_data, 0, sizeof(gd_data));
 	gd = &gd_data;
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	/* Perform initialization sequence */
 	board_early_init_f();
 	cpu_init();
diff --git a/arch/blackfin/include/asm/global_data.h b/arch/blackfin/include/asm/global_data.h
index 67aa30f..33d3cec 100644
--- a/arch/blackfin/include/asm/global_data.h
+++ b/arch/blackfin/include/asm/global_data.h
@@ -59,6 +59,7 @@ typedef struct global_data {
 
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+	void	*early_heap_first;	/* early heap for early_malloc */
 } gd_t;
 
 /*
diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c
index e3ee4cd..35257d7 100644
--- a/arch/blackfin/lib/board.c
+++ b/arch/blackfin/lib/board.c
@@ -24,6 +24,8 @@
 #include <asm/mach-common/bits/mpu.h>
 #include <kgdb.h>
 
+#include <dmmalloc.h>
+
 #ifdef CONFIG_CMD_NAND
 #include <nand.h>	/* cannot even include nand.h if it isnt configured */
 #endif
@@ -250,6 +252,11 @@ void board_init_f(ulong bootflag)
 	bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
 	bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	/* Initialize */
 	serial_early_puts("IRQ init\n");
 	irq_init();
diff --git a/arch/m68k/include/asm/global_data.h b/arch/m68k/include/asm/global_data.h
index 0ba2b43..ddd76f9 100644
--- a/arch/m68k/include/asm/global_data.h
+++ b/arch/m68k/include/asm/global_data.h
@@ -68,6 +68,7 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 /*
diff --git a/arch/m68k/lib/board.c b/arch/m68k/lib/board.c
index 1526967..7ee7830 100644
--- a/arch/m68k/lib/board.c
+++ b/arch/m68k/lib/board.c
@@ -30,6 +30,8 @@
 #include <malloc.h>
 #include <stdio_dev.h>
 
+#include <dmmalloc.h>
+
 #include <asm/immap.h>
 
 #if defined(CONFIG_CMD_IDE)
@@ -227,6 +229,11 @@ board_init_f (ulong bootflag)
 	/* Clear initial global data */
 	memset ((void *) gd, 0, sizeof (gd_t));
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0) {
 			hang ();
diff --git a/arch/microblaze/include/asm/global_data.h b/arch/microblaze/include/asm/global_data.h
index 6e8537c..4e340e6 100644
--- a/arch/microblaze/include/asm/global_data.h
+++ b/arch/microblaze/include/asm/global_data.h
@@ -47,6 +47,7 @@ typedef	struct	global_data {
 	unsigned long	fb_base;	/* base address of frame buffer */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 /*
diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c
index 9828b76..a60e36f 100644
--- a/arch/microblaze/lib/board.c
+++ b/arch/microblaze/lib/board.c
@@ -33,6 +33,8 @@
 #include <net.h>
 #include <asm/processor.h>
 
+#include <dmmalloc.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef CONFIG_SYS_GPIO_0
@@ -101,6 +103,12 @@ void board_init (void)
 	asm ("nop");	/* FIXME gd is not initialize - wait */
 	memset ((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 	memset ((void *)bd, 0, GENERATED_BD_INFO_SIZE);
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	gd->bd = bd;
 	gd->baudrate = CONFIG_BAUDRATE;
 	bd->bi_baudrate = CONFIG_BAUDRATE;
diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
index f6cf9fe..9656fd6 100644
--- a/arch/mips/include/asm/global_data.h
+++ b/arch/mips/include/asm/global_data.h
@@ -61,6 +61,7 @@ typedef	struct	global_data {
 	unsigned long	env_valid;	/* Checksum of Environment valid? */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 /*
diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c
index d998f0e..d2349bf 100644
--- a/arch/mips/lib/board.c
+++ b/arch/mips/lib/board.c
@@ -32,6 +32,8 @@
 #include <onenand_uboot.h>
 #include <spi.h>
 
+#include <dmmalloc.h>
+
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
 #endif
@@ -160,6 +162,11 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0)
 			hang();
diff --git a/arch/nds32/include/asm/global_data.h b/arch/nds32/include/asm/global_data.h
index de20a0a..313fecb 100644
--- a/arch/nds32/include/asm/global_data.h
+++ b/arch/nds32/include/asm/global_data.h
@@ -65,6 +65,7 @@ typedef	struct global_data {
 
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 /*
diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c
index 074aabf..952fc1f 100644
--- a/arch/nds32/lib/board.c
+++ b/arch/nds32/lib/board.c
@@ -36,6 +36,7 @@
 #include <nand.h>
 #include <onenand_uboot.h>
 #include <mmc.h>
+#include <dmmalloc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -190,6 +191,11 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	gd->mon_len = (unsigned int)(&__bss_end__) - (unsigned int)(&_start);
 
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
diff --git a/arch/nios2/include/asm/global_data.h b/arch/nios2/include/asm/global_data.h
index 4b86fbd..02f93d3 100644
--- a/arch/nios2/include/asm/global_data.h
+++ b/arch/nios2/include/asm/global_data.h
@@ -42,6 +42,7 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 /* flags */
diff --git a/arch/nios2/lib/board.c b/arch/nios2/lib/board.c
index 65de26e..8a65c2e 100644
--- a/arch/nios2/lib/board.c
+++ b/arch/nios2/lib/board.c
@@ -30,6 +30,7 @@
 #include <malloc.h>
 #include <mmc.h>
 #include <net.h>
+#include <dmmalloc.h>
 #ifdef CONFIG_STATUS_LED
 #include <status_led.h>
 #endif
@@ -97,6 +98,11 @@ void board_init (void)
 
 	memset( gd, 0, GENERATED_GBL_DATA_SIZE );
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	gd->bd = (bd_t *)(gd+1);	/* At end of global data */
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
diff --git a/arch/openrisc/include/asm/global_data.h b/arch/openrisc/include/asm/global_data.h
index 36de9d0..032b6b2 100644
--- a/arch/openrisc/include/asm/global_data.h
+++ b/arch/openrisc/include/asm/global_data.h
@@ -46,6 +46,7 @@ typedef struct global_data {
 	unsigned long	fb_base;	/* base address of frame buffer */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 /*
diff --git a/arch/openrisc/lib/board.c b/arch/openrisc/lib/board.c
index 85aa189..30fca25 100644
--- a/arch/openrisc/lib/board.c
+++ b/arch/openrisc/lib/board.c
@@ -34,6 +34,7 @@
 #include <malloc.h>
 #include <mmc.h>
 #include <net.h>
+#include <dmmalloc.h>
 #ifdef CONFIG_STATUS_LED
 #include <status_led.h>
 #endif
@@ -86,6 +87,11 @@ void board_init(void)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	gd->bd = (bd_t *)(gd+1);	/* At end of global data */
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
diff --git a/arch/powerpc/include/asm/global_data.h b/arch/powerpc/include/asm/global_data.h
index 01f1d4a..0839d03 100644
--- a/arch/powerpc/include/asm/global_data.h
+++ b/arch/powerpc/include/asm/global_data.h
@@ -184,6 +184,7 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 /*
diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c
index 3f9af1d..41ee9db 100644
--- a/arch/powerpc/lib/board.c
+++ b/arch/powerpc/lib/board.c
@@ -26,6 +26,7 @@
 #include <command.h>
 #include <malloc.h>
 #include <stdio_dev.h>
+#include <dmmalloc.h>
 #ifdef CONFIG_8xx
 #include <mpc8xx.h>
 #endif
@@ -389,6 +390,11 @@ void board_init_f(ulong bootflag)
 	memset((void *) gd, 0, sizeof(gd_t));
 #endif
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)
 		if ((*init_fnc_ptr) () != 0)
 			hang();
diff --git a/arch/sandbox/include/asm/global_data.h b/arch/sandbox/include/asm/global_data.h
index 8d47191..54342c0 100644
--- a/arch/sandbox/include/asm/global_data.h
+++ b/arch/sandbox/include/asm/global_data.h
@@ -47,6 +47,7 @@ typedef	struct global_data {
 	phys_size_t	ram_size;	/* RAM size */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 /*
diff --git a/arch/sandbox/lib/board.c b/arch/sandbox/lib/board.c
index b7997e9..055e493 100644
--- a/arch/sandbox/lib/board.c
+++ b/arch/sandbox/lib/board.c
@@ -44,6 +44,7 @@
 #include <timestamp.h>
 #include <version.h>
 #include <serial.h>
+#include <dmmalloc.h>
 
 #include <os.h>
 
@@ -156,6 +157,11 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0)
 			hang();
diff --git a/arch/sh/include/asm/global_data.h b/arch/sh/include/asm/global_data.h
index 1b782fc..180f56e 100644
--- a/arch/sh/include/asm/global_data.h
+++ b/arch/sh/include/asm/global_data.h
@@ -42,6 +42,7 @@ typedef	struct global_data
 	unsigned long	env_valid;	/* Checksum of Environment valid */
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 #define	GD_FLG_RELOC		0x00001	/* Code was relocated to RAM		*/
diff --git a/arch/sh/lib/board.c b/arch/sh/lib/board.c
index d9c0c22..7d334f4 100644
--- a/arch/sh/lib/board.c
+++ b/arch/sh/lib/board.c
@@ -26,6 +26,7 @@
 #include <watchdog.h>
 #include <net.h>
 #include <environment.h>
+#include <dmmalloc.h>
 
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
@@ -160,6 +161,11 @@ void sh_generic_init(void)
 
 	memset(gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
 
 	gd->bd = (bd_t *)(gd + 1);	/* At end of global data */
diff --git a/arch/sparc/include/asm/global_data.h b/arch/sparc/include/asm/global_data.h
index 613e2d8..82ed56f 100644
--- a/arch/sparc/include/asm/global_data.h
+++ b/arch/sparc/include/asm/global_data.h
@@ -76,6 +76,7 @@ typedef struct global_data {
 #endif
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+	void	*early_heap_first;	/* early heap for early_malloc */
 } gd_t;
 
 /*
diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c
index 519a4fb..3421412 100644
--- a/arch/sparc/lib/board.c
+++ b/arch/sparc/lib/board.c
@@ -30,6 +30,7 @@
 #include <malloc.h>
 #include <stdio_dev.h>
 #include <config.h>
+#include <dmmalloc.h>
 #if defined(CONFIG_CMD_IDE)
 #include <ide.h>
 #endif
@@ -179,6 +180,11 @@ void board_init_f(ulong bootflag)
 	/* Clear initial global data */
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	gd->bd = (bd_t *) (gd + 1);	/* At end of global data */
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
index 908a02c..171f85b 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -59,6 +59,7 @@ typedef	struct global_data {
 	unsigned long	reset_status;	/* reset status register at boot */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+	void		*early_heap_first; /* early heap for early_malloc */
 } gd_t;
 
 static inline gd_t *get_fs_gd_ptr(void)
diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c
index 5f0b62c..b609dbe 100644
--- a/arch/x86/lib/board.c
+++ b/arch/x86/lib/board.c
@@ -40,6 +40,8 @@
 #include <asm/init_helpers.h>
 #include <asm/init_wrappers.h>
 
+#include <dmmalloc.h>
+
 /*
  * Breath some life into the board...
  *
@@ -85,6 +87,17 @@
 typedef int (init_fnc_t) (void);
 
 /*
+ * Initialize early heap (when enabled by config).
+ */
+static void early_malloc_init(void)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	/* Initialize early_malloc */
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+}
+
+/*
  * init_sequence_f is the list of init functions which are run when U-Boot
  * is executing from Flash with a limited 'C' environment. The following
  * limitations must be considered when implementing an '_f' function:
@@ -99,6 +112,7 @@ init_fnc_t *init_sequence_f[] = {
 	cpu_init_f,
 	board_early_init_f,
 	env_init,
+	early_malloc_init,
 	init_baudrate_f,
 	serial_init,
 	console_init_f,
diff --git a/common/Makefile b/common/Makefile
index 2a31c62..dfea4e8 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -188,6 +188,7 @@ COBJS-y += console.o
 COBJS-y += dlmalloc.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-y += dmmalloc.o
 
 
 COBJS	:= $(sort $(COBJS-y))
diff --git a/common/dmmalloc.c b/common/dmmalloc.c
new file mode 100644
index 0000000..18f2d95
--- /dev/null
+++ b/common/dmmalloc.c
@@ -0,0 +1,128 @@
+/*
+ * (C) Copyright 2012
+ * Tomas Hlavacek (tmshlvck at gmail.com)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h> /* for ROUND_UP */
+#include <asm/u-boot.h>
+#include <asm/global_data.h> /* for gd_t and gd */
+#include <asm/types.h> /* for phys_addr_t and size_addt_t */
+
+#include <dmmalloc.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+static struct early_heap_header *def_early_brk(size_t size)
+{
+	struct early_heap_header *h =
+		(struct early_heap_header *)CONFIG_SYS_EARLY_HEAP_ADDR;
+
+	h->free_space_pointer = (void *)(roundup(
+				(phys_addr_t)CONFIG_SYS_EARLY_HEAP_ADDR +
+				sizeof(struct early_heap_header),
+				sizeof(phys_addr_t)));
+	h->free_bytes = size - roundup(sizeof(struct early_heap_header),
+				sizeof(phys_addr_t));
+	h->next_early_heap = NULL;
+
+	return h;
+}
+
+struct early_heap_header *early_brk(size_t size)
+	__attribute__((weak, alias("def_early_brk")));
+
+
+void *early_malloc(size_t size)
+{
+	phys_addr_t addr;
+	struct early_heap_header *h;
+
+	/* Align size. */
+	size = roundup(size, sizeof(phys_addr_t));
+
+	/* Choose early_heap with enough space. */
+	h = gd->early_heap_first;
+	while ((h->free_bytes < size) && (h->next_early_heap != NULL))
+		h = h->next_early_heap;
+
+	if (h->free_bytes < size) {
+		debug("Early heap overflow. Heap %p, free %d, required %d.",
+			h, h->free_bytes, size);
+		return NULL;
+	}
+
+	/* Choose block beginning address and mark next free space. */
+	addr = (phys_addr_t)h->free_space_pointer;
+
+	h->free_space_pointer += size;
+	h->free_bytes -= size;
+
+	return (void *)addr;
+}
+
+static int is_early_malloc_active(void)
+{
+	if (gd->flags & GD_FLG_RELOC)
+		return 0;
+
+	return 1;
+}
+
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+void *dmmalloc(size_t size)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	if (is_early_malloc_active())
+		return early_malloc(size);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+	return malloc(size);
+}
+
+void dmfree(void *ptr)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	if (is_early_malloc_active())
+		return;
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+	free(ptr);
+}
+
+void *dmcalloc(size_t n, size_t elem_size)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	if (is_early_malloc_active())
+		return NULL;
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+	return calloc(n, elem_size);
+}
+
+void *dmrealloc(void *oldmem, size_t bytes)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	if (is_early_malloc_active())
+		return NULL;
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+	return dmrealloc(oldmem, bytes);
+}
+
diff --git a/include/configs/zipitz2.h b/include/configs/zipitz2.h
index 26204af..5cd0dcb 100644
--- a/include/configs/zipitz2.h
+++ b/include/configs/zipitz2.h
@@ -176,8 +176,13 @@ unsigned char zipitz2_spi_read(void);
 
 #define	CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_DRAM_BASE
 
+#define CONFIG_SYS_EARLY_HEAP_ADDR     (GENERATED_GBL_DATA_SIZE + \
+	PHYS_SDRAM_1)
+#define CONFIG_SYS_EARLY_HEAP_SIZE     256
+
 #define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
-#define	CONFIG_SYS_INIT_SP_ADDR		(GENERATED_GBL_DATA_SIZE + PHYS_SDRAM_1 + 2048)
+#define CONFIG_SYS_INIT_SP_ADDR		(GENERATED_GBL_DATA_SIZE + \
+	CONFIG_SYS_EARLY_HEAP_SIZE + PHYS_SDRAM_1 + 2048)
 
 /*
  * NOR FLASH
@@ -260,4 +265,9 @@ unsigned char zipitz2_spi_read(void);
 #define CONFIG_SYS_MCIO0_VAL	0x0001430f
 #define CONFIG_SYS_MCIO1_VAL	0x0001430f
 
+/*
+ * DM components
+ */
+#define CONFIG_SYS_EARLY_MALLOC
+
 #endif	/* __CONFIG_H */
diff --git a/include/dmmalloc.h b/include/dmmalloc.h
new file mode 100644
index 0000000..01beea7
--- /dev/null
+++ b/include/dmmalloc.h
@@ -0,0 +1,51 @@
+/*
+ * (C) Copyright 2012
+ * Tomas Hlavacek (tmshlvck at gmail.com)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __INCLUDE_DMMALLOC_H
+#define __INCLUDE_DMMALLOC_H
+
+#include <config.h>
+#include <linux/stddef.h> /* for size_t */
+
+#if (!defined(CONFIG_SYS_EARLY_HEAP_ADDR)) || \
+	(!defined(CONFIG_SYS_EARLY_HEAP_SIZE))
+#undef CONFIG_SYS_EARLY_MALLOC
+#endif /* CONFIG_SYS_EARLY_HEAP_ADDR */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+struct early_heap_header {
+	void *free_space_pointer;
+	size_t free_bytes;
+	void *next_early_heap;
+};
+
+struct early_heap_header *early_brk(size_t size);
+void *early_malloc(size_t size);
+
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+void *dmmalloc(size_t size);
+void dmfree(void *ptr);
+
+#endif /* __INCLUDE_DMMALLOC_H */
+
-- 
1.7.10.4



More information about the U-Boot mailing list