1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#include "mos/mm/paging/pmlx/pml1.hpp"
4
5#include "mos/assert.hpp"
6#include "mos/mm/paging/pml_types.hpp"
7#include "mos/platform/platform.hpp"
8
9#include <algorithm>
10#include <mos_stdlib.hpp>
11
12#if MOS_PLATFORM_PAGING_LEVELS < 1
13#error "Give up your mind"
14#endif
15
16void pml1_traverse(pml1_t pml1, ptr_t *vaddr, size_t *n_pages, pagetable_walk_options_t callback, void *data)
17{
18 for (size_t pml1_i = pml1_index(*vaddr); pml1_i < PML1_ENTRIES && *n_pages; pml1_i++)
19 {
20 pml1e_t *pml1e = pml1_entry(pml1, vaddr: *vaddr);
21 if (callback.pml1e_callback)
22 callback.pml1e_callback(pml1, pml1e, *vaddr, data);
23 (*vaddr) += std::min(a: *n_pages, b: (size_t) PML1E_NPAGES) * MOS_PAGE_SIZE;
24 (*n_pages) -= std::min(a: *n_pages, b: (size_t) PML1E_NPAGES);
25 }
26}
27
28bool pml1_destroy_range(pml1_t pml1, ptr_t *vaddr, size_t *n_pages)
29{
30 const bool should_zap_this_pml1 = pml1_index(*vaddr) == 0 && *n_pages >= PML1_ENTRIES * PML1E_NPAGES;
31
32 for (size_t pml1_i = pml1_index(*vaddr); pml1_i < PML1_ENTRIES && *n_pages; pml1_i++)
33 {
34 pml1e_t *pml1e = pml1_entry(pml1, vaddr: *vaddr);
35 MOS_ASSERT(!pml1e_is_present(pml1e));
36
37 (*vaddr) += PML1E_NPAGES * MOS_PAGE_SIZE;
38 (*n_pages) -= PML1E_NPAGES;
39 }
40
41 if (should_zap_this_pml1)
42 pml_destroy_table(pml1);
43
44 return should_zap_this_pml1;
45}
46
47pml1e_t *pml1_entry(pml1_t pml1, ptr_t vaddr)
48{
49 return &pml1.table[pml1_index(vaddr)];
50}
51
52bool pml1e_is_present(const pml1e_t *pml1e)
53{
54 return platform_pml1e_get_present(pml1: pml1e);
55}
56
57pfn_t pml1e_get_pfn(const pml1e_t *pml1e)
58{
59 return platform_pml1e_get_pfn(pml1: pml1e);
60}
61