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