MOS Source Code
Loading...
Searching...
No Matches
pml_types.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#pragma once
4
5#include "mos/platform/platform_defs.h"
6
7#include <mos/mos_global.h>
8#include <mos/types.h>
9
10#define MOS_MAX_PAGE_LEVEL 5
11
12#ifndef MOS_PLATFORM_PAGING_LEVELS
13#error "MOS_PLATFORM_PAGING_LEVELS must be defined"
14#endif
15
16#if MOS_PLATFORM_PAGING_LEVELS > 4
17#error "more levels are not supported"
18#endif
19
20// ! platform-independent pml types
21
22#define define_pmlx(pmln) \
23 typedef struct \
24 { \
25 pte_content_t content; \
26 } __packed pmln##e_t; \
27 typedef struct \
28 { \
29 pmln##e_t *table; \
30 } pmln##_t
31
32#define pml_null(pmln) (pmln.table == NULL)
33
34// nah, your platform must have at least 1 level of paging
36
37#define pml1_index(vaddr) ((vaddr >> PML1_SHIFT) & PML1_MASK)
38#define PML1E_NPAGES 1ULL
39
40#if MOS_PLATFORM_PAGING_LEVELS >= 2
41define_pmlx(pml2);
42#define pml2_index(vaddr) ((vaddr >> PML2_SHIFT) & PML2_MASK)
43#define PML2E_NPAGES (PML1_ENTRIES * PML1E_NPAGES)
44#if MOS_CONFIG(PML2_HUGE_CAPABLE)
45#define PML2_HUGE_MASK (PML1_MASK << PML1_SHIFT)
46#endif
47#else
49#endif
50
51#if MOS_PLATFORM_PAGING_LEVELS >= 3
52define_pmlx(pml3);
53#define pml3_index(vaddr) ((vaddr >> PML3_SHIFT) & PML3_MASK)
54#define PML3E_NPAGES (PML2_ENTRIES * PML2E_NPAGES)
55#if MOS_CONFIG(PML3_HUGE_CAPABLE)
56#define PML3_HUGE_MASK (PML2_HUGE_MASK | (PML2_MASK << PML2_SHIFT))
57#endif
58#else
59new_named_opaque_type(pml2_t, next, pml3_t);
60typedef pml2e_t pml3e_t;
61#endif
62
63#if MOS_PLATFORM_PAGING_LEVELS >= 4
64define_pmlx(pml4);
65#define pml4_index(vaddr) ((vaddr >> PML4_SHIFT) & PML4_MASK)
66#define PML4E_NPAGES (PML3_ENTRIES * PML3E_NPAGES)
67#if MOS_CONFIG(PML4_HUGE_CAPABLE)
68#define PML4_HUGE_MASK (PML3_HUGE_MASK | (PML3_MASK << PML3_SHIFT))
69#endif
70#else
71new_named_opaque_type(pml3_t, next, pml4_t);
73#endif
74
75#if MOS_PLATFORM_PAGING_LEVELS >= 5
76#error "TODO: more than 4 levels"
77#else
78new_named_opaque_type(pml4_t, next, pml5_t);
80#endif
81
82#define MOS_PMLTOP MOS_CONCAT(pml, MOS_PLATFORM_PAGING_LEVELS)
83
84typedef struct
85{
87} pgd_t;
88
89#define pgd_create(top) ((pgd_t){ .max = { .next = top } })
90#define pgd_pfn(pgd) va_pfn(pgd.max.next.table)
91
92typedef struct
93{
95 void (*pml4e_pre_traverse)(pml4_t pml4, pml4e_t *e, ptr_t vaddr, void *data);
96 void (*pml3e_pre_traverse)(pml3_t pml3, pml3e_t *e, ptr_t vaddr, void *data);
97 void (*pml2e_pre_traverse)(pml2_t pml2, pml2e_t *e, ptr_t vaddr, void *data);
98 void (*pml1e_callback)(pml1_t pml1, pml1e_t *e, ptr_t vaddr, void *data);
99 void (*pml2e_post_traverse)(pml2_t pml2, pml2e_t *e, ptr_t vaddr, void *data);
100 void (*pml3e_post_traverse)(pml3_t pml3, pml3e_t *e, ptr_t vaddr, void *data);
101 void (*pml4e_post_traverse)(pml4_t pml4, pml4e_t *e, ptr_t vaddr, void *data);
103
105void __destroy_page_table(void *table);
106
107#define pml_create_table(x) ((MOS_CONCAT(x, _t)){ .table = (MOS_CONCAT(x, e_t) *) __create_page_table() })
108#define pml_destroy_table(x) __destroy_page_table(x.table)
109
110#define pmlxe_destroy(pmlxe) (pmlxe)->content = 0
MOSAPI void(1, 2) fatal_abort(const char *fmt
#define __nodiscard
Definition mos_global.h:35
void __destroy_page_table(void *table)
Definition table_ops.c:204
#define define_pmlx(pmln)
Definition pml_types.h:22
#define MOS_MAX_PAGE_LEVEL
Definition pml_types.h:10
pml3e_t pml4e_t
Definition pml_types.h:72
pml4e_t pml5e_t
Definition pml_types.h:79
pml2e_t pml3e_t
Definition pml_types.h:60
__nodiscard void * __create_page_table(void)
Definition table_ops.c:198
MOS_CONCAT(MOS_CONCAT(pml, 5), _t) max
#define new_named_opaque_type(base, name, type)
Definition types.h:88
unsigned long ptr_t
Definition types.h:25