Zephyr Project API 3.7.0
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
40#ifdef CONFIG_MMU
41#define K_MEM_VIRT_OFFSET ((CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) - \
42 (CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_OFFSET))
43#else
44#define K_MEM_VIRT_OFFSET 0
45#endif /* CONFIG_MMU */
46
56#define K_MEM_PHYS_ADDR(virt) ((virt) - K_MEM_VIRT_OFFSET)
57
67#define K_MEM_VIRT_ADDR(phys) ((phys) + K_MEM_VIRT_OFFSET)
68
69#if K_MEM_VIRT_OFFSET != 0
73#define K_MEM_IS_VM_KERNEL 1
74#ifdef CONFIG_XIP
75#error "XIP and a virtual memory kernel are not allowed"
76#endif
77#endif
78
79#ifndef _ASMLANGUAGE
80#include <stdint.h>
81#include <stddef.h>
82#include <inttypes.h>
83#include <zephyr/sys/__assert.h>
85
97static inline uintptr_t k_mem_phys_addr(void *virt)
98{
99 uintptr_t addr = (uintptr_t)virt;
100
101#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK)
102 __ASSERT(sys_mm_is_virt_addr_in_range(virt),
103 "address %p not in permanent mappings", virt);
104#elif defined(CONFIG_MMU)
105 __ASSERT(
106#if CONFIG_KERNEL_VM_BASE != 0
107 (addr >= CONFIG_KERNEL_VM_BASE) &&
108#endif /* CONFIG_KERNEL_VM_BASE != 0 */
109#if (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE) != 0
110 (addr < (CONFIG_KERNEL_VM_BASE +
111 (CONFIG_KERNEL_VM_SIZE))),
112#else
113 false,
114#endif /* CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE != 0 */
115 "address %p not in permanent mappings", virt);
116#else
117 /* Should be identity-mapped */
118 __ASSERT(
119#if CONFIG_SRAM_BASE_ADDRESS != 0
120 (addr >= CONFIG_SRAM_BASE_ADDRESS) &&
121#endif /* CONFIG_SRAM_BASE_ADDRESS != 0 */
122#if (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0
123 (addr < (CONFIG_SRAM_BASE_ADDRESS +
124 (CONFIG_SRAM_SIZE * 1024UL))),
125#else
126 false,
127#endif /* (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0 */
128 "physical address 0x%lx not in RAM",
129 (unsigned long)addr);
130#endif /* CONFIG_MMU */
131
132 /* TODO add assertion that this page is pinned to boot mapping,
133 * the above checks won't be sufficient with demand paging
134 */
135
136 return K_MEM_PHYS_ADDR(addr);
137}
138
150static inline void *k_mem_virt_addr(uintptr_t phys)
151{
152#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK)
153 __ASSERT(sys_mm_is_phys_addr_in_range(phys),
154 "physical address 0x%lx not in RAM", (unsigned long)phys);
155#else
156 __ASSERT(
157#if CONFIG_SRAM_BASE_ADDRESS != 0
158 (phys >= CONFIG_SRAM_BASE_ADDRESS) &&
159#endif /* CONFIG_SRAM_BASE_ADDRESS != 0 */
160#if (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0
161 (phys < (CONFIG_SRAM_BASE_ADDRESS +
162 (CONFIG_SRAM_SIZE * 1024UL))),
163#else
164 false,
165#endif /* (CONFIG_SRAM_BASE_ADDRESS + (CONFIG_SRAM_SIZE * 1024UL)) != 0 */
166 "physical address 0x%lx not in RAM", (unsigned long)phys);
167#endif /* CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK */
168
169 /* TODO add assertion that this page frame is pinned to boot mapping,
170 * the above check won't be sufficient with demand paging
171 */
172
173 return (void *)K_MEM_VIRT_ADDR(phys);
174}
175
176#ifdef __cplusplus
177extern "C" {
178#endif
179
224void k_mem_map_phys_bare(uint8_t **virt_ptr, uintptr_t phys, size_t size,
226
254void k_mem_unmap_phys_bare(uint8_t *virt, size_t size);
255
304void *k_mem_map_phys_guard(uintptr_t phys, size_t size, uint32_t flags, bool is_anon);
305
324void k_mem_unmap_phys_guard(void *addr, size_t size, bool is_anon);
325
326#ifdef __cplusplus
327}
328#endif
329
332#endif /* !_ASMLANGUAGE */
333#endif /* ZEPHYR_INCLUDE_KERNEL_INTERNAL_MM_H */
void * k_mem_map_phys_guard(uintptr_t phys, size_t size, uint32_t flags, bool is_anon)
Map memory into virtual address space with guard pages.
#define K_MEM_PHYS_ADDR(virt)
Get physical address from virtual address.
Definition mm.h:56
#define K_MEM_VIRT_ADDR(phys)
Get virtual address from physical address.
Definition mm.h:67
void k_mem_map_phys_bare(uint8_t **virt_ptr, uintptr_t phys, size_t size, uint32_t flags)
Map a physical memory region into the kernel's virtual address space.
void k_mem_unmap_phys_guard(void *addr, size_t size, bool is_anon)
Un-map memory mapped via k_mem_map_phys_guard().
static uintptr_t k_mem_phys_addr(void *virt)
Get physical address from virtual address.
Definition mm.h:97
void k_mem_unmap_phys_bare(uint8_t *virt, size_t size)
Unmap a virtual memory region from kernel's virtual address space.
static void * k_mem_virt_addr(uintptr_t phys)
Get virtual address from physical address.
Definition mm.h:150
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.