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