1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#pragma once
4
5#include "mos/mm/mm.hpp"
6
7#include <mos/lib/structures/bitmap.hpp>
8#include <mos/lib/sync/spinlock.hpp>
9#include <mos/platform/platform.hpp>
10
11/**
12 * @defgroup paging Paging
13 * @ingroup mm
14 * @brief A platform-independent interface to map/unmap virtual memory to physical memory.
15 *
16 * @{
17 */
18
19/**
20 * @brief Gets npages unmapped free pages from a page table.
21 *
22 * @param mmctx The memory management context to allocate from.
23 * @param n_pages The number of pages to allocate.
24 * @param base_vaddr The base virtual address to allocate at.
25 * @param exact If the address must be exact.
26 * @return ptr_t The virtual address of the block of virtual memory.
27 *
28 * @note This function neither allocates nor maps the pages, it only
29 * determines the block of virtual memory that can be used to allocate
30 * and map the pages.
31 *
32 * @note The returned @ref vmap_t only contains the virtual address
33 * and the number of pages, it does not contain any physical addresses,
34 * nor the flags of the pages.
35 *
36 * @warning Should call with mmctx->mm_lock held.
37 */
38
39PtrResult<vmap_t> mm_get_free_vaddr_locked(MMContext *mmctx, size_t n_pages, ptr_t base_vaddr, bool exact);
40
41/**
42 * @brief Map a block of virtual memory to a block of physical memory.
43 *
44 * @param mmctx The memory management context to map to.
45 * @param vaddr The virtual address to map to.
46 * @param pfn The physical frame to map from.
47 * @param npages The number of pages to map.
48 * @param flags Flags to set on the pages, see @ref VMFlags.
49 * @param exact If the address must be exact.
50 *
51 * @details This function maps the pages in the block, their reference count will NOT be incremented.
52 *
53 * @note This function is rarely used directly, you don't always know the physical address of the
54 * pages you want to map.
55 */
56void mm_map_kernel_pages(MMContext *mmctx, ptr_t vaddr, pfn_t pfn, size_t npages, VMFlags flags);
57PtrResult<vmap_t> mm_map_user_pages(MMContext *mmctx, ptr_t vaddr, pfn_t pfn, size_t npages, VMFlags flags, vmap_type_t type, vmap_content_t content, bool exact = false);
58
59/**
60 * @brief Replace the mappings of a page with a new physical frame.
61 *
62 * @param mmctx The memory management context to replace in.
63 * @param vaddr The virtual address to replace.
64 * @param pfn The physical frame to replace to.
65 * @param flags The new flags to set on the pages.
66 *
67 * @note The reference count of the physical frame will be incremented, and the reference count of the
68 * old physical frame will be decremented.
69 */
70void mm_replace_page_locked(MMContext *mmctx, ptr_t vaddr, pfn_t pfn, VMFlags flags);
71
72/**
73 * @brief Remap a block of virtual memory from one page table to another, i.e. copy the mappings.
74 *
75 * @param src_vmap The source vmap
76 * @param dst_ctx The destination paging context
77 *
78 * @details This function firstly unmaps the pages in the destination page table, then copies the pages
79 * mappings, including the flags and physical addresses, the physical page reference count is updated
80 * accordingly.
81 *
82 * @note If clear_dest is set to true, then the destination page table is cleared before copying, otherwise
83 * the function assumes that there are no existing mappings in the destination page table.
84 */
85PtrResult<vmap_t> mm_clone_vmap_locked(const vmap_t *src_vmap, MMContext *dst_ctx);
86
87/**
88 * @brief Get if a virtual address is mapped in a page table.
89 *
90 * @param mmctx The memory management context to check in.
91 * @param vaddr The virtual address to get the physical address of.
92 * @return bool True if the virtual address is mapped, false otherwise.
93 */
94bool mm_get_is_mapped_locked(MMContext *mmctx, ptr_t vaddr);
95
96/**
97 * @brief Update the flags of a block of virtual memory.
98 *
99 * @param mmctx The memory management context to update the flags in.
100 * @param vaddr The virtual address to update the flags of.
101 * @param npages The number of pages to update the flags of.
102 * @param flags The flags to set on the pages, see @ref VMFlags.
103 */
104void mm_flag_pages_locked(MMContext *mmctx, ptr_t vaddr, size_t npages, VMFlags flags);
105
106ptr_t mm_get_phys_addr(MMContext *ctx, ptr_t vaddr);
107
108/** @} */
109