From 264600f145465bce0411b3600303c412db05e1fc Mon Sep 17 00:00:00 2001 From: equation314 Date: Sun, 25 Nov 2018 18:27:31 +0800 Subject: [PATCH] aarch64/mmu: add io remap --- crate/memory/src/memory_set.rs | 8 +++- crate/memory/src/paging/mod.rs | 2 + kernel/src/arch/aarch64/board/raspi3/mod.rs | 3 +- kernel/src/arch/aarch64/memory.rs | 7 ++- kernel/src/arch/aarch64/paging.rs | 52 ++------------------- kernel/src/arch/riscv32/paging.rs | 2 + kernel/src/arch/x86_64/paging.rs | 4 +- 7 files changed, 24 insertions(+), 54 deletions(-) diff --git a/crate/memory/src/memory_set.rs b/crate/memory/src/memory_set.rs index f67c956..316c28b 100644 --- a/crate/memory/src/memory_set.rs +++ b/crate/memory/src/memory_set.rs @@ -98,6 +98,7 @@ pub struct MemoryAttr { user: bool, readonly: bool, execute: bool, + mmio: bool, hide: bool, } @@ -114,6 +115,10 @@ impl MemoryAttr { self.execute = true; self } + pub fn mmio(mut self) -> Self { + self.mmio = true; + self + } pub fn hide(mut self) -> Self { self.hide = true; self @@ -122,8 +127,9 @@ impl MemoryAttr { if self.user { entry.set_user(true); } if self.readonly { entry.set_writable(false); } if self.execute { entry.set_execute(true); } + if self.mmio { entry.set_mmio(false); } if self.hide { entry.set_present(false); } - if self.user || self.readonly || self.execute || self.hide { entry.update(); } + if self.user || self.readonly || self.execute || self.mmio || self.hide { entry.update(); } } } diff --git a/crate/memory/src/paging/mod.rs b/crate/memory/src/paging/mod.rs index 0a3d4c0..0f38ef1 100644 --- a/crate/memory/src/paging/mod.rs +++ b/crate/memory/src/paging/mod.rs @@ -57,4 +57,6 @@ pub trait Entry { fn set_user(&mut self, value: bool); fn execute(&self) -> bool; fn set_execute(&mut self, value: bool); + fn mmio(&self) -> bool; + fn set_mmio(&mut self, value: bool); } diff --git a/kernel/src/arch/aarch64/board/raspi3/mod.rs b/kernel/src/arch/aarch64/board/raspi3/mod.rs index 0db5133..98e59e0 100644 --- a/kernel/src/arch/aarch64/board/raspi3/mod.rs +++ b/kernel/src/arch/aarch64/board/raspi3/mod.rs @@ -6,7 +6,8 @@ pub mod irq; pub mod timer; pub mod serial; -pub const IO_BASE: usize = bcm2837::IO_BASE; +pub const IO_REMAP_BASE: usize = bcm2837::IO_BASE; +pub const IO_REMAP_END: usize = 0x40001000; pub fn init() { assert_has_not_been_called!("board::init must be called only once"); diff --git a/kernel/src/arch/aarch64/memory.rs b/kernel/src/arch/aarch64/memory.rs index 7536dc4..29f3009 100644 --- a/kernel/src/arch/aarch64/memory.rs +++ b/kernel/src/arch/aarch64/memory.rs @@ -25,7 +25,7 @@ pub fn init_mmu_early() { let frame_lvl4 = Frame::containing_address(PhysAddr::new(&PAGE_TABLE_LVL4 as *const _ as u64)); let frame_lvl3 = Frame::containing_address(PhysAddr::new(&PAGE_TABLE_LVL3 as *const _ as u64)); let frame_lvl2 = Frame::containing_address(PhysAddr::new(&PAGE_TABLE_LVL2 as *const _ as u64)); - super::paging::setup_page_table(frame_lvl4, frame_lvl3, frame_lvl2); + super::paging::setup_temp_page_table(frame_lvl4, frame_lvl3, frame_lvl2); // device. MAIR_EL1.write( @@ -111,9 +111,8 @@ fn remap_the_kernel() { ms.push(MemoryArea::new_identity(srodata as usize, erodata as usize, MemoryAttr::default().readonly(), "rodata")); ms.push(MemoryArea::new_identity(sbss as usize, ebss as usize, MemoryAttr::default(), "bss")); - // ensure the level 2 page table exists - ms.push(MemoryArea::new_identity(0x40000000, 0x40200000, MemoryAttr::default(), "arm_control")); - super::paging::remap_device_2mib(&mut ms, 0x3F000000, 0x40200000); + use arch::board::{IO_REMAP_BASE, IO_REMAP_END}; + ms.push(MemoryArea::new_identity(IO_REMAP_BASE, IO_REMAP_END, MemoryAttr::default().mmio(), "io_remap")); unsafe { ms.activate(); } use core::mem::forget; diff --git a/kernel/src/arch/aarch64/paging.rs b/kernel/src/arch/aarch64/paging.rs index f11820c..eab53f4 100644 --- a/kernel/src/arch/aarch64/paging.rs +++ b/kernel/src/arch/aarch64/paging.rs @@ -12,7 +12,7 @@ use aarch64::paging::{FrameAllocator, FrameDeallocator, Page, PhysFrame as Frame use aarch64::paging::memory_attribute::*; // need 3 page -pub fn setup_page_table(frame_lvl4: Frame, frame_lvl3: Frame, frame_lvl2: Frame) { +pub fn setup_temp_page_table(frame_lvl4: Frame, frame_lvl3: Frame, frame_lvl2: Frame) { let p4 = unsafe { &mut *(frame_lvl4.start_address().as_u64() as *mut Aarch64PageTable) }; let p3 = unsafe { &mut *(frame_lvl3.start_address().as_u64() as *mut Aarch64PageTable) }; let p2 = unsafe { &mut *(frame_lvl2.start_address().as_u64() as *mut Aarch64PageTable) }; @@ -25,8 +25,8 @@ pub fn setup_page_table(frame_lvl4: Frame, frame_lvl3: Frame, frame_lvl2: Frame) for page in Page::::range_of(start_addr, end_addr) { let paddr = PhysAddr::new(page.start_address().as_u64()); - use arch::board::IO_BASE; - if paddr.as_u64() >= IO_BASE as u64 { + use arch::board::IO_REMAP_BASE; + if paddr.as_u64() >= IO_REMAP_BASE as u64 { p2[page.p2_index()].set_block::(paddr, block_flags | EF::PXN, MairDevice::attr_value()); } else { p2[page.p2_index()].set_block::(paddr, block_flags, MairNormal::attr_value()); @@ -39,54 +39,10 @@ pub fn setup_page_table(frame_lvl4: Frame, frame_lvl3: Frame, frame_lvl2: Frame) p4[0].set_frame(frame_lvl3, EF::default(), MairNormal::attr_value()); p4[RECURSIVE_INDEX].set_frame(frame_lvl4, EF::default(), MairNormal::attr_value()); - // warn!("p2"); - // for i in 0..512 { - // if p2[i].flags().bits() != 0 { - // info!("{:x?} {:x?} {:x?}",i, &p2[i] as *const _ as usize, p2[i]); - // } - // } - // warn!("p3"); - // for i in 0..512 { - // if p3[i].flags().bits() != 0 { - // info!("{:x?} {:x?} {:x?}",i, &p3[i] as *const _ as usize, p3[i]); - // } - // } - // warn!("p4"); - // for i in 0..512 { - // if p4[i].flags().bits() != 0 { - // info!("{:x?} {:x?} {:x?}",i, &p4[i] as *const _ as usize, p4[i]); - // } - // } - ttbr_el1_write(0, frame_lvl4); tlb_invalidate_all(); } -/// map the range [start, end) as device memory, insert to the MemorySet -pub fn remap_device_2mib(ms: &mut MemorySet, start_addr: usize, end_addr: usize) { - ms.edit(|active_table| { - for page in Page::::range_of(start_addr, end_addr) { - let paddr = PhysAddr::new(page.start_address().as_u64()); - let p2 = unsafe { &mut *active_table.0.p2_ptr(page) }; - p2[page.p2_index()].set_block::(paddr, EF::default() - EF::TABLE_OR_PAGE, MairDevice::attr_value()); - } - - // let p2 = unsafe { &mut *(0o777_777_000_000_0000 as *mut Aarch64PageTable) }; - // for i in 0..512 { - // if p2[i].flags().bits() != 0 { - // info!("{:x?} {:x?} {:x?}",i, &p2[i] as *const _ as usize, p2[i]); - // } - // } - - // let p2 = unsafe { &mut *(0o777_777_000_001_0000 as *mut Aarch64PageTable) }; - // for i in 0..512 { - // if p2[i].flags().bits() != 0 { - // info!("{:x?} {:x?} {:x?}",i, &p2[i] as *const _ as usize, p2[i]); - // } - // } - }); -} - pub struct ActivePageTable(RecursivePageTable<'static>); pub struct PageEntry(PageTableEntry); @@ -201,6 +157,8 @@ impl Entry for PageEntry { false => self.as_flags().set(EF::PXN, !value), } } + fn mmio(&self) -> bool { self.0.attr().value == MairDevice::attr_value().value } + fn set_mmio(&mut self, value: bool) { self.0.modify_attr(MairDevice::attr_value()); } } impl PageEntry { diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index 680448b..ef0710f 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -126,6 +126,8 @@ impl Entry for PageEntry { fn set_user(&mut self, value: bool) { self.as_flags().set(EF::USER, value); } fn execute(&self) -> bool { self.0.flags().contains(EF::EXECUTABLE) } fn set_execute(&mut self, value: bool) { self.as_flags().set(EF::EXECUTABLE, value); } + fn mmio(&self) -> bool { unimplemented!() } + fn set_mmio(&mut self, value: bool) { unimplemented!() } } impl PageEntry { diff --git a/kernel/src/arch/x86_64/paging.rs b/kernel/src/arch/x86_64/paging.rs index 8717703..9e164bb 100644 --- a/kernel/src/arch/x86_64/paging.rs +++ b/kernel/src/arch/x86_64/paging.rs @@ -138,6 +138,8 @@ impl Entry for PageEntry { } fn execute(&self) -> bool { !self.0.flags().contains(EF::NO_EXECUTE) } fn set_execute(&mut self, value: bool) { self.as_flags().set(EF::NO_EXECUTE, !value); } + fn mmio(&self) -> bool { unimplemented!() } + fn set_mmio(&mut self, value: bool) { unimplemented!() } } impl PageEntry { @@ -261,4 +263,4 @@ impl FrameDeallocator for FrameAllocatorForX86 { fn dealloc(&mut self, frame: Frame) { dealloc_frame(frame.start_address().as_u64() as usize); } -} \ No newline at end of file +}