Zephyr API Documentation  3.6.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
mm.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#ifndef ZEPHYR_INCLUDE_KERNEL_INTERNAL_MM_H
8#define ZEPHYR_INCLUDE_KERNEL_INTERNAL_MM_H
9
10#include <zephyr/sys/util.h>
11#include <zephyr/toolchain.h>
12
19/*
20 * This is the offset to subtract from a virtual address mapped in the
21 * kernel's permanent mapping of RAM, to obtain its physical address.
22 *
23 * virt_addr = phys_addr + Z_MEM_VM_OFFSET
24 *
25 * This only works for virtual addresses within the interval
26 * [CONFIG_KERNEL_VM_BASE, CONFIG_KERNEL_VM_BASE + (CONFIG_SRAM_SIZE * 1024)).
27 *
28 * These macros are intended for assembly, linker code, and static initializers.
29 * Use with care.
30 *
31 * Note that when demand paging is active, these will only work with page
32 * frames that are pinned to their virtual mapping at boot.
33 *
34 * TODO: This will likely need to move to an arch API or need additional
35 * constraints defined.
36 */
37#ifdef CONFIG_MMU
38#define Z_MEM_VM_OFFSET ((CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) - \
39 (CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_OFFSET))
40#else
41#define Z_MEM_VM_OFFSET 0
42#endif /* CONFIG_MMU */
43
44#define Z_MEM_PHYS_ADDR(virt) ((virt) - Z_MEM_VM_OFFSET)
45#define Z_MEM_VIRT_ADDR(phys) ((phys) + Z_MEM_VM_OFFSET)
46
47#if Z_MEM_VM_OFFSET != 0
48#define Z_VM_KERNEL 1
49#ifdef CONFIG_XIP
50#error "XIP and a virtual memory kernel are not allowed"
51#endif
52#endif
53
54#ifndef _ASMLANGUAGE
55#include <stdint.h>
56#include <stddef.h>
57#include <inttypes.h>
58#include <zephyr/sys/__assert.h>
60
61/* Just like Z_MEM_PHYS_ADDR() but with type safety and assertions */
62static inline uintptr_t z_mem_phys_addr(void *virt)
63{
64 uintptr_t addr = (uintptr_t)virt;
65
66#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK)
67 __ASSERT(sys_mm_is_virt_addr_in_range(virt),
68 "address %p not in permanent mappings", virt);
69#elif defined(CONFIG_MMU)
70 __ASSERT(
71#if CONFIG_KERNEL_VM_BASE != 0
72 (addr >= CONFIG_KERNEL_VM_BASE) &&
73#endif /* CONFIG_KERNEL_VM_BASE != 0 */
74#if (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE) != 0
75 (addr < (CONFIG_KERNEL_VM_BASE +
76 (CONFIG_KERNEL_VM_SIZE))),
77#else
78 false,
79#endif /* CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE != 0 */
80 "address %p not in permanent mappings", virt);
81#else
82 /* Should be identity-mapped */
83 __ASSERT(
84#if CONFIG_SRAM_BASE_ADDRESS != 0
85 (addr >= CONFIG_SRAM_BASE_ADDRESS) &&
86#endif /* CONFIG_SRAM_BASE_ADDRESS != 0 */
87#if (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0
88 (addr < (CONFIG_SRAM_BASE_ADDRESS +
89 (CONFIG_SRAM_SIZE * 1024UL))),
90#else
91 false,
92#endif /* (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0 */
93 "physical address 0x%lx not in RAM",
94 (unsigned long)addr);
95#endif /* CONFIG_MMU */
96
97 /* TODO add assertion that this page is pinned to boot mapping,
98 * the above checks won't be sufficient with demand paging
99 */
100
101 return Z_MEM_PHYS_ADDR(addr);
102}
103
104/* Just like Z_MEM_VIRT_ADDR() but with type safety and assertions */
105static inline void *z_mem_virt_addr(uintptr_t phys)
106{
107#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK)
108 __ASSERT(sys_mm_is_phys_addr_in_range(phys),
109 "physical address 0x%lx not in RAM", (unsigned long)phys);
110#else
111 __ASSERT(
112#if CONFIG_SRAM_BASE_ADDRESS != 0
113 (phys >= CONFIG_SRAM_BASE_ADDRESS) &&
114#endif /* CONFIG_SRAM_BASE_ADDRESS != 0 */
115#if (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0
116 (phys < (CONFIG_SRAM_BASE_ADDRESS +
117 (CONFIG_SRAM_SIZE * 1024UL))),
118#else
119 false,
120#endif /* (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0 */
121 "physical address 0x%lx not in RAM", (unsigned long)phys);
122#endif /* CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK */
123
124 /* TODO add assertion that this page frame is pinned to boot mapping,
125 * the above check won't be sufficient with demand paging
126 */
127
128 return (void *)Z_MEM_VIRT_ADDR(phys);
129}
130
131#ifdef __cplusplus
132extern "C" {
133#endif
134
176void z_phys_map(uint8_t **virt_ptr, uintptr_t phys, size_t size,
178
206void z_phys_unmap(uint8_t *virt, size_t size);
207
228void *k_mem_map_impl(uintptr_t phys, size_t size, uint32_t flags, bool is_anon);
229
247void k_mem_unmap_impl(void *addr, size_t size, bool is_anon);
248
249#ifdef __cplusplus
250}
251#endif
252
255#endif /* !_ASMLANGUAGE */
256#endif /* ZEPHYR_INCLUDE_KERNEL_INTERNAL_MM_H */
void k_mem_unmap_impl(void *addr, size_t size, bool is_anon)
Un-map mapped memory.
void * k_mem_map_impl(uintptr_t phys, size_t size, uint32_t flags, bool is_anon)
Map memory into virtual address space with guard pages.
bool sys_mm_is_virt_addr_in_range(void *virt)
Check if a virtual address is within range of virtual memory.
bool sys_mm_is_phys_addr_in_range(uintptr_t phys)
Check if a physical address is within range of physical memory.
flags
Definition: parser.h:96
__UINT32_TYPE__ uint32_t
Definition: stdint.h:90
__UINT8_TYPE__ uint8_t
Definition: stdint.h:88
__UINTPTR_TYPE__ uintptr_t
Definition: stdint.h:105
Macros to abstract toolchain specific capabilities.
Misc utilities.