From 5987c2068b1422b95611a2c83d1a17010976d348 Mon Sep 17 00:00:00 2001 From: equation314 Date: Sun, 16 Dec 2018 22:26:04 +0800 Subject: [PATCH] aarch64/fb: remap framebuffer base address --- crate/memory/src/memory_set.rs | 14 +++-- crate/memory/src/paging/mod.rs | 14 ++++- kernel/Cargo.lock | 2 +- kernel/src/arch/aarch64/board/raspi3/fb.rs | 4 +- kernel/src/arch/aarch64/memory.rs | 64 +++++++++++++++------- kernel/src/arch/aarch64/paging.rs | 13 ++--- 6 files changed, 72 insertions(+), 39 deletions(-) diff --git a/crate/memory/src/memory_set.rs b/crate/memory/src/memory_set.rs index 3c631eb..7c5c1c8 100644 --- a/crate/memory/src/memory_set.rs +++ b/crate/memory/src/memory_set.rs @@ -222,8 +222,8 @@ pub struct MemoryAttr { user: bool, readonly: bool, execute: bool, - mmio: bool, hide: bool, + mmio: usize, } impl MemoryAttr { @@ -251,8 +251,12 @@ impl MemoryAttr { self.execute = true; self } - pub fn mmio(mut self) -> Self { - self.mmio = true; + /* + ** @brief set the MMIO type + ** @retval MemoryAttr the memory attribute itself + */ + pub fn mmio(mut self, value: usize) -> Self { + self.mmio = value; self } /* @@ -273,9 +277,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(true); } + if self.mmio != 0 { entry.set_mmio(self.mmio); } if self.hide { entry.set_present(false); } - if self.user || self.readonly || self.execute || self.mmio || self.hide { entry.update(); } + if self.user || self.readonly || self.execute || self.mmio != 0 || self.hide { entry.update(); } } } diff --git a/crate/memory/src/paging/mod.rs b/crate/memory/src/paging/mod.rs index 6bbe9b2..0fa7447 100644 --- a/crate/memory/src/paging/mod.rs +++ b/crate/memory/src/paging/mod.rs @@ -195,6 +195,16 @@ pub trait Entry { ** @retval none */ fn set_execute(&mut self, value: bool); - fn mmio(&self) -> bool; - fn set_mmio(&mut self, value: bool); + /* + ** @brief get MMIO type + ** (e.g. aarch64 can have normal/device/normal_non_cacheable memory) + ** @retval usize + */ + fn mmio(&self) -> usize; + /* + ** @brief set MMIO type + ** @param value: usize the value distinguished memory type + ** @retval none + */ + fn set_mmio(&mut self, value: usize); } diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index ecc04cb..a39024e 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -1,7 +1,7 @@ [[package]] name = "aarch64" version = "2.2.2" -source = "git+https://github.com/equation314/aarch64#06b2f5507dd5393e40c1506cd4414ef36864afc6" +source = "git+https://github.com/equation314/aarch64#95e875933967067908bf1da66bf74db24d450062" dependencies = [ "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/kernel/src/arch/aarch64/board/raspi3/fb.rs b/kernel/src/arch/aarch64/board/raspi3/fb.rs index 00ff2da..ef3b187 100644 --- a/kernel/src/arch/aarch64/board/raspi3/fb.rs +++ b/kernel/src/arch/aarch64/board/raspi3/fb.rs @@ -143,9 +143,11 @@ impl Framebuffer { ))?; } + use crate::arch::memory; let paddr = info.bus_addr & !0xC0000000; + let vaddr = memory::ioremap(paddr as usize, info.screen_size as usize, "fb") as u32; Ok(Framebuffer { - buf: ColorBuffer::new(color_format, paddr, info.screen_size), + buf: ColorBuffer::new(color_format, vaddr, info.screen_size), color_format, fb_info: info, }) diff --git a/kernel/src/arch/aarch64/memory.rs b/kernel/src/arch/aarch64/memory.rs index 6a5996f..00ff312 100644 --- a/kernel/src/arch/aarch64/memory.rs +++ b/kernel/src/arch/aarch64/memory.rs @@ -1,11 +1,13 @@ //! Memory initialization for aarch64. +use crate::memory::{init_heap, MemoryArea, MemoryAttr, MemorySet, FRAME_ALLOCATOR}; +use aarch64::paging::{memory_attribute::*, PhysFrame as Frame}; +use aarch64::{addr::*, barrier, regs::*}; +use atags::atags::Atags; +use lazy_static::lazy_static; use log::*; +use spin::Mutex; use ucore_memory::PAGE_SIZE; -use atags::atags::Atags; -use aarch64::{barrier, regs::*, addr::*}; -use aarch64::paging::{PhysFrame as Frame, memory_attribute::*}; -use crate::memory::{FRAME_ALLOCATOR, init_heap, MemoryArea, MemoryAttr, MemorySet}; /// Memory initialization. pub fn init() { @@ -62,19 +64,19 @@ pub fn init_mmu_early() { // Switch the MMU on. // // First, force all previous changes to be seen before the MMU is enabled. - unsafe { barrier::isb(barrier::SY); } + unsafe { barrier::isb(barrier::SY) } // Enable the MMU and turn on data and instruction caching. SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable); // Force MMU init to complete before next instruction - unsafe { barrier::isb(barrier::SY); } + unsafe { barrier::isb(barrier::SY) } } fn init_frame_allocator() { + use crate::consts::MEMORY_OFFSET; use bit_allocator::BitAlloc; use core::ops::Range; - use crate::consts::MEMORY_OFFSET; let (start, end) = memory_map().expect("failed to find memory map"); let mut ba = FRAME_ALLOCATOR.lock(); @@ -82,14 +84,14 @@ fn init_frame_allocator() { info!("FrameAllocator init end"); /* - * @param: - * start: start address - * end: end address - * @brief: - * transform the memory address to the page number - * @retval: - * the page number range from start address to end address - */ + * @param: + * start: start address + * end: end address + * @brief: + * transform the memory address to the page number + * @retval: + * the page number range from start address to end address + */ fn to_range(start: usize, end: usize) -> Range { let page_start = (start - MEMORY_OFFSET) / PAGE_SIZE; let page_end = (end - MEMORY_OFFSET - 1) / PAGE_SIZE + 1; @@ -97,9 +99,13 @@ fn init_frame_allocator() { } } +lazy_static! { + pub static ref KERNEL_MEMORY_SET: Mutex = Mutex::new(MemorySet::new_bare()); +} + /// remap kernel page table after all initialization. fn remap_the_kernel() { - let mut ms = MemorySet::new_bare(); + let mut ms = KERNEL_MEMORY_SET.lock(); ms.push(MemoryArea::new_identity(0, bootstacktop as usize, MemoryAttr::default(), "kstack")); ms.push(MemoryArea::new_identity(stext as usize, etext as usize, MemoryAttr::default().execute().readonly(), "text")); ms.push(MemoryArea::new_identity(sdata as usize, edata as usize, MemoryAttr::default(), "data")); @@ -107,13 +113,29 @@ fn remap_the_kernel() { ms.push(MemoryArea::new_identity(sbss as usize, ebss as usize, MemoryAttr::default(), "bss")); use super::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.get_page_table_mut().activate_as_kernel(); } - ::core::mem::forget(ms); + ms.push(MemoryArea::new_identity( + IO_REMAP_BASE, + IO_REMAP_END, + MemoryAttr::default().mmio(MairDevice::attr_value().value as usize), + "io_remap", + )); + + unsafe { ms.get_page_table_mut().activate_as_kernel() } info!("kernel remap end"); } +pub fn ioremap(start: usize, len: usize, name: &'static str) -> usize { + let mut ms = KERNEL_MEMORY_SET.lock(); + let area = MemoryArea::new_identity( + start, + start + len, + MemoryAttr::default().mmio(MairNormalNonCacheable::attr_value().value as usize), + name, + ); + ms.push(area); + start +} + /// Returns the (start address, end address) of the available memory on this /// system if it can be determined. If it cannot, `None` is returned. /// @@ -131,7 +153,7 @@ fn memory_map() -> Option<(usize, usize)> { None } -extern { +extern "C" { fn bootstacktop(); fn stext(); fn etext(); diff --git a/kernel/src/arch/aarch64/paging.rs b/kernel/src/arch/aarch64/paging.rs index fa0e074..cfe1770 100644 --- a/kernel/src/arch/aarch64/paging.rs +++ b/kernel/src/arch/aarch64/paging.rs @@ -162,15 +162,10 @@ impl Entry for PageEntry { 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) { - if value { - self.0.modify_attr(MairDevice::attr_value()) - } else { - self.0.modify_attr(MairNormal::attr_value()) - } + fn mmio(&self) -> usize { self.0.attr().value as usize } + fn set_mmio(&mut self, value: usize) { + use aarch64::paging::{PageTableAttribute, MEMORY_ATTR_MASK}; + self.0.modify_attr(PageTableAttribute::new(MEMORY_ATTR_MASK, 0, value as u64)) } }