summaryrefslogtreecommitdiff
path: root/crates/kernel/src/arch/hosted.rs
blob: ac3d53e1ba4b9c23c51da334f33f40edc8a0c33d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
//! Support for running under an operating system that provides libstd, for testing.

extern crate std;

use crate::PAGE_SIZE;
use std::{iter, thread::sleep, time::Duration};

/// The number of bits in the size of a page of memory.
///
/// Obviously, this value is unrealistic, but for now we just need the hosted arch to compile.
pub const PAGE_SIZE_BITS: usize = 6;

/// The number of bits in the size of the largest huge page.
///
/// This platform doesn't support huge pages (so we claim), so this matches the page size.
pub const MAX_PAGE_SIZE_BITS: usize = PAGE_SIZE_BITS;

/// No-opped interrupt support.
///
/// TODO: Should this use Unix signals?
pub mod interrupts {
    pub fn disable_interrupts() {}
}

/// Sleeps forever, in one-second chunks.
pub fn sleep_forever() -> ! {
    loop {
        sleep(Duration::from_secs(1));
    }
}

/// A dummy implementation of paging.
pub mod paging {
    use super::*;

    /// The number of bits looked up in each page table entry.
    pub const PAGE_TABLE_BITS: usize = 6;

    /// The number of levels of page tables.
    pub const PAGE_TABLE_LEVELS: usize = 2;

    /// An address space ID.
    #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
    pub struct ASID(u8);

    impl ASID {
        /// The kernel's ASID.
        pub const KERNEL: ASID = ASID(0);
    }

    /// A dummy page table type.
    #[derive(Debug)]
    pub struct PageTable;

    impl PageTable {
        /// Set this as the root page table. Note that this does _not_ perform a TLB shootdown.
        ///
        /// # Safety
        ///
        /// - This is a stub.
        pub unsafe fn make_current(&self, asid: ASID) {
            todo!()
        }

        /// Iterates over shared references to the entries in this page table.
        pub fn iter(&self) -> impl Iterator<Item = &PageTableEntry> {
            iter::empty()
        }

        /// Iterates over exclusive references to the entries in this page table.
        pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut PageTableEntry> {
            iter::empty()
        }
    }

    /// An dummy type for an entry in a page table.
    #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
    pub struct PageTableEntry;

    impl PageTableEntry {
        /// Returns the physical address of the backing page or next level page table.
        pub fn addr(&self) -> u64 {
            todo!()
        }

        /// Returns a pointer to the backing page.
        pub fn page(&self) -> *mut [u8; PAGE_SIZE] {
            todo!()
        }

        /// Returns a pointer to the backing page table.
        pub fn page_table(&self) -> *mut PageTable {
            todo!()
        }

        /// Sets the physical address of the backing page or next level page table.
        pub fn set_addr(&mut self, addr: u64) -> &mut PageTableEntry {
            todo!()
        }

        /// Returns whether the dirty bit is set.
        pub fn dirty(&self) -> bool {
            todo!()
        }

        /// Sets the dirty bit.
        pub fn set_dirty(&mut self, dirty: bool) -> &mut PageTableEntry {
            todo!()
        }

        /// Returns whether the accessed bit is set.
        pub fn accessed(&self) -> bool {
            todo!()
        }

        /// Sets the accessed bit.
        pub fn set_accessed(&mut self, accessed: bool) -> &mut PageTableEntry {
            todo!()
        }

        /// Returns whether the global bit is set.
        pub fn global(&self) -> bool {
            todo!()
        }

        /// Sets the global bit.
        pub fn set_global(&mut self, global: bool) -> &mut PageTableEntry {
            todo!()
        }

        /// Returns whether the user bit is set.
        pub fn user(&self) -> bool {
            todo!()
        }

        /// Sets the user bit.
        pub fn set_user(&mut self, user: bool) -> &mut PageTableEntry {
            todo!()
        }

        /// Returns whether the executable bit is set.
        pub fn executable(&self) -> bool {
            todo!()
        }

        /// Sets the executable bit.
        pub fn set_executable(&mut self, executable: bool) -> &mut PageTableEntry {
            todo!()
        }

        /// Returns whether the writable bit is set.
        pub fn writable(&self) -> bool {
            todo!()
        }

        /// Sets the writable bit.
        pub fn set_writable(&mut self, writable: bool) -> &mut PageTableEntry {
            todo!()
        }

        /// Returns whether the readable bit is set.
        pub fn readable(&self) -> bool {
            todo!()
        }

        /// Sets the readable bit.
        pub fn set_readable(&mut self, readable: bool) -> &mut PageTableEntry {
            todo!()
        }

        /// Returns whether the page table entry is for a leaf PTE.
        pub fn leaf_pte(&self) -> bool {
            todo!()
        }

        /// Sets the readable, writable, and executable bits at once.
        pub fn set_rwx(
            &mut self,
            readable: bool,
            writable: bool,
            executable: bool,
        ) -> &mut PageTableEntry {
            self.set_readable(readable)
                .set_writable(writable)
                .set_executable(executable)
        }

        /// Returns whether the valid bit is set.
        pub fn valid(&self) -> bool {
            todo!()
        }

        /// Sets the valid bit.
        pub fn set_valid(&mut self, valid: bool) -> &mut PageTableEntry {
            todo!()
        }
    }
}