Skip to contentSkip to conversation

DM: early_malloc for DM added.

RFC PATCH Superseded Tomas Hlavacek 7 participants 48 messages Aug 27, 2012 – Nov 5, 2013

Subsystems (11)
Arm (32-bit) x86 PowerPC MIPS +7 more subsystems
lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 DM: early_malloc for DM added.

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

(RFC. Not intended for merging!)

---
 arch/arm/include/asm/global_data.h        |    1 +
 arch/arm/lib/board.c                      |    5 ++
 arch/avr32/include/asm/global_data.h      |    1 +
 arch/avr32/lib/board.c                    |    4 ++
 arch/blackfin/include/asm/global_data.h   |    1 +
 arch/blackfin/lib/board.c                 |    4 ++
 arch/m68k/include/asm/global_data.h       |    1 +
 arch/m68k/lib/board.c                     |    4 ++
 arch/microblaze/include/asm/global_data.h |    1 +
 arch/microblaze/lib/board.c               |    5 ++
 arch/mips/include/asm/global_data.h       |    1 +
 arch/mips/lib/board.c                     |    4 ++
 arch/nds32/include/asm/global_data.h      |    1 +
 arch/nds32/lib/board.c                    |    4 ++
 arch/nios2/include/asm/global_data.h      |    1 +
 arch/nios2/lib/board.c                    |    4 ++
 arch/openrisc/include/asm/global_data.h   |    1 +
 arch/openrisc/lib/board.c                 |    4 ++
 arch/powerpc/include/asm/global_data.h    |    1 +
 arch/powerpc/lib/board.c                  |    4 ++
 arch/sandbox/include/asm/global_data.h    |    1 +
 arch/sandbox/lib/board.c                  |    4 ++
 arch/sh/include/asm/global_data.h         |    1 +
 arch/sparc/include/asm/global_data.h      |    1 +
 arch/sparc/lib/board.c                    |    4 ++
 arch/x86/include/asm/global_data.h        |    1 +
 arch/x86/lib/board.c                      |    4 ++
 common/Makefile                           |    1 +
 common/earlymalloc.c                      |   91 +++++++++++++++++++++++++++++
 include/earlymalloc.h                     |   48 +++++++++++++++
 30 files changed, 208 insertions(+)
 create mode 100644 common/earlymalloc.c
 create mode 100644 include/earlymalloc.h
arch/arm/include/asm/global_data.h +1 -0
index c3ff789..71ae6dc 100644
@@ -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;
 
 /*
arch/arm/lib/board.c +5 -0
index 500e216..ad124c6 100644
@@ -52,6 +52,7 @@
 #include <fdtdec.h>
 #include <post.h>
 #include <logbuff.h>
+#include <earlymalloc.h>
 
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
@@ -273,6 +274,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->mon_len = _bss_end_ofs;
 #ifdef CONFIG_OF_EMBED
 	/* Get a pointer to the FDT */
arch/avr32/include/asm/global_data.h +1 -0
index 5c654bd..5edb1f0 100644
@@ -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;
 
 /*
arch/avr32/lib/board.c +4 -0
index 63fe297..8cb56df 100644
@@ -149,6 +149,10 @@ void board_init_f(ulong board_type)
 	memset(&gd_data, 0, sizeof(gd_data));
 	gd = &gd_data;
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	/* Perform initialization sequence */
 	board_early_init_f();
 	cpu_init();
arch/blackfin/include/asm/global_data.h +1 -0
index 67aa30f..33d3cec 100644
@@ -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;
 
 /*
arch/blackfin/lib/board.c +4 -0
index e3ee4cd..f8dade6 100644
@@ -250,6 +250,10 @@ void board_init_f(ulong bootflag)
 	bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
 	bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	/* Initialize */
 	serial_early_puts("IRQ init\n");
 	irq_init();
arch/m68k/include/asm/global_data.h +1 -0
index 0ba2b43..ddd76f9 100644
@@ -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;
 
 /*
arch/m68k/lib/board.c +4 -0
index 1526967..a420d21 100644
@@ -227,6 +227,10 @@ board_init_f (ulong bootflag)
 	/* Clear initial global data */
 	memset ((void *) gd, 0, sizeof (gd_t));
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0) {
 			hang ();
arch/microblaze/include/asm/global_data.h +1 -0
index 6e8537c..4e340e6 100644
@@ -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;
 
 /*
arch/microblaze/lib/board.c +5 -0
index 9828b76..302a323 100644
@@ -101,6 +101,11 @@ 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);
+
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->bd = bd;
 	gd->baudrate = CONFIG_BAUDRATE;
 	bd->bi_baudrate = CONFIG_BAUDRATE;
arch/mips/include/asm/global_data.h +1 -0
index f6cf9fe..9656fd6 100644
@@ -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;
 
 /*
arch/mips/lib/board.c +4 -0
index d998f0e..f40258c 100644
@@ -160,6 +160,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0)
 			hang();
arch/nds32/include/asm/global_data.h +1 -0
index de20a0a..313fecb 100644
@@ -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;
 
 /*
arch/nds32/lib/board.c +4 -0
index 074aabf..34fff30 100644
@@ -190,6 +190,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->mon_len = (unsigned int)(&__bss_end__) - (unsigned int)(&_start);
 
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
arch/nios2/include/asm/global_data.h +1 -0
index 4b86fbd..02f93d3 100644
@@ -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 */
arch/nios2/lib/board.c +4 -0
index 65de26e..87e0559 100644
@@ -97,6 +97,10 @@ void board_init (void)
 
 	memset( gd, 0, GENERATED_GBL_DATA_SIZE );
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->bd = (bd_t *)(gd+1);	/* At end of global data */
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
arch/openrisc/include/asm/global_data.h +1 -0
index 36de9d0..032b6b2 100644
@@ -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;
 
 /*
arch/openrisc/lib/board.c +4 -0
index 85aa189..2a92899 100644
@@ -86,6 +86,10 @@ void board_init(void)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->bd = (bd_t *)(gd+1);	/* At end of global data */
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
arch/powerpc/include/asm/global_data.h +1 -0
index 01f1d4a..0839d03 100644
@@ -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;
 
 /*
arch/powerpc/lib/board.c +4 -0
index 3f9af1d..ac88ae2 100644
@@ -389,6 +389,10 @@ void board_init_f(ulong bootflag)
 	memset((void *) gd, 0, sizeof(gd_t));
 #endif
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)
 		if ((*init_fnc_ptr) () != 0)
 			hang();
arch/sandbox/include/asm/global_data.h +1 -0
index 8d47191..54342c0 100644
@@ -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;
 
 /*
arch/sandbox/lib/board.c +4 -0
index b7997e9..3d06cfc 100644
@@ -156,6 +156,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0)
 			hang();
arch/sh/include/asm/global_data.h +1 -0
index 1b782fc..180f56e 100644
@@ -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		*/
arch/sparc/include/asm/global_data.h +1 -0
index 613e2d8..82ed56f 100644
@@ -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;
 
 /*
arch/sparc/lib/board.c +4 -0
index 519a4fb..86ee8db 100644
@@ -179,6 +179,10 @@ void board_init_f(ulong bootflag)
 	/* Clear initial global data */
 	memset((void *)gd, 0, sizeof(gd_t));
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->bd = (bd_t *) (gd + 1);	/* At end of global data */
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
arch/x86/include/asm/global_data.h +1 -0
index 908a02c..171f85b 100644
@@ -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)
arch/x86/lib/board.c +4 -0
index 5f0b62c..5ff4f42 100644
@@ -220,6 +220,10 @@ void board_init_f(ulong boot_flags)
 {
 	gd->flags = boot_flags;
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	do_init_loop(init_sequence_f);
 
 	/*
common/Makefile +1 -0
index 2a31c62..744beb8 100644
@@ -188,6 +188,7 @@ COBJS-y += console.o
 COBJS-y += dlmalloc.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-y += earlymalloc.o
 
 
 COBJS	:= $(sort $(COBJS-y))
common/earlymalloc.c new file +91 -0

91 lines not on this page · raw message

include/earlymalloc.h new file +48 -0

48 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#1 lore raw

RFC PATCH 1/1 DM: early_malloc for DM added.

Dear Tomas Hlavacek,

Quoted 6 lines

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

(RFC. Not intended for merging!)

[...]

CCing Graeme

Best regards,
Marek Vasut

#2 lore raw

RFC PATCH 1/1 DM: early_malloc for DM added.

Hello Marek and Greame!

Thanks.

I want to add that this patch contains only the early_malloc() backend for prospective dm_malloc(). There are no relocation support or helpers whatsoever yet.

The aim is to present the way of grabbing a chunk of stack and using this memory as the early heap and collect the feedback.

Tomas

Quoted 14 lines · Marek Vasut

Dear Tomas Hlavacek,

Quoted 6 lines

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

(RFC. Not intended for merging!)

[...]

CCing Graeme

Best regards,
Marek Vasut

Signature · 1 line
Tom?? Hlav??ek <[email protected]>
#3 lore raw

RFC PATCH v2 1/1 DM: early_malloc for DM added.

In reply to Tomas Hlavacek

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

(Not intended for merging!)

---
 arch/arm/include/asm/global_data.h        |    1 +
 arch/arm/lib/board.c                      |    5 ++
 arch/avr32/include/asm/global_data.h      |    1 +
 arch/avr32/lib/board.c                    |    4 ++
 arch/blackfin/include/asm/global_data.h   |    1 +
 arch/blackfin/lib/board.c                 |    4 ++
 arch/m68k/include/asm/global_data.h       |    1 +
 arch/m68k/lib/board.c                     |    4 ++
 arch/microblaze/include/asm/global_data.h |    1 +
 arch/microblaze/lib/board.c               |    5 ++
 arch/mips/include/asm/global_data.h       |    1 +
 arch/mips/lib/board.c                     |    4 ++
 arch/nds32/include/asm/global_data.h      |    1 +
 arch/nds32/lib/board.c                    |    4 ++
 arch/nios2/include/asm/global_data.h      |    1 +
 arch/nios2/lib/board.c                    |    4 ++
 arch/openrisc/include/asm/global_data.h   |    1 +
 arch/openrisc/lib/board.c                 |    4 ++
 arch/powerpc/include/asm/global_data.h    |    1 +
 arch/powerpc/lib/board.c                  |    4 ++
 arch/sandbox/include/asm/global_data.h    |    1 +
 arch/sandbox/lib/board.c                  |    4 ++
 arch/sh/include/asm/global_data.h         |    1 +
 arch/sparc/include/asm/global_data.h      |    1 +
 arch/sparc/lib/board.c                    |    4 ++
 arch/x86/include/asm/global_data.h        |    1 +
 arch/x86/lib/board.c                      |    4 ++
 common/Makefile                           |    1 +
 common/earlymalloc.c                      |   91 +++++++++++++++++++++++++++++
 include/earlymalloc.h                     |   49 ++++++++++++++++
 30 files changed, 209 insertions(+)
 create mode 100644 common/earlymalloc.c
 create mode 100644 include/earlymalloc.h
arch/arm/include/asm/global_data.h +1 -0
index c3ff789..8563d49 100644
@@ -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;
 
 /*
arch/arm/lib/board.c +5 -0
index 500e216..ad124c6 100644
@@ -52,6 +52,7 @@
 #include <fdtdec.h>
 #include <post.h>
 #include <logbuff.h>
+#include <earlymalloc.h>
 
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
@@ -273,6 +274,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->mon_len = _bss_end_ofs;
 #ifdef CONFIG_OF_EMBED
 	/* Get a pointer to the FDT */
arch/avr32/include/asm/global_data.h +1 -0
index 5c654bd..9ae7c5e 100644
@@ -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;
 
 /*
arch/avr32/lib/board.c +4 -0
index 63fe297..8cb56df 100644
@@ -149,6 +149,10 @@ void board_init_f(ulong board_type)
 	memset(&gd_data, 0, sizeof(gd_data));
 	gd = &gd_data;
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	/* Perform initialization sequence */
 	board_early_init_f();
 	cpu_init();
arch/blackfin/include/asm/global_data.h +1 -0
index 67aa30f..33d3cec 100644
@@ -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;
 
 /*
arch/blackfin/lib/board.c +4 -0
index e3ee4cd..f8dade6 100644
@@ -250,6 +250,10 @@ void board_init_f(ulong bootflag)
 	bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
 	bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	/* Initialize */
 	serial_early_puts("IRQ init\n");
 	irq_init();
arch/m68k/include/asm/global_data.h +1 -0
index 0ba2b43..ddd76f9 100644
@@ -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;
 
 /*
arch/m68k/lib/board.c +4 -0
index 1526967..a420d21 100644
@@ -227,6 +227,10 @@ board_init_f (ulong bootflag)
 	/* Clear initial global data */
 	memset ((void *) gd, 0, sizeof (gd_t));
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0) {
 			hang ();
arch/microblaze/include/asm/global_data.h +1 -0
index 6e8537c..4e340e6 100644
@@ -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;
 
 /*
arch/microblaze/lib/board.c +5 -0
index 9828b76..302a323 100644
@@ -101,6 +101,11 @@ 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);
+
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->bd = bd;
 	gd->baudrate = CONFIG_BAUDRATE;
 	bd->bi_baudrate = CONFIG_BAUDRATE;
arch/mips/include/asm/global_data.h +1 -0
index f6cf9fe..9656fd6 100644
@@ -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;
 
 /*
arch/mips/lib/board.c +4 -0
index d998f0e..f40258c 100644
@@ -160,6 +160,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0)
 			hang();
arch/nds32/include/asm/global_data.h +1 -0
index de20a0a..313fecb 100644
@@ -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;
 
 /*
arch/nds32/lib/board.c +4 -0
index 074aabf..34fff30 100644
@@ -190,6 +190,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->mon_len = (unsigned int)(&__bss_end__) - (unsigned int)(&_start);
 
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
arch/nios2/include/asm/global_data.h +1 -0
index 4b86fbd..02f93d3 100644
@@ -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 */
arch/nios2/lib/board.c +4 -0
index 65de26e..87e0559 100644
@@ -97,6 +97,10 @@ void board_init (void)
 
 	memset( gd, 0, GENERATED_GBL_DATA_SIZE );
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->bd = (bd_t *)(gd+1);	/* At end of global data */
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
arch/openrisc/include/asm/global_data.h +1 -0
index 36de9d0..032b6b2 100644
@@ -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;
 
 /*
arch/openrisc/lib/board.c +4 -0
index 85aa189..2a92899 100644
@@ -86,6 +86,10 @@ void board_init(void)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->bd = (bd_t *)(gd+1);	/* At end of global data */
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
arch/powerpc/include/asm/global_data.h +1 -0
index 01f1d4a..0839d03 100644
@@ -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;
 
 /*
arch/powerpc/lib/board.c +4 -0
index 3f9af1d..ac88ae2 100644
@@ -389,6 +389,10 @@ void board_init_f(ulong bootflag)
 	memset((void *) gd, 0, sizeof(gd_t));
 #endif
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)
 		if ((*init_fnc_ptr) () != 0)
 			hang();
arch/sandbox/include/asm/global_data.h +1 -0
index 8d47191..54342c0 100644
@@ -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;
 
 /*
arch/sandbox/lib/board.c +4 -0
index b7997e9..3d06cfc 100644
@@ -156,6 +156,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0)
 			hang();
arch/sh/include/asm/global_data.h +1 -0
index 1b782fc..180f56e 100644
@@ -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		*/
arch/sparc/include/asm/global_data.h +1 -0
index 613e2d8..82ed56f 100644
@@ -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;
 
 /*
arch/sparc/lib/board.c +4 -0
index 519a4fb..86ee8db 100644
@@ -179,6 +179,10 @@ void board_init_f(ulong bootflag)
 	/* Clear initial global data */
 	memset((void *)gd, 0, sizeof(gd_t));
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	gd->bd = (bd_t *) (gd + 1);	/* At end of global data */
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
arch/x86/include/asm/global_data.h +1 -0
index 908a02c..171f85b 100644
@@ -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)
arch/x86/lib/board.c +4 -0
index 5f0b62c..5ff4f42 100644
@@ -220,6 +220,10 @@ void board_init_f(ulong boot_flags)
 {
 	gd->flags = boot_flags;
 
+	/* Initialize early_malloc */
+	DECLARE_EARLY_HEAP_ON_STACK;
+	early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
 	do_init_loop(init_sequence_f);
 
 	/*
common/Makefile +1 -0
index 2a31c62..744beb8 100644
@@ -188,6 +188,7 @@ COBJS-y += console.o
 COBJS-y += dlmalloc.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-y += earlymalloc.o
 
 
 COBJS	:= $(sort $(COBJS-y))
common/earlymalloc.c new file +91 -0

91 lines not on this page · raw message

include/earlymalloc.h new file +49 -0

49 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#4 lore raw

RFC PATCH v2 1/1 DM: early_malloc for DM added.

Hi Tomas,

None of my example code is compile tested...

Regards,

Graeme

Quoted 11 lines · Tomas Hlavacek

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

(Not intended for merging!)

arch/arm/include/asm/global_data.h +0 -0
index c3ff789..8563d49 100644

arch/arm/include/asm/global_data.h typedef struct global_data { · line 88

Quoted 5 lines
arch/arm/include/asm/global_data.h +1 -0
@@ -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;

Probably want to put an #ifdef CONFIG_SYS_EARLY_MALLOC around it. Also, it is a struct early_heap_header *

Quoted 15 lines
arch/arm/include/asm/global_data.h +0 -0
 /*
arch/arm/lib/board.c +1 -0
index 500e216..ad124c6 100644
@@ -52,6 +52,7 @@
 #include <fdtdec.h>
 #include <post.h>
 #include <logbuff.h>
+#include <earlymalloc.h>
 
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>

arch/arm/lib/board.c void board_init_f(ulong bootflag) · line 280

Quoted 7 lines
arch/arm/lib/board.c +4 -0
@@ -273,6 +274,10 @@ void board_init_f(ulong bootflag)
 
        memset((void *)gd, 0, sizeof(gd_t));
 
+       /* Initialize early_malloc */
+       DECLARE_EARLY_HEAP_ON_STACK;
+       early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+

I'm not a fan of burying the initialiser in a #define, and we already have a precedent of providing a hard-coded address for the chunk of memory (CONFIG_PRE_CON_BUF_ADDR)

Quoted 5 lines
arch/x86/lib/board.c +0 -0
index 5f0b62c..5ff4f42 100644

arch/x86/lib/board.c void board_init_f(ulong boot_flags) · line 229

Quoted 10 lines
arch/x86/lib/board.c +4 -0
@@ -220,6 +220,10 @@ void board_init_f(ulong boot_flags)
 {
        gd->flags = boot_flags;
 
+       /* Initialize early_malloc */
+       DECLARE_EARLY_HEAP_ON_STACK;
+       early_heap_init(gd->early_heap_first, CONFIG_SYS_EARLY_HEAP_SIZE);
+
        do_init_loop(init_sequence_f);
 
        /*

early_heap_init() should be called via do_init_loop() - i.e. added to the top of the list and added in init_helpers.c

common/Makefile COBJS-y += console.o · line 191

Quoted 9 lines
common/Makefile +1 -0
index 2a31c62..744beb8 100644
@@ -188,6 +188,7 @@ COBJS-y += console.o
 COBJS-y += dlmalloc.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-y += earlymalloc.o

Add the CONFIG_SYS_EARLY_MALLOC check here as well

Quoted 42 lines
common/Makefile +0 -0
 COBJS  := $(sort $(COBJS-y))
common/earlymalloc.c new file +34 -0
new file mode 100644
index 0000000..044b222
@@ -0,0 +1,91 @@
+/*
+ * (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 <earlymalloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+
+void early_heap_init(void *heap, size_t size)

common/earlymalloc.c line 44

Quoted 10 lines
common/earlymalloc.c new file +10 -0
+{
+       struct early_heap_header *h = heap;
+
+       h->free_space_pointer = (void *)(roundup((phys_addr_t)heap +
+                               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;
+}

No need for this - see below for my prefered solution...

Quoted 18 lines
common/earlymalloc.c new file +18 -0
+
+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 %08lX, free %d, required %d.",
+                       h, h->free_bytes, size);
+               return NULL;

common/earlymalloc.c line 72

Quoted 10 lines
common/earlymalloc.c new file +10 -0
+       }
+
+       /* Choose block beginning address and mark next free space. */
+       addr = h->free_space_pointer;
+
+       h->free_space_pointer += size;
+       h->free_bytes -= size;
+
+       return (void *)addr;
+}

static struct early_heap_header *def_early_brk(size_t bytes)

{
        struct early_heap_header *h;

        if(gd->early_heap_first)
                return NULL;

        /* The default implementation allocates all of the reserved space */
        bytes = CONFIG_SYS_EARLY_HEAP_SIZE;
        gd->early_heap_first = bytes;

        h = gd->early_heap_first;

        h->free_space_pointer = (void *)(roundup((phys_addr_t)h +
                                sizeof(struct early_heap_header),
                                sizeof(phys_addr_t)));
        h->free_bytes = bytes - roundup(sizeof(struct early_heap_header),
                                sizeof(phys_addr_t));
        h->next_early_heap = NULL;

        return h;
}
struct early_brk *early_brk(size_t bytes)
        __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));


        /* Find an early heap chunk with enough space. */
        h = gd->early_heap_first;
        while (h && (h->free_bytes < size))
               h = h->next_early_heap;

        /* Initialise a new early heap chunk if required*/
        if(!h) {
                h = early_brk(bytes);

                if(!h) {
                        debug("Out of early heap\n");
                        return NULL;
                }
        }

        /* Choose block beginning address and mark next free space. */
        addr = h->free_space_pointer;

        h->free_space_pointer += size;
        h->free_bytes -= size;

        return (void *)addr;
}

common/earlymalloc.c line 85

Quoted 13 lines
common/earlymalloc.c new file +13 -0
+
+
+int early_malloc_isaddress(void *addr)
+{
+       if ((phys_addr_t)addr < (phys_addr_t)gd->early_heap_first)
+               return 0;
+
+       if ((phys_addr_t)addr >= (phys_addr_t)gd->early_heap_first +
+                       CONFIG_SYS_EARLY_HEAP_SIZE)
+               return 0;
+
+       return 1;
+}

I asked about this function before - it does not seem to serve any useful purpose. And even if it did, it does not scan through the chain of early malloc chunks

common/earlymalloc.c line 90

Quoted 5 lines
common/earlymalloc.c new file +5 -0
+
+int early_malloc_finished(void)
+{
+       return gd->flags & GD_FLG_RELOC;
+}

Again, is this needed? It's not used yet, if it is needed, add it when it is and we can asses if this is the right approach then

Quoted 59 lines
common/earlymalloc.c new file +1 -0
+
include/earlymalloc.h new file +49 -1
new file mode 100644
index 0000000..3b1fac2
@@ -0,0 +1,49 @@
+/*
+ * (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_EARLYMALLOC_H
+#define __INCLUDE_EARLYMALLOC_H
+
+#include <linux/stddef.h> /* for size_t */
+
+struct early_heap_header {
+       void *free_space_pointer;
+       size_t free_bytes;
+       void *next_early_heap;
+};
+
+void early_heap_init(void *heap, size_t size);
+void *early_malloc(size_t size);
+int early_malloc_isaddress(void *addr);
+int early_malloc_finished(void);
+
+#ifndef CONFIG_SYS_EARLY_HEAP_SIZE
+#define CONFIG_SYS_EARLY_HEAP_SIZE 256
+#endif /* CONFIG_SYS_EARLY_HEAP_SIZE */
+
+#define DECLARE_EARLY_HEAP_ON_STACK char \
+       __early_heap[CONFIG_SYS_EARLY_HEAP_SIZE]; \
+       gd->early_heap_first = (void *)__early_heap
+
+#endif /* __INCLUDE_EARLYMALLOC_H */
+
--

1.7.10.4

#5 lore raw

RFC PATCH v2 1/1 DM: early_malloc for DM added.

Hi Tomas

Quoted 10 lines

static struct early_heap_header *def_early_brk(size_t bytes)

{
        struct early_heap_header *h;

        if(gd->early_heap_first)
                return NULL;

        /* The default implementation allocates all of the reserved space */
        bytes = CONFIG_SYS_EARLY_HEAP_SIZE;
        gd->early_heap_first = bytes;

Oops

gd->early_heap_first = CONFIG_SYS_EARLY_HEAP_ADDR;

Regards,

Graeme

#6 lore raw

RFC PATCH v2 1/1 DM: early_malloc for DM added.

In reply to Graeme Russ

Hi Tomas,

Another small correction...

Quoted 8 lines · Graeme Russ

static struct early_heap_header *def_early_brk(size_t bytes)

{
        struct early_heap_header *h;

        if(gd->early_heap_first)
                return NULL;

        /* The default implementation allocates all of the reserved space */

if (bytes > (CONFIG_SYS_EARLY_HEAP_SIZE -
roundup(sizeof(struct early_heap_header), sizeof(phys_addr_t)) return NULL;

Quoted 6 lines
        bytes = CONFIG_SYS_EARLY_HEAP_SIZE;
        gd->early_heap_first = bytes;

        h = gd->early_heap_first;

        h->free_space_pointer = (void *)(roundup((phys_addr_t)h +
Quoted 8 lines
                                sizeof(struct early_heap_header),
                                sizeof(phys_addr_t)));
        h->free_bytes = bytes - roundup(sizeof(struct early_heap_header),
                                sizeof(phys_addr_t));
        h->next_early_heap = NULL;

        return h;
}

Regards,

Graeme

#7 lore raw

RFC PATCH v4 1/1 DM: early_malloc for DM added.

In reply to Tomas Hlavacek

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).

---
 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
arch/arm/include/asm/config.h +3 -0
index c60dba2..8e2f67b 100644
@@ -23,4 +23,7 @@
 
 #define CONFIG_LMB
 #define CONFIG_SYS_BOOT_RAMDISK_HIGH
+
+#define CONFIG_SYS_EARLY_MALLOC
 #endif
+
arch/arm/include/asm/global_data.h +1 -0
index c3ff789..8563d49 100644
@@ -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;
 
 /*
arch/arm/lib/board.c +7 -0
index 500e216..33e74da 100644
@@ -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 */
arch/avr32/include/asm/global_data.h +1 -0
index 5c654bd..9ae7c5e 100644
@@ -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;
 
 /*
arch/avr32/lib/board.c +6 -0
index 63fe297..6c97ef7 100644
@@ -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();
arch/blackfin/include/asm/global_data.h +1 -0
index 67aa30f..33d3cec 100644
@@ -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;
 
 /*
arch/blackfin/lib/board.c +7 -0
index e3ee4cd..35257d7 100644
@@ -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();
arch/m68k/include/asm/global_data.h +1 -0
index 0ba2b43..ddd76f9 100644
@@ -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;
 
 /*
arch/m68k/lib/board.c +7 -0
index 1526967..7ee7830 100644
@@ -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 ();
arch/microblaze/include/asm/global_data.h +1 -0
index 6e8537c..4e340e6 100644
@@ -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;
 
 /*
arch/microblaze/lib/board.c +8 -0
index 9828b76..a60e36f 100644
@@ -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;
arch/mips/include/asm/global_data.h +1 -0
index f6cf9fe..9656fd6 100644
@@ -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;
 
 /*
arch/mips/lib/board.c +7 -0
index d998f0e..d2349bf 100644
@@ -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();
arch/nds32/include/asm/global_data.h +1 -0
index de20a0a..313fecb 100644
@@ -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;
 
 /*
arch/nds32/lib/board.c +6 -0
index 074aabf..952fc1f 100644
@@ -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) {
arch/nios2/include/asm/global_data.h +1 -0
index 4b86fbd..02f93d3 100644
@@ -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 */
arch/nios2/lib/board.c +6 -0
index 65de26e..8a65c2e 100644
@@ -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;
arch/openrisc/include/asm/global_data.h +1 -0
index 36de9d0..032b6b2 100644
@@ -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;
 
 /*
arch/openrisc/lib/board.c +6 -0
index 85aa189..30fca25 100644
@@ -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;
arch/powerpc/include/asm/global_data.h +1 -0
index 01f1d4a..0839d03 100644
@@ -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;
 
 /*
arch/powerpc/lib/board.c +6 -0
index 3f9af1d..41ee9db 100644
@@ -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();
arch/sandbox/include/asm/global_data.h +1 -0
index 8d47191..54342c0 100644
@@ -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;
 
 /*
arch/sandbox/lib/board.c +6 -0
index b7997e9..055e493 100644
@@ -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();
arch/sh/include/asm/global_data.h +1 -0
index 1b782fc..180f56e 100644
@@ -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		*/
arch/sh/lib/board.c +6 -0
index d9c0c22..7d334f4 100644
@@ -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 */
arch/sparc/include/asm/global_data.h +1 -0
index 613e2d8..82ed56f 100644
@@ -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;
 
 /*
arch/sparc/lib/board.c +6 -0
index 519a4fb..3421412 100644
@@ -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;
arch/x86/include/asm/global_data.h +1 -0
index 908a02c..171f85b 100644
@@ -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)
arch/x86/lib/board.c +14 -0
index 5f0b62c..b609dbe 100644
@@ -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,
common/Makefile +1 -0
index 2a31c62..dfea4e8 100644
@@ -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))
common/dmmalloc.c new file +128 -0

128 lines not on this page · raw message

include/configs/zipitz2.h +11 -1
index 26204af..5cd0dcb 100644
@@ -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 */
include/dmmalloc.h new file +51 -0

51 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#8 lore raw

RFC PATCH v4 1/1 DM: early_malloc for DM added.

Dear Tomas Hlavacek,

Quoted 8 lines

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).

---

It looks mostly OK, few comments

I'd say, pull out the modification of global data into separate patch and put it before this patch. That'd make review of the core code much easier.

[...]

Quoted 20 lines
common/dmmalloc.c new file +20 -0
+
+#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),

common/dmmalloc.c line 52

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+				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")));

what about using (it needs <linux/compiler.h>):

__weak struct early_heap_header *early_brk(size_t size) {
...
body
...
}

Quoted 34 lines
common/dmmalloc.c new file +34 -0
+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;

common/dmmalloc.c line 98

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+}
+
+#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 */

Or you can implement empty prototypes for these functions in case CONFIG_SYS ... isn't defined to punt this preprocessor bloat.

Quoted 2 lines
(quoted diff) +2 -0
+	return malloc(size);
+}

[...]

include/configs/zipitz2.h unsigned char zipitz2_spi_read(void); · line 182

Quoted 12 lines
include/configs/zipitz2.h +4 -0
index 26204af..5cd0dcb 100644
@@ -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
+

1) Pull this file into separate patch and order it afterwards this patch.
2) You're putting your early thingie into SDRAM, which works on PXA (sadly) ... looking through the PXA init code, it needs cleanup, damn

... there's no real hint so far, just a rant.

include/configs/zipitz2.h unsigned char zipitz2_spi_read(void); · line 180

Quoted 2 lines
include/configs/zipitz2.h +0 -1
 #define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
-#define	CONFIG_SYS_INIT_SP_ADDR		(GENERATED_GBL_DATA_SIZE + 

PHYS_SDRAM_1 +

Quoted 1 line

2048) +#define CONFIG_SYS_INIT_SP_ADDR (GENERATED_GBL_DATA_SIZE

+ \

Quoted 7 lines
include/configs/zipitz2.h +1 -0
+	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

[...]

#9 lore raw

RFC PATCH v4 1/1 DM: early_malloc for DM added.

Hi Marek,

Quoted 8 lines · Marek Vasut

Dear Tomas Hlavacek,

Quoted 6 lines

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).

Quoted 7 lines
Quoted 2 lines

---

It looks mostly OK, few comments

I'd say, pull out the modification of global data into separate patch and put it before this patch. That'd make review of the core code much easier.

NAK - The addition of the global data member is intrinsic to the early malloc implmentaion. Keep them together

Quoted 36 lines

[...]

Quoted 20 lines
common/dmmalloc.c new file +20 -0
+
+#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),

common/dmmalloc.c line 52

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+                             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")));

what about using (it needs <linux/compiler.h>):

Quoted 6 lines

__weak struct early_heap_header *early_brk(size_t size) {
...
body
...
}

We already have a lot of the former - I prefer not to add additional semantics (unless you want to do a wholesale search/replace ;))

Quoted 9 lines

common/dmmalloc.c line 98

Quoted 6 lines
common/dmmalloc.c new file +6 -0
+void *dmmalloc(size_t size)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+     if (is_early_malloc_active())
+             return early_malloc(size);
+#endif /* CONFIG_SYS_EARLY_MALLOC */

Or you can implement empty prototypes for these functions in case CONFIG_SYS ... isn't defined to punt this preprocessor bloat.

Agree

Quoted 12 lines
Quoted 3 lines
(quoted diff) +2 -0
+     return malloc(size);
+}

[...]

Quoted 6 lines
include/configs/zipitz2.h +0 -0
index 26204af..5cd0dcb 100644
@@ -176,8 +176,13 @@ unsigned char zipitz2_spi_read(void);
 
Quoted 8 lines

include/configs/zipitz2.h unsigned char zipitz2_spi_read(void); · line 182

Quoted 6 lines
include/configs/zipitz2.h +4 -0
 #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
+

1) Pull this file into separate patch and order it afterwards this patch.

Already agreed :)

Regards,

Graeme

#10 lore raw

RFC PATCH v4 1/1 DM: early_malloc for DM added.

Dear Graeme Russ,

Quoted 14 lines

Hi Marek,

Quoted 11 lines · Marek Vasut

Dear Tomas Hlavacek,

Quoted 8 lines

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).

---

Quoted 8 lines
Quoted 5 lines

It looks mostly OK, few comments

I'd say, pull out the modification of global data into separate patch and put it before this patch. That'd make review of the core code much easier.

NAK - The addition of the global data member is intrinsic to the early malloc implmentaion. Keep them together

Very pleasant to review too, I almost didn't manage to find the core dmmalloc code in all that bloat.

Quoted 42 lines
Quoted 35 lines

[...]

Quoted 20 lines
common/dmmalloc.c new file +20 -0
+
+#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),

common/dmmalloc.c line 52

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+                             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")));

what about using (it needs <linux/compiler.h>):

Quoted 6 lines

__weak struct early_heap_header *early_brk(size_t size) {
...
body
...
}

Quoted 2 lines

We already have a lot of the former - I prefer not to add additional semantics (unless you want to do a wholesale search/replace ;))

The former looks like shit and the later is more linux-friendly. I'd say stick with the later to avoid this insane __attribute__(()) construct.

Quoted 32 lines
Quoted 9 lines

common/dmmalloc.c line 98

Quoted 6 lines
common/dmmalloc.c new file +6 -0
+void *dmmalloc(size_t size)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+     if (is_early_malloc_active())
+             return early_malloc(size);
+#endif /* CONFIG_SYS_EARLY_MALLOC */

Or you can implement empty prototypes for these functions in case CONFIG_SYS ... isn't defined to punt this preprocessor bloat.

Agree

Quoted 11 lines
Quoted 2 lines
(quoted diff) +2 -0
+     return malloc(size);
+}

[...]

Quoted 6 lines
include/configs/zipitz2.h +0 -0
index 26204af..5cd0dcb 100644
@@ -176,8 +176,13 @@ unsigned char zipitz2_spi_read(void);
 
Quoted 8 lines

include/configs/zipitz2.h unsigned char zipitz2_spi_read(void); · line 182

Quoted 6 lines
include/configs/zipitz2.h +4 -0
 #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
+

1) Pull this file into separate patch and order it afterwards this patch.

Quoted 5 lines

Already agreed :)

Regards,

Graeme

Best regards,
Marek Vasut

#11 lore raw

RFC PATCH v4 1/1 DM: early_malloc for DM added.

Hi Marek,

Quoted 2 lines · Marek Vasut

Dear Graeme Russ,

[snip]

Quoted 12 lines
Quoted 12 lines
Quoted 11 lines

common/dmmalloc.c line 52

Quoted 2 lines
common/dmmalloc.c new file +2 -0
+struct early_heap_header *early_brk(size_t size)
+     __attribute__((weak, alias("def_early_brk")));

what about using (it needs <linux/compiler.h>):

__weak struct early_heap_header *early_brk(size_t size) {
...
body
...
}

Quoted 5 lines
Quoted 2 lines

We already have a lot of the former - I prefer not to add additional semantics (unless you want to do a wholesale search/replace ;))

The former looks like shit and the later is more linux-friendly. I'd say stick with the later to avoid this insane __attribute__(()) construct.

I agree, but, consistently bad is worse than inconsistently bad :)

I'm look forward to reviewing a cleanup patch ;)

Regards,

Graeme

#12 lore raw

RFC PATCH v4 1/1 DM: early_malloc for DM added.

Dear Graeme Russ,

Quoted 19 lines

Hi Marek,

Quoted 1 line · Marek Vasut

Dear Graeme Russ,

[snip]

Quoted 12 lines
Quoted 12 lines
Quoted 11 lines

common/dmmalloc.c line 52

Quoted 2 lines
common/dmmalloc.c new file +2 -0
+struct early_heap_header *early_brk(size_t size)
+     __attribute__((weak, alias("def_early_brk")));

what about using (it needs <linux/compiler.h>):

__weak struct early_heap_header *early_brk(size_t size) {
...
body
...
}

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

We already have a lot of the former - I prefer not to add additional semantics (unless you want to do a wholesale search/replace ;))

The former looks like shit and the later is more linux-friendly. I'd say stick with the later to avoid this insane __attribute__(()) construct.

I agree, but, consistently bad is worse than inconsistently bad :)

To weed out the old crap, we need linux/compiler.h enabled across whole uboot ... it's in the todo.

Quoted 1 line

I'm look forward to reviewing a cleanup patch ;)

Wait until I get it completely built. linux/compiler.h causes breakage on some ancient PPC crap.

Quoted 3 lines

Regards,

Graeme

Best regards,
Marek Vasut

#13 lore raw

RFC PATCH v4 1/1 DM: early_malloc for DM added.

In reply to Graeme Russ
Quoted 4 lines · Graeme Russ

Hi Marek,

Quoted 1 line · Marek Vasut

Dear Tomas Hlavacek,

[snip]

Quoted 12 lines
Quoted 11 lines

common/dmmalloc.c line 52

Quoted 2 lines
common/dmmalloc.c new file +2 -0
+struct early_heap_header *early_brk(size_t size)
+     __attribute__((weak, alias("def_early_brk")));

what about using (it needs <linux/compiler.h>):

__weak struct early_heap_header *early_brk(size_t size) {
...
body
...
}

Quoted 2 lines

We already have a lot of the former - I prefer not to add additional semantics (unless you want to do a wholesale search/replace ;))

Migrating everyone but the real tricky uses (alias >=2 functions to one weak dummy) to the <linux/compiler.h> semantics is something on my TODO list from ages ago. So yes please, unless it's a complex case, find and use the __shortform that <linux/compiler.h> and company provide (and a git grep for your attribute when in doubt, sometimes it's in <linux/compiler-gcc.h or so).

And a general I know everyone should know but please, checkpatch.pl your work before posting. Getting everyone doing DM series patches to use patman might be a little bit more overhead (sorry!) but it'll help with a lot of the little things like formatting and some of the bigger things like changelog tracking. Don't have to switch but it might make your lives easier.

Signature · 1 line
Tom
#14 lore raw

RFC PATCH v4 1/1 DM: early_malloc for DM added.

In reply to Graeme Russ

Hello all,

I have sent a new version. Although I tried to take into account all the opinions and comments I might have missed something.

Quoted 6 lines · Graeme Russ
Quoted 3 lines

I'd say, pull out the modification of global data into separate patch and put it before this patch. That'd make review of the core code much easier.

NAK - The addition of the global data member is intrinsic to the early malloc implmentaion. Keep them together

Yes, I think that in this case one does not make sense with the other. I kept them rather together.

Quoted 14 lines
Quoted 7 lines

common/dmmalloc.c line 52

Quoted 4 lines
common/dmmalloc.c new file +3 -0
+
+struct early_heap_header *early_brk(size_t size)
+     __attribute__((weak, alias("def_early_brk")));

what about using (it needs <linux/compiler.h>):

Quoted 6 lines

__weak struct early_heap_header *early_brk(size_t size) {
...
body
...
}

Quoted 2 lines

We already have a lot of the former - I prefer not to add additional semantics (unless you want to do a wholesale search/replace ;))

This time I used the shorter / newer variant. Hope this would be better.

Tomas

Signature · 1 line
Tom?? Hlav??ek <[email protected]>
#15 lore raw

RFC PATCH v4 1/1 DM: early_malloc for DM added.

In reply to Tomas Hlavacek

Hi Tomas

Quoted 2 lines · Tomas Hlavacek

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

Technically, you are not putting the first heap on the stack - you are sacrificing some early stack space to create the early heap

Quoted 30 lines

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

---
 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 +
Quoted 8 lines
 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 ++-

WTF! - Move this out into another patch

Quoted 10 lines
 include/dmmalloc.h                        |   51 ++++++++++++
 33 files changed, 306 insertions(+), 1 deletion(-)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/config.h +0 -0
index c60dba2..8e2f67b 100644

arch/arm/include/asm/config.h line 29

Quoted 7 lines
arch/arm/include/asm/config.h +3 -0
@@ -23,4 +23,7 @@
 
 #define CONFIG_LMB
 #define CONFIG_SYS_BOOT_RAMDISK_HIGH
+
+#define CONFIG_SYS_EARLY_MALLOC
 #endif
+

Why are you adding this define to ARM and nothing else? Shouldn't it be an all-in or none-in proposition?

(and why the stray eol white-space?)

arch/arm/include/asm/global_data.h typedef struct global_data { · line 88

Quoted 10 lines
arch/arm/include/asm/global_data.h +1 -0
index c3ff789..8563d49 100644
@@ -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;

early_heap_first is only used if CONFIG_SYS_EARLY_MALLOC is defined, so wrap a #ifdef around it. This will also help to detect unintended usage if CONFIG_SYS_EARLY_MALLOC is not defined.

Quoted 15 lines
arch/arm/include/asm/global_data.h +0 -0
 /*
arch/arm/lib/board.c +1 -0
index 500e216..33e74da 100644
@@ -52,6 +52,7 @@
 #include <fdtdec.h>
 #include <post.h>
 #include <logbuff.h>
+#include <dmmalloc.h>
 
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>

arch/arm/lib/board.c void board_init_f(ulong bootflag) · line 282

Quoted 9 lines
arch/arm/lib/board.c +6 -0
@@ -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 */
+

Did you checkpatch? You've added an additional blank line (for a total of two)

[snip]

Quoted 32 lines
arch/x86/lib/board.c +13 -0
index 5f0b62c..b609dbe 100644
@@ -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:

arch/x86/lib/board.c init_fnc_t *init_sequence_f[] = { · line 115

Quoted 4 lines
arch/x86/lib/board.c +1 -0
@@ -99,6 +112,7 @@ init_fnc_t *init_sequence_f[] = {
        cpu_init_f,
        board_early_init_f,
        env_init,
+       early_malloc_init,

Put the #ifdef here - gc_sections will clean up the unused function

common/Makefile COBJS-y += console.o · line 191

Quoted 12 lines
arch/x86/lib/board.c +0 -0
        init_baudrate_f,
        serial_init,
        console_init_f,
common/Makefile +1 -0
index 2a31c62..dfea4e8 100644
@@ -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-$(CONFIG_SYS_EARLY_MALLOC)

or

COBJS-$(CONFIG_SYS_DM)

If DM mandates early_malloc (which I think it will) then we need to tie the #defines together somehow

Quoted 24 lines
common/Makefile +0 -0
 COBJS  := $(sort $(COBJS-y))
common/dmmalloc.c new file +17 -0
new file mode 100644
index 0000000..18f2d95
@@ -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.
+ *

common/dmmalloc.c line 27

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+ * 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 */

Drop the comments - they are ugly

Quoted 31 lines
common/dmmalloc.c new file +31 -0
+
+#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;

common/dmmalloc.c line 68

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+
+       /* 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) {

You will get a NULL-pointer exception if no early heap has enough space

You also need to add some logic to allocate an additional early heap by calling early_brk. If that call fails (returns NULL) then bail out

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+               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;

common/dmmalloc.c line 88

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+
+       return (void *)addr;
+}
+
+static int is_early_malloc_active(void)
+{
+       if (gd->flags & GD_FLG_RELOC)
+               return 0;
+
+       return 1;

Hmmm, return ((gd->flags & GD_FLG_RELOC) == GD_FLG_RELOC); ?

I also prefer the semantics of not having 'is_'. "if blah" reads better to me than "if is blah" - YMMV

common/dmmalloc.c line 100

Quoted 12 lines
common/dmmalloc.c new file +12 -0
+}
+
+#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);
+}

The argument over dmmalloc() versus transparent malloc() is far from over IMNSHO, but for now, this will have to do :)

Quoted 18 lines
common/dmmalloc.c new file +18 -0
+
+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);
+}

common/dmmalloc.c line 128

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+
+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);
+}
+

[snip]

Regards,

Graeme

#16 lore raw

RFC PATCH v5 1/1 early_malloc for DM added.

In reply to Tomas Hlavacek

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

---
 arch/arm/include/asm/global_data.h        |    3 +
 arch/arm/lib/board.c                      |    8 ++
 arch/avr32/include/asm/global_data.h      |    3 +
 arch/avr32/lib/board.c                    |    9 ++
 arch/blackfin/include/asm/global_data.h   |    3 +
 arch/blackfin/lib/board.c                 |    8 ++
 arch/m68k/include/asm/global_data.h       |    3 +
 arch/m68k/lib/board.c                     |    8 ++
 arch/microblaze/include/asm/global_data.h |    3 +
 arch/microblaze/lib/board.c               |    9 ++
 arch/mips/include/asm/global_data.h       |    3 +
 arch/mips/lib/board.c                     |    8 ++
 arch/nds32/include/asm/global_data.h      |    3 +
 arch/nds32/lib/board.c                    |    8 ++
 arch/nios2/include/asm/global_data.h      |    3 +
 arch/nios2/lib/board.c                    |    8 ++
 arch/openrisc/include/asm/global_data.h   |    3 +
 arch/openrisc/lib/board.c                 |    8 ++
 arch/powerpc/include/asm/global_data.h    |    3 +
 arch/powerpc/lib/board.c                  |    8 ++
 arch/sandbox/include/asm/global_data.h    |    3 +
 arch/sandbox/lib/board.c                  |    8 ++
 arch/sh/include/asm/global_data.h         |    3 +
 arch/sh/lib/board.c                       |    8 ++
 arch/sparc/include/asm/global_data.h      |    3 +
 arch/sparc/lib/board.c                    |    8 ++
 arch/x86/include/asm/global_data.h        |    3 +
 arch/x86/lib/board.c                      |   18 ++++
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |  140 +++++++++++++++++++++++++++++
 include/dmmalloc.h                        |   56 ++++++++++++
 31 files changed, 363 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/global_data.h +3 -0
index f8088fe..ef727b0 100644
@@ -82,6 +82,9 @@ 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
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/arm/lib/board.c +8 -0
index f1951e8..2157a5d 100644
@@ -53,6 +53,10 @@
 #include <post.h>
 #include <logbuff.h>
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
 #endif
@@ -281,6 +285,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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 */
arch/avr32/include/asm/global_data.h +3 -0
index 7878bb1..0654a61 100644
@@ -48,6 +48,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/avr32/lib/board.c +9 -0
index d7a64b4..14ec278 100644
@@ -42,6 +42,11 @@
 #ifdef CONFIG_GENERIC_ATMEL_MCI
 #include <mmc.h>
 #endif
+
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 unsigned long monitor_flash_len;
@@ -161,6 +166,10 @@ void board_init_f(ulong board_type)
 	memset(&gd_data, 0, sizeof(gd_data));
 	gd = &gd_data;
 
+#ifdef CONFIG_SYS_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();
arch/blackfin/include/asm/global_data.h +3 -0
index 290a9e7..2ae395c 100644
@@ -57,6 +57,9 @@ typedef struct global_data {
 
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/blackfin/lib/board.c +8 -0
index c380d27..bb19bdd 100644
@@ -37,6 +37,10 @@
 int post_flag;
 #endif
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 __attribute__((always_inline))
@@ -267,6 +271,10 @@ void board_init_f(ulong bootflag)
 	watchdog_init();
 #endif
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 #ifdef DEBUG
 	if (GENERATED_GBL_DATA_SIZE < sizeof(*gd))
 		hang();
arch/m68k/include/asm/global_data.h +3 -0
index cd55b83..bd30435 100644
@@ -66,6 +66,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/m68k/lib/board.c +8 -0
index 65a8595..8815605 100644
@@ -69,6 +69,10 @@
 
 #include <nand.h>
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static char *failed = "*** failed ***\n";
@@ -227,6 +231,10 @@ board_init_f (ulong bootflag)
 	/* Clear initial global data */
 	memset ((void *) gd, 0, sizeof (gd_t));
 
+#ifdef CONFIG_SYS_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 ();
arch/microblaze/include/asm/global_data.h +3 -0
index de3b8db..6f4066d 100644
@@ -46,6 +46,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/microblaze/lib/board.c +9 -0
index 674b573..869a3ea 100644
@@ -37,6 +37,10 @@
 #include <asm/microblaze_intc.h>
 #include <fdtdec.h>
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -81,6 +85,11 @@ void board_init_f(ulong not_used)
 	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
+	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;
arch/mips/include/asm/global_data.h +3 -0
index 6e2cdc7..ac24e3f 100644
@@ -59,6 +59,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/mips/lib/board.c +8 -0
index 62d47a8..d9ae49f 100644
@@ -36,6 +36,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong monitor_flash_len;
@@ -153,6 +157,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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();
arch/nds32/include/asm/global_data.h +3 -0
index 94bd4c2..d0e2606 100644
@@ -63,6 +63,9 @@ typedef	struct global_data {
 
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nds32/lib/board.c +8 -0
index 2164a50..9c9be4e 100644
@@ -37,6 +37,10 @@
 #include <onenand_uboot.h>
 #include <mmc.h>
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong monitor_flash_len;
@@ -192,6 +196,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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) {
arch/nios2/include/asm/global_data.h +3 -0
index 3b0d9e6..44373f4 100644
@@ -42,6 +42,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nios2/lib/board.c +8 -0
index 1e495d4..96d3827 100644
@@ -40,6 +40,10 @@
 #include <nand.h>	/* cannot even include nand.h if it isnt configured */
 #endif
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -95,6 +99,10 @@ void board_init (void)
 	/* compiler optimization barrier needed for GCC >= 3.4 */
 	__asm__ __volatile__("": : :"memory");
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	gd->bd = &bd_data;
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
arch/openrisc/include/asm/global_data.h +3 -0
index 6a0c0cc..ec2220a 100644
@@ -44,6 +44,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/openrisc/lib/board.c +8 -0
index 85aa189..527de09 100644
@@ -44,6 +44,10 @@
 #include <timestamp.h>
 #include <version.h>
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -86,6 +90,10 @@ void board_init(void)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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;
arch/powerpc/include/asm/global_data.h +3 -0
index 5a5877f..38b63f9 100644
@@ -182,6 +182,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/powerpc/lib/board.c +8 -0
index fea310e..dbf0520 100644
@@ -87,6 +87,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 #ifdef CONFIG_SYS_UPDATE_FLASH_SIZE
 extern int update_flash_size(int flash_size);
 #endif
@@ -389,6 +393,10 @@ void board_init_f(ulong bootflag)
 	memset((void *) gd, 0, sizeof(gd_t));
 #endif
 
+#ifdef CONFIG_SYS_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();
arch/sandbox/include/asm/global_data.h +3 -0
index 581fd2f..00c7c10 100644
@@ -46,6 +46,9 @@ typedef	struct global_data {
 	const void	*fdt_blob;	/* Our device tree, NULL if none */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sandbox/lib/board.c +8 -0
index c173bf9..da4e3ea 100644
@@ -47,6 +47,10 @@
 
 #include <os.h>
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static gd_t gd_mem;
@@ -157,6 +161,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 #if defined(CONFIG_OF_EMBED)
 	/* Get a pointer to the FDT */
 	gd->fdt_blob = _binary_dt_dtb_start;
arch/sh/include/asm/global_data.h +3 -0
index 6e534ad..441fecd 100644
@@ -42,6 +42,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sh/lib/board.c +8 -0
index 34d7881..2cf94d3 100644
@@ -32,6 +32,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 extern int cpu_init(void);
@@ -150,6 +154,10 @@ void sh_generic_init(void)
 
 	memset(gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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 */
arch/sparc/include/asm/global_data.h +3 -0
index 93d3cc0..537e09a 100644
@@ -74,6 +74,9 @@ typedef struct global_data {
 #endif
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sparc/lib/board.c +8 -0
index 6f33666..5a45d7c 100644
@@ -53,6 +53,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /* Debug options
@@ -178,6 +182,10 @@ void board_init_f(ulong bootflag)
 	/* Clear initial global data */
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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;
arch/x86/include/asm/global_data.h +3 -0
index 6d29c0b..920a805 100644
@@ -57,6 +57,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 static inline gd_t *get_fs_gd_ptr(void)
arch/x86/lib/board.c +18 -0
index 90cf7fc..e21c9af 100644
@@ -40,6 +40,10 @@
 #include <asm/init_helpers.h>
 #include <asm/init_wrappers.h>
 
+#ifdef CONFIG_SYS_DM
+#include <dmmalloc.h>
+#endif
+
 /*
  * Breath some life into the board...
  *
@@ -85,6 +89,17 @@
 typedef int (init_fnc_t) (void);
 
 /*
+ * Initialize early heap (when enabled by config).
+ */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+static void early_malloc_init(void)
+{
+	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 +114,9 @@ init_fnc_t *init_sequence_f[] = {
 	cpu_init_f,
 	board_early_init_f,
 	env_init,
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	early_malloc_init,
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 	init_baudrate_f,
 	serial_init,
 	console_init_f,
common/Makefile +1 -0
index 22e8a6f..e0bea58 100644
@@ -201,6 +201,7 @@ COBJS-y += dlmalloc.o
 COBJS-y += image.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-$(CONFIG_SYS_DM) += dmmalloc.o
 
 
 COBJS	:= $(sort $(COBJS-y))
common/dmmalloc.c new file +140 -0

140 lines not on this page · raw message

include/dmmalloc.h new file +56 -0

56 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#17 lore raw

RFC PATCH v5 1/1 early_malloc for DM added.

Dear Tomas Hlavacek,

Quoted 7 lines

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

[...]

Quoted 3 lines
 31 files changed, 363 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h

What exactly changed in this version? Changelog is missing.

[...]

common/dmmalloc.c line 91

Quoted 4 lines
common/dmmalloc.c new file +4 -0
+static int early_malloc_active(void)
+{
+	if ((gd->flags & GD_FLG_RELOC) == GD_FLG_RELOC)
+		return 0;

Did you completely ignore the comments?

common/dmmalloc.c line 105

Quoted 13 lines
common/dmmalloc.c new file +13 -0
+	return 1;
+}
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void *dmmalloc(size_t size)
+{
+	if (early_malloc_active())
+		return early_malloc(size);
+	return malloc(size);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmmalloc malloc

How is this actually supposed to work?

Quoted 78 lines
common/dmmalloc.c new file +35 -0
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void dmfree(void *ptr)
+{
+	if (early_malloc_active())
+		return;
+	free(ptr);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmfree free
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void *dmcalloc(size_t n, size_t elem_size)
+{
+	if (early_malloc_active())
+		return NULL;
+	return calloc(n, elem_size);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmcalloc calloc
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void *dmrealloc(void *oldmem, size_t bytes)
+{
+	if (early_malloc_active())
+		return NULL;
+	return dmrealloc(oldmem, bytes);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmrealloc realloc
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
include/dmmalloc.h new file +37 -0
new file mode 100644
index 0000000..726c6c9
@@ -0,0 +1,56 @@
+/*
+ * (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;

include/dmmalloc.h line 47

Quoted 10 lines
include/dmmalloc.h new file +10 -0
+	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 */
+
+#ifdef CONFIG_SYS_DM

Isn't it CONFIG_DM ?

Quoted 9 lines
include/dmmalloc.h new file +9 -0
+void *dmmalloc(size_t size);
+void dmfree(void *ptr);
+void *dmcalloc(size_t n, size_t elem_size);
+void *dmrealloc(void *oldmem, size_t bytes);
+#endif /* CONFIG_SYS_DM */
+
+
+#endif /* __INCLUDE_DMMALLOC_H */
+
#18 lore raw

RFC PATCH v5 1/1 early_malloc for DM added.

Hello Marek,

Quoted 8 lines · Marek Vasut

Dear Tomas Hlavacek,

Quoted 6 lines

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

Quoted 7 lines
Quoted 1 line

[...]

Quoted 3 lines
 31 files changed, 363 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h

What exactly changed in this version? Changelog is missing.

Preprocessor config-dependent (ifdef ... endif) blocks are different. early_brk call from early_malloc when the heaps are full. default early_brk checks existing heap for before setting.

Quoted 9 lines

[...]

common/dmmalloc.c line 91

Quoted 4 lines
common/dmmalloc.c new file +4 -0
+static int early_malloc_active(void)
+{
+     if ((gd->flags & GD_FLG_RELOC) == GD_FLG_RELOC)
+             return 0;

Did you completely ignore the comments?

Yes, this is ugly and I did not notice the point of (your?) comment while reworking this tiny part again and again... Sorry.

Quoted 16 lines
Quoted 4 lines
common/dmmalloc.c new file +3 -0
+     return 1;
+}
+#endif /* CONFIG_SYS_EARLY_MALLOC */

common/dmmalloc.c line 105

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void *dmmalloc(size_t size)
+{
+     if (early_malloc_active())
+             return early_malloc(size);
+     return malloc(size);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmmalloc malloc

How is this actually supposed to work?

Of course, this have to be in the header file dmmalloc.h. Just ignore the #else ... #endif part.

Quoted 83 lines
Quoted 83 lines
common/dmmalloc.c new file +35 -0
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void dmfree(void *ptr)
+{
+     if (early_malloc_active())
+             return;
+     free(ptr);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmfree free
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void *dmcalloc(size_t n, size_t elem_size)
+{
+     if (early_malloc_active())
+             return NULL;
+     return calloc(n, elem_size);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmcalloc calloc
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void *dmrealloc(void *oldmem, size_t bytes)
+{
+     if (early_malloc_active())
+             return NULL;
+     return dmrealloc(oldmem, bytes);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmrealloc realloc
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
include/dmmalloc.h new file +41 -0
new file mode 100644
index 0000000..726c6c9
@@ -0,0 +1,56 @@
+/*
+ * (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;
+};
+
Quoted 8 lines

include/dmmalloc.h line 47

Quoted 6 lines
include/dmmalloc.h new file +6 -0
+struct early_heap_header *early_brk(size_t size);
+void *early_malloc(size_t size);
+
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_DM

Isn't it CONFIG_DM ?

I will change that. (Is it consistent with the naming convention? I
mean: What the "_SYS_" exactly means?)

Tomas

#19 lore raw

RFC PATCH v5 1/1 early_malloc for DM added.

Dear Tomas Hlavacek,

Quoted 34 lines

Hello Marek,

Quoted 10 lines · Marek Vasut

Dear Tomas Hlavacek,

Quoted 7 lines

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

Quoted 7 lines

[...]

Quoted 3 lines
 31 files changed, 363 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h

What exactly changed in this version? Changelog is missing.

Preprocessor config-dependent (ifdef ... endif) blocks are different. early_brk call from early_malloc when the heaps are full. default early_brk checks existing heap for before setting.

Quoted 8 lines

[...]

common/dmmalloc.c line 91

Quoted 4 lines
common/dmmalloc.c new file +4 -0
+static int early_malloc_active(void)
+{
+     if ((gd->flags & GD_FLG_RELOC) == GD_FLG_RELOC)
+             return 0;

Did you completely ignore the comments?

Quoted 2 lines

Yes, this is ugly and I did not notice the point of (your?) comment while reworking this tiny part again and again... Sorry.

I think it was GR.

Quoted 16 lines
Quoted 7 lines
Quoted 7 lines
common/dmmalloc.c new file +7 -0
+     return 1;
+}
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void *dmmalloc(size_t size)
+{
Quoted 8 lines

common/dmmalloc.c line 105

Quoted 6 lines
common/dmmalloc.c new file +6 -0
+     if (early_malloc_active())
+             return early_malloc(size);
+     return malloc(size);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmmalloc malloc

How is this actually supposed to work?

Quoted 2 lines

Of course, this have to be in the header file dmmalloc.h. Just ignore the #else ... #endif part.

That won't work well either ... I'd say make the wrapper static inline for typechecking, no ?

Quoted 91 lines
Quoted 82 lines
Quoted 82 lines
common/dmmalloc.c new file +35 -0
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void dmfree(void *ptr)
+{
+     if (early_malloc_active())
+             return;
+     free(ptr);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmfree free
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void *dmcalloc(size_t n, size_t elem_size)
+{
+     if (early_malloc_active())
+             return NULL;
+     return calloc(n, elem_size);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmcalloc calloc
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+void *dmrealloc(void *oldmem, size_t bytes)
+{
+     if (early_malloc_active())
+             return NULL;
+     return dmrealloc(oldmem, bytes);
+}
+#else /* CONFIG_SYS_EARLY_MALLOC */
+#define dmrealloc realloc
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
include/dmmalloc.h new file +41 -0
new file mode 100644
index 0000000..726c6c9
@@ -0,0 +1,56 @@
+/*
+ * (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;
+};
+
Quoted 8 lines

include/dmmalloc.h line 47

Quoted 6 lines
include/dmmalloc.h new file +6 -0
+struct early_heap_header *early_brk(size_t size);
+void *early_malloc(size_t size);
+
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_SYS_DM

Isn't it CONFIG_DM ?

Quoted 4 lines

I will change that. (Is it consistent with the naming convention? I
mean: What the "_SYS_" exactly means?)

Tomas

Best regards,
Marek Vasut

#20 lore raw

RFC PATCH v6 1/1 early_malloc for DM added.

In reply to Tomas Hlavacek

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

---

Changelog since v5:
dmmalloc() and all dm* functions has been moved to header, made static inline and preprocessor-dependent blocks are reworked. early_malloc_active() corrected and made not static. s/CONFIG_SYS_DM/CONFIG_DM/ applied.

 arch/arm/include/asm/global_data.h        |    3 +
 arch/arm/lib/board.c                      |    8 +++
 arch/avr32/include/asm/global_data.h      |    3 +
 arch/avr32/lib/board.c                    |    9 +++
 arch/blackfin/include/asm/global_data.h   |    3 +
 arch/blackfin/lib/board.c                 |    8 +++
 arch/m68k/include/asm/global_data.h       |    3 +
 arch/m68k/lib/board.c                     |    8 +++
 arch/microblaze/include/asm/global_data.h |    3 +
 arch/microblaze/lib/board.c               |    9 +++
 arch/mips/include/asm/global_data.h       |    3 +
 arch/mips/lib/board.c                     |    8 +++
 arch/nds32/include/asm/global_data.h      |    3 +
 arch/nds32/lib/board.c                    |    8 +++
 arch/nios2/include/asm/global_data.h      |    3 +
 arch/nios2/lib/board.c                    |    8 +++
 arch/openrisc/include/asm/global_data.h   |    3 +
 arch/openrisc/lib/board.c                 |    8 +++
 arch/powerpc/include/asm/global_data.h    |    3 +
 arch/powerpc/lib/board.c                  |    8 +++
 arch/sandbox/include/asm/global_data.h    |    3 +
 arch/sandbox/lib/board.c                  |    8 +++
 arch/sh/include/asm/global_data.h         |    3 +
 arch/sh/lib/board.c                       |    8 +++
 arch/sparc/include/asm/global_data.h      |    3 +
 arch/sparc/lib/board.c                    |    8 +++
 arch/x86/include/asm/global_data.h        |    3 +
 arch/x86/lib/board.c                      |   18 ++++++
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |   93 +++++++++++++++++++++++++++++
 include/dmmalloc.h                        |   89 +++++++++++++++++++++++++++
 31 files changed, 349 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/global_data.h +3 -0
index f8088fe..ef727b0 100644
@@ -82,6 +82,9 @@ 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
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/arm/lib/board.c +8 -0
index f1951e8..f73d8b2 100644
@@ -53,6 +53,10 @@
 #include <post.h>
 #include <logbuff.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
 #endif
@@ -281,6 +285,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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 */
arch/avr32/include/asm/global_data.h +3 -0
index 7878bb1..0654a61 100644
@@ -48,6 +48,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/avr32/lib/board.c +9 -0
index d7a64b4..f1bd946 100644
@@ -42,6 +42,11 @@
 #ifdef CONFIG_GENERIC_ATMEL_MCI
 #include <mmc.h>
 #endif
+
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 unsigned long monitor_flash_len;
@@ -161,6 +166,10 @@ void board_init_f(ulong board_type)
 	memset(&gd_data, 0, sizeof(gd_data));
 	gd = &gd_data;
 
+#ifdef CONFIG_SYS_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();
arch/blackfin/include/asm/global_data.h +3 -0
index 290a9e7..2ae395c 100644
@@ -57,6 +57,9 @@ typedef struct global_data {
 
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/blackfin/lib/board.c +8 -0
index c380d27..96b7d76 100644
@@ -37,6 +37,10 @@
 int post_flag;
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 __attribute__((always_inline))
@@ -267,6 +271,10 @@ void board_init_f(ulong bootflag)
 	watchdog_init();
 #endif
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 #ifdef DEBUG
 	if (GENERATED_GBL_DATA_SIZE < sizeof(*gd))
 		hang();
arch/m68k/include/asm/global_data.h +3 -0
index cd55b83..bd30435 100644
@@ -66,6 +66,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/m68k/lib/board.c +8 -0
index 65a8595..1b9312c 100644
@@ -69,6 +69,10 @@
 
 #include <nand.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static char *failed = "*** failed ***\n";
@@ -227,6 +231,10 @@ board_init_f (ulong bootflag)
 	/* Clear initial global data */
 	memset ((void *) gd, 0, sizeof (gd_t));
 
+#ifdef CONFIG_SYS_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 ();
arch/microblaze/include/asm/global_data.h +3 -0
index de3b8db..6f4066d 100644
@@ -46,6 +46,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/microblaze/lib/board.c +9 -0
index 674b573..eeb8441 100644
@@ -37,6 +37,10 @@
 #include <asm/microblaze_intc.h>
 #include <fdtdec.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -81,6 +85,11 @@ void board_init_f(ulong not_used)
 	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
+	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;
arch/mips/include/asm/global_data.h +3 -0
index 6e2cdc7..ac24e3f 100644
@@ -59,6 +59,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/mips/lib/board.c +8 -0
index 62d47a8..4657046 100644
@@ -36,6 +36,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong monitor_flash_len;
@@ -153,6 +157,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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();
arch/nds32/include/asm/global_data.h +3 -0
index 94bd4c2..d0e2606 100644
@@ -63,6 +63,9 @@ typedef	struct global_data {
 
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nds32/lib/board.c +8 -0
index 2164a50..97193b0 100644
@@ -37,6 +37,10 @@
 #include <onenand_uboot.h>
 #include <mmc.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong monitor_flash_len;
@@ -192,6 +196,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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) {
arch/nios2/include/asm/global_data.h +3 -0
index 3b0d9e6..44373f4 100644
@@ -42,6 +42,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nios2/lib/board.c +8 -0
index 1e495d4..866dc12 100644
@@ -40,6 +40,10 @@
 #include <nand.h>	/* cannot even include nand.h if it isnt configured */
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -95,6 +99,10 @@ void board_init (void)
 	/* compiler optimization barrier needed for GCC >= 3.4 */
 	__asm__ __volatile__("": : :"memory");
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	gd->bd = &bd_data;
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
arch/openrisc/include/asm/global_data.h +3 -0
index 6a0c0cc..ec2220a 100644
@@ -44,6 +44,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/openrisc/lib/board.c +8 -0
index 85aa189..f1199d6 100644
@@ -44,6 +44,10 @@
 #include <timestamp.h>
 #include <version.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -86,6 +90,10 @@ void board_init(void)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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;
arch/powerpc/include/asm/global_data.h +3 -0
index 5a5877f..38b63f9 100644
@@ -182,6 +182,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/powerpc/lib/board.c +8 -0
index fea310e..39af242 100644
@@ -87,6 +87,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 #ifdef CONFIG_SYS_UPDATE_FLASH_SIZE
 extern int update_flash_size(int flash_size);
 #endif
@@ -389,6 +393,10 @@ void board_init_f(ulong bootflag)
 	memset((void *) gd, 0, sizeof(gd_t));
 #endif
 
+#ifdef CONFIG_SYS_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();
arch/sandbox/include/asm/global_data.h +3 -0
index 581fd2f..00c7c10 100644
@@ -46,6 +46,9 @@ typedef	struct global_data {
 	const void	*fdt_blob;	/* Our device tree, NULL if none */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sandbox/lib/board.c +8 -0
index c173bf9..d384481 100644
@@ -47,6 +47,10 @@
 
 #include <os.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static gd_t gd_mem;
@@ -157,6 +161,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 #if defined(CONFIG_OF_EMBED)
 	/* Get a pointer to the FDT */
 	gd->fdt_blob = _binary_dt_dtb_start;
arch/sh/include/asm/global_data.h +3 -0
index 6e534ad..441fecd 100644
@@ -42,6 +42,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sh/lib/board.c +8 -0
index 34d7881..eb04ed2 100644
@@ -32,6 +32,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 extern int cpu_init(void);
@@ -150,6 +154,10 @@ void sh_generic_init(void)
 
 	memset(gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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 */
arch/sparc/include/asm/global_data.h +3 -0
index 93d3cc0..537e09a 100644
@@ -74,6 +74,9 @@ typedef struct global_data {
 #endif
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sparc/lib/board.c +8 -0
index 6f33666..2ced0a7 100644
@@ -53,6 +53,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /* Debug options
@@ -178,6 +182,10 @@ void board_init_f(ulong bootflag)
 	/* Clear initial global data */
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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;
arch/x86/include/asm/global_data.h +3 -0
index 6d29c0b..920a805 100644
@@ -57,6 +57,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 static inline gd_t *get_fs_gd_ptr(void)
arch/x86/lib/board.c +18 -0
index 90cf7fc..a670f9e 100644
@@ -40,6 +40,10 @@
 #include <asm/init_helpers.h>
 #include <asm/init_wrappers.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 /*
  * Breath some life into the board...
  *
@@ -85,6 +89,17 @@
 typedef int (init_fnc_t) (void);
 
 /*
+ * Initialize early heap (when enabled by config).
+ */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+static void early_malloc_init(void)
+{
+	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 +114,9 @@ init_fnc_t *init_sequence_f[] = {
 	cpu_init_f,
 	board_early_init_f,
 	env_init,
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	early_malloc_init,
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 	init_baudrate_f,
 	serial_init,
 	console_init_f,
common/Makefile +1 -0
index 22e8a6f..5862d34 100644
@@ -201,6 +201,7 @@ COBJS-y += dlmalloc.o
 COBJS-y += image.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-$(CONFIG_DM) += dmmalloc.o
 
 
 COBJS	:= $(sort $(COBJS-y))
common/dmmalloc.c new file +93 -0

93 lines not on this page · raw message

include/dmmalloc.h new file +89 -0

89 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#21 lore raw

RFC PATCH v6 1/1 early_malloc for DM added.

Quoted 9 lines · Tomas Hlavacek

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

---

[snip]

common/dmmalloc.c line 48

Quoted 13 lines
common/dmmalloc.c new file +13 -0
+#ifdef CONFIG_SYS_EARLY_MALLOC
+__weak struct early_heap_header *early_brk(size_t size)
+{
+       struct early_heap_header *h =
+               (struct early_heap_header *)CONFIG_SYS_EARLY_HEAP_ADDR;
+       struct early_heap_header *ehp = gd->early_heap_first;
+
+       while (ehp != NULL) {
+               if (ehp == h)
+                       return NULL;
+
+               ehp = ehp->next_early_heap;
+       }

if (g->early_heap_first == NULL)

    h = CONFIF_SYS_EARLY_HEAP_ADDR);
else
    return NULL;

common/dmmalloc.c line 59

Quoted 11 lines
common/dmmalloc.c new file +11 -0
+
+       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;
+}

Regards,

Graeme

#22 lore raw

RFC PATCH v6 1/1 early_malloc for DM added.

Hello!

Quoted 29 lines · Graeme Russ
Quoted 9 lines · Tomas Hlavacek

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

---

[snip]

common/dmmalloc.c line 48

Quoted 13 lines
common/dmmalloc.c new file +13 -0
+#ifdef CONFIG_SYS_EARLY_MALLOC
+__weak struct early_heap_header *early_brk(size_t size)
+{
+       struct early_heap_header *h =
+               (struct early_heap_header *)CONFIG_SYS_EARLY_HEAP_ADDR;
+       struct early_heap_header *ehp = gd->early_heap_first;
+
+       while (ehp != NULL) {
+               if (ehp == h)
+                       return NULL;
+
+               ehp = ehp->next_early_heap;
+       }

if (g->early_heap_first == NULL)

Quoted 3 lines
    h = CONFIF_SYS_EARLY_HEAP_ADDR);
else
    return NULL;

Yes, I was too paranoid. What about:

if (g->early_heap_first != NULL)

                return NULL;
Quoted 13 lines

common/dmmalloc.c line 59

Quoted 12 lines
common/dmmalloc.c new file +11 -0
+
+       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;
+}

Tomas

#23 lore raw

RFC PATCH v7 1/1 early_malloc for DM added.

In reply to Tomas Hlavacek

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

---
Changelog since v5:
dmmalloc() and all dm* functions has been moved to header, made static inline and preprocessor-dependent blocks are reworked. early_malloc_active() corrected and made not static. s/CONFIG_SYS_DM/CONFIG_DM/ applied.

Changelog sice v6:
Check of first heap emptyness in early_brk() has been simplified.

 arch/arm/include/asm/global_data.h        |    3 +
 arch/arm/lib/board.c                      |    8 +++
 arch/avr32/include/asm/global_data.h      |    3 +
 arch/avr32/lib/board.c                    |    9 +++
 arch/blackfin/include/asm/global_data.h   |    3 +
 arch/blackfin/lib/board.c                 |    8 +++
 arch/m68k/include/asm/global_data.h       |    3 +
 arch/m68k/lib/board.c                     |    8 +++
 arch/microblaze/include/asm/global_data.h |    3 +
 arch/microblaze/lib/board.c               |    9 +++
 arch/mips/include/asm/global_data.h       |    3 +
 arch/mips/lib/board.c                     |    8 +++
 arch/nds32/include/asm/global_data.h      |    3 +
 arch/nds32/lib/board.c                    |    8 +++
 arch/nios2/include/asm/global_data.h      |    3 +
 arch/nios2/lib/board.c                    |    8 +++
 arch/openrisc/include/asm/global_data.h   |    3 +
 arch/openrisc/lib/board.c                 |    8 +++
 arch/powerpc/include/asm/global_data.h    |    3 +
 arch/powerpc/lib/board.c                  |    8 +++
 arch/sandbox/include/asm/global_data.h    |    3 +
 arch/sandbox/lib/board.c                  |    8 +++
 arch/sh/include/asm/global_data.h         |    3 +
 arch/sh/lib/board.c                       |    8 +++
 arch/sparc/include/asm/global_data.h      |    3 +
 arch/sparc/lib/board.c                    |    8 +++
 arch/x86/include/asm/global_data.h        |    3 +
 arch/x86/lib/board.c                      |   18 ++++++
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |   88 ++++++++++++++++++++++++++++
 include/dmmalloc.h                        |   89 +++++++++++++++++++++++++++++
 31 files changed, 344 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/global_data.h +3 -0
index f8088fe..ef727b0 100644
@@ -82,6 +82,9 @@ 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
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/arm/lib/board.c +8 -0
index f1951e8..f73d8b2 100644
@@ -53,6 +53,10 @@
 #include <post.h>
 #include <logbuff.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
 #endif
@@ -281,6 +285,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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 */
arch/avr32/include/asm/global_data.h +3 -0
index 7878bb1..0654a61 100644
@@ -48,6 +48,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/avr32/lib/board.c +9 -0
index d7a64b4..f1bd946 100644
@@ -42,6 +42,11 @@
 #ifdef CONFIG_GENERIC_ATMEL_MCI
 #include <mmc.h>
 #endif
+
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 unsigned long monitor_flash_len;
@@ -161,6 +166,10 @@ void board_init_f(ulong board_type)
 	memset(&gd_data, 0, sizeof(gd_data));
 	gd = &gd_data;
 
+#ifdef CONFIG_SYS_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();
arch/blackfin/include/asm/global_data.h +3 -0
index 290a9e7..2ae395c 100644
@@ -57,6 +57,9 @@ typedef struct global_data {
 
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/blackfin/lib/board.c +8 -0
index c380d27..96b7d76 100644
@@ -37,6 +37,10 @@
 int post_flag;
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 __attribute__((always_inline))
@@ -267,6 +271,10 @@ void board_init_f(ulong bootflag)
 	watchdog_init();
 #endif
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 #ifdef DEBUG
 	if (GENERATED_GBL_DATA_SIZE < sizeof(*gd))
 		hang();
arch/m68k/include/asm/global_data.h +3 -0
index cd55b83..bd30435 100644
@@ -66,6 +66,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/m68k/lib/board.c +8 -0
index 65a8595..1b9312c 100644
@@ -69,6 +69,10 @@
 
 #include <nand.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static char *failed = "*** failed ***\n";
@@ -227,6 +231,10 @@ board_init_f (ulong bootflag)
 	/* Clear initial global data */
 	memset ((void *) gd, 0, sizeof (gd_t));
 
+#ifdef CONFIG_SYS_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 ();
arch/microblaze/include/asm/global_data.h +3 -0
index de3b8db..6f4066d 100644
@@ -46,6 +46,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/microblaze/lib/board.c +9 -0
index 674b573..eeb8441 100644
@@ -37,6 +37,10 @@
 #include <asm/microblaze_intc.h>
 #include <fdtdec.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -81,6 +85,11 @@ void board_init_f(ulong not_used)
 	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
+	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;
arch/mips/include/asm/global_data.h +3 -0
index 6e2cdc7..ac24e3f 100644
@@ -59,6 +59,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/mips/lib/board.c +8 -0
index 62d47a8..4657046 100644
@@ -36,6 +36,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong monitor_flash_len;
@@ -153,6 +157,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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();
arch/nds32/include/asm/global_data.h +3 -0
index 94bd4c2..d0e2606 100644
@@ -63,6 +63,9 @@ typedef	struct global_data {
 
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nds32/lib/board.c +8 -0
index 2164a50..97193b0 100644
@@ -37,6 +37,10 @@
 #include <onenand_uboot.h>
 #include <mmc.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong monitor_flash_len;
@@ -192,6 +196,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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) {
arch/nios2/include/asm/global_data.h +3 -0
index 3b0d9e6..44373f4 100644
@@ -42,6 +42,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nios2/lib/board.c +8 -0
index 1e495d4..866dc12 100644
@@ -40,6 +40,10 @@
 #include <nand.h>	/* cannot even include nand.h if it isnt configured */
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -95,6 +99,10 @@ void board_init (void)
 	/* compiler optimization barrier needed for GCC >= 3.4 */
 	__asm__ __volatile__("": : :"memory");
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	gd->bd = &bd_data;
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
arch/openrisc/include/asm/global_data.h +3 -0
index 6a0c0cc..ec2220a 100644
@@ -44,6 +44,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/openrisc/lib/board.c +8 -0
index 85aa189..f1199d6 100644
@@ -44,6 +44,10 @@
 #include <timestamp.h>
 #include <version.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -86,6 +90,10 @@ void board_init(void)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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;
arch/powerpc/include/asm/global_data.h +3 -0
index 5a5877f..38b63f9 100644
@@ -182,6 +182,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/powerpc/lib/board.c +8 -0
index fea310e..39af242 100644
@@ -87,6 +87,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 #ifdef CONFIG_SYS_UPDATE_FLASH_SIZE
 extern int update_flash_size(int flash_size);
 #endif
@@ -389,6 +393,10 @@ void board_init_f(ulong bootflag)
 	memset((void *) gd, 0, sizeof(gd_t));
 #endif
 
+#ifdef CONFIG_SYS_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();
arch/sandbox/include/asm/global_data.h +3 -0
index 581fd2f..00c7c10 100644
@@ -46,6 +46,9 @@ typedef	struct global_data {
 	const void	*fdt_blob;	/* Our device tree, NULL if none */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sandbox/lib/board.c +8 -0
index c173bf9..d384481 100644
@@ -47,6 +47,10 @@
 
 #include <os.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static gd_t gd_mem;
@@ -157,6 +161,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 #if defined(CONFIG_OF_EMBED)
 	/* Get a pointer to the FDT */
 	gd->fdt_blob = _binary_dt_dtb_start;
arch/sh/include/asm/global_data.h +3 -0
index 6e534ad..441fecd 100644
@@ -42,6 +42,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sh/lib/board.c +8 -0
index 34d7881..eb04ed2 100644
@@ -32,6 +32,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 extern int cpu_init(void);
@@ -150,6 +154,10 @@ void sh_generic_init(void)
 
 	memset(gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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 */
arch/sparc/include/asm/global_data.h +3 -0
index 93d3cc0..537e09a 100644
@@ -74,6 +74,9 @@ typedef struct global_data {
 #endif
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sparc/lib/board.c +8 -0
index 6f33666..2ced0a7 100644
@@ -53,6 +53,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /* Debug options
@@ -178,6 +182,10 @@ void board_init_f(ulong bootflag)
 	/* Clear initial global data */
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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;
arch/x86/include/asm/global_data.h +3 -0
index 6d29c0b..920a805 100644
@@ -57,6 +57,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 static inline gd_t *get_fs_gd_ptr(void)
arch/x86/lib/board.c +18 -0
index 90cf7fc..a670f9e 100644
@@ -40,6 +40,10 @@
 #include <asm/init_helpers.h>
 #include <asm/init_wrappers.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 /*
  * Breath some life into the board...
  *
@@ -85,6 +89,17 @@
 typedef int (init_fnc_t) (void);
 
 /*
+ * Initialize early heap (when enabled by config).
+ */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+static void early_malloc_init(void)
+{
+	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 +114,9 @@ init_fnc_t *init_sequence_f[] = {
 	cpu_init_f,
 	board_early_init_f,
 	env_init,
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	early_malloc_init,
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 	init_baudrate_f,
 	serial_init,
 	console_init_f,
common/Makefile +1 -0
index 22e8a6f..5862d34 100644
@@ -201,6 +201,7 @@ COBJS-y += dlmalloc.o
 COBJS-y += image.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-$(CONFIG_DM) += dmmalloc.o
 
 
 COBJS	:= $(sort $(COBJS-y))
common/dmmalloc.c new file +88 -0

88 lines not on this page · raw message

include/dmmalloc.h new file +89 -0

89 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#24 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

In reply to Tomas Hlavacek

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

---
Changelog since v5:
dmmalloc() and all dm* functions has been moved to header, made static inline and preprocessor-dependent blocks are reworked. early_malloc_active() corrected and made not static. s/CONFIG_SYS_DM/CONFIG_DM/ applied.

Changelog sice v6:
Check of first heap emptyness in early_brk() has been simplified.

Changelog since v7:
dmcalloc() implmentation added.
Comments added to header.

 arch/arm/include/asm/global_data.h        |    3 +
 arch/arm/lib/board.c                      |    8 ++
 arch/avr32/include/asm/global_data.h      |    3 +
 arch/avr32/lib/board.c                    |    9 +++
 arch/blackfin/include/asm/global_data.h   |    3 +
 arch/blackfin/lib/board.c                 |    8 ++
 arch/m68k/include/asm/global_data.h       |    3 +
 arch/m68k/lib/board.c                     |    8 ++
 arch/microblaze/include/asm/global_data.h |    3 +
 arch/microblaze/lib/board.c               |    9 +++
 arch/mips/include/asm/global_data.h       |    3 +
 arch/mips/lib/board.c                     |    8 ++
 arch/nds32/include/asm/global_data.h      |    3 +
 arch/nds32/lib/board.c                    |    8 ++
 arch/nios2/include/asm/global_data.h      |    3 +
 arch/nios2/lib/board.c                    |    8 ++
 arch/openrisc/include/asm/global_data.h   |    3 +
 arch/openrisc/lib/board.c                 |    8 ++
 arch/powerpc/include/asm/global_data.h    |    3 +
 arch/powerpc/lib/board.c                  |    8 ++
 arch/sandbox/include/asm/global_data.h    |    3 +
 arch/sandbox/lib/board.c                  |    8 ++
 arch/sh/include/asm/global_data.h         |    3 +
 arch/sh/lib/board.c                       |    8 ++
 arch/sparc/include/asm/global_data.h      |    3 +
 arch/sparc/lib/board.c                    |    8 ++
 arch/x86/include/asm/global_data.h        |    3 +
 arch/x86/lib/board.c                      |   18 +++++
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |   88 ++++++++++++++++++++++
 include/dmmalloc.h                        |  117 +++++++++++++++++++++++++++++
 31 files changed, 372 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/global_data.h +3 -0
index f8088fe..ef727b0 100644
@@ -82,6 +82,9 @@ 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
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/arm/lib/board.c +8 -0
index f1951e8..f73d8b2 100644
@@ -53,6 +53,10 @@
 #include <post.h>
 #include <logbuff.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
 #endif
@@ -281,6 +285,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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 */
arch/avr32/include/asm/global_data.h +3 -0
index 7878bb1..0654a61 100644
@@ -48,6 +48,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/avr32/lib/board.c +9 -0
index d7a64b4..f1bd946 100644
@@ -42,6 +42,11 @@
 #ifdef CONFIG_GENERIC_ATMEL_MCI
 #include <mmc.h>
 #endif
+
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 unsigned long monitor_flash_len;
@@ -161,6 +166,10 @@ void board_init_f(ulong board_type)
 	memset(&gd_data, 0, sizeof(gd_data));
 	gd = &gd_data;
 
+#ifdef CONFIG_SYS_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();
arch/blackfin/include/asm/global_data.h +3 -0
index 290a9e7..2ae395c 100644
@@ -57,6 +57,9 @@ typedef struct global_data {
 
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/blackfin/lib/board.c +8 -0
index c380d27..96b7d76 100644
@@ -37,6 +37,10 @@
 int post_flag;
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 __attribute__((always_inline))
@@ -267,6 +271,10 @@ void board_init_f(ulong bootflag)
 	watchdog_init();
 #endif
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 #ifdef DEBUG
 	if (GENERATED_GBL_DATA_SIZE < sizeof(*gd))
 		hang();
arch/m68k/include/asm/global_data.h +3 -0
index cd55b83..bd30435 100644
@@ -66,6 +66,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/m68k/lib/board.c +8 -0
index 65a8595..1b9312c 100644
@@ -69,6 +69,10 @@
 
 #include <nand.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static char *failed = "*** failed ***\n";
@@ -227,6 +231,10 @@ board_init_f (ulong bootflag)
 	/* Clear initial global data */
 	memset ((void *) gd, 0, sizeof (gd_t));
 
+#ifdef CONFIG_SYS_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 ();
arch/microblaze/include/asm/global_data.h +3 -0
index de3b8db..6f4066d 100644
@@ -46,6 +46,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/microblaze/lib/board.c +9 -0
index 674b573..eeb8441 100644
@@ -37,6 +37,10 @@
 #include <asm/microblaze_intc.h>
 #include <fdtdec.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -81,6 +85,11 @@ void board_init_f(ulong not_used)
 	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
+	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;
arch/mips/include/asm/global_data.h +3 -0
index 6e2cdc7..ac24e3f 100644
@@ -59,6 +59,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/mips/lib/board.c +8 -0
index 62d47a8..4657046 100644
@@ -36,6 +36,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong monitor_flash_len;
@@ -153,6 +157,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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();
arch/nds32/include/asm/global_data.h +3 -0
index 94bd4c2..d0e2606 100644
@@ -63,6 +63,9 @@ typedef	struct global_data {
 
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nds32/lib/board.c +8 -0
index 2164a50..97193b0 100644
@@ -37,6 +37,10 @@
 #include <onenand_uboot.h>
 #include <mmc.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong monitor_flash_len;
@@ -192,6 +196,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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) {
arch/nios2/include/asm/global_data.h +3 -0
index 3b0d9e6..44373f4 100644
@@ -42,6 +42,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nios2/lib/board.c +8 -0
index 1e495d4..866dc12 100644
@@ -40,6 +40,10 @@
 #include <nand.h>	/* cannot even include nand.h if it isnt configured */
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -95,6 +99,10 @@ void board_init (void)
 	/* compiler optimization barrier needed for GCC >= 3.4 */
 	__asm__ __volatile__("": : :"memory");
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 	gd->bd = &bd_data;
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
arch/openrisc/include/asm/global_data.h +3 -0
index 6a0c0cc..ec2220a 100644
@@ -44,6 +44,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/openrisc/lib/board.c +8 -0
index 85aa189..f1199d6 100644
@@ -44,6 +44,10 @@
 #include <timestamp.h>
 #include <version.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -86,6 +90,10 @@ void board_init(void)
 
 	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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;
arch/powerpc/include/asm/global_data.h +3 -0
index 5a5877f..38b63f9 100644
@@ -182,6 +182,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/powerpc/lib/board.c +8 -0
index fea310e..39af242 100644
@@ -87,6 +87,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 #ifdef CONFIG_SYS_UPDATE_FLASH_SIZE
 extern int update_flash_size(int flash_size);
 #endif
@@ -389,6 +393,10 @@ void board_init_f(ulong bootflag)
 	memset((void *) gd, 0, sizeof(gd_t));
 #endif
 
+#ifdef CONFIG_SYS_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();
arch/sandbox/include/asm/global_data.h +3 -0
index 581fd2f..00c7c10 100644
@@ -46,6 +46,9 @@ typedef	struct global_data {
 	const void	*fdt_blob;	/* Our device tree, NULL if none */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sandbox/lib/board.c +8 -0
index c173bf9..d384481 100644
@@ -47,6 +47,10 @@
 
 #include <os.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static gd_t gd_mem;
@@ -157,6 +161,10 @@ void board_init_f(ulong bootflag)
 
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 #if defined(CONFIG_OF_EMBED)
 	/* Get a pointer to the FDT */
 	gd->fdt_blob = _binary_dt_dtb_start;
arch/sh/include/asm/global_data.h +3 -0
index 6e534ad..441fecd 100644
@@ -42,6 +42,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sh/lib/board.c +8 -0
index 34d7881..eb04ed2 100644
@@ -32,6 +32,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 extern int cpu_init(void);
@@ -150,6 +154,10 @@ void sh_generic_init(void)
 
 	memset(gd, 0, GENERATED_GBL_DATA_SIZE);
 
+#ifdef CONFIG_SYS_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 */
arch/sparc/include/asm/global_data.h +3 -0
index 93d3cc0..537e09a 100644
@@ -74,6 +74,9 @@ typedef struct global_data {
 #endif
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sparc/lib/board.c +8 -0
index 6f33666..2ced0a7 100644
@@ -53,6 +53,10 @@
 #include <miiphy.h>
 #endif
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /* Debug options
@@ -178,6 +182,10 @@ void board_init_f(ulong bootflag)
 	/* Clear initial global data */
 	memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_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;
arch/x86/include/asm/global_data.h +3 -0
index 6d29c0b..920a805 100644
@@ -57,6 +57,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap_first;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 static inline gd_t *get_fs_gd_ptr(void)
arch/x86/lib/board.c +18 -0
index 90cf7fc..a670f9e 100644
@@ -40,6 +40,10 @@
 #include <asm/init_helpers.h>
 #include <asm/init_wrappers.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 /*
  * Breath some life into the board...
  *
@@ -85,6 +89,17 @@
 typedef int (init_fnc_t) (void);
 
 /*
+ * Initialize early heap (when enabled by config).
+ */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+static void early_malloc_init(void)
+{
+	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 +114,9 @@ init_fnc_t *init_sequence_f[] = {
 	cpu_init_f,
 	board_early_init_f,
 	env_init,
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	early_malloc_init,
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 	init_baudrate_f,
 	serial_init,
 	console_init_f,
common/Makefile +1 -0
index 22e8a6f..5862d34 100644
@@ -201,6 +201,7 @@ COBJS-y += dlmalloc.o
 COBJS-y += image.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-$(CONFIG_DM) += dmmalloc.o
 
 
 COBJS	:= $(sort $(COBJS-y))
common/dmmalloc.c new file +88 -0

88 lines not on this page · raw message

include/dmmalloc.h new file +117 -0

117 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#25 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Dear Tomas Hlavacek,

Quoted 14 lines · In message <[email protected]> you wrote:

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

---
Changelog since v5:
dmmalloc() and all dm* functions has been moved to header, made static inline and preprocessor-dependent blocks are reworked. early_malloc_active() corrected and made not static. s/CONFIG_SYS_DM/CONFIG_DM/ applied.

Quoted 6 lines

Changelog sice v6:
Check of first heap emptyness in early_brk() has been simplified.

Changelog since v7:
dmcalloc() implmentation added.
Comments added to header.

Your change log does not make much sense to me. It appears there has been some dmcalloc() implementation already in v5 (and eearlier?), as you write there you moved it into the header file. Now you add it again?

This changelog is intended to desccribe the difference between the patch versions, to allow a reviewer to recognize which comments you addressed, and where you decided otherwise.

Your log does not provide any such information.

Also, please re-read the recommendations for the commit message. "FOO added" is considered bad; please use something like "add FOO" instead (i. e. describe what this commit actually does).

Also, please make sure tu run ALL patches through checkpatch before submitting; your patch throws 4 errors that all need fixing.

Finally, you might want to consult a spell checker every now and then (see for example "implmentation", "perfrom", etc.).

Thanks.

Wolfgang Denk

Signature · 4 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"I'm not a god, I was misquoted."                 - Lister, Red Dwarf
#26 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Dear Wolfgang Denk,

Quoted 9 lines · Wolfgang Denk
Quoted 4 lines

Changelog since v7:
dmcalloc() implmentation added.
Comments added to header.

Your change log does not make much sense to me. It appears there has been some dmcalloc() implementation already in v5 (and eearlier?), as you write there you moved it into the header file. Now you add it again?

Well no. The dmcalloc function returned always NULL in the early stage in the previous versions. The current version of dmcalloc simulates calloc also in the early_mallocator stage.

Quoted 4 lines

Also, please re-read the recommendations for the commit message. "FOO added" is considered bad; please use something like "add FOO" instead (i. e. describe what this commit actually does).

I will do that.

Tomas

#27 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Quoted 18 lines · Tomas Hlavacek

Dear Wolfgang Denk,

Quoted 9 lines · Wolfgang Denk
Quoted 4 lines

Changelog since v7:
dmcalloc() implmentation added.
Comments added to header.

Your change log does not make much sense to me. It appears there has been some dmcalloc() implementation already in v5 (and eearlier?), as you write there you moved it into the header file. Now you add it again?

Well no. The dmcalloc function returned always NULL in the early stage in the previous versions. The current version of dmcalloc simulates calloc also in the early_mallocator stage.

Quoted 1 line
Quoted 5 lines
Quoted 3 lines

Also, please re-read the recommendations for the commit message. "FOO added" is considered bad; please use something like "add FOO" instead (i. e. describe what this commit actually does).

I will do that.

I would strongly recommend and especially as the DM work moves on you try using patman to manage the series as it will help you to keep track of, and format properly, changelogs , run checkpatch and otherwise encourage you to have the other good habits that help us to focus on reviewing the changes themselves.

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120924/cacb0309/attachment.pgp>
#28 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

In reply to Tomas Hlavacek

Dear Tomas Hlavacek,

[..]

include/dmmalloc.h line 98

Quoted 5 lines
include/dmmalloc.h new file +5 -0
+
+	if (early_malloc_active()) {
+		addr = early_malloc(size);
+		for (i=0; i<size; i++)
+			addr[i] = 0;

memset() ?

include/dmmalloc.h line 110

Quoted 12 lines
include/dmmalloc.h new file +12 -0
+
+		return addr;
+	}
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+	return calloc(n, elem_size);
+}
+
+static inline void *dmrealloc(void *oldmem, size_t bytes)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	if (early_malloc_active())
+		return NULL;

I wonder how should this be implemented ... maybe early_malloc + standard memcpy()

include/dmmalloc.h line 117

Quoted 7 lines
include/dmmalloc.h new file +7 -0
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+	return dmrealloc(oldmem, bytes);
+}
+
+#endif /* CONFIG_DM */
+#endif /* __INCLUDE_DMMALLOC_H */
+

Best regards,
Marek Vasut

#29 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Hello Marek,

Quoted 10 lines · Marek Vasut

Dear Tomas Hlavacek,

[..]

include/dmmalloc.h line 98

Quoted 5 lines
include/dmmalloc.h new file +5 -0
+
+     if (early_malloc_active()) {
+             addr = early_malloc(size);
+             for (i=0; i<size; i++)
+                     addr[i] = 0;

memset() ?

Yes, sure. Thanks.

Quoted 16 lines

include/dmmalloc.h line 110

Quoted 13 lines
include/dmmalloc.h new file +12 -0
+
+             return addr;
+     }
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+     return calloc(n, elem_size);
+}
+
+static inline void *dmrealloc(void *oldmem, size_t bytes)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+     if (early_malloc_active())
+             return NULL;

I wonder how should this be implemented ... maybe early_malloc + standard memcpy()

How do you want me to fix all the pointers to the memcpyied part of heap then? I think this will not work unless I make some reservations for eventual growth for each and every early_mallocated area. And I think this is not good idea at all for early_malloc.

I think there are two straight-forward possibilities: a) keep the empty implementation of dmrealloc() in early stage and avoid using it in code which might run in early stage, but retain the dm* version of the symbol. b) remove the dmrealloc() entirely which may have certain negative consequences, because it might be tempting to mix dmmalloc() and (non-dm*) realloc() calls which is obviously wrong.

Tomas

#30 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Dear Tomas Hlavacek,

[...]

Quoted 9 lines
Quoted 8 lines

include/dmmalloc.h line 110

Quoted 5 lines
include/dmmalloc.h new file +5 -0
+static inline void *dmrealloc(void *oldmem, size_t bytes)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+     if (early_malloc_active())
+             return NULL;

I wonder how should this be implemented ... maybe early_malloc + standard memcpy()

Quoted 4 lines

How do you want me to fix all the pointers to the memcpyied part of heap then? I think this will not work unless I make some reservations for eventual growth for each and every early_mallocated area. And I think this is not good idea at all for early_malloc.

What exactly would you need to fix ? It's only a matter of allocating new block, copying the existing data there and returning the pointer to the new block, no?

Quoted 8 lines

I think there are two straight-forward possibilities: a) keep the empty implementation of dmrealloc() in early stage and avoid using it in code which might run in early stage, but retain the dm* version of the symbol. b) remove the dmrealloc() entirely which may have certain negative consequences, because it might be tempting to mix dmmalloc() and (non-dm*) realloc() calls which is obviously wrong.

Tomas

Best regards,
Marek Vasut

#31 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Hi Marek,

Quoted 27 lines · Marek Vasut

Dear Tomas Hlavacek,

[...]

Quoted 9 lines
Quoted 8 lines

include/dmmalloc.h line 110

Quoted 5 lines
include/dmmalloc.h new file +5 -0
+static inline void *dmrealloc(void *oldmem, size_t bytes)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+     if (early_malloc_active())
+             return NULL;

I wonder how should this be implemented ... maybe early_malloc + standard memcpy()

Quoted 4 lines

How do you want me to fix all the pointers to the memcpyied part of heap then? I think this will not work unless I make some reservations for eventual growth for each and every early_mallocated area. And I think this is not good idea at all for early_malloc.

What exactly would you need to fix ? It's only a matter of allocating new block, copying the existing data there and returning the pointer to the new block, no?

Quoted 6 lines

I think there are two straight-forward possibilities: a) keep the empty implementation of dmrealloc() in early stage and avoid using it in code which might run in early stage, but retain the dm* version of the symbol. b) remove the dmrealloc() entirely which may have certain negative consequences, because it might be tempting to mix dmmalloc() and (non-dm*) realloc() calls which is obviously wrong.

#32 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Hello Graeme!

Quoted 1 line · Graeme Russ

Hi Marek,

[...]

Quoted 11 lines

The last two are NOPs for early heap as we have no way to track free'd blocks

Keep in mind that 'real' realloc() has access to information providing the size of the source block of allocated memory, so it can do a memcpy using (at least a good guess of) the size of the source block. In the early heap case, we do not have that data, so we would need to memcpy the entire size of the destination block - this will likely bring in garbage (no problem as we there is nothing in the spec to forbid that) and _might_ have some interesting boundary conditions (what happens if we memcpy past the end of an early heap block into ga-ga land?)

I was thinking about such simple implementation:

static inline void *dmrealloc(void *oldaddr, size_t bytes) {

#ifdef CONFIG_SYS_EARLY_MALLOC
        char *addr;
        if (early_malloc_active()) {
                addr = dmalloc(bytes);
                memcpy(addr, oldaddr, bytes);
                return addr;
        }
#endif /* CONFIG_SYS_EARLY_MALLOC */
        return dmrealloc(oldmem, bytes);
}

But then the fun comes: I can not distinguish the case when you have 100 B char *x allocated and you called dmrealloc(x, 99). And I can hit some boundaries as

But yes, we can have such a stupid implementation. Or I can use early_malloc frame header which would contain magic (to detect wrong dmrealloc calls on arbitrary pointer) and size, so I would be able to do free and realloc. Then I would need new free-space enumeration mechanism to reuse free space (let's say that I can create a linked list of free headers), so the frame header is going to be 12 B total. Or we can have no implementation of dmrealloc at all.

Tomas

#33 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Hi Thomas,

Quoted 4 lines · Tomas Hlavacek

Hello Graeme!

On Tue, Sep 25, 2012 at 2:37 AM, Graeme Russ <[email protected]>

Quoted 5 lines · wrote:
Quoted 1 line

Hi Marek,

[...]

Quoted 1 line

The last two are NOPs for early heap as we have no way to track free'd

blocks

Quoted 30 lines
Quoted 10 lines

Keep in mind that 'real' realloc() has access to information providing the size of the source block of allocated memory, so it can do a memcpy using (at least a good guess of) the size of the source block. In the early heap case, we do not have that data, so we would need to memcpy the entire size of the destination block - this will likely bring in garbage (no problem as we there is nothing in the spec to forbid that) and _might_ have some interesting boundary conditions (what happens if we memcpy past the end of an early heap block into ga-ga land?)

I was thinking about such simple implementation:

static inline void *dmrealloc(void *oldaddr, size_t bytes) {

#ifdef CONFIG_SYS_EARLY_MALLOC
        char *addr;
        if (early_malloc_active()) {
                addr = dmalloc(bytes);
                memcpy(addr, oldaddr, bytes);
                return addr;
        }
#endif /* CONFIG_SYS_EARLY_MALLOC */
        return dmrealloc(oldmem, bytes);
}

But then the fun comes: I can not distinguish the case when you have 100 B char *x allocated and you called dmrealloc(x, 99). And I can hit some boundaries as

Quoted 7 lines

But yes, we can have such a stupid implementation. Or I can use early_malloc frame header which would contain magic (to detect wrong dmrealloc calls on arbitrary pointer) and size, so I would be able to do free and realloc. Then I would need new free-space enumeration mechanism to reuse free space (let's say that I can create a linked list of free headers), so the frame header is going to be 12 B total. Or we can have no implementation of dmrealloc at all.

We should implement each of malloc(), free(), calloc(), and realloc().

Don't worry about reclaiming and reusing space with a proper free() implementation. Remember, all memory allocated on the early heap must be relocated anyway.

Maybe if you add a size_t value immediately before the allocated space which stores the block size. So:

size_t *bytes_ptr = ptr;
bytes_ptr--;
size_t bytes = *bytes_ptr;

gives you the block size

Regards,

Graeme

#34 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Hi Tomas

Quoted 6 lines · Graeme Russ

We should implement each of malloc(), free(), calloc(), and realloc().

Don't worry about reclaiming and reusing space with a proper free() implementation. Remember, all memory allocated on the early heap must be relocated anyway.

Quoted 8 lines

Maybe if you add a size_t value immediately before the allocated space which stores the block size. So:

size_t *bytes_ptr = ptr;
bytes_ptr--;
size_t bytes = *bytes_ptr;

gives you the block size

I've been thinking about this a bit more, and for the sake of 4 bytes, this additional 'size' member could be quite handy:
- We effectively end up with a linked-list of allocated blocks
- free() could set the high bit to tag the block as 'de-allocated'
- When a block is relocated into the permanent heap, free() should be called on the source (early heap) block
- We can call a 'cleanup' function after early heap is no longer needed and check that every block has the high bit set
- We can re-use blocks by scanning for a tagged block with the same size (usefull for drivers that allocate temporary buffers which are always the same size)
- If there are no early heaps with enough space for a given malloc operation, but there is a tagged block that is larger than the requested size, we can split tagged blocks

Remebering back to when I suggested a list of relocation helpers (one for each allocated block), I think we can implement that as an additional field in the block header (stretching the header to 8 bytes). This can come later.

Regards,

Graeme

#35 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Hello Graeme,

Quoted 17 lines · Graeme Russ

Hi Tomas

Quoted 13 lines · Graeme Russ

We should implement each of malloc(), free(), calloc(), and realloc().

Don't worry about reclaiming and reusing space with a proper free() implementation. Remember, all memory allocated on the early heap must be relocated anyway.

Maybe if you add a size_t value immediately before the allocated space which stores the block size. So:

size_t *bytes_ptr = ptr;
bytes_ptr--;
size_t bytes = *bytes_ptr;

Quoted 5 lines
Quoted 1 line

gives you the block size

I've been thinking about this a bit more, and for the sake of 4 bytes, this additional 'size' member could be quite handy:
- We effectively end up with a linked-list of allocated blocks

Yes, this makes sense. Knowing size of allocated blocks enables the early_malloc to do the whole set of malloc* functions.

Do you think it would be also useful to have a basic check that the pointer passed to new early_free() and/or early_realloc() is valid? I mean check that the pointer really points at the start of the block and there is a valid header preceding the block. We can have a magic number in the header for example. Or I can store a list of allocated blocks as a variable-sized array in the early_heap_header.

Quoted 1 line

- free() could set the high bit to tag the block as 'de-allocated'

Well, we would end up with malloc doing:

1) scan through all heaps to find best fit into previously free()-ed block
2) scan through all heaps to find enough free space using the heap header
3) call early_brk to obtain more space

Data structures would be:

The scanning two different header types for free space seems to me being a bit redundant. What do you think about replacing point (2) and using block headers instead of free space pointer in the heap header and just split the block when there is not exact size match. I mean:

1) scan through all heaps to find best fit block
2) scan through all heaps to find greater block and split it
3) call early_brk to obtain more space

Data structures would be:

struct early_heap_header {
    int heap_size;
    phys_addr_t reloc_addr_old;
}
struct early_block_header {
    int magic;
    int size;
}

The brand new early_heap right after it's creation would consist of a early_heap_header followed by a early_block_header with the free bit set to true.

Quoted 2 lines

- When a block is relocated into the permanent heap, free() should be called on the source (early heap) block

Well, that time we would have only a copy of the early_heap on certain platforms. Assuming that first we set off drivers and DM using early_heap(s), then we would copy each early_heap to some computed address and jump to board_init_r. In board_init_r we would access the early_heap copy via translation function using the address offset (early_heap_copy - early_heap_copy->reloc_addr_old).

To do the early_free correctly in this mid-relocation state I would have to allow early_* code to operate during this period. It is not that hard to do, but maybe it is conceptually wrong because it means operating early_malloc/realloc/free code on a copy of it's own data after relocation.

Quoted 2 lines

- We can call a 'cleanup' function after early heap is no longer needed and check that every block has the high bit set

Yes, it would help. When each block has to be free()-ed or relocated and then free()-ed, it could help find memory leaks during early init.

Quoted 10 lines

- We can re-use blocks by scanning for a tagged block with the same size (usefull for drivers that allocate temporary buffers which are always the same size)
- If there are no early heaps with enough space for a given malloc operation, but there is a tagged block that is larger than the requested size, we can split tagged blocks

Remebering back to when I suggested a list of relocation helpers (one for each allocated block), I think we can implement that as an additional field in the block header (stretching the header to 8 bytes). This can come later.

Do you mean we should place a pointer pointing at a relocation function into each block header? I think it would end up in situation
like: Somebody is allocating a tree for example, he would set the helper function into the root element and NULL pointers to other nodes, because it makes more sense to relocate tree recursively from the root.

Tomas

#36 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Hi Tomas,

Quoted 29 lines · Tomas Hlavacek

Hello Graeme,

Quoted 17 lines · Graeme Russ

Hi Tomas

Quoted 13 lines · Graeme Russ

We should implement each of malloc(), free(), calloc(), and realloc().

Don't worry about reclaiming and reusing space with a proper free() implementation. Remember, all memory allocated on the early heap must be relocated anyway.

Maybe if you add a size_t value immediately before the allocated space which stores the block size. So:

size_t *bytes_ptr = ptr;
bytes_ptr--;
size_t bytes = *bytes_ptr;

Quoted 5 lines
Quoted 1 line

gives you the block size

I've been thinking about this a bit more, and for the sake of 4 bytes, this additional 'size' member could be quite handy:
- We effectively end up with a linked-list of allocated blocks

Yes, this makes sense. Knowing size of allocated blocks enables the early_malloc to do the whole set of malloc* functions.

Quoted 6 lines

Do you think it would be also useful to have a basic check that the pointer passed to new early_free() and/or early_realloc() is valid? I mean check that the pointer really points at the start of the block and there is a valid header preceding the block. We can have a magic number in the header for example. Or I can store a list of allocated blocks as a variable-sized array in the early_heap_header.

The goal of early_malloc is to be lightweight and fast, not bullet-proof.

Quoted 19 lines
Quoted 1 line

- free() could set the high bit to tag the block as 'de-allocated'

Well, we would end up with malloc doing:

1) scan through all heaps to find best fit into previously free()-ed block
2) scan through all heaps to find enough free space using the heap header
3) call early_brk to obtain more space

Data structures would be:

The scanning two different header types for free space seems to me being a bit redundant. What do you think about replacing point (2) and using block headers instead of free space pointer in the heap header and just split the block when there is not exact size match. I mean:

1) scan through all heaps to find best fit block
2) scan through all heaps to find greater block and split it
3) call early_brk to obtain more space

Quoted 6 lines

Data structures would be:

struct early_heap_header {
    int heap_size;
    phys_addr_t reloc_addr_old;
}

Hmm, what is reloc_addr_old all about?

Quoted 4 lines
struct early_block_header {
    int magic;
    int size;
}

NAK on the magic - waste of space

Quoted 3 lines

The brand new early_heap right after it's creation would consist of a early_heap_header followed by a early_block_header with the free bit set to true.

Hmm, I think you may be on to something:

struct early_heap_header {
        struct early_heap_header *next_heap;
};
struch early_block {
        size_t size;
        unsigned char *data;
}

We could reserve the upper, say, 8 bits of size as flags. This leaves 24 bits as usable 'size' value (if anyone needs to allocate a 16M chunck of memory early then we have a problem)

So the early heap starts out with an early_heap_header and an early_block with size set to the size of the early heap (minus headers) with the 'free' and 'last block' flags set. The first call to early_malloc() would:
- Split the block
- Set the size to the appropriate value
- Clear the 'free' and 'last block' flags
- Create a new early_block after the allocated space
- Set the size of the new block to the size of the remaining space
- Set the 'free' and 'last block' flags of the new block

When calling early_malloc(), search through the list. If you find a free block of exactly the right size, use it. If not, then while you are scanning, keep a reference to the smallest free block larger than the requested size. That leave a decision:
- Do we always split the first 'smallest free block', or;
- Do we always split the last block?

If there are no free blocks that can be split, call early_brk()

Quoted 9 lines
Quoted 2 lines

- When a block is relocated into the permanent heap, free() should be called on the source (early heap) block

Well, that time we would have only a copy of the early_heap on certain platforms. Assuming that first we set off drivers and DM using early_heap(s), then we would copy each early_heap to some computed address and jump to board_init_r. In board_init_r we would access the early_heap copy via translation function using the address offset (early_heap_copy - early_heap_copy->reloc_addr_old).

Me == 100% lost :)

Looks like you are still clinging onto the double-copy. If so, I'm still not convinced.

Quoted 5 lines

To do the early_free correctly in this mid-relocation state I would have to allow early_* code to operate during this period. It is not that hard to do, but maybe it is conceptually wrong because it means operating early_malloc/realloc/free code on a copy of it's own data after relocation.

Me == 110% lost :(

Quoted 5 lines
Quoted 2 lines

- We can call a 'cleanup' function after early heap is no longer needed and check that every block has the high bit set

Yes, it would help. When each block has to be free()-ed or relocated and then free()-ed, it could help find memory leaks during early init.

That's the idea - find poorly written drivers that assumed they would never be initialised pre-relocation and don't handle relocation correctly.

Quoted 11 lines
Quoted 10 lines

- We can re-use blocks by scanning for a tagged block with the same size (usefull for drivers that allocate temporary buffers which are always the same size)
- If there are no early heaps with enough space for a given malloc operation, but there is a tagged block that is larger than the requested size, we can split tagged blocks

Remebering back to when I suggested a list of relocation helpers (one for each allocated block), I think we can implement that as an additional field in the block header (stretching the header to 8 bytes). This can come later.

Quoted 6 lines

Do you mean we should place a pointer pointing at a relocation function into each block header? I think it would end up in situation
like: Somebody is allocating a tree for example, he would set the helper function into the root element and NULL pointers to other nodes, because it makes more sense to relocate tree recursively from the root.

Exactly - One of the flags could be 'no relocate' or some such

Regards,

Graeme

#37 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

In reply to Tomas Hlavacek

Hi Tomas,

Quoted 86 lines · Tomas Hlavacek

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

---
Changelog since v5:
dmmalloc() and all dm* functions has been moved to header, made static inline and preprocessor-dependent blocks are reworked. early_malloc_active() corrected and made not static. s/CONFIG_SYS_DM/CONFIG_DM/ applied.

Changelog sice v6:
Check of first heap emptyness in early_brk() has been simplified.

Changelog since v7:
dmcalloc() implmentation added.
Comments added to header.

 arch/arm/include/asm/global_data.h        |    3 +
 arch/arm/lib/board.c                      |    8 ++
 arch/avr32/include/asm/global_data.h      |    3 +
 arch/avr32/lib/board.c                    |    9 +++
 arch/blackfin/include/asm/global_data.h   |    3 +
 arch/blackfin/lib/board.c                 |    8 ++
 arch/m68k/include/asm/global_data.h       |    3 +
 arch/m68k/lib/board.c                     |    8 ++
 arch/microblaze/include/asm/global_data.h |    3 +
 arch/microblaze/lib/board.c               |    9 +++
 arch/mips/include/asm/global_data.h       |    3 +
 arch/mips/lib/board.c                     |    8 ++
 arch/nds32/include/asm/global_data.h      |    3 +
 arch/nds32/lib/board.c                    |    8 ++
 arch/nios2/include/asm/global_data.h      |    3 +
 arch/nios2/lib/board.c                    |    8 ++
 arch/openrisc/include/asm/global_data.h   |    3 +
 arch/openrisc/lib/board.c                 |    8 ++
 arch/powerpc/include/asm/global_data.h    |    3 +
 arch/powerpc/lib/board.c                  |    8 ++
 arch/sandbox/include/asm/global_data.h    |    3 +
 arch/sandbox/lib/board.c                  |    8 ++
 arch/sh/include/asm/global_data.h         |    3 +
 arch/sh/lib/board.c                       |    8 ++
 arch/sparc/include/asm/global_data.h      |    3 +
 arch/sparc/lib/board.c                    |    8 ++
 arch/x86/include/asm/global_data.h        |    3 +
 arch/x86/lib/board.c                      |   18 +++++
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |   88 ++++++++++++++++++++++
 include/dmmalloc.h                        |  117 +++++++++++++++++++++++++++++
 31 files changed, 372 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/global_data.h +3 -0
index f8088fe..ef727b0 100644
@@ -82,6 +82,9 @@ 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
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       void    *early_heap_first;      /* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/arm/lib/board.c +4 -0
index f1951e8..f73d8b2 100644
@@ -53,6 +53,10 @@
 #include <post.h>
 #include <logbuff.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
 #endif

arch/arm/lib/board.c void board_init_f(ulong bootflag) · line 291

Quoted 7 lines
arch/arm/lib/board.c +4 -0
@@ -281,6 +285,10 @@ void board_init_f(ulong bootflag)
 
        memset((void *)gd, 0, sizeof(gd_t));
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+

I just realised that all these initialisers can be dumped - early_brk() will be called when early_malloc() is first called

[snip]

Quoted 17 lines
arch/x86/lib/board.c +4 -0
index 90cf7fc..a670f9e 100644
@@ -40,6 +40,10 @@
 #include <asm/init_helpers.h>
 #include <asm/init_wrappers.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 /*
  * Breath some life into the board...
  *
@@ -85,6 +89,17 @@
 typedef int (init_fnc_t) (void);

arch/x86/lib/board.c line 99

Quoted 10 lines
arch/x86/lib/board.c +8 -0
 
 /*
+ * Initialize early heap (when enabled by config).
+ */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+static void early_malloc_init(void)
+{
+       gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+}
+#endif /* CONFIG_SYS_EARLY_MALLOC */

So this uglyness goes

arch/x86/lib/board.c init_fnc_t *init_sequence_f[] = { · line 119

Quoted 13 lines
arch/x86/lib/board.c +6 -0
+
+
+/*
  * 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 +114,9 @@ init_fnc_t *init_sequence_f[] = {
        cpu_init_f,
        board_early_init_f,
        env_init,
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       early_malloc_init,
+#endif /* CONFIG_SYS_EARLY_MALLOC */

And this one as well

Quoted 40 lines
arch/x86/lib/board.c +0 -0
 COBJS  := $(sort $(COBJS-y))
common/dmmalloc.c new file +33 -0
new file mode 100644
index 0000000..6dbb622
@@ -0,0 +1,88 @@
+/*
+ * (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>
+
+#include <linux/compiler.h>
+

common/dmmalloc.c line 43

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+__weak struct early_heap_header *early_brk(size_t size)
+{
+       struct early_heap_header *h =
+               (struct early_heap_header *)CONFIG_SYS_EARLY_HEAP_ADDR;
+
+       if (gd->early_heap_first != NULL)
+               return NULL;

if (gd->early_heap_first != NULL) {
debug("Early Heap: Failed to allocate %d byte block of
early heap.\n",

                     size);
               return NULL;
       }
Quoted 19 lines
common/dmmalloc.c new file +19 -0
+
+       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;
+}
+
+void *early_malloc(size_t size)
+{
+       phys_addr_t addr;
+       struct early_heap_header *h;
+
+       size = roundup(size, sizeof(phys_addr_t));
+

common/dmmalloc.c line 72

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+       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) {
+               h->next_early_heap = early_brk(size);
+               if (h->next_early_heap == NULL)
+                       debug("EH overflow. Can not early_brk. required %d B.",
+                       size);
+               return NULL;

Missing brace and not using the newly allocated block

common/dmmalloc.c line 81

Quoted 9 lines
common/dmmalloc.c new file +9 -0
+       }
+
+       addr = (phys_addr_t)h->free_space_pointer;
+
+       h->free_space_pointer += size;
+       h->free_bytes -= size;
+
+       return (void *)addr;
+}

This is still NULL pointer exception prone, for example calling dmmalloc() before the initialisation function in board.c is called.

void *early_malloc(size_t size)

{
       phys_addr_t addr;
       struct early_heap_header *h;

       size = roundup(size, sizeof(phys_addr_t));

       /* Initialise first block of early heap (if not already done) */
       if (!gd->early_heap_first) {
               gd->early_heap_first = early_brk(size);

               if (!gd->early_heap_first)
                       return NULL;
       }

       /* Find an early heap block with enough free space */
       h = gd->early_heap_first;

       while ((h->free_bytes < size) && (h->next_early_heap != NULL))
               h = h->next_early_heap;

       /* Initialise another block of early heap if neccessary */
       if (h->free_bytes < size) {
               h->next_early_heap = early_brk(size);

               if (!h->next_early_heap)
                       return NULL;

               /* Use the newly allocated block */
               h = h->next_early_heap;
       }

       addr = (phys_addr_t)h->free_space_pointer;

       h->free_space_pointer += size;
       h->free_bytes -= size;

       return (void *)addr;
}

Regards,

Graeme

#38 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Hi Graeme!

Quoted 92 lines · Graeme Russ

Hi Tomas,

Quoted 89 lines · Tomas Hlavacek

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

---
Changelog since v5:
dmmalloc() and all dm* functions has been moved to header, made static inline and preprocessor-dependent blocks are reworked. early_malloc_active() corrected and made not static. s/CONFIG_SYS_DM/CONFIG_DM/ applied.

Changelog sice v6:
Check of first heap emptyness in early_brk() has been simplified.

Changelog since v7:
dmcalloc() implmentation added.
Comments added to header.

 arch/arm/include/asm/global_data.h        |    3 +
 arch/arm/lib/board.c                      |    8 ++
 arch/avr32/include/asm/global_data.h      |    3 +
 arch/avr32/lib/board.c                    |    9 +++
 arch/blackfin/include/asm/global_data.h   |    3 +
 arch/blackfin/lib/board.c                 |    8 ++
 arch/m68k/include/asm/global_data.h       |    3 +
 arch/m68k/lib/board.c                     |    8 ++
 arch/microblaze/include/asm/global_data.h |    3 +
 arch/microblaze/lib/board.c               |    9 +++
 arch/mips/include/asm/global_data.h       |    3 +
 arch/mips/lib/board.c                     |    8 ++
 arch/nds32/include/asm/global_data.h      |    3 +
 arch/nds32/lib/board.c                    |    8 ++
 arch/nios2/include/asm/global_data.h      |    3 +
 arch/nios2/lib/board.c                    |    8 ++
 arch/openrisc/include/asm/global_data.h   |    3 +
 arch/openrisc/lib/board.c                 |    8 ++
 arch/powerpc/include/asm/global_data.h    |    3 +
 arch/powerpc/lib/board.c                  |    8 ++
 arch/sandbox/include/asm/global_data.h    |    3 +
 arch/sandbox/lib/board.c                  |    8 ++
 arch/sh/include/asm/global_data.h         |    3 +
 arch/sh/lib/board.c                       |    8 ++
 arch/sparc/include/asm/global_data.h      |    3 +
 arch/sparc/lib/board.c                    |    8 ++
 arch/x86/include/asm/global_data.h        |    3 +
 arch/x86/lib/board.c                      |   18 +++++
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |   88 ++++++++++++++++++++++
 include/dmmalloc.h                        |  117 +++++++++++++++++++++++++++++
 31 files changed, 372 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/global_data.h +3 -0
index f8088fe..ef727b0 100644
@@ -82,6 +82,9 @@ 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
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       void    *early_heap_first;      /* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/arm/lib/board.c +4 -0
index f1951e8..f73d8b2 100644
@@ -53,6 +53,10 @@
 #include <post.h>
 #include <logbuff.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
 #endif
@@ -281,6 +285,10 @@ void board_init_f(ulong bootflag)
 
        memset((void *)gd, 0, sizeof(gd_t));
 
Quoted 8 lines

arch/arm/lib/board.c void board_init_f(ulong bootflag) · line 291

Quoted 4 lines
arch/arm/lib/board.c +4 -0
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+

I just realised that all these initialisers can be dumped - early_brk() will be called when early_malloc() is first called

Yes, but how can I determine the size of the new heap which the early_brk gives out? When I have CONFIG_SYS_EARLY_HEAP_SIZE macro in board configuration I can ignore the size passed to the "default" early_brk and return the full-sized heap as configuration says (when the requested size is lower than configured heap size and NULL otherwise). But what if somebody implements at some point a dynamic early_brk capable of returning multiple heaps? Should I safely assume that the future dynamic early_brk would give out multiples of page size or so?

All other comments understood and agreed.

Thanks,
Tomas

#39 lore raw

RFC PATCH v8 1/1 early_malloc for DM added.

Hi Thomas,

Quoted 104 lines · Tomas Hlavacek

Hi Graeme!

Quoted 92 lines · Graeme Russ

Hi Tomas,

Quoted 89 lines · Tomas Hlavacek

early_malloc for DM with support for more heaps and lightweight first heap in the same memory as an early stack.

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

---
Changelog since v5:
dmmalloc() and all dm* functions has been moved to header, made static inline and preprocessor-dependent blocks are reworked. early_malloc_active() corrected and made not static. s/CONFIG_SYS_DM/CONFIG_DM/ applied.

Changelog sice v6:
Check of first heap emptyness in early_brk() has been simplified.

Changelog since v7:
dmcalloc() implmentation added.
Comments added to header.

 arch/arm/include/asm/global_data.h        |    3 +
 arch/arm/lib/board.c                      |    8 ++
 arch/avr32/include/asm/global_data.h      |    3 +
 arch/avr32/lib/board.c                    |    9 +++
 arch/blackfin/include/asm/global_data.h   |    3 +
 arch/blackfin/lib/board.c                 |    8 ++
 arch/m68k/include/asm/global_data.h       |    3 +
 arch/m68k/lib/board.c                     |    8 ++
 arch/microblaze/include/asm/global_data.h |    3 +
 arch/microblaze/lib/board.c               |    9 +++
 arch/mips/include/asm/global_data.h       |    3 +
 arch/mips/lib/board.c                     |    8 ++
 arch/nds32/include/asm/global_data.h      |    3 +
 arch/nds32/lib/board.c                    |    8 ++
 arch/nios2/include/asm/global_data.h      |    3 +
 arch/nios2/lib/board.c                    |    8 ++
 arch/openrisc/include/asm/global_data.h   |    3 +
 arch/openrisc/lib/board.c                 |    8 ++
 arch/powerpc/include/asm/global_data.h    |    3 +
 arch/powerpc/lib/board.c                  |    8 ++
 arch/sandbox/include/asm/global_data.h    |    3 +
 arch/sandbox/lib/board.c                  |    8 ++
 arch/sh/include/asm/global_data.h         |    3 +
 arch/sh/lib/board.c                       |    8 ++
 arch/sparc/include/asm/global_data.h      |    3 +
 arch/sparc/lib/board.c                    |    8 ++
 arch/x86/include/asm/global_data.h        |    3 +
 arch/x86/lib/board.c                      |   18 +++++
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |   88 ++++++++++++++++++++++
 include/dmmalloc.h                        |  117 +++++++++++++++++++++++++++++
 31 files changed, 372 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/global_data.h +3 -0
index f8088fe..ef727b0 100644
@@ -82,6 +82,9 @@ 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
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       void    *early_heap_first;      /* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/arm/lib/board.c +4 -0
index f1951e8..f73d8b2 100644
@@ -53,6 +53,10 @@
 #include <post.h>
 #include <logbuff.h>
 
+#ifdef CONFIG_DM
+#include <dmmalloc.h>
+#endif
+
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
 #endif
@@ -281,6 +285,10 @@ void board_init_f(ulong bootflag)
 
        memset((void *)gd, 0, sizeof(gd_t));
 
Quoted 8 lines

arch/arm/lib/board.c void board_init_f(ulong bootflag) · line 291

Quoted 4 lines
arch/arm/lib/board.c +4 -0
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       gd->early_heap_first = early_brk(CONFIG_SYS_EARLY_HEAP_SIZE);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+

I just realised that all these initialisers can be dumped - early_brk() will be called when early_malloc() is first called

Quoted 5 lines

Yes, but how can I determine the size of the new heap which the early_brk gives out? When I have CONFIG_SYS_EARLY_HEAP_SIZE macro in board configuration I can ignore the size passed to the "default" early_brk and return the full-sized heap as configuration says (when the requested size is lower than configured heap size and NULL

default early_brk() should always use CONFIG_SYS_EARLY_HEAP_SIZE

Quoted 4 lines

otherwise). But what if somebody implements at some point a dynamic early_brk capable of returning multiple heaps? Should I safely assume that the future dynamic early_brk would give out multiples of page size or so?

Very good point. I would assume early_brk() will always return the largest possible chunk of memory it can. These sizes might be specified as multiple #defines in the board config or may be dynamically determined via hardware probing. Either way, that is a problem for the implementer to deal with :)

Regards,

Graeme

#40 lore raw

RFC PATCH v9 1/1 Add dmmalloc module for DM.

In reply to Tomas Hlavacek

Add pointer to the first early heap into GD structure. Implement simple early_malloc and early_free functions. Prepare for additional heaps and automated heap initialization. Add temporary early_malloc_active function (to be replaced in future by more coarse DM init flags).
Add DM specific malloc calls - dmmalloc, dmfree, dmrealloc and dmcalloc.

---
Changes in v9:
- Rework early_malloc to keep track of allocated block size.
- Add early_free and dmfree functions.
- Rework dmrealloc.
- Add kerneldoc comments to dmmalloc.h.

Changes in v8:
- Add dmcalloc() implmentation.
- Add comments to function prototypes in dmmalloc.h.

Changes in v7:
- Rework check of first heap in early_brk().

Changes in v6:
- Move dmmalloc() and all dm* functions to dmmalloc.h.
- Fix bool expression in early_malloc_active().

 arch/arm/include/asm/global_data.h        |    3 +
 arch/avr32/include/asm/global_data.h      |    3 +
 arch/blackfin/include/asm/global_data.h   |    3 +
 arch/m68k/include/asm/global_data.h       |    3 +
 arch/microblaze/include/asm/global_data.h |    3 +
 arch/mips/include/asm/global_data.h       |    3 +
 arch/nds32/include/asm/global_data.h      |    3 +
 arch/nios2/include/asm/global_data.h      |    3 +
 arch/openrisc/include/asm/global_data.h   |    3 +
 arch/powerpc/include/asm/global_data.h    |    3 +
 arch/sandbox/include/asm/global_data.h    |    3 +
 arch/sh/include/asm/global_data.h         |    3 +
 arch/sparc/include/asm/global_data.h      |    3 +
 arch/x86/include/asm/global_data.h        |    3 +
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |  188 ++++++++++++++++++++++++++++
 include/dmmalloc.h                        |  194 +++++++++++++++++++++++++++++
 17 files changed, 425 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/global_data.h +3 -0
index 2b9af93..9045829 100644
@@ -82,6 +82,9 @@ 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
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/avr32/include/asm/global_data.h +3 -0
index bf661e2..f18f480 100644
@@ -48,6 +48,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/blackfin/include/asm/global_data.h +3 -0
index d91e5a4..0725d55 100644
@@ -57,6 +57,9 @@ typedef struct global_data {
 
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap;		/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/m68k/include/asm/global_data.h +3 -0
index 0cdb11c..ab73499 100644
@@ -66,6 +66,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/microblaze/include/asm/global_data.h +3 -0
index 2111c7c..f991e5d 100644
@@ -46,6 +46,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/mips/include/asm/global_data.h +3 -0
index a735a8a..8167d39 100644
@@ -59,6 +59,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nds32/include/asm/global_data.h +3 -0
index b1feb2c..f7480e9 100644
@@ -63,6 +63,9 @@ typedef	struct global_data {
 
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nios2/include/asm/global_data.h +3 -0
index 413b485..8881e31 100644
@@ -42,6 +42,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/openrisc/include/asm/global_data.h +3 -0
index 96f3f1c..6ed6a15 100644
@@ -44,6 +44,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/powerpc/include/asm/global_data.h +3 -0
index 374fc6d..f8d440b 100644
@@ -182,6 +182,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sandbox/include/asm/global_data.h +3 -0
index 78a751d..6ee20e2 100644
@@ -46,6 +46,9 @@ typedef	struct global_data {
 	const void	*fdt_blob;	/* Our device tree, NULL if none */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sh/include/asm/global_data.h +3 -0
index 9a2c193..6e0ae54 100644
@@ -42,6 +42,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sparc/include/asm/global_data.h +3 -0
index aa63b35..9be8f27 100644
@@ -74,6 +74,9 @@ typedef struct global_data {
 #endif
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void	*early_heap;		/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/x86/include/asm/global_data.h +3 -0
index bce999f..60384a5 100644
@@ -57,6 +57,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	void		*early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 static inline gd_t *get_fs_gd_ptr(void)
common/Makefile +1 -0
index fdfead7..bfb4d7a 100644
@@ -209,6 +209,7 @@ COBJS-y += dlmalloc.o
 COBJS-y += image.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-$(CONFIG_DM) += dmmalloc.o
 
 
 COBJS	:= $(sort $(COBJS-y))
common/dmmalloc.c new file +188 -0

188 lines not on this page · raw message

include/dmmalloc.h new file +194 -0

194 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#41 lore raw

RFC PATCH v9 1/1 Add dmmalloc module for DM.

Hi Tomas,

Overall impression - Very nice indeed :)

A couple of nit-picks (some of which may be wrong on my part) and one lingering question around the switch over from early to late heap...

Quoted 52 lines · Tomas Hlavacek

Add pointer to the first early heap into GD structure. Implement simple early_malloc and early_free functions. Prepare for additional heaps and automated heap initialization. Add temporary early_malloc_active function (to be replaced in future by more coarse DM init flags).
Add DM specific malloc calls - dmmalloc, dmfree, dmrealloc and dmcalloc.

---
Changes in v9:
- Rework early_malloc to keep track of allocated block size.
- Add early_free and dmfree functions.
- Rework dmrealloc.
- Add kerneldoc comments to dmmalloc.h.

Changes in v8:
- Add dmcalloc() implmentation.
- Add comments to function prototypes in dmmalloc.h.

Changes in v7:
- Rework check of first heap in early_brk().

Changes in v6:
- Move dmmalloc() and all dm* functions to dmmalloc.h.
- Fix bool expression in early_malloc_active().

 arch/arm/include/asm/global_data.h        |    3 +
 arch/avr32/include/asm/global_data.h      |    3 +
 arch/blackfin/include/asm/global_data.h   |    3 +
 arch/m68k/include/asm/global_data.h       |    3 +
 arch/microblaze/include/asm/global_data.h |    3 +
 arch/mips/include/asm/global_data.h       |    3 +
 arch/nds32/include/asm/global_data.h      |    3 +
 arch/nios2/include/asm/global_data.h      |    3 +
 arch/openrisc/include/asm/global_data.h   |    3 +
 arch/powerpc/include/asm/global_data.h    |    3 +
 arch/sandbox/include/asm/global_data.h    |    3 +
 arch/sh/include/asm/global_data.h         |    3 +
 arch/sparc/include/asm/global_data.h      |    3 +
 arch/x86/include/asm/global_data.h        |    3 +
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |  188 ++++++++++++++++++++++++++++
 include/dmmalloc.h                        |  194 +++++++++++++++++++++++++++++
 17 files changed, 425 insertions(+)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/global_data.h +0 -0
index 2b9af93..9045829 100644

arch/arm/include/asm/global_data.h typedef struct global_data { · line 87

Quoted 6 lines
arch/arm/include/asm/global_data.h +3 -0
@@ -82,6 +82,9 @@ 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
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       void            *early_heap;    /* heap for early_malloc */
+#endif

Why not early_heap_header *early_heap; ?

diff --git a/common/Makefile b/common/Makefile

common/Makefile COBJS-y += dlmalloc.o · line 212

Quoted 8 lines

index fdfead7..bfb4d7a 100644

common/Makefile +1 -0
@@ -209,6 +209,7 @@ COBJS-y += dlmalloc.o
 COBJS-y += image.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-$(CONFIG_DM) += dmmalloc.o

COBJS-$(CONFIG_SYS_EARLY_MALLOC) += dmmalloc.o ?

Quoted 33 lines
common/Makefile +0 -0
 COBJS  := $(sort $(COBJS-y))
common/dmmalloc.c new file +26 -0
new file mode 100644
index 0000000..41589dd
@@ -0,0 +1,188 @@
+/*
+ * (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 */

common/dmmalloc.c line 36

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+#include <asm/types.h> /* for phys_addr_t and size_addt_t */
+
+#include <dmmalloc.h>
+#include <malloc.h>
+
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SYS_EARLY_MALLOC

If you use COBJS-$(CONFIG_SYS_EARLY_MALLOC) += dmmalloc.o in the Makefile, you can drop this #ifdef

common/dmmalloc.c line 46

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+__weak struct early_heap_header *early_brk(size_t size)
+{
+       struct early_heap_header *h;
+       struct early_block_header *b;
+
+       if (gd->early_heap != NULL)
+               return NULL;
+
+       h = (struct early_heap_header *)CONFIG_SYS_EARLY_HEAP_ADDR;
+       b = (struct early_block_header *)(h + 1);

Hmmm, does this really work? I would have thought:

b = (struct early_block_header *)(h + sizeof(struct early_heap_header));

but I could be mistaken

Quoted 109 lines
common/dmmalloc.c new file +109 -0
+
+       size = CONFIG_SYS_EARLY_HEAP_SIZE;
+       h->size = size;
+       h->early_heap_next = NULL;
+       b->size = size - sizeof(struct early_heap_header) -
+                       sizeof(struct early_block_header);
+       b->size = BLOCK_SET_FREE(b->size);
+
+       return h;
+}
+
+static struct early_block_header *find_free_space(struct early_heap_header *h,
+                                                       size_t size)
+{
+       struct early_block_header *b;
+
+       b = (struct early_block_header *)(h+1);
+       while ((phys_addr_t)b + sizeof(struct early_block_header)
+                       < (phys_addr_t)h + h->size) {
+               if (BLOCK_FREE(b->size) && (BLOCK_SIZE(b->size) >= size))
+                       return b;
+               b = (struct early_block_header *)((phys_addr_t)b +
+                               sizeof(struct early_block_header) +
+                               BLOCK_SIZE(b->size));
+       }
+
+       return NULL;
+}
+
+static struct early_block_header *split_block(struct early_block_header *b,
+              size_t size)
+{
+       struct early_block_header *nb;
+
+       if ((BLOCK_SIZE(b->size) < size) || (BLOCK_USED(b->size)))
+               return NULL;
+
+       if (BLOCK_SIZE(b->size) <= (size + sizeof(struct early_block_header)))
+               return b;
+
+       nb = (struct early_block_header *)((phys_addr_t)b +
+               sizeof(struct early_block_header) + size);
+       nb->size = b->size - size - sizeof(struct early_block_header);
+       b->size = size;
+
+       return b;
+}
+
+void *early_malloc(size_t size)
+{
+       struct early_heap_header *h;
+       struct early_block_header *b;
+
+       size = roundup(size, sizeof(phys_addr_t));
+       if (size == 0)
+               return NULL;
+
+       if (gd->early_heap == NULL)
+               gd->early_heap = early_brk(size);
+
+       if (gd->early_heap == NULL) {
+               debug("early_brk failed to initialize heap\n");
+               return NULL;
+       }
+
+       h = gd->early_heap;
+       while (1) {
+               b = find_free_space(h, size);
+               if (b != NULL)
+                       break;
+
+               if (h->early_heap_next != NULL)
+                       h = h->early_heap_next;
+               else
+                       break;
+       }
+
+       if (b == NULL) {
+               h->early_heap_next = early_brk(size+
+                               sizeof(struct early_heap_header)+
+                               sizeof(struct early_block_header));
+               h = h->early_heap_next;
+               if (h == NULL) {
+                       debug("early_brk failed to extend heap by %d B\n",
+                                       size);
+                       return NULL;
+               }
+
+               b = find_free_space(h, size);
+               if (b == NULL) {
+                       debug("early_malloc failed to extend heap by %d B\n",
+                                       size);
+                       return NULL;
+               }
+       }
+
+       if (b->size != size)
+               b = split_block(b, size);
+       if (b == NULL) {
+               debug("early_malloc failed to split block to %d B\n", size);
+               return NULL;
+       }
+
+       b->size = BLOCK_SET_USED(b->size);
+
+       return BLOCK_DATA(b);
+}
+
+void early_free(void *addr)

common/dmmalloc.c line 165

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+{
+       struct early_block_header *h = BLOCK_HEADER(addr);
+       assert(BLOCK_USED(h->size));
+       h->size = BLOCK_SET_FREE(h->size);
+}
+
+int early_malloc_active(void)
+{
+       return ((gd->flags & GD_FLG_RELOC) != GD_FLG_RELOC);
+}

I think we need another flag - GD_FLG_RELOC gets set before the permanent heap is initialised, so there is a window of opportunity where things may break

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+
+void early_heap_dump(struct early_heap_header *h)
+{
+       struct early_block_header *b;
+
+       debug("heap: h=%p, h->size=%d\n", h, h->size);
+
+       b = (struct early_block_header *)(h+1);
+       while ((phys_addr_t)b + sizeof(struct early_block_header)
+                       < (phys_addr_t)h + h->size) {

common/dmmalloc.c line 185

Quoted 10 lines
common/dmmalloc.c new file +10 -0
+               debug("block: h=%p h->size=%d b=%p b->size=%d b->(used)=%d\n",
+                               h, h->size, b, BLOCK_SIZE(b->size),
+                               BLOCK_USED(b->size));
+               assert(BLOCK_SIZE(b->size) > 0);
+               b = (struct early_block_header *)((phys_addr_t)b +
+                               sizeof(struct early_block_header) +
+                               BLOCK_SIZE(b->size));
+       }
+       debug("--- heap dump end ---\n");
+}

Nice touch, but could we just iterate through all ealry heap chunks starting from gd->early_heap?

Quoted 33 lines
common/dmmalloc.c new file +3 -0
+
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
include/dmmalloc.h new file +24 -0
new file mode 100644
index 0000000..a241e19
@@ -0,0 +1,194 @@
+/*
+ * (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

include/dmmalloc.h line 34

Quoted 10 lines
include/dmmalloc.h new file +10 -0
+#define __INCLUDE_DMMALLOC_H
+
+#include <config.h>
+#include <linux/stddef.h> /* for size_t */
+#include <malloc.h>
+
+#if (!defined(CONFIG_SYS_EARLY_HEAP_ADDR)) || \
+       (!defined(CONFIG_SYS_EARLY_HEAP_SIZE))
+#undef CONFIG_SYS_EARLY_MALLOC
+#endif /* CONFIG_SYS_EARLY_HEAP_ADDR */

If a board implements early_brk() using non-fixed a address and/or size then this is going to cause trouble

include/dmmalloc.h line 35

Quoted 1 line
include/dmmalloc.h new file +1 -0
+#ifdef CONFIG_SYS_EARLY_MALLOC

I see no need for the #ifdef

include/dmmalloc.h line 47

Quoted 11 lines
include/dmmalloc.h new file +11 -0
+struct early_heap_header {
+       size_t size;
+       void *early_heap_next;
+};
+
+struct early_block_header {
+       size_t size;
+};
+
+#define BLOCK_DATA(header) ((void *)(((struct early_block_header *)header)+1))
+#define BLOCK_HEADER(addr) (((struct early_block_header *)addr)-1)

Again, not sure if this is correct. I would have thought:

(struct early_block_header *)(addr - sizeof(struct early_block_header)

And again, not sure if I'm right

include/dmmalloc.h line 53

Quoted 6 lines
include/dmmalloc.h new file +6 -0
+#define BLOCK_USED_FLAG 0x80000000
+#define BLOCK_SIZE(size) (size & (~BLOCK_USED_FLAG))
+#define BLOCK_USED(size) ((size & BLOCK_USED_FLAG) == BLOCK_USED_FLAG)
+#define BLOCK_FREE(size) (!BLOCK_USED(size))
+#define BLOCK_SET_FREE(size) BLOCK_SIZE(size)
+#define BLOCK_SET_USED(size) (size | BLOCK_USED_FLAG)

Hmmm, I'm not sure what the general policy is about where to put 'stuff' that is only used by the implementation and does not 'need' to be made publically available. i.e. I don't know if these #defines and the early_block_header struct belong here or in the .c file...

Quoted 39 lines
include/dmmalloc.h new file +39 -0
+
+/**
+ * early_brk() - obtain address of the heap
+ * @size:      Minimal size of the new early heap to be allocated.
+ *
+ * Function returns a new heap pointer.
+ *
+ * Allocate and initialize early_heap at least size bytes long.
+ * This function can be platform dependent or board dependent but sensible
+ * default is provided.
+ */
+struct early_heap_header *early_brk(size_t size);
+
+/**
+ * early_malloc() - malloc operating on the early_heap(s)
+ * @size:      Size in bytes.
+ *
+ * Function returns a pointer to the allocated block.
+ */
+void *early_malloc(size_t size);
+
+/**
+ * early_free() - free operating on the early_heap(s)
+ * @addr:      Pointer to the allocated block to be released.
+ */
+void early_free(void *addr);
+
+/**
+ * early_malloc_active() - indicate if the early mallocator is active
+ *
+ * Function returns true when the early_malloc and early_free are used and
+ * false otherwise.
+ */
+int early_malloc_active(void);
+
+/**
+ * early_heap_dump() - print blocks contained in an early_heap
+ * @h:         Address of the early heap.
+ */

include/dmmalloc.h line 102

Quoted 10 lines
include/dmmalloc.h new file +10 -0
+void early_heap_dump(struct early_heap_header *h);
+
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_DM
+
+/*
+ * DM versions of malloc* functions. In early init it calls early_malloc.
+ * It wraps around normal malloc* functions afterwards.
+ */

I don't think these _need_ to be inline functions - The compiler should be smart enough no (non-)inline them as appropriate.

Quoted 78 lines
include/dmmalloc.h new file +78 -0
+
+/**
+ * dmmalloc() - malloc working seamlessly in early as well as in RAM stages
+ * @size:      Size of the block to be allocated.
+ *
+ * Function returns an address of the newly allocated block when successful
+ * or NULL otherwise.
+ */
+static inline void *dmmalloc(size_t size)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       if (early_malloc_active())
+               return early_malloc(size);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+       return malloc(size);
+}
+
+/**
+ * dmfree() - free working seamlessly in early as well as in RAM stages
+ * @ptr:       Pointer to the allocated block to be released.
+ */
+static inline void dmfree(void *ptr)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       if (early_malloc_active()) {
+               early_free(ptr);
+               return;
+       }
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+       free(ptr);
+}
+
+/**
+ * dmcalloc() - calloc working seamlessly in early as well as in RAM stages
+ * @n:         Number of elements to be allocated.
+ * @elem_size: Size of elements to be allocated.
+ *
+ * Function returns a pointer to newly the allocated area (n*elem_size) long.
+ */
+static inline void *dmcalloc(size_t n, size_t elem_size)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       char *addr;
+       int size = elem_size * n;
+
+       if (early_malloc_active()) {
+               addr = early_malloc(size);
+               memset(addr, 0, size);
+               return addr;
+       }
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+       return calloc(n, elem_size);
+}
+
+/**
+ * dmrealloc() - realloc working seamlessly in early as well as in RAM stages
+ * @oldaddr:   Pointer to the old memory block.
+ * @bytes:     New size to of the block to be reallocated.
+ *
+ * Function returns an address of the newly allocated block when successful
+ * or NULL otherwise.
+ *
+ * Data are copied from the block specified by oldaddr to the new block.
+ */
+static inline void *dmrealloc(void *oldaddr, size_t bytes)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       char *addr;
+       struct early_block_header *h;
+       if (early_malloc_active()) {
+               addr = dmmalloc(bytes);
+               if (addr == NULL)
+                       return NULL;
+
+               h = BLOCK_HEADER(oldaddr);
+               if (BLOCK_FREE(h->size))
+                       return NULL;
+

include/dmmalloc.h line 190

Quoted 10 lines
include/dmmalloc.h new file +10 -0
+               if (bytes > BLOCK_SIZE(h->size))
+                       bytes = BLOCK_SIZE(h->size);
+
+               memcpy(addr, oldaddr, bytes);
+               dmfree(oldaddr);
+               return addr;
+       }
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+       return realloc(oldaddr, bytes);
+}

Hmmm, we have a very intersting corner case to deal with. What if we use dmrealloc() to move allocated data from the early malloc pool to the final malloc pool?

At some point, we need to assume the developer is only ever going to pass early malloc'd memory to dmrealloc()

The other option is to use the gd->flags...

Define two flags - something like:

GD_FLG_HEAP_INIT -> Final heap has been initialised
GD_FLG_EH_DONE -> free(), realloc() refer to final heap

(I don't like the names, I'm just not up to thinking of anything better)

This way we can use dmalloc() prior to the heap being initialised and then set GD_FLG_HEAP_INIT. Once GD_FLG_HEAP_INIT has been set, do a bunch of dmrealloc() calls to essentially move the data into the permanent heap (of course pointers int the structures need to be fixed up by the drivers) and finally set GD_FLG_EH_DONE (and call early_heap_dump)

One problem I see is what happens of you call malloc() and free() on the same block between the setting of GD_FLG_HEAP_INIT and GD_FLG_EH_DONE? The code will try to reference the block as if it is in the early heap, but it won't be.

One solution is, on detection of GD_FLG_HEAP_INIT being set, dmfree() and dmrealloc() could search the early heap chunks instead of just assuming that the referenced block is in the early heap (if GD_FLG_HEAP_INIT has not been set, it will be safe to assume the memory is on the early heap)

Quoted 7 lines
include/dmmalloc.h new file +4 -1
+
+#endif /* CONFIG_DM */
+#endif /* __INCLUDE_DMMALLOC_H */
+
--

1.7.10.4

Regards,

Graeme

#42 lore raw

RFC PATCH v9 1/1 Add dmmalloc module for DM.

Hello Graeme,

Quoted 5 lines · Graeme Russ
Quoted 5 lines
arch/arm/include/asm/global_data.h +0 -0
index 2b9af93..9045829 100644
@@ -82,6 +82,9 @@ typedef       struct  global_data {
Quoted 9 lines

arch/arm/include/asm/global_data.h typedef struct global_data { · line 87

Quoted 6 lines
arch/arm/include/asm/global_data.h +3 -0
        unsigned long   post_log_res; /* success of POST test */
        unsigned long   post_init_f_time; /* When post_init_f started */
 #endif
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       void            *early_heap;    /* heap for early_malloc */
+#endif

Why not early_heap_header *early_heap; ?

It might be.

Actually it is a good point because I am using 3 different ways of dealing with addresses: 1) struct early_heap header * or struct early_block_header * - I am using this when I want to access members of the stucture or compute address past the structure (which is where the heap or block starts); 2) phys_addr_t - which is plain integer and I use this for simple computations when I do not want to worry about pointer arithmetic; 3) void * when I have just plain address, especially when I want to pass an addres among logical parts of the mallocator or outside. This may a bit controversial and perhaps I should replace it by specific strucutre pointers internally.

I am unable to decide: Should I remove struct early_heap_header from dmmalloc.h making it publicly unavailable or should I rather change the void * to struct early_heap_header * in the GD structure? What do you think is better?

Quoted 11 lines

diff --git a/common/Makefile b/common/Makefile

common/Makefile COBJS-y += dlmalloc.o · line 212

Quoted 8 lines

index fdfead7..bfb4d7a 100644

common/Makefile +1 -0
@@ -209,6 +209,7 @@ COBJS-y += dlmalloc.o
 COBJS-y += image.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-$(CONFIG_DM) += dmmalloc.o

COBJS-$(CONFIG_SYS_EARLY_MALLOC) += dmmalloc.o ?

Oh yes, now it is redundant to #ifdef CONFIG_SYS_EARLY_MALLOC inside the dmmalloc.c file. I had a plan to extend the dmmalloc.c file by relocation routines and then it would make sense. But I will shufle the code a bit in the v10 anyway and we will see if the #ifdefs can still be reduced.

Quoted 9 lines
Quoted 9 lines
common/Makefile +9 -0
+
+#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>
+
Quoted 8 lines

common/Makefile

Quoted 5 lines
common/Makefile +5 -0
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SYS_EARLY_MALLOC

If you use COBJS-$(CONFIG_SYS_EARLY_MALLOC) += dmmalloc.o in the Makefile, you can drop this #ifdef

Yes, that is redundant now.

Quoted 14 lines

common/Makefile

Quoted 11 lines
common/Makefile +10 -0
+__weak struct early_heap_header *early_brk(size_t size)
+{
+       struct early_heap_header *h;
+       struct early_block_header *b;
+
+       if (gd->early_heap != NULL)
+               return NULL;
+
+       h = (struct early_heap_header *)CONFIG_SYS_EARLY_HEAP_ADDR;
+       b = (struct early_block_header *)(h + 1);

Hmmm, does this really work? I would have thought:

Quoted 3 lines

b = (struct early_block_header *)(h + sizeof(struct early_heap_header));

but I could be mistaken

It seems that it works as it is (at least I wrote bunch of tests and I inspected resulting heaps and it was all right). I believe that since h is a pointer to the struct early_heap_header then pointer arithmetic is in effect and h+1 actually means "next element in the array of struct early_heap_header". Which is the address past the header that equals beginning of the heap data block. (?)

Quoted 8 lines

common/Makefile

Quoted 4 lines
common/Makefile +4 -0
+int early_malloc_active(void)
+{
+       return ((gd->flags & GD_FLG_RELOC) != GD_FLG_RELOC);
+}

I think we need another flag - GD_FLG_RELOC gets set before the permanent heap is initialised, so there is a window of opportunity where things may break

Well, as I wrote in the commit message - this is only a temporary implementation. I suppose I am going to change this when we have more coarse initialization flags wired into DM (which I believe we are going to have it anyway). So now I am just working around "forward dependency" here.

Quoted 16 lines
Quoted 16 lines
common/Makefile +15 -0
+
+void early_heap_dump(struct early_heap_header *h)
+{
+       struct early_block_header *b;
+
+       debug("heap: h=%p, h->size=%d\n", h, h->size);
+
+       b = (struct early_block_header *)(h+1);
+       while ((phys_addr_t)b + sizeof(struct early_block_header)
+                       < (phys_addr_t)h + h->size) {
+               debug("block: h=%p h->size=%d b=%p b->size=%d b->(used)=%d\n",
+                               h, h->size, b, BLOCK_SIZE(b->size),
+                               BLOCK_USED(b->size));
+               assert(BLOCK_SIZE(b->size) > 0);
+               b = (struct early_block_header *)((phys_addr_t)b +
Quoted 8 lines

common/Makefile

Quoted 5 lines
common/Makefile +5 -0
+                               sizeof(struct early_block_header) +
+                               BLOCK_SIZE(b->size));
+       }
+       debug("--- heap dump end ---\n");
+}

Nice touch, but could we just iterate through all ealry heap chunks starting from gd->early_heap?

Or I can have two functions. One heap specific and one for all heaps. I think both might be useful when somebody needs to debug early_malloc or memory usage etc. in the early stage. Thanks.

Quoted 7 lines
Quoted 7 lines
common/Makefile +7 -0
+
+#ifndef __INCLUDE_DMMALLOC_H
+#define __INCLUDE_DMMALLOC_H
+
+#include <config.h>
+#include <linux/stddef.h> /* for size_t */
+#include <malloc.h>
Quoted 8 lines

common/Makefile

Quoted 5 lines
common/Makefile +5 -0
+
+#if (!defined(CONFIG_SYS_EARLY_HEAP_ADDR)) || \
+       (!defined(CONFIG_SYS_EARLY_HEAP_SIZE))
+#undef CONFIG_SYS_EARLY_MALLOC
+#endif /* CONFIG_SYS_EARLY_HEAP_ADDR */

If a board implements early_brk() using non-fixed a address and/or size then this is going to cause trouble

Right, I will drop this.

Quoted 15 lines
Quoted 2 lines

+#ifdef CONFIG_SYS_EARLY_MALLOC

I see no need for the #ifdef

Quoted 9 lines
common/Makefile +9 -0
+struct early_heap_header {
+       size_t size;
+       void *early_heap_next;
+};
+
+struct early_block_header {
+       size_t size;
+};
+
Quoted 11 lines

common/Makefile

Quoted 6 lines
common/Makefile +6 -0
+#define BLOCK_USED_FLAG 0x80000000
+#define BLOCK_SIZE(size) (size & (~BLOCK_USED_FLAG))
+#define BLOCK_USED(size) ((size & BLOCK_USED_FLAG) == BLOCK_USED_FLAG)
+#define BLOCK_FREE(size) (!BLOCK_USED(size))
+#define BLOCK_SET_FREE(size) BLOCK_SIZE(size)
+#define BLOCK_SET_USED(size) (size | BLOCK_USED_FLAG)

Hmmm, I'm not sure what the general policy is about where to put 'stuff' that is only used by the implementation and does not 'need' to be made publically available. i.e. I don't know if these #defines and the early_block_header struct belong here or in the .c file...

You are right, I will put it to the .c.

Quoted 45 lines
Quoted 45 lines
common/Makefile +44 -0
+
+/**
+ * early_brk() - obtain address of the heap
+ * @size:      Minimal size of the new early heap to be allocated.
+ *
+ * Function returns a new heap pointer.
+ *
+ * Allocate and initialize early_heap at least size bytes long.
+ * This function can be platform dependent or board dependent but sensible
+ * default is provided.
+ */
+struct early_heap_header *early_brk(size_t size);
+
+/**
+ * early_malloc() - malloc operating on the early_heap(s)
+ * @size:      Size in bytes.
+ *
+ * Function returns a pointer to the allocated block.
+ */
+void *early_malloc(size_t size);
+
+/**
+ * early_free() - free operating on the early_heap(s)
+ * @addr:      Pointer to the allocated block to be released.
+ */
+void early_free(void *addr);
+
+/**
+ * early_malloc_active() - indicate if the early mallocator is active
+ *
+ * Function returns true when the early_malloc and early_free are used and
+ * false otherwise.
+ */
+int early_malloc_active(void);
+
+/**
+ * early_heap_dump() - print blocks contained in an early_heap
+ * @h:         Address of the early heap.
+ */
+void early_heap_dump(struct early_heap_header *h);
+
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_DM
Quoted 8 lines

common/Makefile

Quoted 5 lines
common/Makefile +5 -0
+
+/*
+ * DM versions of malloc* functions. In early init it calls early_malloc.
+ * It wraps around normal malloc* functions afterwards.
+ */

I don't think these _need_ to be inline functions - The compiler should be smart enough no (non-)inline them as appropriate.

Yes. Now I am thinking about pulling all this into the .c file and making the functions non-static. Actually, this "static inline" evolved from really simple "if(...) early_malloc() else malloc()", but now it is not always straight-forward and even more future extensions are expected to these functions due to relocation-related code.

Quoted 94 lines
Quoted 79 lines
common/Makefile +78 -0
+
+/**
+ * dmmalloc() - malloc working seamlessly in early as well as in RAM stages
+ * @size:      Size of the block to be allocated.
+ *
+ * Function returns an address of the newly allocated block when successful
+ * or NULL otherwise.
+ */
+static inline void *dmmalloc(size_t size)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       if (early_malloc_active())
+               return early_malloc(size);
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+       return malloc(size);
+}
+
+/**
+ * dmfree() - free working seamlessly in early as well as in RAM stages
+ * @ptr:       Pointer to the allocated block to be released.
+ */
+static inline void dmfree(void *ptr)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       if (early_malloc_active()) {
+               early_free(ptr);
+               return;
+       }
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+       free(ptr);
+}
+
+/**
+ * dmcalloc() - calloc working seamlessly in early as well as in RAM stages
+ * @n:         Number of elements to be allocated.
+ * @elem_size: Size of elements to be allocated.
+ *
+ * Function returns a pointer to newly the allocated area (n*elem_size) long.
+ */
+static inline void *dmcalloc(size_t n, size_t elem_size)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       char *addr;
+       int size = elem_size * n;
+
+       if (early_malloc_active()) {
+               addr = early_malloc(size);
+               memset(addr, 0, size);
+               return addr;
+       }
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+       return calloc(n, elem_size);
+}
+
+/**
+ * dmrealloc() - realloc working seamlessly in early as well as in RAM stages
+ * @oldaddr:   Pointer to the old memory block.
+ * @bytes:     New size to of the block to be reallocated.
+ *
+ * Function returns an address of the newly allocated block when successful
+ * or NULL otherwise.
+ *
+ * Data are copied from the block specified by oldaddr to the new block.
+ */
+static inline void *dmrealloc(void *oldaddr, size_t bytes)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       char *addr;
+       struct early_block_header *h;
+       if (early_malloc_active()) {
+               addr = dmmalloc(bytes);
+               if (addr == NULL)
+                       return NULL;
+
+               h = BLOCK_HEADER(oldaddr);
+               if (BLOCK_FREE(h->size))
+                       return NULL;
+

common/Makefile

Quoted 10 lines
common/Makefile +10 -0
+               if (bytes > BLOCK_SIZE(h->size))
+                       bytes = BLOCK_SIZE(h->size);
+
+               memcpy(addr, oldaddr, bytes);
+               dmfree(oldaddr);
+               return addr;
+       }
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+       return realloc(oldaddr, bytes);
+}

Hmmm, we have a very intersting corner case to deal with. What if we use dmrealloc() to move allocated data from the early malloc pool to the final malloc pool?

Quoted 2 lines

At some point, we need to assume the developer is only ever going to pass early malloc'd memory to dmrealloc()

Good point! The current code would do the job assuming that the early_malloc can still access the proper early_heap (or a copy, but in that case some additional magic is needed) and the real malloc is already initialized.

As you can see I am still sticking with the double-copy method. It is maybe due to lack of insight. But the discussion here was not absolutely conclusive last time. I have even some experimental code (not ready for submitting at all) for double copy method but I would prefer to discuss it separately when the early_malloc() is done.

Quoted 21 lines

The other option is to use the gd->flags...

Define two flags - something like:

GD_FLG_HEAP_INIT -> Final heap has been initialised
GD_FLG_EH_DONE -> free(), realloc() refer to final heap

(I don't like the names, I'm just not up to thinking of anything better)

This way we can use dmalloc() prior to the heap being initialised and then set GD_FLG_HEAP_INIT. Once GD_FLG_HEAP_INIT has been set, do a bunch of dmrealloc() calls to essentially move the data into the permanent heap (of course pointers int the structures need to be fixed up by the drivers) and finally set GD_FLG_EH_DONE (and call early_heap_dump)

One problem I see is what happens of you call malloc() and free() on the same block between the setting of GD_FLG_HEAP_INIT and GD_FLG_EH_DONE? The code will try to reference the block as if it is in the early heap, but it won't be.

Quoted 4 lines

One solution is, on detection of GD_FLG_HEAP_INIT being set, dmfree() and dmrealloc() could search the early heap chunks instead of just assuming that the referenced block is in the early heap (if GD_FLG_HEAP_INIT has not been set, it will be safe to assume the memory is on the early heap)

Sure we will have that flags. But I think we can use them as well for switching from DM driver instance list to tree for example. Or other way around: I can use DM flags for early_malloc. Therefore I would like to synchronize with DM cores for PCI and another low-level things which are certainly going to start in early stage. It would be best to use the same flags and switch on/off early_malloc based on DM internal state.

Best regards,
Tomas

#43 lore raw

RFC PATCH v9 1/1 Add dmmalloc module for DM.

Hi Tomas,

Quoted 32 lines · Tomas Hlavacek

Hello Graeme,

Quoted 5 lines · Graeme Russ
Quoted 5 lines
arch/arm/include/asm/global_data.h +0 -0
index 2b9af93..9045829 100644
@@ -82,6 +82,9 @@ typedef       struct  global_data {
Quoted 9 lines

arch/arm/include/asm/global_data.h typedef struct global_data { · line 87

Quoted 6 lines
arch/arm/include/asm/global_data.h +3 -0
        unsigned long   post_log_res; /* success of POST test */
        unsigned long   post_init_f_time; /* When post_init_f started */
 #endif
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       void            *early_heap;    /* heap for early_malloc */
+#endif

Why not early_heap_header *early_heap; ?

It might be.

Actually it is a good point because I am using 3 different ways of dealing with addresses: 1) struct early_heap header * or struct early_block_header * - I am using this when I want to access members of the stucture or compute address past the structure (which is where the heap or block starts); 2) phys_addr_t - which is plain integer and I use this for simple computations when I do not want to worry about pointer arithmetic; 3) void * when I have just plain address, especially when I want to pass an addres among logical parts of the mallocator or outside. This may a bit controversial and perhaps I should replace it by specific strucutre pointers internally.

Quoted 4 lines

I am unable to decide: Should I remove struct early_heap_header from dmmalloc.h making it publicly unavailable or should I rather change the void * to struct early_heap_header * in the GD structure? What do you think is better?

I think struct early_heap_header * in the GD structure is the better way to go as that is exactly what it is.

[snip]

Quoted 7 lines
Quoted 7 lines

arch/arm/include/asm/global_data.h typedef struct global_data { · line 89

Quoted 2 lines
arch/arm/include/asm/global_data.h +2 -0
+       h = (struct early_heap_header *)CONFIG_SYS_EARLY_HEAP_ADDR;
+       b = (struct early_block_header *)(h + 1);

Hmmm, does this really work? I would have thought:

b = (struct early_block_header *)(h + sizeof(struct early_heap_header));

Quoted 8 lines
Quoted 1 line

but I could be mistaken

It seems that it works as it is (at least I wrote bunch of tests and I inspected resulting heaps and it was all right). I believe that since h is a pointer to the struct early_heap_header then pointer arithmetic is in effect and h+1 actually means "next element in the array of struct early_heap_header". Which is the address past the header that equals beginning of the heap data block. (?)

As I said, I could be mistaken - it appears I am :)

Quoted 40 lines
Quoted 8 lines

arch/arm/include/asm/global_data.h typedef struct global_data {

Quoted 4 lines
arch/arm/include/asm/global_data.h +4 -0
+int early_malloc_active(void)
+{
+       return ((gd->flags & GD_FLG_RELOC) != GD_FLG_RELOC);
+}

I think we need another flag - GD_FLG_RELOC gets set before the permanent heap is initialised, so there is a window of opportunity where things may break

Well, as I wrote in the commit message - this is only a temporary implementation. I suppose I am going to change this when we have more coarse initialization flags wired into DM (which I believe we are going to have it anyway). So now I am just working around "forward dependency" here.

Quoted 16 lines
Quoted 16 lines
arch/arm/include/asm/global_data.h +15 -0
+
+void early_heap_dump(struct early_heap_header *h)
+{
+       struct early_block_header *b;
+
+       debug("heap: h=%p, h->size=%d\n", h, h->size);
+
+       b = (struct early_block_header *)(h+1);
+       while ((phys_addr_t)b + sizeof(struct early_block_header)
+                       < (phys_addr_t)h + h->size) {
+               debug("block: h=%p h->size=%d b=%p b->size=%d b->(used)=%d\n",
+                               h, h->size, b, BLOCK_SIZE(b->size),
+                               BLOCK_USED(b->size));
+               assert(BLOCK_SIZE(b->size) > 0);
+               b = (struct early_block_header *)((phys_addr_t)b +
Quoted 8 lines

arch/arm/include/asm/global_data.h

Quoted 5 lines
arch/arm/include/asm/global_data.h +5 -0
+                               sizeof(struct early_block_header) +
+                               BLOCK_SIZE(b->size));
+       }
+       debug("--- heap dump end ---\n");
+}

Nice touch, but could we just iterate through all ealry heap chunks starting from gd->early_heap?

Quoted 3 lines

Or I can have two functions. One heap specific and one for all heaps. I think both might be useful when somebody needs to debug early_malloc or memory usage etc. in the early stage. Thanks.

True, just adding another function which iterates through the heaps and calls this function would be fine.

[snip]

Quoted 37 lines
Quoted 29 lines
Quoted 14 lines
arch/arm/include/asm/global_data.h +14 -0
+static inline void *dmrealloc(void *oldaddr, size_t bytes)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+       char *addr;
+       struct early_block_header *h;
+       if (early_malloc_active()) {
+               addr = dmmalloc(bytes);
+               if (addr == NULL)
+                       return NULL;
+
+               h = BLOCK_HEADER(oldaddr);
+               if (BLOCK_FREE(h->size))
+                       return NULL;
+

arch/arm/include/asm/global_data.h

Quoted 10 lines
arch/arm/include/asm/global_data.h +10 -0
+               if (bytes > BLOCK_SIZE(h->size))
+                       bytes = BLOCK_SIZE(h->size);
+
+               memcpy(addr, oldaddr, bytes);
+               dmfree(oldaddr);
+               return addr;
+       }
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+       return realloc(oldaddr, bytes);
+}

Hmmm, we have a very intersting corner case to deal with. What if we use dmrealloc() to move allocated data from the early malloc pool to the final malloc pool?

Quoted 2 lines

At some point, we need to assume the developer is only ever going to pass early malloc'd memory to dmrealloc()

Good point! The current code would do the job assuming that the early_malloc can still access the proper early_heap (or a copy, but in that case some additional magic is needed) and the real malloc is already initialized.

Quoted 5 lines

As you can see I am still sticking with the double-copy method. It is maybe due to lack of insight. But the discussion here was not absolutely conclusive last time. I have even some experimental code (not ready for submitting at all) for double copy method but I would prefer to discuss it separately when the early_malloc() is done.

Well the double-copy approach to reallocating early-malloc'd memory and how dmrealloc() is implemented are tightly coupled.

I understand the reason for the double copy is performance related (getting into a position to enable cache as early as possible), but I wonder how much will really be gained. It seems to me that the only performance gain will be for the execution of the driver 'relocation fixup' code wich, I assume, would not really consume that many CPU cycles.

There is a point where code simplicity outweighs performance gains.

Quoted 25 lines
Quoted 20 lines

The other option is to use the gd->flags...

Define two flags - something like:

GD_FLG_HEAP_INIT -> Final heap has been initialised
GD_FLG_EH_DONE -> free(), realloc() refer to final heap

(I don't like the names, I'm just not up to thinking of anything better)

This way we can use dmalloc() prior to the heap being initialised and then set GD_FLG_HEAP_INIT. Once GD_FLG_HEAP_INIT has been set, do a bunch of dmrealloc() calls to essentially move the data into the permanent heap (of course pointers int the structures need to be fixed up by the drivers) and finally set GD_FLG_EH_DONE (and call early_heap_dump)

One problem I see is what happens of you call malloc() and free() on the same block between the setting of GD_FLG_HEAP_INIT and GD_FLG_EH_DONE? The code will try to reference the block as if it is in the early heap, but it won't be.

Quoted 4 lines

One solution is, on detection of GD_FLG_HEAP_INIT being set, dmfree() and dmrealloc() could search the early heap chunks instead of just assuming that the referenced block is in the early heap (if GD_FLG_HEAP_INIT has not been set, it will be safe to assume the memory is on the early heap)

Quoted 7 lines

Sure we will have that flags. But I think we can use them as well for switching from DM driver instance list to tree for example. Or other way around: I can use DM flags for early_malloc. Therefore I would like to synchronize with DM cores for PCI and another low-level things which are certainly going to start in early stage. It would be best to use the same flags and switch on/off early_malloc based on DM internal state.

Ah, I see where more performance gains are to be made by switching on cache earlier - During the reallocation phase, you are switching from the list based structure (fast for the small number of pre-SDRAM drivers) into the final tree based structure.

I'm looking at this early malloc code from a much more generic point of view - I think there are use-cases outside the driver model, so I don't see a need (rather the opposite) to tie early malloc to the driver model

Regards,

Graeme

#44 lore raw

PATCH v10 1/1 Add dmmalloc module for DM.

In reply to Tomas Hlavacek

Add pointer to the first early heap into GD structure. Implement simple early_malloc and early_free functions. Prepare for additional heaps and automated heap initialization. Add temporary early_malloc_active function (to be replaced in future by more coarse DM init flags).
Add DM specific malloc calls - dmmalloc, dmfree, dmrealloc and dmcalloc.

---
Changes in v10:
- Change GD type to struct early_heap_header *.
- Move dmmalloc, dmfree, ... function from .h to dmmalloc.c .
- Rework early_malloc_active() to use new GD_FLG_HEAP_INIT flag.
- Add early_heap_active() and GD_FLG_EARLY_HEAP_DONE flag.
- Rework dmrealloc() and dmfree() to use new flags and support relocation.
- Rename early_heap_dump() to early_malloc_heap_dump().
- Add early_malloc_dump.
- Drop conditional undef CONFIG_SYS_EARLY_MALLOC in dmmalloc.h.
- Moved struct early_block_header and macros to dmmalloc.c.

Changes in v9:
- Rework early_malloc to keep track of allocated block size.
- Add early_free and dmfree functions.
- Rework dmrealloc.

Changes in v8:
- Add dmcalloc() implementation.
- Add comments to function prototypes in dmmalloc.h.

Changes in v7:
- Rework check of first heap in early_brk().

Changes in v6:
- Move dmmalloc() and all dm* functions to dmmalloc.h.
- Fix bool expression in early_malloc_active().

 arch/arm/include/asm/global_data.h        |    8 +
 arch/avr32/include/asm/global_data.h      |    7 +
 arch/blackfin/include/asm/global_data.h   |    6 +
 arch/m68k/include/asm/global_data.h       |    8 +
 arch/microblaze/include/asm/global_data.h |    8 +
 arch/mips/include/asm/global_data.h       |    6 +
 arch/nds32/include/asm/global_data.h      |    8 +
 arch/nios2/include/asm/global_data.h      |    7 +
 arch/openrisc/include/asm/global_data.h   |    8 +
 arch/powerpc/include/asm/global_data.h    |    6 +
 arch/sandbox/include/asm/global_data.h    |    7 +
 arch/sh/include/asm/global_data.h         |    7 +
 arch/sparc/include/asm/global_data.h      |    6 +
 arch/x86/include/asm/global_data.h        |    8 +
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |  297 +++++++++++++++++++++++++++++
 include/asm-generic/global_data_flags.h   |    6 +-
 include/dmmalloc.h                        |  132 +++++++++++++
 18 files changed, 534 insertions(+), 2 deletions(-)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/global_data.h +8 -0
index 2b9af93..01075dc 100644
@@ -23,6 +23,11 @@
 
 #ifndef	__ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory which is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -82,6 +87,9 @@ 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
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/avr32/include/asm/global_data.h +7 -0
index bf661e2..ba9cf0e 100644
@@ -22,6 +22,10 @@
 #ifndef __ASM_GLOBAL_DATA_H__
 #define __ASM_GLOBAL_DATA_H__
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -48,6 +52,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/blackfin/include/asm/global_data.h +6 -0
index d91e5a4..daeb314 100644
@@ -29,6 +29,9 @@
 #define __ASM_GBL_DATA_H
 
 #include <asm/u-boot.h>
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 
 /*
  * The following data structure is placed in some memory wich is
@@ -57,6 +60,9 @@ typedef struct global_data {
 
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/m68k/include/asm/global_data.h +8 -0
index 0cdb11c..dad2ba5 100644
@@ -23,6 +23,11 @@
 
 #ifndef	__ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -66,6 +71,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/microblaze/include/asm/global_data.h +8 -0
index 2111c7c..f6609b8 100644
@@ -24,6 +24,11 @@
 
 #ifndef	__ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -46,6 +51,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/mips/include/asm/global_data.h +6 -0
index a735a8a..c9b76f6 100644
@@ -25,6 +25,9 @@
 #define __ASM_GBL_DATA_H
 
 #include <asm/regdef.h>
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 
 /*
  * The following data structure is placed in some memory wich is
@@ -59,6 +62,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nds32/include/asm/global_data.h +8 -0
index b1feb2c..6d972c2 100644
@@ -33,6 +33,11 @@
 
 #ifndef	__ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -63,6 +68,9 @@ typedef	struct global_data {
 
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nios2/include/asm/global_data.h +7 -0
index 413b485..441e566 100644
@@ -23,6 +23,10 @@
 #ifndef	__ASM_NIOS2_GLOBALDATA_H_
 #define __ASM_NIOS2_GLOBALDATA_H_
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 typedef	struct	global_data {
 	bd_t		*bd;
 	unsigned long	flags;
@@ -42,6 +46,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/openrisc/include/asm/global_data.h +8 -0
index 96f3f1c..94fcef1 100644
@@ -24,6 +24,11 @@
 
 #ifndef __ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -44,6 +49,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/powerpc/include/asm/global_data.h +6 -0
index 374fc6d..ed67bfd 100644
@@ -26,6 +26,9 @@
 
 #include "config.h"
 #include "asm/types.h"
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 
 /*
  * The following data structure is placed in some memory wich is
@@ -182,6 +185,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sandbox/include/asm/global_data.h +7 -0
index 78a751d..0d4b4b0 100644
@@ -33,6 +33,10 @@
  * up the memory controller so that we can use RAM).
  */
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 typedef	struct global_data {
 	bd_t		*bd;
 	unsigned long	flags;
@@ -46,6 +50,9 @@ typedef	struct global_data {
 	const void	*fdt_blob;	/* Our device tree, NULL if none */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sh/include/asm/global_data.h +7 -0
index 9a2c193..acacae7 100644
@@ -27,6 +27,10 @@
 #ifndef	__ASM_SH_GLOBALDATA_H_
 #define __ASM_SH_GLOBALDATA_H_
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 typedef	struct global_data
 {
 	bd_t		*bd;
@@ -42,6 +46,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sparc/include/asm/global_data.h +6 -0
index aa63b35..aad97e1 100644
@@ -28,6 +28,9 @@
 #define __ASM_GBL_DATA_H
 
 #include "asm/types.h"
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 
 /*
  * The following data structure is placed in some memory wich is
@@ -74,6 +77,9 @@ typedef struct global_data {
 #endif
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/x86/include/asm/global_data.h +8 -0
index bce999f..9eff403 100644
@@ -23,6 +23,11 @@
 
 #ifndef	__ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -57,6 +62,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 static inline gd_t *get_fs_gd_ptr(void)
common/Makefile +1 -0
index fdfead7..bfb4d7a 100644
@@ -209,6 +209,7 @@ COBJS-y += dlmalloc.o
 COBJS-y += image.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-$(CONFIG_DM) += dmmalloc.o
 
 
 COBJS	:= $(sort $(COBJS-y))
common/dmmalloc.c new file +297 -0

297 lines not on this page · raw message

include/asm-generic/global_data_flags.h +4 -2
index bb57fb6..97db2c2 100644
@@ -13,8 +13,8 @@
 /*
  * Global Data Flags
  *
- * Note: The low 16 bits are expected for common code.  If your arch
- *       really needs to add your own, use the high 16bits.
+ * Note: The low 18 bits are expected for common code.  If your arch
+ *       really needs to add your own, use the high 14 bits.
  */
 #define GD_FLG_RELOC		0x0001	/* Code was relocated to RAM */
 #define GD_FLG_DEVINIT		0x0002	/* Devices have been initialized */
@@ -24,5 +24,7 @@
 #define GD_FLG_LOGINIT		0x0020	/* Log Buffer has been initialized */
 #define GD_FLG_DISABLE_CONSOLE	0x0040	/* Disable console (in & out) */
 #define GD_FLG_ENV_READY	0x0080	/* Environment imported into hash table */
+#define GD_FLG_HEAP_INIT	0x0100	/* malloc() in RAM is available */
+#define GD_FLG_EARLY_HEAP_DONE	0x0200	/* early_malloc() heap relocated. */
 
 #endif
include/dmmalloc.h new file +132 -0

132 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#45 lore raw

PATCH v10 1/1 Add dmmalloc module for DM.

Quoted 877 lines · Tomas Hlavacek

Add pointer to the first early heap into GD structure. Implement simple early_malloc and early_free functions. Prepare for additional heaps and automated heap initialization. Add temporary early_malloc_active function (to be replaced in future by more coarse DM init flags).
Add DM specific malloc calls - dmmalloc, dmfree, dmrealloc and dmcalloc.

---
Changes in v10:
- Change GD type to struct early_heap_header *.
- Move dmmalloc, dmfree, ... function from .h to dmmalloc.c .
- Rework early_malloc_active() to use new GD_FLG_HEAP_INIT flag.
- Add early_heap_active() and GD_FLG_EARLY_HEAP_DONE flag.
- Rework dmrealloc() and dmfree() to use new flags and support relocation.
- Rename early_heap_dump() to early_malloc_heap_dump().
- Add early_malloc_dump.
- Drop conditional undef CONFIG_SYS_EARLY_MALLOC in dmmalloc.h.
- Moved struct early_block_header and macros to dmmalloc.c.

Changes in v9:
- Rework early_malloc to keep track of allocated block size.
- Add early_free and dmfree functions.
- Rework dmrealloc.

Changes in v8:
- Add dmcalloc() implementation.
- Add comments to function prototypes in dmmalloc.h.

Changes in v7:
- Rework check of first heap in early_brk().

Changes in v6:
- Move dmmalloc() and all dm* functions to dmmalloc.h.
- Fix bool expression in early_malloc_active().

 arch/arm/include/asm/global_data.h        |    8 +
 arch/avr32/include/asm/global_data.h      |    7 +
 arch/blackfin/include/asm/global_data.h   |    6 +
 arch/m68k/include/asm/global_data.h       |    8 +
 arch/microblaze/include/asm/global_data.h |    8 +
 arch/mips/include/asm/global_data.h       |    6 +
 arch/nds32/include/asm/global_data.h      |    8 +
 arch/nios2/include/asm/global_data.h      |    7 +
 arch/openrisc/include/asm/global_data.h   |    8 +
 arch/powerpc/include/asm/global_data.h    |    6 +
 arch/sandbox/include/asm/global_data.h    |    7 +
 arch/sh/include/asm/global_data.h         |    7 +
 arch/sparc/include/asm/global_data.h      |    6 +
 arch/x86/include/asm/global_data.h        |    8 +
 common/Makefile                           |    1 +
 common/dmmalloc.c                         |  297 +++++++++++++++++++++++++++++
 include/asm-generic/global_data_flags.h   |    6 +-
 include/dmmalloc.h                        |  132 +++++++++++++
 18 files changed, 534 insertions(+), 2 deletions(-)
 create mode 100644 common/dmmalloc.c
 create mode 100644 include/dmmalloc.h
arch/arm/include/asm/global_data.h +8 -0
index 2b9af93..01075dc 100644
@@ -23,6 +23,11 @@
 
 #ifndef	__ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory which is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -82,6 +87,9 @@ 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
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/avr32/include/asm/global_data.h +7 -0
index bf661e2..ba9cf0e 100644
@@ -22,6 +22,10 @@
 #ifndef __ASM_GLOBAL_DATA_H__
 #define __ASM_GLOBAL_DATA_H__
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -48,6 +52,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/blackfin/include/asm/global_data.h +6 -0
index d91e5a4..daeb314 100644
@@ -29,6 +29,9 @@
 #define __ASM_GBL_DATA_H
 
 #include <asm/u-boot.h>
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 
 /*
  * The following data structure is placed in some memory wich is
@@ -57,6 +60,9 @@ typedef struct global_data {
 
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/m68k/include/asm/global_data.h +8 -0
index 0cdb11c..dad2ba5 100644
@@ -23,6 +23,11 @@
 
 #ifndef	__ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -66,6 +71,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/microblaze/include/asm/global_data.h +8 -0
index 2111c7c..f6609b8 100644
@@ -24,6 +24,11 @@
 
 #ifndef	__ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -46,6 +51,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/mips/include/asm/global_data.h +6 -0
index a735a8a..c9b76f6 100644
@@ -25,6 +25,9 @@
 #define __ASM_GBL_DATA_H
 
 #include <asm/regdef.h>
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 
 /*
  * The following data structure is placed in some memory wich is
@@ -59,6 +62,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nds32/include/asm/global_data.h +8 -0
index b1feb2c..6d972c2 100644
@@ -33,6 +33,11 @@
 
 #ifndef	__ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -63,6 +68,9 @@ typedef	struct global_data {
 
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/nios2/include/asm/global_data.h +7 -0
index 413b485..441e566 100644
@@ -23,6 +23,10 @@
 #ifndef	__ASM_NIOS2_GLOBALDATA_H_
 #define __ASM_NIOS2_GLOBALDATA_H_
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 typedef	struct	global_data {
 	bd_t		*bd;
 	unsigned long	flags;
@@ -42,6 +46,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* Standalone app jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/openrisc/include/asm/global_data.h +8 -0
index 96f3f1c..94fcef1 100644
@@ -24,6 +24,11 @@
 
 #ifndef __ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -44,6 +49,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/powerpc/include/asm/global_data.h +6 -0
index 374fc6d..ed67bfd 100644
@@ -26,6 +26,9 @@
 
 #include "config.h"
 #include "asm/types.h"
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 
 /*
  * The following data structure is placed in some memory wich is
@@ -182,6 +185,9 @@ typedef	struct	global_data {
 #endif
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sandbox/include/asm/global_data.h +7 -0
index 78a751d..0d4b4b0 100644
@@ -33,6 +33,10 @@
  * up the memory controller so that we can use RAM).
  */
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 typedef	struct global_data {
 	bd_t		*bd;
 	unsigned long	flags;
@@ -46,6 +50,9 @@ typedef	struct global_data {
 	const void	*fdt_blob;	/* Our device tree, NULL if none */
 	void		**jt;		/* jump table */
 	char		env_buf[32];	/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sh/include/asm/global_data.h +7 -0
index 9a2c193..acacae7 100644
@@ -27,6 +27,10 @@
 #ifndef	__ASM_SH_GLOBALDATA_H_
 #define __ASM_SH_GLOBALDATA_H_
 
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 typedef	struct global_data
 {
 	bd_t		*bd;
@@ -42,6 +46,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/sparc/include/asm/global_data.h +6 -0
index aa63b35..aad97e1 100644
@@ -28,6 +28,9 @@
 #define __ASM_GBL_DATA_H
 
 #include "asm/types.h"
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
 
 /*
  * The following data structure is placed in some memory wich is
@@ -74,6 +77,9 @@ typedef struct global_data {
 #endif
 	void	**jt;			/* jump table */
 	char	env_buf[32];		/* buffer for getenv() before reloc. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 #include <asm-generic/global_data_flags.h>
arch/x86/include/asm/global_data.h +8 -0
index bce999f..9eff403 100644
@@ -23,6 +23,11 @@
 
 #ifndef	__ASM_GBL_DATA_H
 #define __ASM_GBL_DATA_H
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+#include <dmmalloc.h>
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
 /*
  * The following data structure is placed in some memory wich is
  * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
@@ -57,6 +62,9 @@ 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. */
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	struct early_heap_header *early_heap;	/* heap for early_malloc */
+#endif
 } gd_t;
 
 static inline gd_t *get_fs_gd_ptr(void)
common/Makefile +1 -0
index fdfead7..bfb4d7a 100644
@@ -209,6 +209,7 @@ COBJS-y += dlmalloc.o
 COBJS-y += image.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
+COBJS-$(CONFIG_DM) += dmmalloc.o
 
 
 COBJS	:= $(sort $(COBJS-y))
common/dmmalloc.c new file +297 -0
new file mode 100644
index 0000000..4a1a241
@@ -0,0 +1,297 @@
+/*
+ * (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>
+
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+
+struct early_block_header {
+	size_t size;
+};
+
+#define BLOCK_DATA(header) ((void *)(((struct early_block_header *)header)+1))
+#define BLOCK_HEADER(addr) (((struct early_block_header *)addr)-1)
+#define BLOCK_USED_FLAG 0x80000000
+#define BLOCK_SIZE(size) (size & (~BLOCK_USED_FLAG))
+#define BLOCK_USED(size) ((size & BLOCK_USED_FLAG) == BLOCK_USED_FLAG)
+#define BLOCK_FREE(size) (!BLOCK_USED(size))
+#define BLOCK_SET_FREE(size) BLOCK_SIZE(size)
+#define BLOCK_SET_USED(size) (size | BLOCK_USED_FLAG)
+
+
+__weak struct early_heap_header *early_brk(size_t size)
+{
+	struct early_heap_header *h;
+	struct early_block_header *b;
+
+	if (gd->early_heap != NULL)
+		return NULL;
+
+	h = (struct early_heap_header *)CONFIG_SYS_EARLY_HEAP_ADDR;
+	b = (struct early_block_header *)(h + 1);
+
+	size = CONFIG_SYS_EARLY_HEAP_SIZE;
+	h->size = size;
+	h->early_heap_next = NULL;
+	b->size = size - sizeof(struct early_heap_header) -
+			sizeof(struct early_block_header);
+	b->size = BLOCK_SET_FREE(b->size);
+
+	return h;
+}
+
+static struct early_block_header *find_free_space(struct early_heap_header *h,
+							size_t size)
+{
+	struct early_block_header *b;
+
+	b = (struct early_block_header *)(h+1);
+	while ((phys_addr_t)b + sizeof(struct early_block_header)
+			< (phys_addr_t)h + h->size) {
+		if (BLOCK_FREE(b->size) && (BLOCK_SIZE(b->size) >= size))
+			return b;
+		b = (struct early_block_header *)((phys_addr_t)b +
+				sizeof(struct early_block_header) +
+				BLOCK_SIZE(b->size));
+	}
+
+	return NULL;
+}
+
+static struct early_block_header *split_block(struct early_block_header *b,
+	       size_t size)
+{
+	struct early_block_header *nb;
+
+	if ((BLOCK_SIZE(b->size) < size) || (BLOCK_USED(b->size)))
+		return NULL;
+
+	if (BLOCK_SIZE(b->size) <= (size + sizeof(struct early_block_header)))
+		return b;
+
+	nb = (struct early_block_header *)((phys_addr_t)b +
+		sizeof(struct early_block_header) + size);
+	nb->size = b->size - size - sizeof(struct early_block_header);
+	b->size = size;
+
+	return b;
+}
+
+void *early_malloc(size_t size)
+{
+	struct early_heap_header *h;
+	struct early_block_header *b;
+
+	size = roundup(size, sizeof(phys_addr_t));
+	if (size == 0)
+		return NULL;
+
+	if (gd->early_heap == NULL)
+		gd->early_heap = early_brk(size);
+
+	if (gd->early_heap == NULL) {
+		debug("early_brk failed to initialize heap\n");
+		return NULL;
+	}
+
+	h = gd->early_heap;
+	while (1) {
+		b = find_free_space(h, size);
+		if (b != NULL)
+			break;
+
+		if (h->early_heap_next != NULL)
+			h = h->early_heap_next;
+		else
+			break;
+	}
+
+	if (b == NULL) {
+		h->early_heap_next = early_brk(size+
+				sizeof(struct early_heap_header)+
+				sizeof(struct early_block_header));
+		h = h->early_heap_next;
+		if (h == NULL) {
+			debug("early_brk failed to extend heap by %d B\n",
+					size);
+			return NULL;
+		}
+
+		b = find_free_space(h, size);
+		if (b == NULL) {
+			debug("early_malloc failed to extend heap by %d B\n",
+					size);
+			return NULL;
+		}
+	}
+
+	if (b->size != size)
+		b = split_block(b, size);
+	if (b == NULL) {
+		debug("early_malloc failed to split block to %d B\n", size);
+		return NULL;
+	}
+
+	b->size = BLOCK_SET_USED(b->size);
+
+	return BLOCK_DATA(b);
+}
+
+void early_free(void *addr)
+{
+	struct early_block_header *h = BLOCK_HEADER(addr);
+	assert(BLOCK_USED(h->size));
+	h->size = BLOCK_SET_FREE(h->size);
+}
+
+void early_malloc_heap_dump(struct early_heap_header *h)
+{
+	struct early_block_header *b;
+
+	debug("heap: h=%p, h->size=%d\n", h, h->size);
+
+	b = (struct early_block_header *)(h+1);
+	while ((phys_addr_t)b + sizeof(struct early_block_header)
+			< (phys_addr_t)h + h->size) {
+		debug("block: h=%p h->size=%d b=%p b->size=%d b->(used)=%d\n",
+				h, h->size, b, BLOCK_SIZE(b->size),
+				BLOCK_USED(b->size));
+		assert(BLOCK_SIZE(b->size) > 0);
+		b = (struct early_block_header *)((phys_addr_t)b +
+				sizeof(struct early_block_header) +
+				BLOCK_SIZE(b->size));
+	}
+	debug("--- heap dump end ---\n");
+}
+
+void early_malloc_dump(void)
+{
+	struct early_heap_header *h = gd->early_heap;
+	while (h != NULL) {
+		early_malloc_heap_dump(h);
+		h = h->early_heap_next;
+	}
+}
+
+static int early_malloc_active(void)
+{
+	return ((gd->flags & GD_FLG_HEAP_INIT) != GD_FLG_HEAP_INIT);
+}
+
+static int early_heap_active(void)
+{
+	return ((gd->flags & GD_FLG_EARLY_HEAP_DONE) !=
+			GD_FLG_EARLY_HEAP_DONE);
+}
+
+static int early_address(void *ptr)
+{
+	struct early_heap_header *h = gd->early_heap;
+	while (h != NULL) {
+		if (((phys_addr_t)ptr >= (phys_addr_t)h) &&
+				((phys_addr_t)ptr < (phys_addr_t)h + h->size))
+			return 1;
+
+		h = h->early_heap_next;
+	}
+
+	return 0;
+}
+
+
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+
+void *dmmalloc(size_t size)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	if (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 (early_heap_active()) {
+		if (early_address(ptr))
+			early_free(ptr);
+		return;
+	}
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+	free(ptr);
+}
+
+void *dmcalloc(size_t n, size_t elem_size)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	char *addr;
+	int size = elem_size * n;
+
+	if (early_malloc_active()) {
+		addr = early_malloc(size);
+		memset(addr, 0, size);
+		return addr;
+	}
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+	return calloc(n, elem_size);
+}
+
+void *dmrealloc(void *oldaddr, size_t bytes)
+{
+#ifdef CONFIG_SYS_EARLY_MALLOC
+	char *addr;
+	struct early_block_header *h;
+
+	if (early_heap_active() && early_address(oldaddr)) {
+		addr = dmmalloc(bytes);
+		if (addr == NULL)
+			return NULL;
+
+		h = BLOCK_HEADER(oldaddr);
+		if (BLOCK_FREE(h->size))
+			return NULL;
+
+		if (bytes > BLOCK_SIZE(h->size))
+			bytes = BLOCK_SIZE(h->size);
+
+		memcpy(addr, oldaddr, bytes);
+		dmfree(oldaddr);
+		return addr;
+	}
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+	return realloc(oldaddr, bytes);
+}
+
include/asm-generic/global_data_flags.h +4 -2
index bb57fb6..97db2c2 100644
@@ -13,8 +13,8 @@
 /*
  * Global Data Flags
  *
- * Note: The low 16 bits are expected for common code.  If your arch
- *       really needs to add your own, use the high 16bits.
+ * Note: The low 18 bits are expected for common code.  If your arch
+ *       really needs to add your own, use the high 14 bits.
  */
 #define GD_FLG_RELOC		0x0001	/* Code was relocated to RAM */
 #define GD_FLG_DEVINIT		0x0002	/* Devices have been initialized */
@@ -24,5 +24,7 @@
 #define GD_FLG_LOGINIT		0x0020	/* Log Buffer has been initialized */
 #define GD_FLG_DISABLE_CONSOLE	0x0040	/* Disable console (in & out) */
 #define GD_FLG_ENV_READY	0x0080	/* Environment imported into hash table */
+#define GD_FLG_HEAP_INIT	0x0100	/* malloc() in RAM is available */
+#define GD_FLG_EARLY_HEAP_DONE	0x0200	/* early_malloc() heap relocated. */
 
 #endif
include/dmmalloc.h new file +122 -0
new file mode 100644
index 0000000..c99f423
@@ -0,0 +1,132 @@
+/*
+ * (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 */
+#include <malloc.h>
+
+#ifdef CONFIG_SYS_EARLY_MALLOC
+
+/**
+ * struct early_heap_header - header preceding an early heap
+ * @size - length of the heap in bytes (including the heap header).
+ * @early_heap_next - pointer to the following heap.
+ *
+ * Heaps are organized in the single direction linked list. Each heap
+ * contains own size. Pointer to the first (left-most) heap is
+ * contained in global data.
+ */
+struct early_heap_header {
+	size_t size;
+	void *early_heap_next;
+};
+
+/**
+ * early_brk() - obtain address of the heap
+ * @size:	Minimal size of the new early heap to be allocated.
+ *
+ * Function returns a new heap pointer.
+ *
+ * Allocate and initialize early_heap at least size bytes long.
+ * This function can be platform dependent or board dependent but sensible
+ * default is provided.
+ */
+struct early_heap_header *early_brk(size_t size);
+
+/**
+ * early_malloc() - malloc operating on the early_heap(s)
+ * @size:	Size in bytes.
+ *
+ * Function returns a pointer to the allocated block.
+ */
+void *early_malloc(size_t size);
+
+/**
+ * early_free() - free operating on the early_heap(s)
+ * @addr:	Pointer to the allocated block to be released.
+ */
+void early_free(void *addr);
+
+/**
+ * early_malloc_heap_dump() - print blocks contained in an early_heap
+ * @h:		Address of the early heap.
+ */
+void early_malloc_heap_dump(struct early_heap_header *h);
+
+/**
+ * early_malloc_dump() - print blocks contained in all early_heaps
+ */
+void early_malloc_dump(void);
+
+
+#endif /* CONFIG_SYS_EARLY_MALLOC */
+
+#ifdef CONFIG_DM
+
+/*
+ * DM versions of malloc* functions. In early init it calls early_malloc.
+ * It wraps around normal malloc* functions afterwards.
+ */
+
+/**
+ * dmmalloc() - malloc working seamlessly in early as well as in RAM stages
+ * @size:	Size of the block to be allocated.
+ *
+ * Function returns an address of the newly allocated block when successful
+ * or NULL otherwise.
+ */
+void *dmmalloc(size_t size);
+
+/**
+ * dmfree() - free working seamlessly in early as well as in RAM stages
+ * @ptr:	Pointer to the allocated block to be released.
+ */
+void dmfree(void *ptr);
+
+/**
+ * dmcalloc() - calloc working seamlessly in early as well as in RAM stages
+ * @n:		Number of elements to be allocated.
+ * @elem_size:	Size of elements to be allocated.
+ *
+ * Function returns a pointer to newly the allocated area (n*elem_size) long.
+ */
+void *dmcalloc(size_t n, size_t elem_size);
+
+/**
+ * dmrealloc() - realloc working seamlessly in early as well as in RAM stages
+ * @oldaddr:	Pointer to the old memory block.
+ * @bytes:	New size to of the block to be reallocated.
+ *

include/dmmalloc.h line 132

Quoted 10 lines
include/dmmalloc.h new file +10 -0
+ * Function returns an address of the newly allocated block when successful
+ * or NULL otherwise.
+ *
+ * Data are copied from the block specified by oldaddr to the new block.
+ */
+void *dmrealloc(void *oldaddr, size_t bytes);
+
+#endif /* CONFIG_DM */
+#endif /* __INCLUDE_DMMALLOC_H */
+

*you may stop your scrolling now*

Hello,
does it ring a bell? I need to get it (or an equivalent solution) to work before implementing a working DM2-I2C uclass. I don't see any replies to the original v10 e-mail. Why wasn't it accepted into U-Boot? Should I work on top of this patch, or start from scratch?

Regards,

#46 lore raw

PATCH v10 1/1 Add dmmalloc module for DM.

Quoted 9 lines · Mateusz Zalega
Quoted 8 lines · Tomas Hlavacek

Add pointer to the first early heap into GD structure. Implement simple early_malloc and early_free functions. Prepare for additional heaps and automated heap initialization. Add temporary early_malloc_active function (to be replaced in future by more coarse DM init flags).
Add DM specific malloc calls - dmmalloc, dmfree, dmrealloc and dmcalloc.

[snip]

Quoted 4 lines

does it ring a bell? I need to get it (or an equivalent solution) to work before implementing a working DM2-I2C uclass. I don't see any replies to the original v10 e-mail. Why wasn't it accepted into U-Boot? Should I work on top of this patch, or start from scratch?

The patch itself was OK, but the rest of the DM work did not end up going in, so there was no user of this change. If you have a user, please re-use his patch (and it'll need a v11 to apply again on top of tree and comply with SPDX licenisng tags) and push it forward, thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20131105/33377baa/attachment.pgp>
#47 lore raw

PATCH v10 1/1 Add dmmalloc module for DM.

Quoted 14 lines
Quoted 8 lines
Quoted 8 lines

Add pointer to the first early heap into GD structure. Implement simple early_malloc and early_free functions. Prepare for additional heaps and automated heap initialization. Add temporary early_malloc_active function (to be replaced in future by more coarse DM init flags).
Add DM specific malloc calls - dmmalloc, dmfree, dmrealloc and dmcalloc.

[snip]

Quoted 4 lines

does it ring a bell? I need to get it (or an equivalent solution) to work before implementing a working DM2-I2C uclass. I don't see any replies to the original v10 e-mail. Why wasn't it accepted into U-Boot? Should I work on top of this patch, or start from scratch?

Quoted 5 lines

The patch itself was OK, but the rest of the DM work did not end up going in, so there was no user of this change. If you have a user, please re-use his patch (and it'll need a v11 to apply again on top of tree and comply with SPDX licenisng tags) and push it forward, thanks!

will do, thx!

Signature · 2 lines
Mateusz Zalega
Samsung R&D Institute Poland