sel4/arch/x86/
vspace.rs

1//
2// Copyright 2023, Colias Group, LLC
3//
4// SPDX-License-Identifier: MIT
5//
6
7use sel4_config::{sel4_cfg, sel4_cfg_enum, sel4_cfg_wrap_match};
8
9use crate::{
10    CapTypeForFrameObject, CapTypeForFrameObjectOfFixedSize, CapTypeForTranslationTableObject,
11    ObjectBlueprint, ObjectBlueprintX64, ObjectBlueprintX86, cap_type,
12    const_helpers::u32_into_usize, sys,
13};
14
15/// Frame object types for this kernel configuration.
16#[derive(Copy, Clone, Debug, PartialEq, Eq)]
17pub enum FrameObjectType {
18    _4k,
19    LargePage,
20    HugePage,
21}
22
23impl FrameObjectType {
24    pub const GRANULE: Self = Self::_4k;
25
26    pub const fn blueprint(self) -> ObjectBlueprint {
27        match self {
28            Self::_4k => ObjectBlueprint::Arch(ObjectBlueprintX86::_4k),
29            Self::LargePage => ObjectBlueprint::Arch(ObjectBlueprintX86::LargePage),
30            Self::HugePage => {
31                ObjectBlueprint::Arch(ObjectBlueprintX86::SeL4Arch(ObjectBlueprintX64::HugePage))
32            }
33        }
34    }
35
36    pub const fn from_bits(bits: usize) -> Option<Self> {
37        Some(match bits {
38            Self::_4K_BITS => Self::_4k,
39            Self::LARGE_PAGE_BITS => Self::LargePage,
40            Self::HUGE_PAGE_BITS => Self::HugePage,
41            _ => return None,
42        })
43    }
44
45    // For match arm LHS's, as we can't call const fn's
46    pub const _4K_BITS: usize = Self::_4k.bits();
47    pub const LARGE_PAGE_BITS: usize = Self::LargePage.bits();
48    pub const HUGE_PAGE_BITS: usize = Self::HugePage.bits();
49}
50
51impl CapTypeForFrameObject for cap_type::_4k {}
52
53impl CapTypeForFrameObjectOfFixedSize for cap_type::_4k {
54    const FRAME_OBJECT_TYPE: FrameObjectType = FrameObjectType::_4k;
55}
56
57impl CapTypeForFrameObject for cap_type::LargePage {}
58
59impl CapTypeForFrameObjectOfFixedSize for cap_type::LargePage {
60    const FRAME_OBJECT_TYPE: FrameObjectType = FrameObjectType::LargePage;
61}
62
63impl CapTypeForFrameObject for cap_type::HugePage {}
64
65impl CapTypeForFrameObjectOfFixedSize for cap_type::HugePage {
66    const FRAME_OBJECT_TYPE: FrameObjectType = FrameObjectType::HugePage;
67}
68
69// // //
70
71/// Translation table object types for this kernel configuration.
72#[sel4_cfg_enum]
73#[derive(Copy, Clone, Debug, PartialEq, Eq)]
74pub enum TranslationTableObjectType {
75    PML4,
76    PDPT,
77    PageDirectory,
78    PageTable,
79    #[sel4_cfg(VTX)]
80    EPTPML4,
81    #[sel4_cfg(VTX)]
82    EPTPDPT,
83    #[sel4_cfg(VTX)]
84    EPTPageDirectory,
85    #[sel4_cfg(VTX)]
86    EPTPageTable,
87}
88
89impl TranslationTableObjectType {
90    pub const fn blueprint(&self) -> ObjectBlueprint {
91        sel4_cfg_wrap_match! {
92            match self {
93                Self::PML4 => {
94                    ObjectBlueprint::Arch(ObjectBlueprintX86::SeL4Arch(ObjectBlueprintX64::PML4))
95                }
96                Self::PDPT => {
97                    ObjectBlueprint::Arch(ObjectBlueprintX86::SeL4Arch(ObjectBlueprintX64::PDPT))
98                }
99                Self::PageDirectory => ObjectBlueprint::Arch(ObjectBlueprintX86::PageDirectory),
100                Self::PageTable => ObjectBlueprint::Arch(ObjectBlueprintX86::PageTable),
101                #[sel4_cfg(VTX)]
102                Self::EPTPML4 => {
103                    ObjectBlueprint::Arch(ObjectBlueprintX86::SeL4Arch(ObjectBlueprintX64::EPTPML4))
104                }
105                #[sel4_cfg(VTX)]
106                Self::EPTPDPT => {
107                    ObjectBlueprint::Arch(ObjectBlueprintX86::SeL4Arch(ObjectBlueprintX64::EPTPDPT))
108                }
109                #[sel4_cfg(VTX)]
110                Self::EPTPageDirectory => ObjectBlueprint::Arch(ObjectBlueprintX86::EPTPageDirectory),
111                #[sel4_cfg(VTX)]
112                Self::EPTPageTable => ObjectBlueprint::Arch(ObjectBlueprintX86::EPTPageTable),
113            }
114        }
115    }
116
117    pub const fn index_bits(&self) -> usize {
118        sel4_cfg_wrap_match! {
119            match self {
120                Self::PML4 => u32_into_usize(sys::seL4_PML4IndexBits),
121                Self::PDPT => u32_into_usize(sys::seL4_PDPTIndexBits),
122                Self::PageDirectory => u32_into_usize(sys::seL4_PageDirIndexBits),
123                Self::PageTable => u32_into_usize(sys::seL4_PageTableIndexBits),
124                #[sel4_cfg(VTX)]
125                Self::EPTPML4 => u32_into_usize(sys::seL4_X86_EPTPML4IndexBits),
126                #[sel4_cfg(VTX)]
127                Self::EPTPDPT => u32_into_usize(sys::seL4_X86_EPTPDPTIndexBits),
128                #[sel4_cfg(VTX)]
129                Self::EPTPageDirectory => u32_into_usize(sys::seL4_X86_EPTPDIndexBits),
130                #[sel4_cfg(VTX)]
131                Self::EPTPageTable => u32_into_usize(sys::seL4_X86_EPTPTIndexBits),
132            }
133        }
134    }
135
136    pub const fn from_level(level: usize) -> Option<Self> {
137        Some(match level {
138            0 => Self::PML4,
139            1 => Self::PDPT,
140            2 => Self::PageDirectory,
141            3 => Self::PageTable,
142            _ => return None,
143        })
144    }
145
146    #[sel4_cfg(VTX)]
147    pub const fn from_level_ept(level: usize) -> Option<Self> {
148        Some(match level {
149            0 => Self::EPTPML4,
150            1 => Self::EPTPDPT,
151            2 => Self::EPTPageDirectory,
152            3 => Self::EPTPageTable,
153            _ => return None,
154        })
155    }
156}
157
158impl CapTypeForTranslationTableObject for cap_type::PML4 {
159    const TRANSLATION_TABLE_OBJECT_TYPE: TranslationTableObjectType =
160        TranslationTableObjectType::PML4;
161}
162
163impl CapTypeForTranslationTableObject for cap_type::PDPT {
164    const TRANSLATION_TABLE_OBJECT_TYPE: TranslationTableObjectType =
165        TranslationTableObjectType::PDPT;
166}
167
168impl CapTypeForTranslationTableObject for cap_type::PageDirectory {
169    const TRANSLATION_TABLE_OBJECT_TYPE: TranslationTableObjectType =
170        TranslationTableObjectType::PageDirectory;
171}
172
173impl CapTypeForTranslationTableObject for cap_type::PageTable {
174    const TRANSLATION_TABLE_OBJECT_TYPE: TranslationTableObjectType =
175        TranslationTableObjectType::PageTable;
176}
177
178pub mod vspace_levels {
179    pub const NUM_LEVELS: usize = 4;
180
181    pub const HIGHEST_LEVEL_WITH_PAGE_ENTRIES: usize = NUM_LEVELS - 3;
182}