sel4/arch/riscv/
vspace.rs

1//
2// Copyright 2023, Colias Group, LLC
3//
4// SPDX-License-Identifier: MIT
5//
6
7#![allow(clippy::eq_op)]
8
9use sel4_config::sel4_cfg_wrap_match;
10
11#[allow(unused_imports)]
12use crate::{
13    CapTypeForFrameObject, CapTypeForFrameObjectOfFixedSize, CapTypeForTranslationTableObject,
14    ObjectBlueprint, ObjectBlueprintRiscV, cap_type, const_helpers::u32_into_usize, sys,
15};
16
17/// Frame object types for this kernel configuration.
18#[sel4_config::sel4_cfg_enum]
19#[derive(Copy, Clone, Debug, PartialEq, Eq)]
20pub enum FrameObjectType {
21    _4kPage,
22    MegaPage,
23    #[sel4_cfg(any(PT_LEVELS = "3", PT_LEVELS = "4"))]
24    GigaPage,
25}
26
27impl FrameObjectType {
28    pub const GRANULE: Self = Self::_4kPage;
29
30    pub const fn blueprint(self) -> ObjectBlueprint {
31        sel4_cfg_wrap_match! {
32            match self {
33                FrameObjectType::_4kPage => ObjectBlueprint::Arch(ObjectBlueprintRiscV::_4kPage),
34                FrameObjectType::MegaPage => ObjectBlueprint::Arch(ObjectBlueprintRiscV::MegaPage),
35                #[sel4_cfg(any(PT_LEVELS = "3", PT_LEVELS = "4"))]
36                FrameObjectType::GigaPage => ObjectBlueprint::Arch(ObjectBlueprintRiscV::GigaPage),
37            }
38        }
39    }
40
41    pub const fn from_bits(bits: usize) -> Option<Self> {
42        Some(sel4_cfg_wrap_match! {
43            match bits {
44                Self::_4K_PAGE_BITS => Self::_4kPage,
45                Self::MEGA_PAGE_BITS => Self::MegaPage,
46                #[sel4_cfg(any(PT_LEVELS = "3", PT_LEVELS = "4"))]
47                Self::GIGA_PAGE_BITS => Self::GigaPage,
48                _ => return None,
49            }
50        })
51    }
52
53    // For match arm LHS's, as we can't call const fn's
54
55    pub const _4K_PAGE_BITS: usize = Self::_4kPage.bits();
56    pub const MEGA_PAGE_BITS: usize = Self::MegaPage.bits();
57
58    #[sel4_config::sel4_cfg(any(PT_LEVELS = "3", PT_LEVELS = "4"))]
59    pub const GIGA_PAGE_BITS: usize = Self::GigaPage.bits();
60}
61
62impl CapTypeForFrameObject for cap_type::_4kPage {}
63
64impl CapTypeForFrameObjectOfFixedSize for cap_type::_4kPage {
65    const FRAME_OBJECT_TYPE: FrameObjectType = FrameObjectType::_4kPage;
66}
67
68impl CapTypeForFrameObject for cap_type::MegaPage {}
69
70impl CapTypeForFrameObjectOfFixedSize for cap_type::MegaPage {
71    const FRAME_OBJECT_TYPE: FrameObjectType = FrameObjectType::MegaPage;
72}
73
74#[sel4_config::sel4_cfg(any(PT_LEVELS = "3", PT_LEVELS = "4"))]
75impl CapTypeForFrameObject for cap_type::GigaPage {}
76
77#[sel4_config::sel4_cfg(any(PT_LEVELS = "3", PT_LEVELS = "4"))]
78impl CapTypeForFrameObjectOfFixedSize for cap_type::GigaPage {
79    const FRAME_OBJECT_TYPE: FrameObjectType = FrameObjectType::GigaPage;
80}
81
82// // //
83
84/// Translation table object types for this kernel configuration.
85#[derive(Copy, Clone, Debug, PartialEq, Eq)]
86pub enum TranslationTableObjectType {
87    PageTable,
88}
89
90impl TranslationTableObjectType {
91    pub const fn blueprint(&self) -> ObjectBlueprint {
92        ObjectBlueprint::Arch(ObjectBlueprintRiscV::PageTable)
93    }
94
95    pub const fn index_bits(&self) -> usize {
96        u32_into_usize(sys::seL4_PageTableIndexBits)
97    }
98
99    pub const fn from_level(level: usize) -> Option<Self> {
100        if level < vspace_levels::NUM_LEVELS {
101            Some(Self::PageTable)
102        } else {
103            None
104        }
105    }
106}
107
108impl CapTypeForTranslationTableObject for cap_type::PageTable {
109    const TRANSLATION_TABLE_OBJECT_TYPE: TranslationTableObjectType =
110        TranslationTableObjectType::PageTable;
111}
112
113pub mod vspace_levels {
114    use sel4_config::sel4_cfg_usize;
115
116    pub const NUM_LEVELS: usize = sel4_cfg_usize!(PT_LEVELS);
117
118    pub const HIGHEST_LEVEL_WITH_PAGE_ENTRIES: usize = NUM_LEVELS
119        - if sel4_cfg_usize!(PT_LEVELS) == 3 || sel4_cfg_usize!(PT_LEVELS) == 4 {
120            3
121        } else {
122            2
123        };
124}