Zephyr Project API 4.4.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#include <zephyr/devicetree.h>
13
19
41#ifdef CONFIG_MMU
42#define K_MEM_VIRT_OFFSET ((CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) - \
43 (DT_CHOSEN_SRAM_ADDR + CONFIG_SRAM_OFFSET))
44#else
45#define K_MEM_VIRT_OFFSET 0
46#endif /* CONFIG_MMU */
47
48#if DT_CHOSEN_SRAM_ADDR != 0
49#define IS_SRAM_ADDRESS_LOWER(ADDR) ((ADDR) >= DT_CHOSEN_SRAM_ADDR)
50#else
51#define IS_SRAM_ADDRESS_LOWER(ADDR) true
52#endif /* DT_CHOSEN_SRAM_ADDR != 0 */
53
54#if (DT_CHOSEN_SRAM_ADDR + DT_CHOSEN_SRAM_SIZE) != 0
55#define IS_SRAM_ADDRESS_UPPER(ADDR) \
56 ((ADDR) < (DT_CHOSEN_SRAM_ADDR + DT_CHOSEN_SRAM_SIZE))
57#else
58#define IS_SRAM_ADDRESS_UPPER(ADDR) false
59#endif
60
61#define IS_SRAM_ADDRESS(ADDR) \
62 (IS_SRAM_ADDRESS_LOWER(ADDR) && \
63 IS_SRAM_ADDRESS_UPPER(ADDR))
64
74#define K_MEM_PHYS_ADDR(virt) ((virt) - K_MEM_VIRT_OFFSET)
75
85#define K_MEM_VIRT_ADDR(phys) ((phys) + K_MEM_VIRT_OFFSET)
86
87#if K_MEM_VIRT_OFFSET != 0
91#define K_MEM_IS_VM_KERNEL 1
92#ifdef CONFIG_XIP
93#error "XIP and a virtual memory kernel are not allowed"
94#endif
95#endif
96
97#ifndef _ASMLANGUAGE
98#include <stdint.h>
99#include <stddef.h>
100#include <inttypes.h>
101#include <zephyr/sys/__assert.h>
103
115static inline uintptr_t k_mem_phys_addr(void *virt)
116{
117 uintptr_t addr = (uintptr_t)virt;
118
119#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK)
120 __ASSERT(sys_mm_is_virt_addr_in_range(virt),
121 "address %p not in permanent mappings", virt);
122#elif defined(CONFIG_MMU)
123#if CONFIG_KERNEL_VM_BASE != 0
124 /* Skipped when the VM base is 0, where the comparison is always true and
125 * some compilers warn about it (-Wtype-limits).
126 */
127 __ASSERT(addr >= (uintptr_t)CONFIG_KERNEL_VM_BASE, "address %p below VM base", virt);
128#endif /* CONFIG_KERNEL_VM_BASE != 0 */
129 __ASSERT((addr - (uintptr_t)CONFIG_KERNEL_VM_BASE) < (uintptr_t)CONFIG_KERNEL_VM_SIZE,
130 "address %p above VM limit", virt);
131#else
132 /* Should be identity-mapped */
133 __ASSERT(IS_SRAM_ADDRESS(addr),
134 "physical address 0x%lx not in RAM",
135 (unsigned long)addr);
136#endif /* CONFIG_MMU */
137
138 /* TODO add assertion that this page is pinned to boot mapping,
139 * the above checks won't be sufficient with demand paging
140 */
141
142 return K_MEM_PHYS_ADDR(addr);
143}
144
156static inline void *k_mem_virt_addr(uintptr_t phys)
157{
158#if defined(CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK)
159 __ASSERT(sys_mm_is_phys_addr_in_range(phys),
160 "physical address 0x%lx not in RAM", (unsigned long)phys);
161#else
162 __ASSERT(IS_SRAM_ADDRESS(phys),
163 "physical address 0x%lx not in RAM", (unsigned long)phys);
164#endif /* CONFIG_KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK */
165
166 /* TODO add assertion that this page frame is pinned to boot mapping,
167 * the above check won't be sufficient with demand paging
168 */
169
170 return (void *)K_MEM_VIRT_ADDR(phys);
171}
172
173#ifdef __cplusplus
174extern "C" {
175#endif
176
221void k_mem_map_phys_bare(uint8_t **virt_ptr, uintptr_t phys, size_t size,
223
251void k_mem_unmap_phys_bare(uint8_t *virt, size_t size);
252
301void *k_mem_map_phys_guard(uintptr_t phys, size_t size, uint32_t flags, bool is_anon);
302
321void k_mem_unmap_phys_guard(void *addr, size_t size, bool is_anon);
322
323#ifdef __cplusplus
324}
325#endif
326
328
329#endif /* !_ASMLANGUAGE */
330#endif /* ZEPHYR_INCLUDE_KERNEL_INTERNAL_MM_H */
Devicetree main header.
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:74
#define K_MEM_VIRT_ADDR(phys)
Get virtual address from physical address.
Definition mm.h:85
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:115
#define IS_SRAM_ADDRESS(ADDR)
Definition mm.h:61
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:156
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.
Memory management helpers.
flags
Definition parser.h:97
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:105
Misc utilities.
Macros to abstract toolchain specific capabilities.