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