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