summaryrefslogtreecommitdiff
path: root/crates/kernel/src/arch/hosted.rs
diff options
context:
space:
mode:
authorNathan Ringo <nathan@remexre.com>2024-09-04 02:19:32 -0500
committerNathan Ringo <nathan@remexre.com>2024-09-04 02:19:32 -0500
commitcbee8b7dde708164081fdb979e2b96740ba516a6 (patch)
treef18bcf8da431d85fb09c4f3884de85a739edc860 /crates/kernel/src/arch/hosted.rs
parentc27e5ca6bf2b4040abd628ef59f8a3bc9326749c (diff)
Enables paging.
Diffstat (limited to 'crates/kernel/src/arch/hosted.rs')
-rw-r--r--crates/kernel/src/arch/hosted.rs181
1 files changed, 175 insertions, 6 deletions
diff --git a/crates/kernel/src/arch/hosted.rs b/crates/kernel/src/arch/hosted.rs
index df62bab..ac3d53e 100644
--- a/crates/kernel/src/arch/hosted.rs
+++ b/crates/kernel/src/arch/hosted.rs
@@ -2,18 +2,19 @@
extern crate std;
-use std::{thread::sleep, time::Duration};
-
-/// 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: usize = 64;
+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?
@@ -27,3 +28,171 @@ pub fn sleep_forever() -> ! {
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!()
+ }
+ }
+}