PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
pmm.h
Go to the documentation of this file.
1#pragma once
2
3#include <boot/boot_info.h>
4
5#include <sys/proc.h>
6
7/**
8 * @brief Physical Memory Manager (PMM).
9 * @defgroup kernel_mem_pmm PMM
10 * @ingroup kernel_mem
11 *
12 * The Physical Memory Manager (PMM) is responsible for allocating and freeing physical memory pages.
13 *
14 * ## The Free Page Stack
15 *
16 * For most allocations, the PMM uses a fast `O(1)` stack-based allocator to manage free pages, with the limitation that
17 * only single pages can be allocated or freed at a time.
18 *
19 * ## The Bitmap Allocator
20 *
21 * For larger, contiguous or aligned allocations, the PMM uses a bitmap allocator. This allocator is slower (`O(n)`) but
22 * is usefull for more specialized allocations.
23 *
24 * ## Reference Counting
25 *
26 * All allocations from the PMM are referenced counted, meaning that a page is only freed when its reference count
27 * reaches zero. This allows pages to be passed around between subsystems without fear of double frees or
28 * use-after-frees.
29 *
30 * @see kernel_mem_mem_desc
31 *
32 * @{
33 */
34
35/**
36 * @brief Page metadata structure.
37 * @struct page_t
38 *
39 * Used internally by the PMM.
40 */
41typedef struct
42{
44} page_t;
45
46/**
47 * @brief Maximum number of free pages that can be stored in a free page.
48 */
49#define FREE_PAGE_MAX (PAGE_SIZE / sizeof(pfn_t) - 1)
50
51/**
52 * @brief Stored in free pages to form a stack of free pages.
53 * @struct page_stack_t
54 */
55typedef struct page_stack
56{
57 struct page_stack* next;
60
61static_assert(sizeof(page_stack_t) == PAGE_SIZE, "page_stack_t must be exactly one page in size");
62
63/**
64 * @brief Read the boot info memory map and initialize the PMM.
65 */
66void pmm_init(void);
67
68/**
69 * @brief Allocate a single page of physical memory.
70 *
71 * Will by default use the free stack allocator, but if no pages are available there, it will fall back to the bitmap
72 * allocator.
73 *
74 * @return On success, the PFN of the allocated page. On failure, `ERR`.
75 */
76pfn_t pmm_alloc(void);
77
78/**
79 * @brief Allocate multiple pages of physical memory.
80 *
81 * Usefull for reducing overhead from locking when allocating many pages.
82 *
83 * @param pfns Array to store the allocated page PFNs.
84 * @param count Number of pages to allocate.
85 * @return On success, `0`. On failure, `ERR` and no pages are allocated.
86 */
87uint64_t pmm_alloc_pages(pfn_t* pfns, size_t count);
88
89/**
90 * @brief Allocate a contiguous region of physical memory using the bitmap.
91 *
92 * @param count Number of pages to allocate.
93 * @param maxPfn Maximum PFN to allocate up to (exclusive).
94 * @param alignPfn Alignment of the region in pages.
95 * @return On success, the PFN of the first page of the allocated region. On failure, `ERR`.
96 */
97pfn_t pmm_alloc_bitmap(size_t count, pfn_t maxPfn, pfn_t alignPfn);
98
99/**
100 * @brief Free a single page of physical memory.
101 *
102 * The page will only be reclaimed if its reference count reaches zero.
103 *
104 * @param pfn The PFN of the page to free.
105 */
106void pmm_free(pfn_t pfn);
107
108/**
109 * @brief Free multiple pages of physical memory.
110 *
111 * Useful for reducing overhead from locking when freeing many pages.
112 *
113 * The pages will only be reclaimed if its reference count reaches zero.
114 *
115 * @param pfns Array of PFNs to free.
116 * @param count Number of pages to free.
117 */
118void pmm_free_pages(pfn_t* pfns, size_t count);
119
120/**
121 * @brief Free a contiguous region of physical memory.
122 *
123 * The pages will only be reclaimed if its reference count reaches zero.
124 *
125 * @param pfn The PFN of the first page of the region to free.
126 * @param count Number of pages to free.
127 */
128void pmm_free_region(pfn_t pfn, size_t count);
129
130/**
131 * @brief Increment the reference count of a physical region.
132 *
133 * Will fail if any of the pages are not allocated.
134 *
135 * @param pfn The PFN of the first physical page.
136 * @param count Number of pages to increment the reference count of.
137 * @return On success, the new reference count. On failure, `ERR`.
138 */
139uint64_t pmm_ref_inc(pfn_t pfn, size_t count);
140
141/**
142 * @brief Decrement the reference count of a physical region.
143 *
144 * If the reference count reaches zero, the pages will be freed.
145 *
146 * @param pfn The PFN of the first physical page.
147 * @param count Number of pages to decrement the reference count of.
148 */
149static inline void pmm_ref_dec(pfn_t pfn, size_t count)
150{
152}
153
154/**
155 * @brief Get the total number of physical pages.
156 *
157 * @return Total number of physical pages.
158 */
159size_t pmm_total_pages(void);
160
161/**
162 * @brief Get the number of available physical pages.
163 *
164 * @return Number of available physical pages.
165 */
166size_t pmm_avail_pages(void);
167
168/**
169 * @brief Get the number of used physical pages.
170 *
171 * @return Number of used physical pages.
172 */
173size_t pmm_used_pages(void);
174
175/** @} */
size_t pfn_t
Page Frame Number type.
void pmm_free_pages(pfn_t *pfns, size_t count)
Free multiple pages of physical memory.
Definition pmm.c:348
uint64_t pmm_alloc_pages(pfn_t *pfns, size_t count)
Allocate multiple pages of physical memory.
Definition pmm.c:275
#define FREE_PAGE_MAX
Maximum number of free pages that can be stored in a free page.
Definition pmm.h:49
size_t pmm_total_pages(void)
Get the total number of physical pages.
Definition pmm.c:387
static void pmm_ref_dec(pfn_t pfn, size_t count)
Decrement the reference count of a physical region.
Definition pmm.h:149
void pmm_free(pfn_t pfn)
Free a single page of physical memory.
Definition pmm.c:341
uint64_t pmm_ref_inc(pfn_t pfn, size_t count)
Increment the reference count of a physical region.
Definition pmm.c:365
pfn_t pmm_alloc(void)
Allocate a single page of physical memory.
Definition pmm.c:249
size_t pmm_used_pages(void)
Get the number of used physical pages.
Definition pmm.c:403
size_t pmm_avail_pages(void)
Get the number of available physical pages.
Definition pmm.c:395
void pmm_free_region(pfn_t pfn, size_t count)
Free a contiguous region of physical memory.
Definition pmm.c:358
pfn_t pmm_alloc_bitmap(size_t count, pfn_t maxPfn, pfn_t alignPfn)
Allocate a contiguous region of physical memory using the bitmap.
Definition pmm.c:317
void pmm_init(void)
Read the boot info memory map and initialize the PMM.
Definition pmm.c:239
#define PAGE_SIZE
The size of a memory page in bytes.
Definition PAGE_SIZE.h:8
static page_t * pages
Definition pmm.c:38
static atomic_long count
Definition main.c:11
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT16_TYPE__ uint16_t
Definition stdint.h:13
Stored in free pages to form a stack of free pages.
Definition pmm.h:56
struct page_stack * next
Definition pmm.h:57
Page metadata structure.
Definition pmm.h:42
uint16_t ref
Definition pmm.h:43