DM: early_malloc for DM added.
Subsystems (11)
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -42,6 +42,7 @@ typedef struct global_dataunsigned 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
RFC PATCH 1/1 DM: early_malloc for DM added.
Dear Tomas Hlavacek,
Quoted 6 lines
Modular
early_mallocfor DM with support for more heaps and lightweight first heap on stack.(RFC. Not intended for merging!)
Signed-off-by Tomas Hlavacek <[email protected]>
[...]
CCing Graeme
Best regards,
Marek Vasut
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_mallocfor DM with support for more heaps and lightweight first heap on stack.(RFC. Not intended for merging!)
Signed-off-by Tomas Hlavacek <[email protected]>[...]
CCing Graeme
Best regards,
Marek Vasut
Signature · 1 line
Tom?? Hlav??ek <[email protected]>
RFC PATCH v2 1/1 DM: early_malloc for DM added.
In reply to Tomas HlavacekModular 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -42,6 +42,7 @@ typedef struct global_dataunsigned 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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_mallocfor 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
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@@ -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
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@@ -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
-0COBJS := $(sort $(COBJS-y))common/earlymalloc.c new file +34
-0@@ -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@@ -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
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
RFC PATCH v2 1/1 DM: early_malloc for DM added.
In reply to Graeme RussHi 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
RFC PATCH v4 1/1 DM: early_malloc for DM added.
In reply to Tomas Hlavacekearly_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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -42,6 +42,7 @@ typedef struct global_dataunsigned 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
RFC PATCH v4 1/1 DM: early_malloc for DM added.
Dear Tomas Hlavacek,
Quoted 8 lines
early_mallocfor DM with support for more heaps and lightweight first heap on stack.Adaptation layer for seamless calling of
early_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).Signed-off-by Tomas Hlavacek <[email protected]>---
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@@ -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
[...]
Graeme Russ
NAKRFC PATCH v4 1/1 DM: early_malloc for DM added.
Hi Marek,
Quoted 8 lines · Marek Vasut
Dear Tomas Hlavacek,
Quoted 6 lines
early_mallocfor DM with support for more heaps and lightweight first heap on stack.Adaptation layer for seamless calling of
early_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).
Quoted 7 lines
Quoted 2 lines
Signed-off-by Tomas Hlavacek <[email protected]>---
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
__weakstructearly_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@@ -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
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_mallocfor DM with support for more heaps and lightweight first heap on stack.Adaptation layer for seamless calling of
early_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).Signed-off-by Tomas Hlavacek <[email protected]>---
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
__weakstructearly_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@@ -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
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>):
__weakstructearly_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
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>):
__weakstructearly_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
RFC PATCH v4 1/1 DM: early_malloc for DM added.
In reply to Graeme RussQuoted 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>):
__weakstructearly_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
RFC PATCH v4 1/1 DM: early_malloc for DM added.
In reply to Graeme RussHello 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
__weakstructearly_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]>
RFC PATCH v4 1/1 DM: early_malloc for DM added.
In reply to Tomas HlavacekHi Tomas
Quoted 2 lines · Tomas Hlavacek
early_mallocfor 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_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).Signed-off-by Tomas Hlavacek <[email protected]>--- 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.harch/arm/include/asm/config.h +0
-0
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@@ -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@@ -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@@ -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
-0init_baudrate_f, serial_init, console_init_f,common/Makefile +1
-0@@ -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
-0COBJS := $(sort $(COBJS-y))common/dmmalloc.c new file +17
-0@@ -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
RFC PATCH v5 1/1 early_malloc for DM added.
In reply to Tomas Hlavacekearly_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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -42,6 +42,9 @@ typedef struct global_dataunsigned 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
RFC PATCH v5 1/1 early_malloc for DM added.
Dear Tomas Hlavacek,
Quoted 7 lines
early_mallocfor 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_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).Signed-off-by Tomas Hlavacek <[email protected]>
[...]
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@@ -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 */ +
RFC PATCH v5 1/1 early_malloc for DM added.
Hello Marek,
Quoted 8 lines · Marek Vasut
Dear Tomas Hlavacek,
Quoted 6 lines
early_mallocfor 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_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).
Quoted 7 lines
Quoted 1 line
Signed-off-by Tomas Hlavacek <[email protected]>[...]
Quoted 3 lines
31 files changed, 363 insertions(+) create mode 100644 common/dmmalloc.c create mode 100644 include/dmmalloc.hWhat 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 mallocHow 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@@ -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
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_mallocfor 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_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).Signed-off-by Tomas Hlavacek <[email protected]>Quoted 7 lines
[...]
Quoted 3 lines
31 files changed, 363 insertions(+) create mode 100644 common/dmmalloc.c create mode 100644 include/dmmalloc.hWhat exactly changed in this version? Changelog is missing.
Preprocessor config-dependent (ifdef ... endif) blocks are different.
early_brkcall fromearly_mallocwhen the heaps are full. defaultearly_brkchecks 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 mallocHow 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@@ -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
RFC PATCH v6 1/1 early_malloc for DM added.
In reply to Tomas Hlavacekearly_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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -42,6 +42,9 @@ typedef struct global_dataunsigned 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
RFC PATCH v6 1/1 early_malloc for DM added.
Quoted 9 lines · Tomas Hlavacek
early_mallocfor 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_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).Signed-off-by Tomas Hlavacek <[email protected]>---
[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
RFC PATCH v6 1/1 early_malloc for DM added.
Hello!
Quoted 29 lines · Graeme Russ
Quoted 9 lines · Tomas Hlavacek
early_mallocfor 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_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).Signed-off-by Tomas Hlavacek <[email protected]>---
[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
RFC PATCH v7 1/1 early_malloc for DM added.
In reply to Tomas Hlavacekearly_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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -42,6 +42,9 @@ typedef struct global_dataunsigned 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
RFC PATCH v8 1/1 early_malloc for DM added.
In reply to Tomas Hlavacekearly_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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -42,6 +42,9 @@ typedef struct global_dataunsigned 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
RFC PATCH v8 1/1 early_malloc for DM added.
Dear Tomas Hlavacek,
Quoted 14 lines · In message <[email protected]> you wrote:
early_mallocfor 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_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).Signed-off-by Tomas Hlavacek <[email protected]>---
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 inearly_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
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
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_mallocatorstage.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>
RFC PATCH v8 1/1 early_malloc for DM added.
In reply to Tomas HlavacekDear 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
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+ standardmemcpy()
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
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+ standardmemcpy()
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_mallocatedarea. And I think this is not good idea at all forearly_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 thedmrealloc()entirely which may have certain negative consequences, because it might be tempting to mixdmmalloc()and (non-dm*)realloc()calls which is obviously wrong.Tomas
Best regards,
Marek Vasut
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+ standardmemcpy()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_mallocatedarea. And I think this is not good idea at all forearly_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 thedmrealloc()entirely which may have certain negative consequences, because it might be tempting to mixdmmalloc()and (non-dm*)realloc()calls which is obviously wrong.
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
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_tbytes) {#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_mallocframe 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
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(), andrealloc().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_tvalue immediately before the allocated space which stores the block size. So:
size_t*bytes_ptr= ptr;
bytes_ptr--;size_tbytes =*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
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(), andrealloc().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_tvalue immediately before the allocated space which stores the block size. So:
size_t*bytes_ptr= ptr;
bytes_ptr--;size_tbytes =*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 blocksRemebering 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
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(), andrealloc().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_tvalue immediately before the allocated space which stores the block size. So:
size_t*bytes_ptr= ptr;
bytes_ptr--;size_tbytes =*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 blocksYes, this makes sense. Knowing size of allocated blocks enables the
early_mallocto 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/orearly_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 theearly_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) callearly_brkto obtain more spaceData 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) callearly_brkto 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_heapright after it's creation would consist of aearly_heap_headerfollowed by aearly_block_headerwith 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) blockWell, that time we would have only a copy of the
early_heapon certain platforms. Assuming that first we set off drivers and DM usingearly_heap(s), then we would copy eachearly_heapto some computed address and jump toboard_init_r. Inboard_init_rwe would access theearly_heapcopy 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_freecorrectly 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 blocksRemebering 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
RFC PATCH v8 1/1 early_malloc for DM added.
In reply to Tomas HlavacekHi Tomas,
Quoted 86 lines · Tomas Hlavacek
early_mallocfor 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_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).Signed-off-by Tomas Hlavacek <[email protected]>---
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 inearly_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.harch/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_first;/* heap for early_malloc */ +#endif } gd_t;#include <asm-generic/global_data_flags.h> arch/arm/lib/board.c +4
-0@@ -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@@ -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
-0COBJS := $(sort $(COBJS-y))common/dmmalloc.c new file +33
-0@@ -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
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_mallocfor 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_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).Signed-off-by Tomas Hlavacek <[email protected]>---
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 inearly_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.harch/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_first;/* heap for early_malloc */ +#endif } gd_t;#include <asm-generic/global_data_flags.h> arch/arm/lib/board.c +4
-0@@ -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 whenearly_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
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_mallocfor 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_mallocor dlmalloc from DM based on init stage added (dmmalloc()and related functions).Signed-off-by Tomas Hlavacek <[email protected]>---
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 inearly_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.harch/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_first;/* heap for early_malloc */ +#endif } gd_t;#include <asm-generic/global_data_flags.h> arch/arm/lib/board.c +4
-0@@ -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 whenearly_malloc()is first called
Quoted 5 lines
Yes, but how can I determine the size of the new heap which the
early_brkgives out? When I haveCONFIG_SYS_EARLY_HEAP_SIZEmacro in board configuration I can ignore the size passed to the "default"early_brkand 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_brkcapable of returning multiple heaps? Should I safely assume that the future dynamicearly_brkwould 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
RFC PATCH v9 1/1 Add dmmalloc module for DM.
In reply to Tomas HlavacekAdd 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -42,6 +42,9 @@ typedef struct global_dataunsigned 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
@@ -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
@@ -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
@@ -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
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_mallocandearly_freefunctions. Prepare for additional heaps and automated heap initialization. Add temporaryearly_malloc_activefunction (to be replaced in future by more coarse DM init flags).
Add DM specific malloc calls - dmmalloc, dmfree, dmrealloc and dmcalloc.Signed-off-by Tomas Hlavacek <[email protected]>---
Changes in v9:
- Reworkearly_mallocto keep track of allocated block size.
- Addearly_freeand dmfree functions.
- Rework dmrealloc.
- Add kerneldoc comments todmmalloc.h.Changes in v8:
- Adddmcalloc()implmentation.
- Add comments to function prototypes indmmalloc.h.Changes in v7:
- Rework check of first heap inearly_brk().Changes in v6:
- Movedmmalloc()and all dm* functions todmmalloc.h.
- Fix bool expression inearly_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.harch/arm/include/asm/global_data.h +0
-0
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
-0COBJS := $(sort $(COBJS-y))common/dmmalloc.c new file +26
-0@@ -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@@ -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 initialisedGD_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
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@@ -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
-0unsigned 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.oCOBJS-$(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_MALLOCIf 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_RELOCgets 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_MALLOCI 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_headerstruct 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 initialisedGD_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 setGD_FLG_HEAP_INIT. OnceGD_FLG_HEAP_INIThas been set, do a bunch ofdmrealloc()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 setGD_FLG_EH_DONE(and callearly_heap_dump)One problem I see is what happens of you call
malloc()andfree()on the same block between the setting ofGD_FLG_HEAP_INITandGD_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_INITbeing set,dmfree()anddmrealloc()could search the early heap chunks instead of just assuming that the referenced block is in the early heap (ifGD_FLG_HEAP_INIThas 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
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@@ -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
-0unsigned 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_heapheader * or structearly_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_headerfromdmmalloc.hmaking it publicly unavailable or should I rather change the void * to structearly_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_headerthen pointer arithmetic is in effect and h+1 actually means "next element in the array of structearly_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_RELOCgets set before the permanent heap is initialised, so there is a window of opportunity where things may breakWell, 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_mallocor 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_malloccan still access the properearly_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 initialisedGD_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 setGD_FLG_HEAP_INIT. OnceGD_FLG_HEAP_INIThas been set, do a bunch ofdmrealloc()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 setGD_FLG_EH_DONE(and callearly_heap_dump)One problem I see is what happens of you call
malloc()andfree()on the same block between the setting ofGD_FLG_HEAP_INITandGD_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_INITbeing set,dmfree()anddmrealloc()could search the early heap chunks instead of just assuming that the referenced block is in the early heap (ifGD_FLG_HEAP_INIThas 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/offearly_mallocbased 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
PATCH v10 1/1 Add dmmalloc module for DM.
In reply to Tomas HlavacekAdd 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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_dataunsigned 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
@@ -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
@@ -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
@@ -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
@@ -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
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_mallocandearly_freefunctions. Prepare for additional heaps and automated heap initialization. Add temporaryearly_malloc_activefunction (to be replaced in future by more coarse DM init flags).
Add DM specific malloc calls - dmmalloc, dmfree, dmrealloc and dmcalloc.Signed-off-by Tomas Hlavacek <[email protected]>---
Changes in v10:
- Change GD type to structearly_heap_header*.
- Move dmmalloc, dmfree, ... function from .h todmmalloc.c.
- Reworkearly_malloc_active()to use newGD_FLG_HEAP_INITflag.
- Addearly_heap_active()andGD_FLG_EARLY_HEAP_DONEflag.
- Reworkdmrealloc()anddmfree()to use new flags and support relocation.
- Renameearly_heap_dump()toearly_malloc_heap_dump().
- Addearly_malloc_dump.
- Drop conditional undefCONFIG_SYS_EARLY_MALLOCindmmalloc.h.
- Moved structearly_block_headerand macros todmmalloc.c.Changes in v9:
- Reworkearly_mallocto keep track of allocated block size.
- Addearly_freeand dmfree functions.
- Rework dmrealloc.Changes in v8:
- Adddmcalloc()implementation.
- Add comments to function prototypes indmmalloc.h.Changes in v7:
- Rework check of first heap inearly_brk().Changes in v6:
- Movedmmalloc()and all dm* functions todmmalloc.h.
- Fix bool expression inearly_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.harch/arm/include/asm/global_data.h +8
-0@@ -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@@ -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@@ -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@@ -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@@ -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@@ -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@@ -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@@ -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@@ -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@@ -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@@ -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@@ -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_dataunsigned 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@@ -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@@ -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@@ -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@@ -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@@ -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@@ -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,
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_mallocandearly_freefunctions. Prepare for additional heaps and automated heap initialization. Add temporaryearly_malloc_activefunction (to be replaced in future by more coarse DM init flags).
Add DM specific malloc calls - dmmalloc, dmfree, dmrealloc and dmcalloc.Signed-off-by Tomas Hlavacek <[email protected]>
[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>
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_mallocandearly_freefunctions. Prepare for additional heaps and automated heap initialization. Add temporaryearly_malloc_activefunction (to be replaced in future by more coarse DM init flags).
Add DM specific malloc calls - dmmalloc, dmfree, dmrealloc and dmcalloc.Signed-off-by Tomas Hlavacek <[email protected]>[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