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