[Sound-open-firmware] [PATCH] memory: allocator: Add support for different memory types and mappings

Liam Girdwood liam.r.girdwood at linux.intel.com
Thu Mar 1 13:16:03 CET 2018


Currently memory heap pools are statically defined in the allocator core
and don't define the capabilities of the memory in each pool.

This patch adds support for different memory capabilities so that users
can allocate memory that complies with any capability requirements for
requested memory.

The patch also moves the memory heap pool mappings to platform specific
code so that platforms can define their own mappings, support multiple
mappings and can move the mappings into different physical memory areas.
mappings

Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
---
 src/audio/eq_fir.c                                 |   3 +-
 src/include/reef/alloc.h                           |  50 ++-
 src/include/uapi/ipc.h                             |  12 +
 src/lib/alloc.c                                    | 383 +++++++++------------
 src/platform/apollolake/Makefile.am                |   3 +-
 src/platform/apollolake/include/platform/memory.h  |  12 +-
 .../apollolake/include/platform/platform.h         |   6 +
 src/platform/apollolake/memory.c                   | 119 +++++++
 src/platform/baytrail/Makefile.am                  |   3 +-
 src/platform/baytrail/include/platform/memory.h    |   7 +-
 src/platform/baytrail/memory.c                     |  89 +++++
 src/platform/cannonlake/Makefile.am                |   3 +-
 src/platform/cannonlake/include/platform/memory.h  |  15 +-
 src/platform/cannonlake/memory.c                   | 119 +++++++
 src/platform/haswell/Makefile.am                   |   3 +-
 src/platform/haswell/include/platform/memory.h     |   7 +-
 src/platform/haswell/memory.c                      |  89 +++++
 17 files changed, 668 insertions(+), 255 deletions(-)
 create mode 100644 src/platform/apollolake/memory.c
 create mode 100644 src/platform/baytrail/memory.c
 create mode 100644 src/platform/cannonlake/memory.c
 create mode 100644 src/platform/haswell/memory.c

diff --git a/src/audio/eq_fir.c b/src/audio/eq_fir.c
index 2dfa11c..a723cf0 100644
--- a/src/audio/eq_fir.c
+++ b/src/audio/eq_fir.c
@@ -149,8 +149,7 @@ static void eq_fir_free_delaylines(struct fir_state_32x16 fir[])
 	}
 
 	if (data != NULL)
-		rbfree(data);
-
+		rfree(data);
 }
 
 static int eq_fir_setup(struct fir_state_32x16 fir[],
diff --git a/src/include/reef/alloc.h b/src/include/reef/alloc.h
index 982af90..6b61b04 100644
--- a/src/include/reef/alloc.h
+++ b/src/include/reef/alloc.h
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <stdint.h>
 #include <reef/dma.h>
+#include <platform/memory.h>
 
 struct reef;
 
@@ -61,23 +62,58 @@ struct reef;
  */
 #define RFLAGS_NONE		0
 #define RFLAGS_USED		1
-#define RFLAGS_ATOMIC	2   /* allocation with IRQs off */
-#define RFLAGS_DMA		4   /* DMA-able memory */
-#define RFLAGS_POWER	8   /* low power memory */
 
 struct mm_info {
 	uint32_t used;
 	uint32_t free;
 };
 
+struct block_hdr {
+	uint16_t size;		/* size in blocks for continuous allocation */
+	uint16_t flags;		/* usage flags for page */
+} __attribute__ ((packed));
+
+struct block_map {
+	uint16_t block_size;	/* size of block in bytes */
+	uint16_t count;		/* number of blocks in map */
+	uint16_t free_count;	/* number of free blocks */
+	uint16_t first_free;	/* index of first free block */
+	struct block_hdr *block;	/* base block header */
+	uint32_t base;		/* base address of space */
+} __attribute__ ((packed));
+
+#define BLOCK_DEF(sz, cnt, hdr) \
+	{.block_size = sz, .count = cnt, .free_count = cnt, .block = hdr}
+
+struct mm_heap {
+	uint32_t blocks;
+	struct block_map *map;
+	uint32_t heap;
+	uint32_t size;
+	uint32_t caps;
+	struct mm_info info;
+};
+
+/* heap block memory map */
+struct mm {
+	/* system heap - used during init cannot be freed */
+	struct mm_heap system;
+	/* general heap for components */
+	struct mm_heap runtime[PLATFORM_HEAP_RUNTIME];
+	/* general component buffer heap */
+	struct mm_heap buffer[PLATFORM_HEAP_BUFFER];
+
+	struct mm_info total;
+	spinlock_t lock;	/* all allocs and frees are atomic */
+};
+
 /* heap allocation and free */
-void *rmalloc(int zone, int flags, size_t bytes);
-void *rzalloc(int zone, int flags, size_t bytes);
+void *rmalloc(int zone, uint32_t caps, size_t bytes);
+void *rzalloc(int zone, uint32_t caps, size_t bytes);
 void rfree(void *ptr);
 
 /* heap allocation and free for buffers on 1k boundary */
-void *rballoc(int zone, int flags, size_t bytes);
-void rbfree(void *ptr);
+void *rballoc(int zone, uint32_t flags, size_t bytes);
 
 /* utility */
 void bzero(void *s, size_t n);
diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h
index 87b01e3..dec8abd 100644
--- a/src/include/uapi/ipc.h
+++ b/src/include/uapi/ipc.h
@@ -143,6 +143,17 @@
 #define SOF_IPC_PANIC_STACK			(SOF_IPC_PANIC_MAGIC | 8)
 #define SOF_IPC_PANIC_IDLE			(SOF_IPC_PANIC_MAGIC | 9)
 
+/*
+ * SOF memory capabilities, add new ones at the end
+ */
+#define SOF_MEM_CAPS_RAM			(1 << 0)
+#define SOF_MEM_CAPS_ROM			(1 << 1)
+#define SOF_MEM_CAPS_EXT			(1 << 2) /* external */
+#define SOF_MEM_CAPS_LP			(1 << 3) /* low power */
+#define SOF_MEM_CAPS_HP			(1 << 4) /* high performance */
+#define SOF_MEM_CAPS_DMA			(1 << 5) /* DMA'able */
+#define SOF_MEM_CAPS_CACHE			(1 << 6) /* cacheable */
+
 /*
  * Command Header - Header for all IPC. Identifies IPC message.
  * The size can be greater than the structure size and that means there is
@@ -561,6 +572,7 @@ struct sof_ipc_comp {
 struct sof_ipc_buffer {
 	struct sof_ipc_comp comp;
 	uint32_t size;		/* buffer size in bytes */
+	uint32_t type;		/* SOF_MEM_CAPS_ */
 } __attribute__((packed));
 
 
diff --git a/src/lib/alloc.c b/src/lib/alloc.c
index 803b7af..bbc32a3 100644
--- a/src/lib/alloc.c
+++ b/src/lib/alloc.c
@@ -55,6 +55,8 @@
 
 #define trace_mem_error(__e)	trace_error(TRACE_CLASS_MEM, __e)
 
+extern struct mm memmap;
+
 /* We have 3 memory pools
  *
  * 1) System memory pool does not have a map and it's size is fixed at build
@@ -67,115 +69,6 @@
  *    module removal or calls to rfree(). Saved as part of PM context.
  */
 
-struct block_hdr {
-	uint16_t size;		/* size in blocks of this continuous allocation */
-	uint16_t flags;		/* usage flags for page */
-} __attribute__ ((packed));
-
-struct block_map {
-	uint16_t block_size;	/* size of block in bytes */
-	uint16_t count;		/* number of blocks in map */
-	uint16_t free_count;	/* number of free blocks */
-	uint16_t first_free;	/* index of first free block */
-	struct block_hdr *block;	/* base block header */
-	uint32_t base;		/* base address of space */
-} __attribute__ ((packed));
-
-#define BLOCK_DEF(sz, cnt, hdr) \
-	{.block_size = sz, .count = cnt, .free_count = cnt, .block = hdr}
-
-/* Heap blocks for modules */
-//static struct block_hdr mod_block8[HEAP_RT_COUNT8];
-static struct block_hdr mod_block16[HEAP_RT_COUNT16];
-static struct block_hdr mod_block32[HEAP_RT_COUNT32];
-static struct block_hdr mod_block64[HEAP_RT_COUNT64];
-static struct block_hdr mod_block128[HEAP_RT_COUNT128];
-static struct block_hdr mod_block256[HEAP_RT_COUNT256];
-static struct block_hdr mod_block512[HEAP_RT_COUNT512];
-static struct block_hdr mod_block1024[HEAP_RT_COUNT1024];
-
-/* Heap memory map for modules */
-static struct block_map rt_heap_map[] = {
-/*	BLOCK_DEF(8, HEAP_RT_COUNT8, mod_block8), */
-	BLOCK_DEF(16, HEAP_RT_COUNT16, mod_block16),
-	BLOCK_DEF(32, HEAP_RT_COUNT32, mod_block32),
-	BLOCK_DEF(64, HEAP_RT_COUNT64, mod_block64),
-	BLOCK_DEF(128, HEAP_RT_COUNT128, mod_block128),
-	BLOCK_DEF(256, HEAP_RT_COUNT256, mod_block256),
-	BLOCK_DEF(512, HEAP_RT_COUNT512, mod_block512),
-	BLOCK_DEF(1024, HEAP_RT_COUNT1024, mod_block1024),
-};
-
-/* Heap blocks for buffers */
-static struct block_hdr buf_block[HEAP_BUFFER_COUNT];
-
-/* Heap memory map for buffers */
-static struct block_map buf_heap_map[] = {
-	BLOCK_DEF(HEAP_BUFFER_BLOCK_SIZE, HEAP_BUFFER_COUNT, buf_block),
-};
-
-#if (HEAP_DMA_BUFFER_SIZE > 0)
-/* Heap memory map for DMA buffers - only used for HW with special DMA memories */
-static struct block_map dma_buf_heap_map[] = {
-	BLOCK_DEF(HEAP_DMA_BUFFER_BLOCK_SIZE, HEAP_DMA_BUFFER_COUNT, buf_block),
-};
-#endif
-
-struct mm_heap {
-	uint32_t blocks;
-	struct block_map *map;
-	uint32_t heap;
-	uint32_t size;
-	struct mm_info info;
-};
-
-/* heap block memory map */
-struct mm {
-	struct mm_heap runtime;	/* general heap for components */
-	struct mm_heap system;	/* system heap - used during init cannot be freed */
-	struct mm_heap buffer;	/* general component buffer heap */
-#if (HEAP_DMA_BUFFER_SIZE > 0)
-	struct mm_heap dma;	/* general component DMA buffer heap */
-#endif
-	struct mm_info total;
-	spinlock_t lock;	/* all allocs and frees are atomic */
-};
-
-struct mm memmap = {
-	.system = {
-		.heap = HEAP_SYSTEM_BASE,
-		.size = HEAP_SYSTEM_SIZE,
-		.info = {.free = HEAP_SYSTEM_SIZE,},
-	},
-
-	.runtime = {
-		.blocks = ARRAY_SIZE(rt_heap_map),
-		.map = rt_heap_map,
-		.heap = HEAP_RUNTIME_BASE,
-		.size = HEAP_RUNTIME_SIZE,
-		.info = {.free = HEAP_RUNTIME_SIZE,},
-	},
-
-	.buffer = {
-		.blocks = ARRAY_SIZE(buf_heap_map),
-		.map = buf_heap_map,
-		.heap = HEAP_BUFFER_BASE,
-		.size = HEAP_BUFFER_SIZE,
-		.info = {.free = HEAP_BUFFER_SIZE,},
-	},
-
-#if (HEAP_DMA_BUFFER_SIZE > 0)
-	.dma = {
-		.blocks = ARRAY_SIZE(dma_buf_heap_map),
-		.map = dma_buf_heap_map,
-		.heap = HEAP_DMA_BUFFER_BASE,
-		.size = HEAP_DMA_BUFFER_SIZE,
-		.info = {.free = HEAP_DMA_BUFFER_SIZE,},
-	},
-#endif
-	.total = {.free = HEAP_SYSTEM_SIZE + HEAP_RUNTIME_SIZE + 
-		HEAP_BUFFER_SIZE + HEAP_DMA_BUFFER_SIZE,},
-};
 
 /* total size of block */
 static inline uint32_t block_get_size(struct block_map *map)
@@ -228,7 +121,8 @@ static void *rmalloc_sys(size_t bytes)
 }
 
 /* allocate single block */
-static void *alloc_block(struct mm_heap *heap, int level, int bflags)
+static void *alloc_block(struct mm_heap *heap, int level,
+	uint32_t caps)
 {
 	struct block_map *map = &heap->map[level];
 	struct block_hdr *hdr = &map->block[map->first_free];
@@ -238,7 +132,7 @@ static void *alloc_block(struct mm_heap *heap, int level, int bflags)
 	map->free_count--;
 	ptr = (void *)(map->base + map->first_free * map->block_size);
 	hdr->size = 1;
-	hdr->flags = RFLAGS_USED | bflags;
+	hdr->flags = RFLAGS_USED;
 	heap->info.used += map->block_size;
 	heap->info.free -= map->block_size;
 
@@ -261,8 +155,8 @@ static void *alloc_block(struct mm_heap *heap, int level, int bflags)
 }
 
 /* allocates continuous blocks */
-static void *alloc_cont_blocks(struct mm_heap *heap, int level, int bflags,
-	size_t bytes)
+static void *alloc_cont_blocks(struct mm_heap *heap, int level,
+	uint32_t caps, size_t bytes)
 {
 	struct block_map *map = &heap->map[level];
 	struct block_hdr *hdr = &map->block[map->first_free];
@@ -311,7 +205,7 @@ found:
 	/* allocate each block */
 	for (current = start; current < end; current++) {
 		hdr = &map->block[current];
-		hdr->flags = RFLAGS_USED | bflags;
+		hdr->flags = RFLAGS_USED;
 	}
 
 	/* do we need to find a new first free block ? */
@@ -336,43 +230,87 @@ found:
 	return ptr;
 }
 
+static struct mm_heap *get_heap_from_ptr(void *ptr)
+{
+	struct mm_heap *heap;
+	int i;
+
+	/* find mm_heap that ptr belongs to */
+	for (i = 0; i < PLATFORM_HEAP_RUNTIME; i++) {
+		heap = &memmap.runtime[i];
+
+		if ((uint32_t)ptr >= heap->heap &&
+			(uint32_t)ptr < heap->heap + heap->size)
+			return heap;
+	}
+
+	for (i = 0; i < PLATFORM_HEAP_BUFFER; i++) {
+		heap = &memmap.buffer[i];
+
+		if ((uint32_t)ptr >= heap->heap &&
+			(uint32_t)ptr < heap->heap + heap->size)
+			return heap;
+	}
+
+	return NULL;
+}
+
+static struct mm_heap *get_runtime_heap_from_caps(uint32_t caps)
+{
+	struct mm_heap *heap;
+	uint32_t mask;
+	int i;
+
+	/* find first heap that support type */
+	for (i = 0; i < PLATFORM_HEAP_RUNTIME; i++) {
+		heap = &memmap.runtime[i];
+		mask = heap->caps & caps;
+		if (mask == caps)
+			return heap;
+	}
+
+	return NULL;
+}
+
+static struct mm_heap *get_buffer_heap_from_caps(uint32_t caps)
+{
+	struct mm_heap *heap;
+	uint32_t mask;
+	int i;
+
+	/* find first heap that support type */
+	for (i = 0; i < PLATFORM_HEAP_BUFFER; i++) {
+		heap = &memmap.buffer[i];
+		mask = heap->caps & caps;
+		if (mask == caps)
+			return heap;
+	}
+
+	return NULL;
+}
+
 /* free block(s) */
-static void free_block(struct mm_heap *heap, void *ptr)
+static void free_block(void *ptr)
 {
-	struct mm_heap * mm_heap;
-	struct block_map * block_map;
+	struct mm_heap *heap;
+	struct block_map *block_map;
 	struct block_hdr *hdr;
 	int i;
 	int block;
-	int array_size;
 
 	/* sanity check */
 	if (ptr == NULL)
 		return;
 
-	/* find mm_heap that ptr belongs to */
-	if ((uint32_t)ptr >= memmap.runtime.heap &&
-		(uint32_t)ptr < memmap.runtime.heap + memmap.runtime.size) {
-		mm_heap = &memmap.runtime;
-		array_size = ARRAY_SIZE(rt_heap_map);
-	} else if ((uint32_t)ptr >= memmap.buffer.heap &&
-		(uint32_t)ptr < memmap.buffer.heap + memmap.buffer.size) {
-		mm_heap = &memmap.buffer;
-		array_size = ARRAY_SIZE(buf_heap_map);
-#if (HEAP_DMA_BUFFER_SIZE > 0)
-	} else if ((uint32_t)ptr >= memmap.dma.heap &&
-		(uint32_t)ptr < memmap.dma.heap + memmap.dma.size) {
-		mm_heap = &memmap.dma;
-		array_size = ARRAY_SIZE(dma_buf_heap_map);
-#endif
-	} else
+	heap = get_heap_from_ptr(ptr);
+	if (heap == NULL)
 		return;
 
 	/* find block that ptr belongs to */
-	for (i = 0; i < array_size - 1; i ++) {
+	for (i = 0; i < heap->blocks - 1; i++) {
 
 		/* is ptr in this block */
-		if ((uint32_t)ptr < mm_heap->map[i + 1].base)
+		if ((uint32_t)ptr < heap->map[i + 1].base)
 			goto found;
 	}
 
@@ -382,7 +320,7 @@ static void free_block(struct mm_heap *heap, void *ptr)
 
 found:
 	/* the block i is it */
-	block_map = &mm_heap->map[i];
+	block_map = &heap->map[i];
 
 	/* calculate block header */
 	block = ((uint32_t)ptr - block_map->base) / block_map->block_size;
@@ -398,7 +336,7 @@ found:
 		heap->info.free += block_map->block_size;
 	}
 
-	/* set first free */
+	/* set first free block */
 	if (block < block_map->first_free)
 		block_map->first_free = block;
 
@@ -408,31 +346,37 @@ found:
 }
 
 /* allocate single block for runtime */
-static void *rmalloc_runtime(int bflags, size_t bytes)
+static void *rmalloc_runtime(uint32_t caps, size_t bytes)
 {
+	struct mm_heap *heap;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(rt_heap_map); i ++) {
+	heap = get_runtime_heap_from_caps(caps);
+	if (heap == NULL)
+		goto error;
+
+	for (i = 0; i < heap->blocks; i++) {
 
 		/* is block big enough */
-		if (rt_heap_map[i].block_size < bytes)
+		if (heap->map[i].block_size < bytes)
 			continue;
 
 		/* does block have free space */
-		if (rt_heap_map[i].free_count == 0)
+		if (heap->map[i].free_count == 0)
 			continue;
 
 		/* free block space exists */
-		return alloc_block(&memmap.runtime, i, bflags);
+		return alloc_block(heap, i, caps);
 	}
 
+error:
 	trace_mem_error("eMm");
 	trace_value(bytes);
-	trace_value(bflags);
+	trace_value(caps);
 	return NULL;
 }
 
-void *rmalloc(int zone, int bflags, size_t bytes)
+void *rmalloc(int zone, uint32_t caps, size_t bytes)
 {
 	uint32_t flags;
 	void *ptr = NULL;
@@ -444,7 +388,7 @@ void *rmalloc(int zone, int bflags, size_t bytes)
 		ptr = rmalloc_sys(bytes);
 		break;
 	case RZONE_RUNTIME:
-		ptr = rmalloc_runtime(bflags, bytes);
+		ptr = rmalloc_runtime(caps, bytes);
 		break;
 	default:
 		trace_mem_error("eMz");
@@ -455,11 +399,11 @@ void *rmalloc(int zone, int bflags, size_t bytes)
 	return ptr;
 }
 
-void *rzalloc(int zone, int bflags, size_t bytes)
+void *rzalloc(int zone, uint32_t caps, size_t bytes)
 {
 	void *ptr = NULL;
 
-	ptr = rmalloc(zone, bflags, bytes);
+	ptr = rmalloc(zone, caps, bytes);
 	if (ptr != NULL) {
 		bzero(ptr, bytes);
 	}
@@ -467,61 +411,54 @@ void *rzalloc(int zone, int bflags, size_t bytes)
 	return ptr;
 }
 
-/* allocates continuous buffer on 1k boundary */
-void *rballoc(int zone, int bflags, size_t bytes)
+/* allocates continuous buffers */
+void *rballoc(int zone, uint32_t caps, size_t bytes)
 {
-	struct block_map * block_map = buf_heap_map;
-	struct mm_heap * mm_heap = &memmap.buffer;
+	struct mm_heap *heap;
 	int i;
-	int array_size = ARRAY_SIZE(buf_heap_map);
 	uint32_t flags;
 	void *ptr = NULL;
 
-#if (HEAP_DMA_BUFFER_SIZE > 0)
-	if (bflags & RFLAGS_DMA) {
-		mm_heap = &memmap.dma;
-		block_map = dma_buf_heap_map;
-		array_size = ARRAY_SIZE(dma_buf_heap_map);
-	}
-#endif
 	spin_lock_irq(&memmap.lock, flags);
 
+	heap = get_buffer_heap_from_caps(caps);
+	if (heap == NULL)
+		goto out;
+
 	/* will request fit in single block */
-	for (i = 0; i < array_size; i++) {
+	for (i = 0; i < heap->blocks; i++) {
 
 		/* is block big enough */
-		if (block_map[i].block_size < bytes)
+		if (heap->map[i].block_size < bytes)
 			continue;
 
 		/* does block have free space */
-		if (block_map[i].free_count == 0)
+		if (heap->map[i].free_count == 0)
 			continue;
 
 		/* allocate block */
-		ptr = alloc_block(mm_heap, i, bflags);
+		ptr = alloc_block(heap, i, caps);
 		goto out;
 	}
 
 	/* request spans > 1 block */
 
 	/* only 1 choice for block size */
-	if (array_size == 1) {
-		ptr = alloc_cont_blocks(mm_heap, 0, bflags, bytes);
+	if (heap->blocks == 1) {
+		ptr = alloc_cont_blocks(heap, 0, caps, bytes);
 		goto out;
 	} else {
 
 		/* find best block size for request */
-		for (i = 0; i < array_size; i++) {
+		for (i = 0; i < heap->blocks; i++) {
 
 			/* allocate is block size smaller than request */
-			if (block_map[i].block_size < bytes)
-				alloc_cont_blocks(mm_heap, i, bflags,
-					bytes);
+			if (heap->map[i].block_size < bytes)
+				alloc_cont_blocks(heap, i, caps, bytes);
 		}
 	}
 
-	ptr = alloc_cont_blocks(mm_heap, array_size - 1,
-		bflags, bytes);
+	ptr = alloc_cont_blocks(heap, heap->blocks - 1, caps, bytes);
 
 out:
 	spin_unlock_irq(&memmap.lock, flags);
@@ -533,38 +470,42 @@ void rfree(void *ptr)
 	uint32_t flags;
 
 	spin_lock_irq(&memmap.lock, flags);
-	free_block(&memmap.runtime, ptr);
-	spin_unlock_irq(&memmap.lock, flags);
-}
-
-void rbfree(void *ptr)
-{
-	uint32_t flags;
-
-	spin_lock_irq(&memmap.lock, flags);
-	free_block(&memmap.buffer, ptr);
+	free_block(ptr);
 	spin_unlock_irq(&memmap.lock, flags);
 }
 
 uint32_t mm_pm_context_size(void)
 {
-	uint32_t size;
+	uint32_t size = 0;
+	int i;
 
 	/* calc context size for each area  */
-	size = memmap.buffer.info.used;
-	size += memmap.runtime.info.used;
+	for (i = 0; i < PLATFORM_HEAP_BUFFER; i++)
+		size += memmap.buffer[i].info.used;
+	for (i = 0; i < PLATFORM_HEAP_RUNTIME; i++)
+		size += memmap.runtime[i].info.used;
 	size += memmap.system.info.used;
 
 	/* add memory maps */
-	size += heap_get_size(&memmap.buffer);
-	size += heap_get_size(&memmap.runtime);
+	for (i = 0; i < PLATFORM_HEAP_BUFFER; i++)
+		size += heap_get_size(&memmap.buffer[i]);
+	for (i = 0; i < PLATFORM_HEAP_RUNTIME; i++)
+		size += heap_get_size(&memmap.runtime[i]);
 	size += heap_get_size(&memmap.system);
 
 	/* recalc totals */
-	memmap.total.free = memmap.buffer.info.free +
-		memmap.runtime.info.free + memmap.system.info.free;
-	memmap.total.used = memmap.buffer.info.used +
-		memmap.runtime.info.used + memmap.system.info.used;
+	memmap.total.free = memmap.system.info.free;
+	memmap.total.used = memmap.system.info.used;
+
+	for (i = 0; i < PLATFORM_HEAP_BUFFER; i++) {
+		memmap.total.free += memmap.buffer[i].info.free;
+		memmap.total.used += memmap.buffer[i].info.used;
+	}
+
+	for (i = 0; i < PLATFORM_HEAP_RUNTIME; i++) {
+		memmap.total.free = memmap.runtime[i].info.free;
+		memmap.total.used = memmap.runtime[i].info.used;
+	}
 
 	return size;
 }
@@ -643,9 +584,12 @@ int mm_pm_context_restore(struct dma_copy *dc, struct dma_sg_config *sg)
 /* initialise map */
 void init_heap(struct reef *reef)
 {
+	struct mm_heap *heap;
 	struct block_map *next_map;
 	struct block_map *current_map;
 	int i;
+	int j;
+	int k;
 
 	/* sanity check for malformed images or loader issues */
 	if (memmap.system.heap != HEAP_SYSTEM_BASE)
@@ -654,37 +598,40 @@ void init_heap(struct reef *reef)
 	spinlock_init(&memmap.lock);
 
 	/* initialise buffer map */
-	current_map = &buf_heap_map[0];
-	current_map->base = memmap.buffer.heap;
-
-	for (i = 1; i < ARRAY_SIZE(buf_heap_map); i++) {
-		next_map = &buf_heap_map[i];
-		next_map->base = current_map->base +
-			current_map->block_size * current_map->count;
-		current_map = &buf_heap_map[i];
+	for (i = 0; i < PLATFORM_HEAP_BUFFER; i++) {
+		heap = &memmap.buffer[i];
+
+		for (j = 0; j < heap->blocks; j++) {
+
+			current_map = &heap->map[j];
+			current_map->base = heap->heap;
+
+			for (k = 1; k < heap->blocks; k++) {
+				next_map = &heap->map[k];
+				next_map->base = current_map->base +
+					current_map->block_size *
+					current_map->count;
+				current_map = &heap->map[k];
+			}
+		}
 	}
 
 	/* initialise runtime map */
-	current_map = &rt_heap_map[0];
-	current_map->base = memmap.runtime.heap;
-
-	for (i = 1; i < ARRAY_SIZE(rt_heap_map); i++) {
-		next_map = &rt_heap_map[i];
-		next_map->base = current_map->base +
-			current_map->block_size * current_map->count;
-		current_map = &rt_heap_map[i];
-	}
+	for (i = 0; i < PLATFORM_HEAP_RUNTIME; i++) {
+		heap = &memmap.runtime[i];
 
-#if (HEAP_DMA_BUFFER_SIZE > 0)
-	/* initialise DMA map */
-	current_map = &dma_buf_heap_map[0];
-	current_map->base = memmap.dma.heap;
+		for (j = 0; j < heap->blocks; j++) {
 
-	for (i = 1; i < ARRAY_SIZE(dma_buf_heap_map); i++) {
-		next_map = &dma_buf_heap_map[i];
-		next_map->base = current_map->base +
-			current_map->block_size * current_map->count;
-		current_map = &dma_buf_heap_map[i];
+			current_map = &heap->map[j];
+			current_map->base = heap->heap;
+
+			for (k = 1; k < heap->blocks; k++) {
+				next_map = &heap->map[k];
+				next_map->base = current_map->base +
+					current_map->block_size *
+					current_map->count;
+				current_map = &heap->map[k];
+			}
+		}
 	}
-#endif
 }
diff --git a/src/platform/apollolake/Makefile.am b/src/platform/apollolake/Makefile.am
index d4fe06a..7e776e3 100644
--- a/src/platform/apollolake/Makefile.am
+++ b/src/platform/apollolake/Makefile.am
@@ -8,7 +8,8 @@ libplatform_a_SOURCES = \
 	dma.c \
 	clk.c \
 	timer.c \
-	interrupt.c
+	interrupt.c \
+	memory.c
 
 libplatform_a_CFLAGS = \
 	$(ARCH_CFLAGS) \
diff --git a/src/platform/apollolake/include/platform/memory.h b/src/platform/apollolake/include/platform/memory.h
index b4fae8e..b633637 100644
--- a/src/platform/apollolake/include/platform/memory.h
+++ b/src/platform/apollolake/include/platform/memory.h
@@ -174,7 +174,7 @@
 #define REEF_DATA_SIZE			0x18000
 
 /* bss data */
-#define REEF_BSS_DATA_SIZE		0x2000
+#define REEF_BSS_DATA_SIZE		0x2800
 
 /* Heap configuration */
 #define HEAP_SYSTEM_BASE \
@@ -262,12 +262,6 @@
 #define HP_SRAM_WIN3_BASE	SRAM_TRACE_BASE
 #define HP_SRAM_WIN3_SIZE	SRAM_TRACE_SIZE
 
-/* DMA buffer heap is the HP physical memory on Broxton */
-#define HEAP_DMA_BUFFER_BASE		HP_SRAM_BASE
-#define HEAP_DMA_BUFFER_SIZE		HEAP_HP_BUFFER_SIZE
-#define HEAP_DMA_BUFFER_BLOCK_SIZE	HEAP_HP_BUFFER_BLOCK_SIZE
-#define HEAP_DMA_BUFFER_COUNT		HEAP_HP_BUFFER_COUNT
-
 /* HP SRAM Heap */
 #define HEAP_HP_BUFFER_BASE	HP_SRAM_BASE
 #define HEAP_HP_BUFFER_SIZE \
@@ -283,7 +277,7 @@
 	(HEAP_HP_BUFFER_SIZE / HEAP_HP_BUFFER_BLOCK_SIZE)
 
 /*
- * The LP SRAM Heap and Stack on Apololake are organised like this :-
+ * The LP SRAM Heap and Stack on Apollolake are organised like this :-
  *
  * +--------------------------------------------------------------------------+
  * | Offset              | Region         |  Size                             |
@@ -341,6 +335,8 @@
 #define HEAP_LP_BUFFER_COUNT \
 	(HEAP_LP_BUFFER_SIZE / HEAP_LP_BUFFER_BLOCK_SIZE)
 
+#define PLATFORM_HEAP_RUNTIME		1
+#define PLATFORM_HEAP_BUFFER		3
 
 /* Stack configuration */
 #define REEF_LP_STACK_SIZE		0x1000
diff --git a/src/platform/apollolake/include/platform/platform.h b/src/platform/apollolake/include/platform/platform.h
index 8e18d53..995efca 100644
--- a/src/platform/apollolake/include/platform/platform.h
+++ b/src/platform/apollolake/include/platform/platform.h
@@ -103,6 +103,12 @@ struct reef;
 /* DSP should be idle in this time frame */
 #define PLATFORM_IDLE_TIME	750000
 
+/* platform has DMA memory type */
+#define PLATFORM_MEM_HAS_DMA
+
+/* platform has low power memory type */
+#define PLATFORM_MEM_HAS_LP_RAM
+
 /* Platform defined panic code */
 #define platform_panic(__x) \
 	sw_reg_write(SRAM_REG_FW_STATUS, (0xdead000 | __x) & 0x3fffffff)
diff --git a/src/platform/apollolake/memory.c b/src/platform/apollolake/memory.c
new file mode 100644
index 0000000..aa3dfaa
--- /dev/null
+++ b/src/platform/apollolake/memory.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2018, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ */
+
+#include <reef/alloc.h>
+
+/* Heap blocks for modules */
+static struct block_hdr mod_block16[HEAP_RT_COUNT16];
+static struct block_hdr mod_block32[HEAP_RT_COUNT32];
+static struct block_hdr mod_block64[HEAP_RT_COUNT64];
+static struct block_hdr mod_block128[HEAP_RT_COUNT128];
+static struct block_hdr mod_block256[HEAP_RT_COUNT256];
+static struct block_hdr mod_block512[HEAP_RT_COUNT512];
+static struct block_hdr mod_block1024[HEAP_RT_COUNT1024];
+
+/* Heap memory map for modules */
+static struct block_map rt_heap_map[] = {
+	BLOCK_DEF(16, HEAP_RT_COUNT16, mod_block16),
+	BLOCK_DEF(32, HEAP_RT_COUNT32, mod_block32),
+	BLOCK_DEF(64, HEAP_RT_COUNT64, mod_block64),
+	BLOCK_DEF(128, HEAP_RT_COUNT128, mod_block128),
+	BLOCK_DEF(256, HEAP_RT_COUNT256, mod_block256),
+	BLOCK_DEF(512, HEAP_RT_COUNT512, mod_block512),
+	BLOCK_DEF(1024, HEAP_RT_COUNT1024, mod_block1024),
+};
+
+/* Heap blocks for buffers */
+static struct block_hdr buf_block[HEAP_BUFFER_COUNT];
+static struct block_hdr hp_buf_block[HEAP_HP_BUFFER_COUNT];
+static struct block_hdr lp_buf_block[HEAP_LP_BUFFER_COUNT];
+
+/* Heap memory map for buffers */
+static struct block_map buf_heap_map[] = {
+	BLOCK_DEF(HEAP_BUFFER_BLOCK_SIZE, HEAP_BUFFER_COUNT, buf_block),
+};
+
+static struct block_map hp_buf_heap_map[] = {
+	BLOCK_DEF(HEAP_HP_BUFFER_BLOCK_SIZE, HEAP_HP_BUFFER_COUNT,
+		hp_buf_block),
+};
+
+static struct block_map lp_buf_heap_map[] = {
+	BLOCK_DEF(HEAP_LP_BUFFER_BLOCK_SIZE, HEAP_LP_BUFFER_COUNT,
+		lp_buf_block),
+};
+
+struct mm memmap = {
+	.system = {
+		.heap = HEAP_SYSTEM_BASE,
+		.size = HEAP_SYSTEM_SIZE,
+		.info = {.free = HEAP_SYSTEM_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_EXT |
+			SOF_MEM_CAPS_CACHE,
+	},
+	.runtime[0] = {
+		.blocks = ARRAY_SIZE(rt_heap_map),
+		.map = rt_heap_map,
+		.heap = HEAP_RUNTIME_BASE,
+		.size = HEAP_RUNTIME_SIZE,
+		.info = {.free = HEAP_RUNTIME_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_EXT |
+			SOF_MEM_CAPS_CACHE,
+	},
+	.buffer[0] = {
+		.blocks = ARRAY_SIZE(buf_heap_map),
+		.map = buf_heap_map,
+		.heap = HEAP_BUFFER_BASE,
+		.size = HEAP_BUFFER_SIZE,
+		.info = {.free = HEAP_BUFFER_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_EXT |
+			SOF_MEM_CAPS_CACHE,
+	},
+	.buffer[1] = {
+		.blocks = ARRAY_SIZE(hp_buf_heap_map),
+		.map = hp_buf_heap_map,
+		.heap = HEAP_HP_BUFFER_BASE,
+		.size = HEAP_HP_BUFFER_SIZE,
+		.info = {.free = HEAP_HP_BUFFER_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_HP |
+			SOF_MEM_CAPS_CACHE | SOF_MEM_CAPS_DMA,
+	},
+	.buffer[2] = {
+		.blocks = ARRAY_SIZE(lp_buf_heap_map),
+		.map = lp_buf_heap_map,
+		.heap = HEAP_LP_BUFFER_BASE,
+		.size = HEAP_LP_BUFFER_SIZE,
+		.info = {.free = HEAP_LP_BUFFER_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_LP |
+			SOF_MEM_CAPS_CACHE | SOF_MEM_CAPS_DMA,
+	},
+	.total = {.free = HEAP_SYSTEM_SIZE + HEAP_RUNTIME_SIZE +
+			HEAP_HP_BUFFER_SIZE + HEAP_LP_BUFFER_SIZE,},
+};
diff --git a/src/platform/baytrail/Makefile.am b/src/platform/baytrail/Makefile.am
index 05b1235..571a957 100644
--- a/src/platform/baytrail/Makefile.am
+++ b/src/platform/baytrail/Makefile.am
@@ -9,7 +9,8 @@ libplatform_a_SOURCES = \
 	dai.c \
 	dma.c \
 	clk.c \
-	timer.c
+	timer.c \
+	memory.c
 
 libplatform_a_CFLAGS = \
 	$(ARCH_CFLAGS) \
diff --git a/src/platform/baytrail/include/platform/memory.h b/src/platform/baytrail/include/platform/memory.h
index 082592c..5bf7141 100644
--- a/src/platform/baytrail/include/platform/memory.h
+++ b/src/platform/baytrail/include/platform/memory.h
@@ -129,11 +129,8 @@
 #define HEAP_BUFFER_BLOCK_SIZE		0x180
 #define HEAP_BUFFER_COUNT	(HEAP_BUFFER_SIZE / HEAP_BUFFER_BLOCK_SIZE)
 
-/* DMA buffer heap is the same physical memory as buffer heap on baytrail */
-#define HEAP_DMA_BUFFER_BASE		0
-#define HEAP_DMA_BUFFER_SIZE		0
-#define HEAP_DMA_BUFFER_BLOCK_SIZE	0
-#define HEAP_DMA_BUFFER_COUNT		0
+#define PLATFORM_HEAP_RUNTIME		1
+#define PLATFORM_HEAP_BUFFER		1
 
 /* Stack configuration */
 #define REEF_STACK_SIZE				0x1000
diff --git a/src/platform/baytrail/memory.c b/src/platform/baytrail/memory.c
new file mode 100644
index 0000000..12e7399
--- /dev/null
+++ b/src/platform/baytrail/memory.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2018, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ */
+
+#include <reef/alloc.h>
+
+/* Heap blocks for modules */
+static struct block_hdr mod_block16[HEAP_RT_COUNT16];
+static struct block_hdr mod_block32[HEAP_RT_COUNT32];
+static struct block_hdr mod_block64[HEAP_RT_COUNT64];
+static struct block_hdr mod_block128[HEAP_RT_COUNT128];
+static struct block_hdr mod_block256[HEAP_RT_COUNT256];
+static struct block_hdr mod_block512[HEAP_RT_COUNT512];
+static struct block_hdr mod_block1024[HEAP_RT_COUNT1024];
+
+/* Heap memory map for modules */
+static struct block_map rt_heap_map[] = {
+	BLOCK_DEF(16, HEAP_RT_COUNT16, mod_block16),
+	BLOCK_DEF(32, HEAP_RT_COUNT32, mod_block32),
+	BLOCK_DEF(64, HEAP_RT_COUNT64, mod_block64),
+	BLOCK_DEF(128, HEAP_RT_COUNT128, mod_block128),
+	BLOCK_DEF(256, HEAP_RT_COUNT256, mod_block256),
+	BLOCK_DEF(512, HEAP_RT_COUNT512, mod_block512),
+	BLOCK_DEF(1024, HEAP_RT_COUNT1024, mod_block1024),
+};
+
+/* Heap blocks for buffers */
+static struct block_hdr buf_block[HEAP_BUFFER_COUNT];
+
+/* Heap memory map for buffers */
+static struct block_map buf_heap_map[] = {
+	BLOCK_DEF(HEAP_BUFFER_BLOCK_SIZE, HEAP_BUFFER_COUNT, buf_block),
+};
+
+struct mm memmap = {
+	.system = {
+		.heap = HEAP_SYSTEM_BASE,
+		.size = HEAP_SYSTEM_SIZE,
+		.info = {.free = HEAP_SYSTEM_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_CACHE |
+			SOF_MEM_CAPS_DMA,
+	},
+	.runtime[0] = {
+		.blocks = ARRAY_SIZE(rt_heap_map),
+		.map = rt_heap_map,
+		.heap = HEAP_RUNTIME_BASE,
+		.size = HEAP_RUNTIME_SIZE,
+		.info = {.free = HEAP_RUNTIME_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_CACHE |
+			SOF_MEM_CAPS_DMA,
+	},
+	.buffer[0] = {
+		.blocks = ARRAY_SIZE(buf_heap_map),
+		.map = buf_heap_map,
+		.heap = HEAP_BUFFER_BASE,
+		.size = HEAP_BUFFER_SIZE,
+		.info = {.free = HEAP_BUFFER_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_CACHE |
+			SOF_MEM_CAPS_DMA,
+	},
+	.total = {.free = HEAP_SYSTEM_SIZE + HEAP_RUNTIME_SIZE +
+		HEAP_BUFFER_SIZE,},
+};
diff --git a/src/platform/cannonlake/Makefile.am b/src/platform/cannonlake/Makefile.am
index 9f3d591..2e9019d 100644
--- a/src/platform/cannonlake/Makefile.am
+++ b/src/platform/cannonlake/Makefile.am
@@ -8,7 +8,8 @@ libplatform_a_SOURCES = \
 	dma.c \
 	clk.c \
 	timer.c \
-	interrupt.c
+	interrupt.c \
+	memory.c
 
 libplatform_a_CFLAGS = \
 	$(ARCH_CFLAGS) \
diff --git a/src/platform/cannonlake/include/platform/memory.h b/src/platform/cannonlake/include/platform/memory.h
index 7e7af82..a341b4f 100644
--- a/src/platform/cannonlake/include/platform/memory.h
+++ b/src/platform/cannonlake/include/platform/memory.h
@@ -219,11 +219,11 @@
 #define HP_SRAM_WIN3_BASE	SRAM_TRACE_BASE
 #define HP_SRAM_WIN3_SIZE	SRAM_TRACE_SIZE
 
-#define HEAP_DMA_BUFFER_BASE		(SRAM_TRACE_BASE + SRAM_TRACE_SIZE)
-#define HEAP_DMA_BUFFER_SIZE		0x20000
-#define HEAP_DMA_BUFFER_BLOCK_SIZE	0x180
-#define HEAP_DMA_BUFFER_COUNT \
-				(HEAP_DMA_BUFFER_SIZE / HEAP_DMA_BUFFER_BLOCK_SIZE)
+#define HEAP_HP_BUFFER_BASE		(SRAM_TRACE_BASE + SRAM_TRACE_SIZE)
+#define HEAP_HP_BUFFER_SIZE		0x20000
+#define HEAP_HP_BUFFER_BLOCK_SIZE	0x180
+#define HEAP_HP_BUFFER_COUNT \
+			(HEAP_HP_BUFFER_SIZE / HEAP_HP_BUFFER_BLOCK_SIZE)
 
 #define REEF_TEXT_BASE		(REEF_TEXT_START + REEF_TEXT_START_SIZE)
 #define REEF_TEXT_SIZE		0x18000
@@ -315,6 +315,9 @@
 #define HEAP_LP_BUFFER_COUNT	(HEAP_LP_BUFFER_SIZE / HEAP_LP_BUFFER_BLOCK_SIZE)
 
 
+#define PLATFORM_HEAP_RUNTIME		1
+#define PLATFORM_HEAP_BUFFER		3
+
 /* Stack configuration */
 #define REEF_LP_STACK_SIZE			0x1000
 #define REEF_LP_STACK_BASE			(LP_SRAM_BASE + LP_SRAM_SIZE)
@@ -335,7 +338,7 @@
 
 #define REEF_MEM_RO_SIZE			0x8
 
-/* boot loadee in IMR */
+/* boot loader in IMR */
 #define IMR_BOOT_LDR_TEXT_ENTRY_BASE	0xB0038000
 #define IMR_BOOT_LDR_TEXT_ENTRY_SIZE	0x40
 #define IMR_BOOT_LDR_LIT_BASE		(IMR_BOOT_LDR_TEXT_ENTRY_BASE + IMR_BOOT_LDR_TEXT_ENTRY_SIZE)
diff --git a/src/platform/cannonlake/memory.c b/src/platform/cannonlake/memory.c
new file mode 100644
index 0000000..16fa600
--- /dev/null
+++ b/src/platform/cannonlake/memory.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2018, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ */
+
+#include <reef/alloc.h>
+
+/* Heap blocks for modules */
+static struct block_hdr mod_block16[HEAP_RT_COUNT16];
+static struct block_hdr mod_block32[HEAP_RT_COUNT32];
+static struct block_hdr mod_block64[HEAP_RT_COUNT64];
+static struct block_hdr mod_block128[HEAP_RT_COUNT128];
+static struct block_hdr mod_block256[HEAP_RT_COUNT256];
+static struct block_hdr mod_block512[HEAP_RT_COUNT512];
+static struct block_hdr mod_block1024[HEAP_RT_COUNT1024];
+
+/* Heap memory map for modules */
+static struct block_map rt_heap_map[] = {
+	BLOCK_DEF(16, HEAP_RT_COUNT16, mod_block16),
+	BLOCK_DEF(32, HEAP_RT_COUNT32, mod_block32),
+	BLOCK_DEF(64, HEAP_RT_COUNT64, mod_block64),
+	BLOCK_DEF(128, HEAP_RT_COUNT128, mod_block128),
+	BLOCK_DEF(256, HEAP_RT_COUNT256, mod_block256),
+	BLOCK_DEF(512, HEAP_RT_COUNT512, mod_block512),
+	BLOCK_DEF(1024, HEAP_RT_COUNT1024, mod_block1024),
+};
+
+/* Heap blocks for buffers */
+static struct block_hdr buf_block[HEAP_BUFFER_COUNT];
+static struct block_hdr hp_buf_block[HEAP_HP_BUFFER_COUNT];
+static struct block_hdr lp_buf_block[HEAP_LP_BUFFER_COUNT];
+
+/* Heap memory map for buffers */
+static struct block_map buf_heap_map[] = {
+	BLOCK_DEF(HEAP_BUFFER_BLOCK_SIZE, HEAP_BUFFER_COUNT, buf_block),
+};
+
+static struct block_map hp_buf_heap_map[] = {
+	BLOCK_DEF(HEAP_HP_BUFFER_BLOCK_SIZE, HEAP_HP_BUFFER_COUNT,
+		hp_buf_block),
+};
+
+static struct block_map lp_buf_heap_map[] = {
+	BLOCK_DEF(HEAP_LP_BUFFER_BLOCK_SIZE, HEAP_LP_BUFFER_COUNT,
+		lp_buf_block),
+};
+
+struct mm memmap = {
+	.system = {
+		.heap = HEAP_SYSTEM_BASE,
+		.size = HEAP_SYSTEM_SIZE,
+		.info = {.free = HEAP_SYSTEM_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_CACHE |
+			SOF_MEM_CAPS_HP | SOF_MEM_CAPS_DMA,
+	},
+	.runtime[0] = {
+		.blocks = ARRAY_SIZE(rt_heap_map),
+		.map = rt_heap_map,
+		.heap = HEAP_RUNTIME_BASE,
+		.size = HEAP_RUNTIME_SIZE,
+		.info = {.free = HEAP_RUNTIME_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_CACHE |
+			SOF_MEM_CAPS_HP | SOF_MEM_CAPS_DMA,
+	},
+	.buffer[0] = {
+		.blocks = ARRAY_SIZE(buf_heap_map),
+		.map = buf_heap_map,
+		.heap = HEAP_BUFFER_BASE,
+		.size = HEAP_BUFFER_SIZE,
+		.info = {.free = HEAP_BUFFER_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_CACHE |
+			SOF_MEM_CAPS_HP | SOF_MEM_CAPS_DMA,
+	},
+	.buffer[1] = {
+		.blocks = ARRAY_SIZE(hp_buf_heap_map),
+		.map = hp_buf_heap_map,
+		.heap = HEAP_HP_BUFFER_BASE,
+		.size = HEAP_HP_BUFFER_SIZE,
+		.info = {.free = HEAP_HP_BUFFER_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_HP |
+			SOF_MEM_CAPS_CACHE | SOF_MEM_CAPS_DMA,
+	},
+	.buffer[2] = {
+		.blocks = ARRAY_SIZE(lp_buf_heap_map),
+		.map = lp_buf_heap_map,
+		.heap = HEAP_LP_BUFFER_BASE,
+		.size = HEAP_LP_BUFFER_SIZE,
+		.info = {.free = HEAP_LP_BUFFER_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_LP |
+			SOF_MEM_CAPS_CACHE | SOF_MEM_CAPS_DMA,
+	},
+	.total = {.free = HEAP_SYSTEM_SIZE + HEAP_RUNTIME_SIZE +
+		HEAP_BUFFER_SIZE,},
+};
diff --git a/src/platform/haswell/Makefile.am b/src/platform/haswell/Makefile.am
index bf9d40a..c132f53 100644
--- a/src/platform/haswell/Makefile.am
+++ b/src/platform/haswell/Makefile.am
@@ -7,7 +7,8 @@ libplatform_a_SOURCES = \
 	dai.c \
 	dma.c \
 	clk.c \
-	timer.c
+	timer.c \
+	memory.c
 
 libplatform_a_CFLAGS = \
 	$(ARCH_CFLAGS) \
diff --git a/src/platform/haswell/include/platform/memory.h b/src/platform/haswell/include/platform/memory.h
index 83d11a5..f04ef97 100644
--- a/src/platform/haswell/include/platform/memory.h
+++ b/src/platform/haswell/include/platform/memory.h
@@ -124,11 +124,8 @@
 #define HEAP_BUFFER_BLOCK_SIZE		0x180
 #define HEAP_BUFFER_COUNT		(HEAP_BUFFER_SIZE / HEAP_BUFFER_BLOCK_SIZE)
 
-/* DMA buffer heap is the same physical memory as buffer heap on baytrail */
-#define HEAP_DMA_BUFFER_BASE		0
-#define HEAP_DMA_BUFFER_SIZE		0
-#define HEAP_DMA_BUFFER_BLOCK_SIZE	0
-#define HEAP_DMA_BUFFER_COUNT		0
+#define PLATFORM_HEAP_RUNTIME		1
+#define PLATFORM_HEAP_BUFFER		1
 
 /* Stack configuration */
 #define REEF_STACK_SIZE			0x1000
diff --git a/src/platform/haswell/memory.c b/src/platform/haswell/memory.c
new file mode 100644
index 0000000..12e7399
--- /dev/null
+++ b/src/platform/haswell/memory.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2018, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ */
+
+#include <reef/alloc.h>
+
+/* Heap blocks for modules */
+static struct block_hdr mod_block16[HEAP_RT_COUNT16];
+static struct block_hdr mod_block32[HEAP_RT_COUNT32];
+static struct block_hdr mod_block64[HEAP_RT_COUNT64];
+static struct block_hdr mod_block128[HEAP_RT_COUNT128];
+static struct block_hdr mod_block256[HEAP_RT_COUNT256];
+static struct block_hdr mod_block512[HEAP_RT_COUNT512];
+static struct block_hdr mod_block1024[HEAP_RT_COUNT1024];
+
+/* Heap memory map for modules */
+static struct block_map rt_heap_map[] = {
+	BLOCK_DEF(16, HEAP_RT_COUNT16, mod_block16),
+	BLOCK_DEF(32, HEAP_RT_COUNT32, mod_block32),
+	BLOCK_DEF(64, HEAP_RT_COUNT64, mod_block64),
+	BLOCK_DEF(128, HEAP_RT_COUNT128, mod_block128),
+	BLOCK_DEF(256, HEAP_RT_COUNT256, mod_block256),
+	BLOCK_DEF(512, HEAP_RT_COUNT512, mod_block512),
+	BLOCK_DEF(1024, HEAP_RT_COUNT1024, mod_block1024),
+};
+
+/* Heap blocks for buffers */
+static struct block_hdr buf_block[HEAP_BUFFER_COUNT];
+
+/* Heap memory map for buffers */
+static struct block_map buf_heap_map[] = {
+	BLOCK_DEF(HEAP_BUFFER_BLOCK_SIZE, HEAP_BUFFER_COUNT, buf_block),
+};
+
+struct mm memmap = {
+	.system = {
+		.heap = HEAP_SYSTEM_BASE,
+		.size = HEAP_SYSTEM_SIZE,
+		.info = {.free = HEAP_SYSTEM_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_CACHE |
+			SOF_MEM_CAPS_DMA,
+	},
+	.runtime[0] = {
+		.blocks = ARRAY_SIZE(rt_heap_map),
+		.map = rt_heap_map,
+		.heap = HEAP_RUNTIME_BASE,
+		.size = HEAP_RUNTIME_SIZE,
+		.info = {.free = HEAP_RUNTIME_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_CACHE |
+			SOF_MEM_CAPS_DMA,
+	},
+	.buffer[0] = {
+		.blocks = ARRAY_SIZE(buf_heap_map),
+		.map = buf_heap_map,
+		.heap = HEAP_BUFFER_BASE,
+		.size = HEAP_BUFFER_SIZE,
+		.info = {.free = HEAP_BUFFER_SIZE,},
+		.caps = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_CACHE |
+			SOF_MEM_CAPS_DMA,
+	},
+	.total = {.free = HEAP_SYSTEM_SIZE + HEAP_RUNTIME_SIZE +
+		HEAP_BUFFER_SIZE,},
+};
-- 
2.14.1



More information about the Sound-open-firmware mailing list