Line data Source code
1 0 : /*
2 : * Copyright (c) 2020 Intel Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_KERNEL_MM_H
8 : #define ZEPHYR_INCLUDE_KERNEL_MM_H
9 :
10 : #include <zephyr/sys/util.h>
11 : #include <zephyr/toolchain.h>
12 : #if defined(CONFIG_ARM_MMU) && defined(CONFIG_ARM64)
13 : #include <zephyr/arch/arm64/arm_mem.h>
14 : #endif /* CONFIG_ARM_MMU && CONFIG_ARM64 */
15 :
16 : #include <zephyr/kernel/internal/mm.h>
17 :
18 : /**
19 : * @brief Kernel Memory Management
20 : * @defgroup kernel_memory_management Kernel Memory Management
21 : * @ingroup kernel_apis
22 : * @{
23 : */
24 :
25 : /**
26 : * @name Caching mode definitions.
27 : *
28 : * These are mutually exclusive.
29 : *
30 : * @{
31 : */
32 :
33 : /** No caching. Most drivers want this. */
34 1 : #define K_MEM_CACHE_NONE 2
35 :
36 : /** Write-through caching. Used by certain drivers. */
37 1 : #define K_MEM_CACHE_WT 1
38 :
39 : /** Full write-back caching. Any RAM mapped wants this. */
40 1 : #define K_MEM_CACHE_WB 0
41 :
42 : /*
43 : * ARM64 Specific flags are defined in arch/arm64/arm_mem.h,
44 : * pay attention to be not conflicted when updating these flags.
45 : */
46 :
47 : /** Reserved bits for cache modes in k_map() flags argument */
48 1 : #define K_MEM_CACHE_MASK (BIT(3) - 1)
49 :
50 : /** @} */
51 :
52 : /**
53 : * @name Region permission attributes.
54 : *
55 : * Default is read-only, no user, no exec
56 : *
57 : * @{
58 : */
59 :
60 : /** Region will have read/write access (and not read-only) */
61 1 : #define K_MEM_PERM_RW BIT(3)
62 :
63 : /** Region will be executable (normally forbidden) */
64 1 : #define K_MEM_PERM_EXEC BIT(4)
65 :
66 : /** Region will be accessible to user mode (normally supervisor-only) */
67 1 : #define K_MEM_PERM_USER BIT(5)
68 :
69 : /** @} */
70 :
71 : /**
72 : * @name Region mapping behaviour attributes
73 : *
74 : * @{
75 : */
76 :
77 : /** Region will be mapped to 1:1 virtual and physical address */
78 1 : #define K_MEM_DIRECT_MAP BIT(6)
79 :
80 : /** @} */
81 :
82 : #ifndef _ASMLANGUAGE
83 : #include <stdint.h>
84 : #include <stddef.h>
85 : #include <inttypes.h>
86 :
87 : #ifdef __cplusplus
88 : extern "C" {
89 : #endif
90 :
91 : /**
92 : * @name k_mem_map() control flags
93 : *
94 : * @{
95 : */
96 :
97 : /**
98 : * @brief The mapped region is not guaranteed to be zeroed.
99 : *
100 : * This may improve performance. The associated page frames may contain
101 : * indeterminate data, zeroes, or even sensitive information.
102 : *
103 : * This may not be used with K_MEM_PERM_USER as there are no circumstances
104 : * where this is safe.
105 : */
106 1 : #define K_MEM_MAP_UNINIT BIT(16)
107 :
108 : /**
109 : * Region will be pinned in memory and never paged
110 : *
111 : * Such memory is guaranteed to never produce a page fault due to page-outs
112 : * or copy-on-write once the mapping call has returned. Physical page frames
113 : * will be pre-fetched as necessary and pinned.
114 : */
115 1 : #define K_MEM_MAP_LOCK BIT(17)
116 :
117 : /**
118 : * Region will be unpaged i.e. not mapped into memory
119 : *
120 : * This is meant to be used by kernel code and not by application code.
121 : *
122 : * Corresponding memory address range will be set so no actual memory will
123 : * be allocated initially. Allocation will happen through demand paging when
124 : * addresses in that range are accessed. This is incompatible with
125 : * K_MEM_MAP_LOCK.
126 : *
127 : * When this flag is specified, the phys argument to arch_mem_map()
128 : * is interpreted as a backing store location value not a physical address.
129 : * This is very similar to arch_mem_page_out() in that regard.
130 : * Two special location values are defined: ARCH_UNPAGED_ANON_ZERO and
131 : * ARCH_UNPAGED_ANON_UNINIT. Those are to be used with anonymous memory
132 : * mappings for zeroed and uninitialized pages respectively.
133 : */
134 1 : #define K_MEM_MAP_UNPAGED BIT(18)
135 :
136 : /** @} */
137 :
138 : /**
139 : * Return the amount of free memory available
140 : *
141 : * The returned value will reflect how many free RAM page frames are available.
142 : * If demand paging is enabled, it may still be possible to allocate more.
143 : *
144 : * The information reported by this function may go stale immediately if
145 : * concurrent memory mappings or page-ins take place.
146 : *
147 : * @return Free physical RAM, in bytes
148 : */
149 1 : size_t k_mem_free_get(void);
150 :
151 : /**
152 : * Map anonymous memory into Zephyr's address space
153 : *
154 : * This function effectively increases the data space available to Zephyr.
155 : * The kernel will choose a base virtual address and return it to the caller.
156 : * The memory will have access permissions for all contexts set per the
157 : * provided flags argument.
158 : *
159 : * If user thread access control needs to be managed in any way, do not enable
160 : * K_MEM_PERM_USER flags here; instead manage the region's permissions
161 : * with memory domain APIs after the mapping has been established. Setting
162 : * K_MEM_PERM_USER here will allow all user threads to access this memory
163 : * which is usually undesirable.
164 : *
165 : * Unless K_MEM_MAP_UNINIT is used, the returned memory will be zeroed.
166 : *
167 : * The mapped region is not guaranteed to be physically contiguous in memory.
168 : * Physically contiguous buffers should be allocated statically and pinned
169 : * at build time.
170 : *
171 : * Pages mapped in this way have write-back cache settings.
172 : *
173 : * The returned virtual memory pointer will be page-aligned. The size
174 : * parameter, and any base address for re-mapping purposes must be page-
175 : * aligned.
176 : *
177 : * Note that the allocation includes two guard pages immediately before
178 : * and after the requested region. The total size of the allocation will be
179 : * the requested size plus the size of these two guard pages.
180 : *
181 : * Many K_MEM_MAP_* flags have been implemented to alter the behavior of this
182 : * function, with details in the documentation for these flags.
183 : *
184 : * @param size Size of the memory mapping. This must be page-aligned.
185 : * @param flags K_MEM_PERM_*, K_MEM_MAP_* control flags.
186 : * @return The mapped memory location, or NULL if insufficient virtual address
187 : * space, insufficient physical memory to establish the mapping,
188 : * or insufficient memory for paging structures.
189 : */
190 1 : static inline void *k_mem_map(size_t size, uint32_t flags)
191 : {
192 : return k_mem_map_phys_guard((uintptr_t)NULL, size, flags, true);
193 : }
194 :
195 : #ifdef CONFIG_DEMAND_MAPPING
196 : /**
197 : * Create an unpaged mapping
198 : *
199 : * This maps backing-store "location" tokens into Zephyr's address space.
200 : * Corresponding memory address range will be set so no actual memory will
201 : * be allocated initially. Allocation will happen through demand paging when
202 : * addresses in the mapped range are accessed.
203 : *
204 : * The kernel will choose a base virtual address and return it to the caller.
205 : * The memory access permissions for all contexts will be set per the
206 : * provided flags argument.
207 : *
208 : * If user thread access control needs to be managed in any way, do not enable
209 : * K_MEM_PERM_USER flags here; instead manage the region's permissions
210 : * with memory domain APIs after the mapping has been established. Setting
211 : * K_MEM_PERM_USER here will allow all user threads to access this memory
212 : * which is usually undesirable.
213 : *
214 : * This is incompatible with K_MEM_MAP_LOCK.
215 : *
216 : * The provided backing-store "location" token must be linearly incrementable
217 : * by a page size across the entire mapping.
218 : *
219 : * Allocated pages will have write-back cache settings.
220 : *
221 : * The returned virtual memory pointer will be page-aligned. The size
222 : * parameter, and any base address for re-mapping purposes must be page-
223 : * aligned.
224 : *
225 : * Note that the allocation includes two guard pages immediately before
226 : * and after the requested region. The total size of the allocation will be
227 : * the requested size plus the size of these two guard pages.
228 : *
229 : * @param location Backing store initial location token
230 : * @param size Size of the memory mapping. This must be page-aligned.
231 : * @param flags K_MEM_PERM_*, K_MEM_MAP_* control flags.
232 : * @return The mapping location, or NULL if insufficient virtual address
233 : * space to establish the mapping, or insufficient memory for paging
234 : * structures.
235 : */
236 : static inline void *k_mem_map_unpaged(uintptr_t location, size_t size, uint32_t flags)
237 : {
238 : flags |= K_MEM_MAP_UNPAGED;
239 : return k_mem_map_phys_guard(location, size, flags, false);
240 : }
241 : #endif
242 :
243 : /**
244 : * Un-map mapped memory
245 : *
246 : * This removes a memory mapping for the provided page-aligned region.
247 : * Associated page frames will be free and the kernel may re-use the associated
248 : * virtual address region. Any paged out data pages may be discarded.
249 : *
250 : * Calling this function on a region which was not mapped to begin with is
251 : * undefined behavior.
252 : *
253 : * @param addr Page-aligned memory region base virtual address
254 : * @param size Page-aligned memory region size
255 : */
256 1 : static inline void k_mem_unmap(void *addr, size_t size)
257 : {
258 : k_mem_unmap_phys_guard(addr, size, true);
259 : }
260 :
261 : /**
262 : * Modify memory mapping attribute flags
263 : *
264 : * This updates caching, access and control flags for the provided
265 : * page-aligned memory region.
266 : *
267 : * Calling this function on a region which was not mapped to begin with is
268 : * undefined behavior. However system memory implicitly mapped at boot time
269 : * is supported.
270 : *
271 : * @param addr Page-aligned memory region base virtual address
272 : * @param size Page-aligned memory region size
273 : * @param flags K_MEM_PERM_*, K_MEM_MAP_* control flags.
274 : * @return 0 for success, negative error code otherwise.
275 : */
276 1 : int k_mem_update_flags(void *addr, size_t size, uint32_t flags);
277 :
278 : /**
279 : * Given an arbitrary region, provide a aligned region that covers it
280 : *
281 : * The returned region will have both its base address and size aligned
282 : * to the provided alignment value.
283 : *
284 : * @param[out] aligned_addr Aligned address
285 : * @param[out] aligned_size Aligned region size
286 : * @param[in] addr Region base address
287 : * @param[in] size Region size
288 : * @param[in] align What to align the address and size to
289 : * @retval offset between aligned_addr and addr
290 : */
291 1 : size_t k_mem_region_align(uintptr_t *aligned_addr, size_t *aligned_size,
292 : uintptr_t addr, size_t size, size_t align);
293 :
294 : #ifdef __cplusplus
295 : }
296 : #endif
297 :
298 : /** @} */
299 :
300 : #endif /* !_ASMLANGUAGE */
301 : #endif /* ZEPHYR_INCLUDE_KERNEL_MM_H */
|