diff --git a/src/memory/mod.rs b/src/memory/mod.rs
index 2225308f..57335343 100644
--- a/src/memory/mod.rs
+++ b/src/memory/mod.rs
@@ -1,7 +1,6 @@
pub use self::area_frame_allocator::AreaFrameAllocator;
pub mod paging;
-pub mod paging_new;
mod area_frame_allocator;
pub const PAGE_SIZE: usize = 4096;
@@ -13,7 +12,7 @@ pub struct Frame {
impl Frame {
fn containing_address(address: usize) -> Frame {
- Frame{ number: address / PAGE_SIZE }
+ Frame { number: address / PAGE_SIZE }
}
}
diff --git a/src/memory/paging_new/entry.rs b/src/memory/paging/entry.rs
similarity index 100%
rename from src/memory/paging_new/entry.rs
rename to src/memory/paging/entry.rs
diff --git a/src/memory/paging/mapping.rs b/src/memory/paging/mapping.rs
new file mode 100644
index 00000000..8a6af29f
--- /dev/null
+++ b/src/memory/paging/mapping.rs
@@ -0,0 +1,24 @@
+use memory::Frame;
+use super::Page;
+use super::entry::{EntryFlags, PRESENT};
+use memory::FrameAllocator;
+use super::table::P4;
+
+pub fn map(page: &Page, flags: EntryFlags, allocator: &mut A)
+ where A: FrameAllocator
+{
+ let frame = allocator.allocate_frame().expect("out of memory");
+ map_to(page, frame, flags, allocator)
+}
+
+pub fn map_to(page: &Page, frame: Frame, flags: EntryFlags, allocator: &mut A)
+ where A: FrameAllocator
+{
+ let p4 = unsafe { &mut *P4 };
+ let mut p3 = p4.next_table_create(page.p4_index(), allocator);
+ let mut p2 = p3.next_table_create(page.p3_index(), allocator);
+ let mut p1 = p2.next_table_create(page.p2_index(), allocator);
+
+ assert!(!p1[page.p1_index()].flags().contains(PRESENT));
+ p1[page.p1_index()].set(frame, flags | PRESENT);
+}
diff --git a/src/memory/paging/mod.rs b/src/memory/paging/mod.rs
index 5421f472..5130b982 100644
--- a/src/memory/paging/mod.rs
+++ b/src/memory/paging/mod.rs
@@ -1,88 +1,38 @@
-use memory::{Frame, FrameAllocator};
+mod entry;
+mod table;
+pub mod translate;
+pub mod mapping;
+
+pub fn test(frame_allocator: &mut A)
+ where A: super::FrameAllocator
+{
+ use self::entry::PRESENT;
+ mapping::map(&Page::containing_address(0xdeadbeaa000),
+ PRESENT,
+ frame_allocator);
+ mapping::map(&Page::containing_address(0xdeadbeab000),
+ PRESENT,
+ frame_allocator);
+ mapping::map(&Page::containing_address(0xdeadbeac000),
+ PRESENT,
+ frame_allocator);
+ mapping::map(&Page::containing_address(0xdeadbead000),
+ PRESENT,
+ frame_allocator);
+ mapping::map(&Page::containing_address(0xcafebeaf000),
+ PRESENT,
+ frame_allocator);
+ mapping::map(&Page::containing_address(0x0),
+ PRESENT,
+ frame_allocator);
+}
pub const PAGE_SIZE: usize = 4096;
-const ENTRY_SIZE: usize = 8;
const ENTRY_COUNT: usize = 512;
pub type PhysicalAddress = usize;
pub type VirtualAddress = usize;
-pub fn translate(virtual_address: usize) -> Option {
- let page = Page::containing_address(virtual_address);
- let offset = virtual_address % PAGE_SIZE;
-
- let frame_number = {
- let p4_entry = page.p4_table().entry(page.p4_index());
- assert!(!p4_entry.flags().contains(HUGE_PAGE));
- if !p4_entry.flags().contains(PRESENT) {
- return None;
- }
-
- let p3_entry = unsafe { page.p3_table() }.entry(page.p3_index());
- if !p3_entry.flags().contains(PRESENT) {
- return None;
- }
- if p3_entry.flags().contains(HUGE_PAGE) {
- // 1GiB page (address must be 1GiB aligned)
- let start_frame_number = p3_entry.pointed_frame().number;
- assert!(start_frame_number % (ENTRY_COUNT * ENTRY_COUNT) == 0);
- start_frame_number + page.p2_index() * ENTRY_COUNT + page.p1_index()
- } else {
- // 2MiB or 4KiB page
- let p2_entry = unsafe { page.p2_table() }.entry(page.p2_index());
- if !p2_entry.flags().contains(PRESENT) {
- return None;
- }
- if p2_entry.flags().contains(HUGE_PAGE) {
- // 2MiB page (address must be 2MiB aligned)
- let start_frame_number = p2_entry.pointed_frame().number;
- assert!(start_frame_number % ENTRY_COUNT == 0);
- start_frame_number + page.p1_index()
- } else {
- // standard 4KiB page
- let p1_entry = unsafe { page.p1_table() }.entry(page.p1_index());
- assert!(!p1_entry.flags().contains(HUGE_PAGE));
- if !p1_entry.flags().contains(PRESENT) {
- return None;
- }
- p1_entry.pointed_frame().number
- }
- }
- };
- Some(frame_number * PAGE_SIZE + offset)
-}
-
-pub fn map_to(page: &Page, frame: Frame, flags: TableEntryFlags, allocator: &mut A)
- where A: FrameAllocator
-{
- let p4_index = page.p4_index();
- let p3_index = page.p3_index();
- let p2_index = page.p2_index();
- let p1_index = page.p1_index();
-
- let mut p4 = page.p4_table();
- if !p4.entry(p4_index).flags().contains(PRESENT) {
- let frame = allocator.allocate_frame().expect("no frames available");
- p4.set_entry(p4_index, TableEntry::new(frame, PRESENT | WRITABLE));
- unsafe { page.p3_table() }.zero();
- }
- let mut p3 = unsafe { page.p3_table() };
- if !p3.entry(p3_index).flags().contains(PRESENT) {
- let frame = allocator.allocate_frame().expect("no frames available");
- p3.set_entry(p3_index, TableEntry::new(frame, PRESENT | WRITABLE));
- unsafe { page.p2_table() }.zero();
- }
- let mut p2 = unsafe { page.p2_table() };
- if !p2.entry(p2_index).flags().contains(PRESENT) {
- let frame = allocator.allocate_frame().expect("no frames available");
- p2.set_entry(p2_index, TableEntry::new(frame, PRESENT | WRITABLE));
- unsafe { page.p1_table() }.zero();
- }
- let mut p1 = unsafe { page.p1_table() };
- assert!(!p1.entry(p1_index).flags().contains(PRESENT));
- p1.set_entry(p1_index, TableEntry::new(frame, flags));
-}
-
pub struct Page {
number: usize,
}
@@ -119,90 +69,4 @@ impl Page {
fn p1_index(&self) -> usize {
(self.number >> 0) & 0o777
}
-
- const fn p4_table(&self) -> Table {
- Table(Page { number: 0o_777_777_777_777 })
- }
-
- /// # Safety
- /// Only valid if the corresponding entry in the parent table is PRESENT and not HUGE_PAGE.
- unsafe fn p3_table(&self) -> Table {
- Table(Page { number: 0o_777_777_777_000 | self.p4_index() })
- }
-
- /// # Safety
- /// Only valid if the corresponding entry in the parent table is PRESENT and not HUGE_PAGE.
- unsafe fn p2_table(&self) -> Table {
- Table(Page { number: 0o_777_777_000_000 | (self.p4_index() << 9) | self.p3_index() })
- }
-
- /// # Safety
- /// Only valid if the corresponding entry in the parent table is PRESENT and not HUGE_PAGE.
- unsafe fn p1_table(&self) -> Table {
- Table(Page {
- number: 0o_777_000_000_000 | (self.p4_index() << 18) | (self.p3_index() << 9) |
- self.p2_index(),
- })
- }
}
-
-struct Table(Page);
-
-impl Table {
- fn entry(&self, index: usize) -> TableEntry {
- assert!(index < ENTRY_COUNT);
- let entry_address = self.0.start_address() + index * ENTRY_SIZE;
- unsafe { *(entry_address as *const _) }
- }
-
- fn set_entry(&mut self, index: usize, value: TableEntry) {
- assert!(index < ENTRY_COUNT);
- let entry_address = self.0.start_address() + index * ENTRY_SIZE;
- unsafe { *(entry_address as *mut _) = value }
- }
-
- fn zero(&mut self) {
- let page = self.0.start_address() as *mut [TableEntry; ENTRY_COUNT];
- unsafe { *page = [TableEntry::unused(); ENTRY_COUNT] };
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-struct TableEntry(u64);
-
-impl TableEntry {
- const fn unused() -> TableEntry {
- TableEntry(0)
- }
-
- fn new(frame: Frame, flags: TableEntryFlags) -> TableEntry {
- let frame_addr = (frame.number << 12) & 0x000fffff_fffff000;
- TableEntry((frame_addr as u64) | flags.bits())
- }
-
- fn flags(&self) -> TableEntryFlags {
- TableEntryFlags::from_bits_truncate(self.0)
- }
-
- fn pointed_frame(&self) -> Frame {
- Frame { number: ((self.0 & 0x000fffff_fffff000) >> 12) as usize }
- }
-}
-
-bitflags! {
- flags TableEntryFlags: u64 {
- const PRESENT = 1 << 0,
- const WRITABLE = 1 << 1,
- const USER_ACCESSIBLE = 1 << 2,
- const WRITE_THROUGH = 1 << 3,
- const NO_CACHE = 1 << 4,
- const ACCESSED = 1 << 5,
- const DIRTY = 1 << 6,
- const HUGE_PAGE = 1 << 7,
- const GLOBAL = 1 << 8,
- const NO_EXECUTE = 1 << 63,
- }
-}
-
-
-mod tables;
diff --git a/src/memory/paging/multilevel.rs b/src/memory/paging/multilevel.rs
deleted file mode 100644
index 50dc0995..00000000
--- a/src/memory/paging/multilevel.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-use core::marker::PhantomData;
-use super::{VirtualAddress, Page, ENTRY_COUNT};
-use super::table::{Entry, Table, PRESENT};
-use super::levels::{TableLevel, HierachicalLevel, Level4, Level3, Level2, Level1};
-
-pub fn P4_entry(address: VirtualAddress) -> EntryRef {
- let p4_page = Page { number: 0o_777_777_777_777 };
- let p4 = p4_page.start_address() as *mut Table;
- EntryRef {
- target_address: address,
- table: p4,
- _phantom: PhantomData,
- }
-}
-
-pub struct EntryRef {
- target_address: VirtualAddress,
- table: *mut Table,
- _phantom: PhantomData,
-}
-
-impl EntryRef where L: HierachicalLevel
-{
- pub fn next_level(&self) -> Option> {
- if self.entry().flags().contains(PRESENT) {
- let next_table_page = {
- let table_page = Page::containing_address(self.table as usize);
- let index = table_index::(self.target_address);
- Page { number: ((table_page.number << 9) & 0o_777_777_777_777) | index }
- };
- let next_table = next_table_page.start_address() as *mut Table;
- Some(EntryRef {
- target_address: self.target_address,
- table: next_table,
- _phantom: PhantomData,
- })
- } else {
- None
- }
- }
-
- fn entry(&self) -> &Entry {
- unsafe { &(*self.table).0[table_index::(self.target_address)] }
- }
-}
-
-fn table_index(address: VirtualAddress) -> usize
- where L: TableLevel
-{
- let shift = 12 + (L::level_number() - 1) * 9;
- (address >> shift) & 0o777
-}
diff --git a/src/memory/paging/multilevel2.rs b/src/memory/paging/multilevel2.rs
deleted file mode 100644
index 5a844386..00000000
--- a/src/memory/paging/multilevel2.rs
+++ /dev/null
@@ -1,125 +0,0 @@
-use core::marker::PhantomData;
-
-pub const fn P4(page: &Page) -> Table {
- Table {
- table_page: Page { number: 0o_777_777_777_777 },
- target_page_number: page.number,
- _phantom: PhantomData,
- }
-}
-
-impl Table where L: TableLevel
-{
- pub fn index_of(page: &Page) -> usize {
- Self::index_of_page_number(page.number)
- }
-
- fn index_of_page_number(page_number: usize) -> usize {
- let s = (L::level_number() - 1) * 9;
- (page_number >> s) & 0o777
- }
-
- fn index(&self) -> usize {
- Self::index_of_page_number(self.target_page_number)
- }
-}
-
-use memory::{Frame, FrameAllocator};
-
-
-pub struct Table {
- table_page: Page,
- target_page_number: usize,
- _phantom: PhantomData,
-}
-
-impl Table where L: TableLevel
-{
- fn entry(&self) -> TableEntry {
- let entry_address = self.table_page.start_address() + self.index() * ENTRY_SIZE;
- unsafe { *(entry_address as *const _) }
- }
-
- fn set_entry(&mut self, value: TableEntry) {
- let entry_address = self.table_page.start_address() + self.index() * ENTRY_SIZE;
- unsafe { *(entry_address as *mut _) = value }
- }
-
- fn zero(&mut self) {
- let page = self.table_page.start_address() as *mut [TableEntry; ENTRY_COUNT];
- unsafe { *page = [TableEntry::unused(); ENTRY_COUNT] };
- }
-}
-
-impl Table where L: HierachicalLevel
-{
- fn next_table_internal(&self) -> Table {
- Table {
- table_page: Page {
- number: ((self.table_page.number << 9) & 0o_777_777_777_777) | self.index(),
- },
- target_page_number: self.target_page_number,
- _phantom: PhantomData,
- }
- }
-
- fn next_table(&self) -> Option> {
- if self.entry().flags().contains(PRESENT) {
- Some(self.next_table_internal())
- } else {
- None
- }
- }
-
- fn next_table_create(&mut self, allocator: &mut A) -> Table
- where A: FrameAllocator
- {
- match self.next_table() {
- Some(table) => table,
- None => {
- let frame = allocator.allocate_frame().expect("no frames available");
- self.set_entry(TableEntry::new(frame, PRESENT | WRITABLE));
- let mut next_table = self.next_table_internal();
- next_table.zero();
- next_table
- }
- }
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-struct TableEntry(u64);
-
-impl TableEntry {
- const fn unused() -> TableEntry {
- TableEntry(0)
- }
-
- fn new(frame: Frame, flags: TableEntryFlags) -> TableEntry {
- let frame_addr = (frame.number << 12) & 0x000fffff_fffff000;
- TableEntry((frame_addr as u64) | flags.bits())
- }
-
- fn flags(&self) -> TableEntryFlags {
- TableEntryFlags::from_bits_truncate(self.0)
- }
-
- fn pointed_frame(&self) -> Frame {
- Frame { number: ((self.0 & 0x000fffff_fffff000) >> 12) as usize }
- }
-}
-
-bitflags! {
- flags TableEntryFlags: u64 {
- const PRESENT = 1 << 0,
- const WRITABLE = 1 << 1,
- const USER_ACCESSIBLE = 1 << 2,
- const WRITE_THROUGH = 1 << 3,
- const NO_CACHE = 1 << 4,
- const ACCESSED = 1 << 5,
- const DIRTY = 1 << 6,
- const HUGE_PAGE = 1 << 7,
- const GLOBAL = 1 << 8,
- const NO_EXECUTE = 1 << 63,
- }
-}
diff --git a/src/memory/paging_new/table.rs b/src/memory/paging/table.rs
similarity index 53%
rename from src/memory/paging_new/table.rs
rename to src/memory/paging/table.rs
index cb4b3c49..dcbc4c80 100644
--- a/src/memory/paging_new/table.rs
+++ b/src/memory/paging/table.rs
@@ -1,32 +1,16 @@
-use super::{ENTRY_COUNT, Page};
-use super::entry::{Entry, PRESENT, HUGE_PAGE};
-use super::levels::{TableLevel, HierachicalLevel, Level4};
+use memory::FrameAllocator;
+use memory::paging::{ENTRY_COUNT, Page};
+use memory::paging::entry::*;
use core::ops::{Index, IndexMut};
use core::marker::PhantomData;
-pub const P4: *const Table = 0xffffffff_fffff000 as *const _;
+pub const P4: *mut Table = 0xffffffff_fffff000 as *mut _;
pub struct Table {
entries: [Entry; ENTRY_COUNT],
_phantom: PhantomData,
}
-impl Index for Table where L: TableLevel
-{
- type Output = Entry;
-
- fn index(&self, index: usize) -> &Entry {
- &self.entries[index]
- }
-}
-
-impl IndexMut for Table where L: TableLevel
-{
- fn index_mut(&mut self, index: usize) -> &mut Entry {
- &mut self.entries[index]
- }
-}
-
impl Table where L: TableLevel
{
pub fn zero(&mut self) {
@@ -46,6 +30,22 @@ impl Table where L: HierachicalLevel
self.next_table_address(index).map(|t| unsafe { &mut *(t as *mut _) })
}
+ pub fn next_table_create(&mut self,
+ index: usize,
+ allocator: &mut A)
+ -> &mut Table
+ where A: FrameAllocator
+ {
+ if let None = self.next_table_address(index) {
+ assert!(!self.entries[index].flags().contains(HUGE_PAGE),
+ "mapping code does not support huge pages");
+ let frame = allocator.allocate_frame().expect("no frames available");
+ self.entries[index].set(frame, PRESENT | WRITABLE);
+ self.next_table_mut(index).unwrap().zero();
+ }
+ self.next_table_mut(index).unwrap()
+ }
+
fn next_table_address(&self, index: usize) -> Option {
let entry_flags = self[index].flags();
if entry_flags.contains(PRESENT) && !entry_flags.contains(HUGE_PAGE) {
@@ -60,3 +60,50 @@ impl Table where L: HierachicalLevel
}
}
}
+
+impl Index for Table where L: TableLevel
+{
+ type Output = Entry;
+
+ fn index(&self, index: usize) -> &Entry {
+ &self.entries[index]
+ }
+}
+
+impl IndexMut for Table where L: TableLevel
+{
+ fn index_mut(&mut self, index: usize) -> &mut Entry {
+ &mut self.entries[index]
+ }
+}
+
+pub trait TableLevel {}
+
+pub enum Level4 {}
+#[allow(dead_code)]
+enum Level3 {}
+#[allow(dead_code)]
+enum Level2 {}
+#[allow(dead_code)]
+enum Level1 {}
+
+impl TableLevel for Level4 {}
+impl TableLevel for Level3 {}
+impl TableLevel for Level2 {}
+impl TableLevel for Level1 {}
+
+trait HierachicalLevel: TableLevel {
+ type NextLevel: TableLevel;
+}
+
+impl HierachicalLevel for Level4 {
+ type NextLevel = Level3;
+}
+
+impl HierachicalLevel for Level3 {
+ type NextLevel = Level2;
+}
+
+impl HierachicalLevel for Level2 {
+ type NextLevel = Level1;
+}
diff --git a/src/memory/paging/tables.rs b/src/memory/paging/tables.rs
deleted file mode 100644
index 2e554f5d..00000000
--- a/src/memory/paging/tables.rs
+++ /dev/null
@@ -1,256 +0,0 @@
-use core::marker::PhantomData;
-
-pub const fn P4(page: &Page) -> Table {
- Table {
- table_page: Page { number: 0o_777_777_777_777 },
- target_page_number: page.number,
- _phantom: PhantomData,
- }
-}
-
-
-pub fn translate(virtual_address: usize) -> Option {
- let page = Page::containing_address(virtual_address);
- let offset = virtual_address % PAGE_SIZE;
-
- let frame_number = {
- let p3 = match P4(&page).next_table() {
- None => return None,
- Some(t) => t,
- };
-
- if p3.entry().flags().contains(PRESENT | HUGE_PAGE) {
- // 1GiB page (address must be 1GiB aligned)
- let start_frame_number = p3.entry().pointed_frame().number;
- assert!(start_frame_number % (ENTRY_COUNT * ENTRY_COUNT) == 0);
- start_frame_number + Table::::index_of(&page) * ENTRY_COUNT +
- Table::::index_of(&page)
- } else {
- // 2MiB or 4KiB page
- let p2 = match p3.next_table() {
- None => return None,
- Some(t) => t,
- };
-
- if p2.entry().flags().contains(PRESENT | HUGE_PAGE) {
- // 2MiB page (address must be 2MiB aligned)
- let start_frame_number = p2.entry().pointed_frame().number;
- assert!(start_frame_number % ENTRY_COUNT == 0);
- start_frame_number + Table::::index_of(&page)
- } else {
- // standard 4KiB page
- let p1 = match p2.next_table() {
- None => return None,
- Some(t) => t,
- };
- p1.entry().pointed_frame().number
- }
- }
- };
- Some(frame_number * PAGE_SIZE + offset)
-}
-
-
-pub fn map_to(page: &Page, frame: Frame, flags: TableEntryFlags, allocator: &mut A)
- where A: FrameAllocator
-{
- let mut p3 = P4(page).next_table_create(allocator);
- let mut p2 = p3.next_table_create(allocator);
- let mut p1 = p2.next_table_create(allocator);
-
- assert!(!p1.entry().flags().contains(PRESENT));
- p1.set_entry(TableEntry::new(frame, flags));
-}
-
-trait TableLevel{
- fn level_number() -> usize;
-}
-pub enum Level1 {}
-pub enum Level2 {}
-pub enum Level3 {}
-pub enum Level4 {}
-
-impl TableLevel for Level4 {
- fn level_number() -> usize {
- 4
- }
-}
-impl TableLevel for Level3 {
- fn level_number() -> usize {
- 3
- }
-}
-impl TableLevel for Level2 {
- fn level_number() -> usize {
- 2
- }
-}
-impl TableLevel for Level1 {
- fn level_number() -> usize {
- 1
- }
-}
-
-trait HierachicalLevel: TableLevel {
- type NextLevel: TableLevel;
-}
-
-impl HierachicalLevel for Level4 {
- type NextLevel = Level3;
-}
-
-impl HierachicalLevel for Level3 {
- type NextLevel = Level2;
-}
-
-impl HierachicalLevel for Level2 {
- type NextLevel = Level1;
-}
-
-impl Table where L: TableLevel
-{
- pub fn index_of(page: &Page) -> usize {
- Self::index_of_page_number(page.number)
- }
-
- fn index_of_page_number(page_number: usize) -> usize {
- let s = (L::level_number() - 1) * 9;
- (page_number >> s) & 0o777
- }
-
- fn index(&self) -> usize {
- Self::index_of_page_number(self.target_page_number)
- }
-}
-
-use memory::{Frame, FrameAllocator};
-
-pub const PAGE_SIZE: usize = 4096;
-const ENTRY_SIZE: usize = 8;
-const ENTRY_COUNT: usize = 512;
-
-pub type PhysicalAddress = usize;
-pub type VirtualAddress = usize;
-
-
-pub struct Page {
- number: usize,
-}
-
-impl Page {
- fn containing_address(address: VirtualAddress) -> Page {
- match address {
- addr if addr < 0o_400_000_000_000_0000 => Page { number: addr / PAGE_SIZE },
- addr if addr >= 0o177777_400_000_000_000_0000 => {
- Page { number: (address / PAGE_SIZE) & 0o_777_777_777_777 }
- }
- _ => panic!("invalid address: 0x{:x}", address),
- }
- }
-
- pub fn start_address(&self) -> VirtualAddress {
- if self.number >= 0x800000000 {
- // sign extension necessary
- (self.number << 12) | 0xffff_000000000000
- } else {
- self.number << 12
- }
- }
-}
-
-pub struct Table {
- table_page: Page,
- target_page_number: usize,
- _phantom: PhantomData,
-}
-
-impl Table where L: TableLevel
-{
- fn entry(&self) -> TableEntry {
- let entry_address = self.table_page.start_address() + self.index() * ENTRY_SIZE;
- unsafe { *(entry_address as *const _) }
- }
-
- fn set_entry(&mut self, value: TableEntry) {
- let entry_address = self.table_page.start_address() + self.index() * ENTRY_SIZE;
- unsafe { *(entry_address as *mut _) = value }
- }
-
- fn zero(&mut self) {
- let page = self.table_page.start_address() as *mut [TableEntry; ENTRY_COUNT];
- unsafe { *page = [TableEntry::unused(); ENTRY_COUNT] };
- }
-}
-
-impl Table where L: HierachicalLevel
-{
- fn next_table_internal(&self) -> Table {
- Table {
- table_page: Page {
- number: ((self.table_page.number << 9) & 0o_777_777_777_777) | self.index(),
- },
- target_page_number: self.target_page_number,
- _phantom: PhantomData,
- }
- }
-
- fn next_table(&self) -> Option> {
- if self.entry().flags().contains(PRESENT) {
- Some(self.next_table_internal())
- } else {
- None
- }
- }
-
- fn next_table_create(&mut self, allocator: &mut A) -> Table
- where A: FrameAllocator
- {
- match self.next_table() {
- Some(table) => table,
- None => {
- let frame = allocator.allocate_frame().expect("no frames available");
- self.set_entry(TableEntry::new(frame, PRESENT | WRITABLE));
- let mut next_table = self.next_table_internal();
- next_table.zero();
- next_table
- }
- }
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-struct TableEntry(u64);
-
-impl TableEntry {
- const fn unused() -> TableEntry {
- TableEntry(0)
- }
-
- fn new(frame: Frame, flags: TableEntryFlags) -> TableEntry {
- let frame_addr = (frame.number << 12) & 0x000fffff_fffff000;
- TableEntry((frame_addr as u64) | flags.bits())
- }
-
- fn flags(&self) -> TableEntryFlags {
- TableEntryFlags::from_bits_truncate(self.0)
- }
-
- fn pointed_frame(&self) -> Frame {
- Frame { number: ((self.0 & 0x000fffff_fffff000) >> 12) as usize }
- }
-}
-
-bitflags! {
- flags TableEntryFlags: u64 {
- const PRESENT = 1 << 0,
- const WRITABLE = 1 << 1,
- const USER_ACCESSIBLE = 1 << 2,
- const WRITE_THROUGH = 1 << 3,
- const NO_CACHE = 1 << 4,
- const ACCESSED = 1 << 5,
- const DIRTY = 1 << 6,
- const HUGE_PAGE = 1 << 7,
- const GLOBAL = 1 << 8,
- const NO_EXECUTE = 1 << 63,
- }
-}
diff --git a/src/memory/paging_new/translate.rs b/src/memory/paging/translate.rs
similarity index 94%
rename from src/memory/paging_new/translate.rs
rename to src/memory/paging/translate.rs
index d9b3ac32..28190aa7 100644
--- a/src/memory/paging_new/translate.rs
+++ b/src/memory/paging/translate.rs
@@ -1,10 +1,9 @@
use super::{VirtualAddress, PhysicalAddress, Page, PAGE_SIZE, ENTRY_COUNT};
-use super::table::{Table, P4};
+use super::table::P4;
use super::entry::{PRESENT, HUGE_PAGE};
use memory::Frame;
-
-pub fn translate(virtual_address: usize) -> Option {
+pub fn translate(virtual_address: VirtualAddress) -> Option {
let page = Page::containing_address(virtual_address);
let offset = virtual_address % PAGE_SIZE;
diff --git a/src/memory/paging_new/levels.rs b/src/memory/paging_new/levels.rs
deleted file mode 100644
index ca28b8d3..00000000
--- a/src/memory/paging_new/levels.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-pub trait TableLevel {}
-
-pub struct Level4;
-pub struct Level3;
-pub struct Level2;
-pub struct Level1;
-
-impl TableLevel for Level4 {}
-impl TableLevel for Level3 {}
-impl TableLevel for Level2 {}
-impl TableLevel for Level1 {}
-
-pub trait HierachicalLevel: TableLevel {
- type NextLevel: TableLevel;
-}
-
-impl HierachicalLevel for Level4 {
- type NextLevel = Level3;
-}
-
-impl HierachicalLevel for Level3 {
- type NextLevel = Level2;
-}
-
-impl HierachicalLevel for Level2 {
- type NextLevel = Level1;
-}
diff --git a/src/memory/paging_new/mod.rs b/src/memory/paging_new/mod.rs
deleted file mode 100644
index 7685f86f..00000000
--- a/src/memory/paging_new/mod.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-mod entry;
-mod table;
-mod levels;
-mod translate;
-
-pub const PAGE_SIZE: usize = 4096;
-const ENTRY_SIZE: usize = 8;
-const ENTRY_COUNT: usize = 512;
-
-pub type PhysicalAddress = usize;
-pub type VirtualAddress = usize;
-
-pub struct Page {
- number: usize,
-}
-
-impl Page {
- fn containing_address(address: VirtualAddress) -> Page {
- match address {
- addr if addr < 0o_400_000_000_000_0000 => Page { number: addr / PAGE_SIZE },
- addr if addr >= 0o177777_400_000_000_000_0000 => {
- Page { number: (address / PAGE_SIZE) & 0o_777_777_777_777 }
- }
- _ => panic!("invalid address: 0x{:x}", address),
- }
- }
-
- pub fn start_address(&self) -> VirtualAddress {
- if self.number >= 0x800000000 {
- // sign extension necessary
- (self.number << 12) | 0xffff_000000000000
- } else {
- self.number << 12
- }
- }
-
- fn p4_index(&self) -> usize {
- (self.number >> 27) & 0o777
- }
- fn p3_index(&self) -> usize {
- (self.number >> 18) & 0o777
- }
- fn p2_index(&self) -> usize {
- (self.number >> 9) & 0o777
- }
- fn p1_index(&self) -> usize {
- (self.number >> 0) & 0o777
- }
-}