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