@@ -84,7 +84,112 @@ one by renaming the property and changing its value according to the following l
8484 "IO" -> <( DT_ARM_MPU(ATTR_MPU_IO) )>
8585 "EXTMEM" -> <( DT_ARM_MPU(ATTR_MPU_EXTMEM) )>
8686
87+ Memory Attributes Heap Allocator
88+ ********************************
89+
90+ It is possible to leverage the memory attribute property ``zephyr,memory-attr ``
91+ to define and create a set of memory heaps from which the user can allocate
92+ memory from with certain attributes / capabilities.
93+
94+ When the :kconfig:option: `CONFIG_MEM_ATTR_HEAP ` is set, every region marked
95+ with one of the memory attributes listed in in
96+ :zephyr_file: `include/zephyr/dt-bindings/memory-attr/memory-attr-sw.h ` is added
97+ to a pool of memory heaps used for dynamic allocation of memory buffers with
98+ certain attributes.
99+
100+ Here a non exhaustive list of possible attributes:
101+
102+ .. code-block :: none
103+
104+ DT_MEM_SW_ALLOC_CACHE
105+ DT_MEM_SW_ALLOC_NON_CACHE
106+ DT_MEM_SW_ALLOC_DMA
107+
108+ For example we can define several memory regions with different attributes and
109+ use the appropriate attribute to indicate that it is possible to dynamically
110+ allocate memory from those regions:
111+
112+ .. code-block :: devicetree
113+
114+ mem_cacheable: memory@10000000 {
115+ compatible = "mmio-sram";
116+ reg = <0x10000000 0x1000>;
117+ zephyr,memory-attr = <( DT_MEM_CACHEABLE | DT_MEM_SW_ALLOC_CACHE )>;
118+ };
119+
120+ mem_non_cacheable: memory@20000000 {
121+ compatible = "mmio-sram";
122+ reg = <0x20000000 0x1000>;
123+ zephyr,memory-attr = <( DT_MEM_NON_CACHEABLE | ATTR_SW_ALLOC_NON_CACHE )>;
124+ };
125+
126+ mem_cacheable_big: memory@30000000 {
127+ compatible = "mmio-sram";
128+ reg = <0x30000000 0x10000>;
129+ zephyr,memory-attr = <( DT_MEM_CACHEABLE | DT_MEM_OOO | DT_MEM_SW_ALLOC_CACHE )>;
130+ };
131+
132+ mem_cacheable_dma: memory@40000000 {
133+ compatible = "mmio-sram";
134+ reg = <0x40000000 0x10000>;
135+ zephyr,memory-attr = <( DT_MEM_CACHEABLE | DT_MEM_DMA |
136+ DT_MEM_SW_ALLOC_CACHE | DT_MEM_SW_ALLOC_DMA )>;
137+ };
138+
139+ The user can then dynamically carve memory out of those regions using the
140+ provided functions, the library will take care of allocating memory from the
141+ correct heap depending on the provided attribute and size:
142+
143+ .. code-block :: c
144+
145+ // Init the pool
146+ mem_attr_heap_pool_init();
147+
148+ // Allocate 0x100 bytes of cacheable memory from `mem_cacheable`
149+ block = mem_attr_heap_alloc(DT_MEM_SW_ALLOC_CACHE, 0x100);
150+
151+ // Allocate 0x200 bytes of non-cacheable memory aligned to 32 bytes
152+ // from `mem_non_cacheable`
153+ block = mem_attr_heap_aligned_alloc(ATTR_SW_ALLOC_NON_CACHE, 0x100, 32);
154+
155+ // Allocate 0x100 bytes of cacheable and dma-able memory from `mem_cacheable_dma`
156+ block = mem_attr_heap_alloc(DT_MEM_SW_ALLOC_CACHE | DT_MEM_SW_ALLOC_DMA, 0x100);
157+
158+ When several regions are marked with the same attributes, the memory is allocated:
159+
160+ 1. From the regions where the ``zephyr,memory-attr `` property has the requested
161+ property (or properties).
162+
163+ 2. Among the regions as at point 1, from the smallest region if there is any
164+ unallocated space left for the requested size
165+
166+ 3. If there is not enough space, from the next bigger region able to
167+ accommodate the requested size
168+
169+ The following example shows the point 3:
170+
171+ .. code-block :: c
172+
173+ // This memory is allocated from `mem_non_cacheable`
174+ block = mem_attr_heap_alloc(DT_MEM_SW_ALLOC_CACHE, 0x100);
175+
176+ // This memory is allocated from `mem_cacheable_big`
177+ block = mem_attr_heap_alloc(DT_MEM_SW_ALLOC_CACHE, 0x5000);
178+
179+ .. note ::
180+
181+ The framework is assuming that the memory regions used to create the heaps
182+ are usable by the code and available at init time. The user must take of
183+ initializing and setting the memory area before calling
184+ :c:func: `mem_attr_heap_pool_init `.
185+
186+ That means that the region must be correctly configured in terms of MPU /
187+ MMU (if needed) and that an actual heap can be created out of it, for
188+ example by leveraging the ``zephyr,memory-region `` property to create a
189+ proper linker section to accommodate the heap.
190+
87191API Reference
88192*************
89193
90194.. doxygengroup :: memory_attr_interface
195+ .. doxygengroup :: memory_attr_heap
0 commit comments