
On 10/29/12 00:20, Tomas Hlavacek wrote:
Add pointer to the first early heap into GD structure. Implement simple early_malloc and early_free functions. Prepare for additional heaps and automated heap initialization. Add temporary early_malloc_active function (to be replaced in future by more coarse DM init flags). Add DM specific malloc calls - dmmalloc, dmfree, dmrealloc and dmcalloc.
Signed-off-by: Tomas Hlavacek tmshlvck@gmail.com
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
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 2b9af93..01075dc 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -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> diff --git a/arch/avr32/include/asm/global_data.h b/arch/avr32/include/asm/global_data.h index bf661e2..ba9cf0e 100644 --- a/arch/avr32/include/asm/global_data.h +++ b/arch/avr32/include/asm/global_data.h @@ -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> diff --git a/arch/blackfin/include/asm/global_data.h b/arch/blackfin/include/asm/global_data.h index d91e5a4..daeb314 100644 --- a/arch/blackfin/include/asm/global_data.h +++ b/arch/blackfin/include/asm/global_data.h @@ -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> diff --git a/arch/m68k/include/asm/global_data.h b/arch/m68k/include/asm/global_data.h index 0cdb11c..dad2ba5 100644 --- a/arch/m68k/include/asm/global_data.h +++ b/arch/m68k/include/asm/global_data.h @@ -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> diff --git a/arch/microblaze/include/asm/global_data.h b/arch/microblaze/include/asm/global_data.h index 2111c7c..f6609b8 100644 --- a/arch/microblaze/include/asm/global_data.h +++ b/arch/microblaze/include/asm/global_data.h @@ -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> diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h index a735a8a..c9b76f6 100644 --- a/arch/mips/include/asm/global_data.h +++ b/arch/mips/include/asm/global_data.h @@ -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> diff --git a/arch/nds32/include/asm/global_data.h b/arch/nds32/include/asm/global_data.h index b1feb2c..6d972c2 100644 --- a/arch/nds32/include/asm/global_data.h +++ b/arch/nds32/include/asm/global_data.h @@ -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> diff --git a/arch/nios2/include/asm/global_data.h b/arch/nios2/include/asm/global_data.h index 413b485..441e566 100644 --- a/arch/nios2/include/asm/global_data.h +++ b/arch/nios2/include/asm/global_data.h @@ -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> diff --git a/arch/openrisc/include/asm/global_data.h b/arch/openrisc/include/asm/global_data.h index 96f3f1c..94fcef1 100644 --- a/arch/openrisc/include/asm/global_data.h +++ b/arch/openrisc/include/asm/global_data.h @@ -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> diff --git a/arch/powerpc/include/asm/global_data.h b/arch/powerpc/include/asm/global_data.h index 374fc6d..ed67bfd 100644 --- a/arch/powerpc/include/asm/global_data.h +++ b/arch/powerpc/include/asm/global_data.h @@ -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> diff --git a/arch/sandbox/include/asm/global_data.h b/arch/sandbox/include/asm/global_data.h index 78a751d..0d4b4b0 100644 --- a/arch/sandbox/include/asm/global_data.h +++ b/arch/sandbox/include/asm/global_data.h @@ -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> diff --git a/arch/sh/include/asm/global_data.h b/arch/sh/include/asm/global_data.h index 9a2c193..acacae7 100644 --- a/arch/sh/include/asm/global_data.h +++ b/arch/sh/include/asm/global_data.h @@ -27,6 +27,10 @@ #ifndef __ASM_SH_GLOBALDATA_H_ #define __ASM_SH_GLOBALDATA_H_
+#ifdef CONFIG_SYS_EARLY_MALLOC +#include <dmmalloc.h> +#endif /* CONFIG_SYS_EARLY_MALLOC */
typedef struct global_data { bd_t *bd; @@ -42,6 +46,9 @@ typedef struct global_data unsigned long env_valid; /* Checksum of Environment valid */ void **jt; /* Standalone app jump table */ char env_buf[32]; /* buffer for getenv() before reloc. */ +#ifdef CONFIG_SYS_EARLY_MALLOC
- struct early_heap_header *early_heap; /* heap for early_malloc */
+#endif } gd_t;
#include <asm-generic/global_data_flags.h> diff --git a/arch/sparc/include/asm/global_data.h b/arch/sparc/include/asm/global_data.h index aa63b35..aad97e1 100644 --- a/arch/sparc/include/asm/global_data.h +++ b/arch/sparc/include/asm/global_data.h @@ -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> diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index bce999f..9eff403 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -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) diff --git a/common/Makefile b/common/Makefile index fdfead7..bfb4d7a 100644 --- a/common/Makefile +++ b/common/Makefile @@ -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)) diff --git a/common/dmmalloc.c b/common/dmmalloc.c new file mode 100644 index 0000000..4a1a241 --- /dev/null +++ b/common/dmmalloc.c @@ -0,0 +1,297 @@ +/*
- (C) Copyright 2012
- Tomas Hlavacek (tmshlvck@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);
+}
diff --git a/include/asm-generic/global_data_flags.h b/include/asm-generic/global_data_flags.h index bb57fb6..97db2c2 100644 --- a/include/asm-generic/global_data_flags.h +++ b/include/asm-generic/global_data_flags.h @@ -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 diff --git a/include/dmmalloc.h b/include/dmmalloc.h new file mode 100644 index 0000000..c99f423 --- /dev/null +++ b/include/dmmalloc.h @@ -0,0 +1,132 @@ +/*
- (C) Copyright 2012
- Tomas Hlavacek (tmshlvck@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.
- 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,