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