aarch64/fb: remap framebuffer base address

master
equation314 6 years ago
parent 6ba9e34f77
commit 5987c2068b

@ -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(); }
}
}

@ -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);
}

2
kernel/Cargo.lock generated

@ -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)",

@ -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,
})

@ -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<usize> {
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<MemorySet> = 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();

@ -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))
}
}

Loading…
Cancel
Save