summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payloads/libpayload/include/stdlib.h34
-rw-r--r--payloads/libpayload/libc/malloc.c89
2 files changed, 86 insertions, 37 deletions
diff --git a/payloads/libpayload/include/stdlib.h b/payloads/libpayload/include/stdlib.h
index d3448b96cc..1ed92d5cfd 100644
--- a/payloads/libpayload/include/stdlib.h
+++ b/payloads/libpayload/include/stdlib.h
@@ -101,7 +101,35 @@
printf("PRE memalign\n"); \
print_malloc_map(); \
ptr = memalign(a,s); \
- printf("POST realloc (ptr = %p)\n", ptr); \
+ printf("POST memalign (ptr = %p)\n", ptr); \
+ print_malloc_map(); \
+ ptr; \
+ })
+#define dma_malloc(s) \
+ ({ \
+ extern void print_malloc_map(void); \
+ extern void *dma_malloc(size_t); \
+ void *ptr; \
+ printf("dma_malloc(%u) called from %s:%s:%d...\n", s, __FILE__, \
+ __func__, __LINE__);\
+ printf("PRE dma_malloc\n"); \
+ print_malloc_map(); \
+ ptr = dma_malloc(s); \
+ printf("POST dma_malloc (ptr = %p)\n", ptr); \
+ print_malloc_map(); \
+ ptr; \
+ })
+#define dma_memalign(a,s) \
+ ({ \
+ extern void print_malloc_map(void); \
+ extern void *dma_memalign(size_t, size_t); \
+ void *ptr; \
+ printf("dma_memalign(%u, %u) called from %s:%s:%d...\n", a, s, \
+ __FILE__, __func__, __LINE__);\
+ printf("PRE dma_memalign\n"); \
+ print_malloc_map(); \
+ ptr = dma_memalign(a,s); \
+ printf("POST dma_memalign (ptr = %p)\n", ptr); \
print_malloc_map(); \
ptr; \
})
@@ -111,10 +139,10 @@ void *malloc(size_t size);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
void *memalign(size_t align, size_t size);
-#endif
-void init_dma_memory(void *start, u32 size);
void *dma_malloc(size_t size);
void *dma_memalign(size_t align, size_t size);
+#endif
+void init_dma_memory(void *start, u32 size);
int dma_initialized(void);
int dma_coherent(void *ptr);
/** @} */
diff --git a/payloads/libpayload/libc/malloc.c b/payloads/libpayload/libc/malloc.c
index 11dfeefadd..0f2845d4ea 100644
--- a/payloads/libpayload/libc/malloc.c
+++ b/payloads/libpayload/libc/malloc.c
@@ -46,11 +46,21 @@ struct memory_type {
void *start;
void *end;
struct align_region_t* align_regions;
+#ifdef CONFIG_LP_DEBUG_MALLOC
+ int magic_initialized;
+ size_t minimal_free;
+ const char *name;
+#endif
};
extern char _heap, _eheap; /* Defined in the ldscript. */
-static struct memory_type default_type = { (void *)&_heap, (void *)&_eheap, NULL };
+static struct memory_type default_type =
+ { (void *)&_heap, (void *)&_eheap, NULL
+#ifdef CONFIG_LP_DEBUG_MALLOC
+ , 0, 0, "HEAP"
+#endif
+ };
static struct memory_type *const heap = &default_type;
static struct memory_type *dma = &default_type;
@@ -75,26 +85,31 @@ typedef u64 hdrtype_t;
static int free_aligned(void* addr, struct memory_type *type);
void print_malloc_map(void);
-#ifdef CONFIG_LP_DEBUG_MALLOC
-static int heap_initialized = 0;
-static int minimal_free = 0;
-#endif
-
void init_dma_memory(void *start, u32 size)
{
-#ifdef CONFIG_LP_DEBUG_MALLOC
if (dma_initialized()) {
- printf("WARNING: %s called twice!\n");
+ printf("ERROR: %s called twice!\n", __func__);
return;
}
- printf("Initializing cache-coherent DMA memory at [%p:%p]\n", start, start + size);
-#endif
+ /*
+ * DMA memory might not be zeroed by Coreboot on stage loading, so make
+ * sure we clear the magic cookie from last boot.
+ */
+ *(hdrtype_t *)start = 0;
dma = malloc(sizeof(*dma));
dma->start = start;
dma->end = start + size;
dma->align_regions = NULL;
+
+#ifdef CONFIG_LP_DEBUG_MALLOC
+ dma->minimal_free = 0;
+ dma->magic_initialized = 0;
+ dma->name = "DMA";
+
+ printf("Initialized cache-coherent DMA memory at [%p:%p]\n", start, start + size);
+#endif
}
int dma_initialized()
@@ -108,16 +123,6 @@ int dma_coherent(void *ptr)
return !dma_initialized() || (dma->start <= ptr && dma->end > ptr);
}
-static void setup(hdrtype_t volatile *start, int size)
-{
- *start = FREE_BLOCK(size);
-
-#ifdef CONFIG_LP_DEBUG_MALLOC
- heap_initialized = 1;
- minimal_free = size;
-#endif
-}
-
static void *alloc(int len, struct memory_type *type)
{
hdrtype_t header;
@@ -130,8 +135,14 @@ static void *alloc(int len, struct memory_type *type)
return (void *)NULL;
/* Make sure the region is setup correctly. */
- if (!HAS_MAGIC(*ptr))
- setup(ptr, (int)((type->end - type->start) - HDRSIZE));
+ if (!HAS_MAGIC(*ptr)) {
+ size_t size = (type->end - type->start) - HDRSIZE;
+ *ptr = FREE_BLOCK(size);
+#ifdef CONFIG_LP_DEBUG_MALLOC
+ type->magic_initialized = 1;
+ type->minimal_free = size;
+#endif
+ }
/* Find some free space. */
do {
@@ -452,24 +463,29 @@ void *dma_memalign(size_t align, size_t size)
#ifdef CONFIG_LP_DEBUG_MALLOC
void print_malloc_map(void)
{
- void *ptr = heap->start;
- int free_memory = 0;
+ struct memory_type *type = heap;
+ void *ptr;
+ int free_memory;
- while (ptr < heap->end) {
+again:
+ ptr = type->start;
+ free_memory = 0;
+
+ while (ptr < type->end) {
hdrtype_t hdr = *((hdrtype_t *) ptr);
if (!HAS_MAGIC(hdr)) {
- if (heap_initialized)
- printf("Poisoned magic - we're toast\n");
+ if (type->magic_initialized)
+ printf("%s: Poisoned magic - we're toast\n", type->name);
else
- printf("No magic yet - going to initialize\n");
+ printf("%s: No magic yet - going to initialize\n", type->name);
break;
}
/* FIXME: Verify the size of the block. */
- printf("%x: %s (%x bytes)\n",
- (unsigned int)(ptr - heap->start),
+ printf("%s %x: %s (%x bytes)\n", type->name,
+ (unsigned int)(ptr - type->start),
hdr & FLAG_FREE ? "FREE" : "USED", SIZE(hdr));
if (hdr & FLAG_FREE)
@@ -478,9 +494,14 @@ void print_malloc_map(void)
ptr += HDRSIZE + SIZE(hdr);
}
- if (free_memory && (minimal_free > free_memory))
- minimal_free = free_memory;
- printf("Maximum memory consumption: %d bytes\n",
- (unsigned int)(heap->end - heap->start) - HDRSIZE - minimal_free);
+ if (free_memory && (type->minimal_free > free_memory))
+ type->minimal_free = free_memory;
+ printf("%s: Maximum memory consumption: %u bytes\n", type->name,
+ (type->end - type->start) - HDRSIZE - type->minimal_free);
+
+ if (type != dma) {
+ type = dma;
+ goto again;
+ }
}
#endif