1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2016 Intel Corporation. All rights reserved.
4  *
5  * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6  *         Keyon Jie <yang.jie@linux.intel.com>
7  */
8 
9 #ifndef __SOF_LIB_MM_HEAP_H__
10 #define __SOF_LIB_MM_HEAP_H__
11 
12 #include <sof/common.h>
13 #include <sof/lib/alloc.h>
14 #include <sof/lib/cache.h>
15 #include <sof/lib/memory.h>
16 #include <sof/sof.h>
17 #include <sof/spinlock.h>
18 
19 #include <stddef.h>
20 #include <stdint.h>
21 
22 struct dma_copy;
23 struct dma_sg_config;
24 
25 struct mm_info {
26 	uint32_t used;
27 	uint32_t free;
28 };
29 
30 struct block_hdr {
31 	uint16_t size;		/* size in blocks for continuous allocation */
32 	uint16_t used;		/* usage flags for page */
33 	void *unaligned_ptr;	/* align ptr */
34 } __packed;
35 
36 struct block_map {
37 	uint16_t block_size;	/* size of block in bytes */
38 	uint16_t count;		/* number of blocks in map */
39 	uint16_t free_count;	/* number of free blocks */
40 	uint16_t first_free;	/* index of first free block */
41 	struct block_hdr *block;	/* base block header */
42 	uint32_t base;		/* base address of space */
43 };
44 
45 #define BLOCK_DEF(sz, cnt, hdr) \
46 	{.block_size = sz, .count = cnt, .free_count = cnt, .block = hdr, \
47 	 .first_free = 0}
48 
49 struct mm_heap {
50 	uint32_t blocks;
51 	struct block_map *map;
52 #if CONFIG_LIBRARY
53 	unsigned long heap;
54 #else
55 	uint32_t heap;
56 #endif
57 	uint32_t size;
58 	uint32_t caps;
59 	struct mm_info info;
60 };
61 
62 /* heap block memory map */
63 struct mm {
64 	/* system heap - used during init cannot be freed */
65 	struct mm_heap system[PLATFORM_HEAP_SYSTEM];
66 	/* system runtime heap - used for runtime system components */
67 	struct mm_heap system_runtime[PLATFORM_HEAP_SYSTEM_RUNTIME];
68 #if CONFIG_CORE_COUNT > 1
69 	/* object shared between different cores - used during init cannot be freed */
70 	struct mm_heap system_shared[PLATFORM_HEAP_SYSTEM_SHARED];
71 	/* object shared between different cores */
72 	struct mm_heap runtime_shared[PLATFORM_HEAP_RUNTIME_SHARED];
73 #endif
74 	/* general heap for components */
75 	struct mm_heap runtime[PLATFORM_HEAP_RUNTIME];
76 	/* general component buffer heap */
77 	struct mm_heap buffer[PLATFORM_HEAP_BUFFER];
78 
79 	struct mm_info total;
80 	uint32_t heap_trace_updated;	/* updates that can be presented */
81 	spinlock_t lock;	/* all allocs and frees are atomic */
82 };
83 
84 /* Heap save/restore contents and context for PM D0/D3 events */
85 uint32_t mm_pm_context_size(void);
86 int mm_pm_context_save(struct dma_copy *dc, struct dma_sg_config *sg);
87 int mm_pm_context_restore(struct dma_copy *dc, struct dma_sg_config *sg);
88 
89 /* heap initialisation */
90 void init_heap(struct sof *sof);
91 
92 /* frees entire heap (supported for secondary core system heap atm) */
93 void free_heap(enum mem_zone zone);
94 
95 /* status */
96 void heap_trace_all(int force);
97 void heap_trace(struct mm_heap *heap, int size);
98 
99 #if CONFIG_DEBUG_MEMORY_USAGE_SCAN
100 /** Fetch runtime information about heap, like used and free memory space
101  * @param zone to check, see enum mem_zone.
102  * @param index heap index, eg. cpu core index for any *SYS* zone
103  * @param out output variable
104  * @return error code or zero
105  */
106 int heap_info(enum mem_zone zone, int index, struct mm_info *out);
107 #endif
108 
109 /* retrieve memory map pointer */
memmap_get(void)110 static inline struct mm *memmap_get(void)
111 {
112 	return sof_get()->memory_map;
113 }
114 
115 #endif /* __SOF_LIB_MM_HEAP_H__ */
116