MOS Source Code
Loading...
Searching...
No Matches
pml2.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"
8#include "mos/platform/platform_defs.hpp"
9
10#include <algorithm>
11#include <mos_stdlib.hpp>
12#include <mos_string.hpp>
13
14void pml2_traverse(pml2_t pml2, ptr_t *vaddr, size_t *n_pages, pagetable_walk_options_t options, void *data)
15{
16 for (size_t i = pml2_index(*vaddr); i < PML2_ENTRIES && *n_pages; i++)
17 {
18 pml2e_t *pml2e = pml2_entry(pml2, *vaddr);
19 pml1_t pml1 = { 0 };
20
21 if (pml2e_is_present(pml2e))
22 {
23 pml1 = pml2e_get_or_create_pml1(pml2e);
24 }
25 else
26 {
27 if (options.readonly)
28 {
29 // skip to the next pml2e, but don't go past the end of the range
30 *vaddr += std::min(*n_pages, (size_t) PML2E_NPAGES) * MOS_PAGE_SIZE;
31 *n_pages -= std::min(*n_pages, (size_t) PML2E_NPAGES);
32 continue;
33 }
34
35 pml1 = pml_create_table(pml1);
36 platform_pml2e_set_pml1(pml2e, pml1, va_pfn(pml1.table));
37 }
38
39 if (options.pml2e_pre_traverse)
40 options.pml2e_pre_traverse(pml2, pml2e, *vaddr, data);
41 pml1_traverse(pml1, vaddr, n_pages, options, data);
42 }
43}
44
45bool pml2_destroy_range(pml2_t pml2, ptr_t *vaddr, size_t *n_pages)
46{
47 const bool should_zap_this_pml2 = pml2_index(*vaddr) == 0 && *n_pages >= PML2_ENTRIES * PML2E_NPAGES;
48
49 for (size_t i = pml2_index(*vaddr); i < PML2_ENTRIES && *n_pages; i++)
50 {
51 pml2e_t *pml2e = pml2_entry(pml2, *vaddr);
52
53 if (pml2e_is_present(pml2e))
54 {
55 pml1_t pml1 = platform_pml2e_get_pml1(pml2e);
56 if (pml1_destroy_range(pml1, vaddr, n_pages))
57 pmlxe_destroy(pml2e); // pml1 was destroyed
58 }
59 else
60 {
61 // skip to the next pml2e
62 *vaddr += std::min(*n_pages, (size_t) PML2E_NPAGES) * MOS_PAGE_SIZE;
63 *n_pages -= std::min(*n_pages, (size_t) PML2E_NPAGES);
64 continue;
65 }
66 }
67
68 if (should_zap_this_pml2)
70
71 return should_zap_this_pml2;
72}
73
74pml2e_t *pml2_entry(pml2_t pml2, ptr_t vaddr)
75{
76 return &pml2.table[pml2_index(vaddr)];
77}
78
79bool pml2e_is_present(const pml2e_t *pml2e)
80{
81 return platform_pml2e_get_present(pml2e);
82}
83
85{
86 if (pml2e_is_present(pml2e))
87 return platform_pml2e_get_pml1(pml2e);
88
89 pml1_t pml1 = pml_create_table(pml1);
90 platform_pml2e_set_pml1(pml2e, pml1, va_pfn(pml1.table));
91 return pml1;
92}
pml1_t platform_pml2e_get_pml1(const pml2e_t *pml2e)
Definition mm.cpp:107
void platform_pml2e_set_pml1(pml2e_t *pml2e, pml1_t pml1, pfn_t pml1_pfn)
Definition mm.cpp:112
bool platform_pml2e_get_present(const pml2e_t *pml2e)
Definition mm.cpp:120
#define MOS_PAGE_SIZE
Definition autoconf.h:6
#define va_pfn(va)
Definition mm.hpp:78
void pml1_traverse(pml1_t pml1, ptr_t *vaddr, size_t *n_pages, pagetable_walk_options_t callback, void *data)
Definition pml1.cpp:16
__nodiscard bool pml1_destroy_range(pml1_t pml1, ptr_t *vaddr, size_t *n_pages)
Definition pml1.cpp:28
pml1_t pml2e_get_or_create_pml1(pml2e_t *pml2e)
Definition pml2.cpp:84
bool pml2e_is_present(const pml2e_t *pml2e)
Definition pml2.cpp:79
pml2e_t * pml2_entry(pml2_t pml2, ptr_t vaddr)
Definition pml2.cpp:74
void pml2_traverse(pml2_t pml2, ptr_t *vaddr, size_t *n_pages, pagetable_walk_options_t options, void *data)
Definition pml2.cpp:14
bool pml2_destroy_range(pml2_t pml2, ptr_t *vaddr, size_t *n_pages)
Definition pml2.cpp:45
#define pml_destroy_table(x)
#define pml_create_table(x)
#define pmlxe_destroy(pmlxe)
#define PML2_ENTRIES
void(* pml2e_pre_traverse)(pml2_t pml2, pml2e_t *e, ptr_t vaddr, void *data)
pml1e_t * table
Definition pml_types.hpp:35
unsigned long ptr_t
Definition types.h:21