From 0d478bbf94767d3de31820d7096b77c3be0d80bf Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Fri, 14 May 2021 01:49:00 -0700 Subject: [PATCH 1/2] Cleanup const_fn! Fixes #222 The following methods can be made `const` on stable: - `GlobalDescriptorTable::from_raw_slice` - `MappedFrame::{start_address, size}` - `Page::p1_index` The remaining functions still need `const_fn` because: - Some GDT methods use `&mut self` - The IDT uses function pointers as a type argument - The PageSize marker trait is used all over Comments were updated where appropriate. Signed-off-by: Joe Richey --- src/lib.rs | 8 ++++---- src/structures/gdt.rs | 14 ++++++++------ src/structures/paging/frame.rs | 2 +- src/structures/paging/mapper/mod.rs | 28 ++++++++++++---------------- src/structures/paging/page.rs | 10 ++++------ src/structures/paging/page_table.rs | 11 ----------- 6 files changed, 29 insertions(+), 44 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d5cc3632e..42be18368 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,10 +2,10 @@ //! and access to various system registers. #![cfg_attr(not(test), no_std)] -#![cfg_attr(feature = "const_fn", feature(const_panic))] -#![cfg_attr(feature = "const_fn", feature(const_mut_refs))] -#![cfg_attr(feature = "const_fn", feature(const_fn_fn_ptr_basics))] -#![cfg_attr(feature = "const_fn", feature(const_fn_trait_bound))] +#![cfg_attr(feature = "const_fn", feature(const_panic))] // Better panic messages +#![cfg_attr(feature = "const_fn", feature(const_mut_refs))] // GDT add_entry() +#![cfg_attr(feature = "const_fn", feature(const_fn_fn_ptr_basics))] // IDT new() +#![cfg_attr(feature = "const_fn", feature(const_fn_trait_bound))] // PageSize marker trait #![cfg_attr(feature = "inline_asm", feature(asm))] #![cfg_attr(feature = "abi_x86_interrupt", feature(abi_x86_interrupt))] #![cfg_attr(docsrs, feature(doc_cfg))] diff --git a/src/structures/gdt.rs b/src/structures/gdt.rs index 641b3d70b..02007fb71 100644 --- a/src/structures/gdt.rs +++ b/src/structures/gdt.rs @@ -112,17 +112,19 @@ impl GlobalDescriptorTable { /// * The user must make sure that the entries are well formed /// * The provided slice **must not be larger than 8 items** (only up to the first 8 will be observed.) #[inline] - #[cfg(feature = "const_fn")] pub const unsafe fn from_raw_slice(slice: &[u64]) -> GlobalDescriptorTable { - assert!( - slice.len() <= 8, - "initializing a GDT from a slice requires it to be **at most** 8 elements." - ); let next_free = slice.len(); - let mut table = [0; 8]; let mut idx = 0; + #[cfg(feature = "const_fn")] + assert!( + next_free <= 8, + "initializing a GDT from a slice requires it to be **at most** 8 elements." + ); + #[cfg(not(feature = "const_fn"))] + table[next_free]; // Will fail if slice.len() > 8 + while idx != next_free { table[idx] = slice[idx]; idx += 1; diff --git a/src/structures/paging/frame.rs b/src/structures/paging/frame.rs index 9a00de3aa..f125404fc 100644 --- a/src/structures/paging/frame.rs +++ b/src/structures/paging/frame.rs @@ -11,7 +11,7 @@ use core::ops::{Add, AddAssign, Sub, SubAssign}; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] #[repr(C)] pub struct PhysFrame { - start_address: PhysAddr, + pub(crate) start_address: PhysAddr, // TODO: remove when start_address() is const size: PhantomData, } diff --git a/src/structures/paging/mapper/mod.rs b/src/structures/paging/mapper/mod.rs index a7c089621..a73f2d8c4 100644 --- a/src/structures/paging/mapper/mod.rs +++ b/src/structures/paging/mapper/mod.rs @@ -85,25 +85,21 @@ pub enum MappedFrame { } impl MappedFrame { - const_fn! { - /// Returns the start address of the frame. - pub fn start_address(&self) -> PhysAddr { - match self { - MappedFrame::Size4KiB(frame) => frame.start_address(), - MappedFrame::Size2MiB(frame) => frame.start_address(), - MappedFrame::Size1GiB(frame) => frame.start_address(), - } + /// Returns the start address of the frame. + pub const fn start_address(&self) -> PhysAddr { + match self { + MappedFrame::Size4KiB(frame) => frame.start_address, + MappedFrame::Size2MiB(frame) => frame.start_address, + MappedFrame::Size1GiB(frame) => frame.start_address, } } - const_fn! { - /// Returns the size the frame (4KB, 2MB or 1GB). - pub fn size(&self) -> u64 { - match self { - MappedFrame::Size4KiB(frame) => frame.size(), - MappedFrame::Size2MiB(frame) => frame.size(), - MappedFrame::Size1GiB(frame) => frame.size(), - } + /// Returns the size the frame (4KB, 2MB or 1GB). + pub const fn size(&self) -> u64 { + match self { + MappedFrame::Size4KiB(_) => Size4KiB::SIZE, + MappedFrame::Size2MiB(_) => Size2MiB::SIZE, + MappedFrame::Size1GiB(_) => Size1GiB::SIZE, } } } diff --git a/src/structures/paging/page.rs b/src/structures/paging/page.rs index 46a00b921..1169946a5 100644 --- a/src/structures/paging/page.rs +++ b/src/structures/paging/page.rs @@ -210,12 +210,10 @@ impl Page { Page::containing_address(VirtAddr::new(addr)) } - const_fn! { - /// Returns the level 1 page table index of this page. - #[inline] - pub fn p1_index(self) -> PageTableIndex { - self.start_address().p1_index() - } + /// Returns the level 1 page table index of this page. + #[inline] + pub const fn p1_index(self) -> PageTableIndex { + self.start_address.p1_index() } } diff --git a/src/structures/paging/page_table.rs b/src/structures/paging/page_table.rs index 115abc2bd..ac83a2c52 100644 --- a/src/structures/paging/page_table.rs +++ b/src/structures/paging/page_table.rs @@ -189,7 +189,6 @@ pub struct PageTable { impl PageTable { /// Creates an empty page table. - #[cfg(feature = "const_fn")] #[inline] pub const fn new() -> Self { const EMPTY: PageTableEntry = PageTableEntry::new(); @@ -198,16 +197,6 @@ impl PageTable { } } - /// Creates an empty page table. - #[cfg(not(feature = "const_fn"))] - #[inline] - pub fn new() -> Self { - const EMPTY: PageTableEntry = PageTableEntry::new(); - PageTable { - entries: [EMPTY; ENTRY_COUNT], - } - } - /// Clears all entries. #[inline] pub fn zero(&mut self) { From a53a57a4c2a2581f7206cd0e09a3c9f6bbbccd35 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Fri, 14 May 2021 02:00:41 -0700 Subject: [PATCH 2/2] Update changelog Signed-off-by: Joe Richey --- Changelog.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Changelog.md b/Changelog.md index 291807462..6a5683698 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,10 @@ # Unreleased +- The following methods no longer require the `nightly` feature to be `const fn`s`: + - `PageTable::new` + - `GlobalDescriptorTable::from_raw_slice` + - `MappedFrame::{start_address, size}` + - `Page::p1_index` - Add `Debug` implementation for `InterruptDescriptorTable` ([#253](https://github.com/rust-osdev/x86_64/pull/253)) - Improve `Debug` implementations for `Entry` and `EntryOptions`