MOS Source Code
Loading...
Searching...
No Matches
pml3.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
4
5#include "mos/mm/mm.hpp"
9
10#include <algorithm>
11#include <mos/mos_global.h>
12#include <mos_stdlib.hpp>
13#include <mos_string.hpp>
14
15#if MOS_PLATFORM_PAGING_LEVELS < 3
16void pml3_traverse(pml3_t pml3, ptr_t *vaddr, size_t *n_pages, pagetable_walk_options_t callback, void *data)
17{
18 pml2_traverse(pml3.pml2, vaddr, n_pages, callback, data);
19}
20
21pml3e_t *pml3_entry(pml3_t pml3, ptr_t vaddr)
22{
23 MOS_UNUSED(vaddr);
24 return pml3.pml2.table;
25}
26
27bool pml3e_is_present(const pml3e_t *pml3e)
28{
29 return pml2e_is_present(pml3e);
30}
31
32pml2_t pml3e_get_pml2(const pml3e_t *pml3e)
33{
34 return (pml2_t) { .table = (pml2e_t *) pml3e };
35}
36
37#else
38void pml3_traverse(pml3_t pml3, ptr_t *vaddr, size_t *n_pages, pagetable_walk_options_t options, void *data)
39{
40 for (size_t i = pml3_index(*vaddr); i < PML3_ENTRIES && *n_pages; i++)
41 {
42 pml3e_t *pml3e = pml3_entry(pml3, *vaddr);
43 pml2_t pml2 = { 0 };
44
45 if (pml3e_is_present(pml3e))
46 {
47 pml2 = pml3e_get_or_create_pml2(pml3e);
48 }
49 else
50 {
51 if (options.readonly)
52 {
53 // skip to the next pml2e
54 *vaddr += std::min(*n_pages, (size_t) PML3E_NPAGES) * MOS_PAGE_SIZE;
55 *n_pages -= std::min(*n_pages, (size_t) PML3E_NPAGES);
56 continue;
57 }
58
59 pml2 = pml_create_table(pml2);
60 platform_pml3e_set_pml2(pml3e, pml2, va_pfn(pml2.table));
61 }
62
63 if (options.pml3e_pre_traverse)
64 options.pml3e_pre_traverse(pml3, pml3e, *vaddr, data);
65 pml2_traverse(pml2, vaddr, n_pages, options, data);
66 }
67}
68
69bool pml3_destroy_range(pml3_t pml3, ptr_t *vaddr, size_t *n_pages)
70{
71 const bool should_zap_this_pml3 = pml3_index(*vaddr) == 0 && *n_pages >= PML3_ENTRIES * PML3E_NPAGES;
72
73 for (size_t i = pml3_index(*vaddr); i < PML3_ENTRIES && *n_pages; i++)
74 {
75 pml3e_t *pml3e = pml3_entry(pml3, *vaddr);
76
77 if (pml3e_is_present(pml3e))
78 {
79 pml2_t pml2 = platform_pml3e_get_pml2(pml3e);
80 if (pml2_destroy_range(pml2, vaddr, n_pages))
81 pmlxe_destroy(pml3e); // pml2 was destroyed
82 }
83 else
84 {
85 // skip to the next pml2e
86 *vaddr += std::min(*n_pages, (size_t) PML3E_NPAGES) * MOS_PAGE_SIZE;
87 *n_pages -= std::min(*n_pages, (size_t) PML3E_NPAGES);
88 continue;
89 }
90 }
91
92 if (should_zap_this_pml3)
94
95 return should_zap_this_pml3;
96}
97
98pml3e_t *pml3_entry(pml3_t pml3, ptr_t vaddr)
99{
100 return &pml3.table[pml3_index(vaddr)];
101}
102
103bool pml3e_is_present(const pml3e_t *pml3e)
104{
105 return platform_pml3e_get_present(pml3e);
106}
107
109{
110 if (pml3e_is_present(pml3e))
111 return platform_pml3e_get_pml2(pml3e);
112
113 pml2_t pml2 = pml_create_table(pml2);
114 platform_pml3e_set_pml2(pml3e, pml2, va_pfn(pml2.table));
115 return pml2;
116}
117#endif
bool platform_pml3e_get_present(const pml3e_t *pml3e)
Definition mm.cpp:170
void platform_pml3e_set_pml2(pml3e_t *pml3e, pml2_t pml2, pfn_t pml2_pfn)
Definition mm.cpp:162
pml2_t platform_pml3e_get_pml2(const pml3e_t *pml3e)
Definition mm.cpp:157
#define MOS_PAGE_SIZE
Definition autoconf.h:6
bool callback(pb_istream_t *stream, uint8_t *buf, size_t count)
#define va_pfn(va)
Definition mm.hpp:78
#define MOS_UNUSED(x)
Definition mos_global.h:65
bool pml2e_is_present(const pml2e_t *pml2e)
Definition pml2.cpp:79
void pml2_traverse(pml2_t pml2, ptr_t *vaddr, size_t *n_pages, pagetable_walk_options_t callback, void *data)
Definition pml2.cpp:14
__nodiscard bool pml2_destroy_range(pml2_t pml2, ptr_t *vaddr, size_t *n_pages)
Definition pml2.cpp:45
pml2_t pml3e_get_pml2(const pml3e_t *pml3e)
Definition pml3.cpp:32
bool pml3e_is_present(const pml3e_t *pml3e)
Definition pml3.cpp:27
void pml3_traverse(pml3_t pml3, ptr_t *vaddr, size_t *n_pages, pagetable_walk_options_t callback, void *data)
Definition pml3.cpp:16
pml3e_t * pml3_entry(pml3_t pml3, ptr_t vaddr)
Definition pml3.cpp:21
pml2_t pml3e_get_or_create_pml2(pml3e_t *pml3e)
__nodiscard bool pml3_destroy_range(pml3_t pml3, ptr_t *vaddr, size_t *n_pages)
#define pml_destroy_table(x)
#define pml_create_table(x)
pml2e_t pml3e_t
Definition pml_types.hpp:60
#define pmlxe_destroy(pmlxe)
#define PML3_ENTRIES
void(* pml3e_pre_traverse)(pml3_t pml3, pml3e_t *e, ptr_t vaddr, void *data)
Definition pml_types.hpp:99
unsigned long ptr_t
Definition types.h:21