|
|
@ -1,11 +1,13 @@
|
|
|
|
//! Memory initialization for aarch64.
|
|
|
|
//! 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 log::*;
|
|
|
|
|
|
|
|
use spin::Mutex;
|
|
|
|
use ucore_memory::PAGE_SIZE;
|
|
|
|
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.
|
|
|
|
/// Memory initialization.
|
|
|
|
pub fn init() {
|
|
|
|
pub fn init() {
|
|
|
@ -62,19 +64,19 @@ pub fn init_mmu_early() {
|
|
|
|
// Switch the MMU on.
|
|
|
|
// Switch the MMU on.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// First, force all previous changes to be seen before the MMU is enabled.
|
|
|
|
// 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.
|
|
|
|
// 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);
|
|
|
|
SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable);
|
|
|
|
|
|
|
|
|
|
|
|
// Force MMU init to complete before next instruction
|
|
|
|
// Force MMU init to complete before next instruction
|
|
|
|
unsafe { barrier::isb(barrier::SY); }
|
|
|
|
unsafe { barrier::isb(barrier::SY) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn init_frame_allocator() {
|
|
|
|
fn init_frame_allocator() {
|
|
|
|
|
|
|
|
use crate::consts::MEMORY_OFFSET;
|
|
|
|
use bit_allocator::BitAlloc;
|
|
|
|
use bit_allocator::BitAlloc;
|
|
|
|
use core::ops::Range;
|
|
|
|
use core::ops::Range;
|
|
|
|
use crate::consts::MEMORY_OFFSET;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let (start, end) = memory_map().expect("failed to find memory map");
|
|
|
|
let (start, end) = memory_map().expect("failed to find memory map");
|
|
|
|
let mut ba = FRAME_ALLOCATOR.lock();
|
|
|
|
let mut ba = FRAME_ALLOCATOR.lock();
|
|
|
@ -82,14 +84,14 @@ fn init_frame_allocator() {
|
|
|
|
info!("FrameAllocator init end");
|
|
|
|
info!("FrameAllocator init end");
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* @param:
|
|
|
|
* @param:
|
|
|
|
* start: start address
|
|
|
|
* start: start address
|
|
|
|
* end: end address
|
|
|
|
* end: end address
|
|
|
|
* @brief:
|
|
|
|
* @brief:
|
|
|
|
* transform the memory address to the page number
|
|
|
|
* transform the memory address to the page number
|
|
|
|
* @retval:
|
|
|
|
* @retval:
|
|
|
|
* the page number range from start address to end address
|
|
|
|
* the page number range from start address to end address
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
fn to_range(start: usize, end: usize) -> Range<usize> {
|
|
|
|
fn to_range(start: usize, end: usize) -> Range<usize> {
|
|
|
|
let page_start = (start - MEMORY_OFFSET) / PAGE_SIZE;
|
|
|
|
let page_start = (start - MEMORY_OFFSET) / PAGE_SIZE;
|
|
|
|
let page_end = (end - MEMORY_OFFSET - 1) / PAGE_SIZE + 1;
|
|
|
|
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.
|
|
|
|
/// remap kernel page table after all initialization.
|
|
|
|
fn remap_the_kernel() {
|
|
|
|
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(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(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"));
|
|
|
|
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"));
|
|
|
|
ms.push(MemoryArea::new_identity(sbss as usize, ebss as usize, MemoryAttr::default(), "bss"));
|
|
|
|
|
|
|
|
|
|
|
|
use super::board::{IO_REMAP_BASE, IO_REMAP_END};
|
|
|
|
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"));
|
|
|
|
ms.push(MemoryArea::new_identity(
|
|
|
|
|
|
|
|
IO_REMAP_BASE,
|
|
|
|
unsafe { ms.get_page_table_mut().activate_as_kernel(); }
|
|
|
|
IO_REMAP_END,
|
|
|
|
::core::mem::forget(ms);
|
|
|
|
MemoryAttr::default().mmio(MairDevice::attr_value().value as usize),
|
|
|
|
|
|
|
|
"io_remap",
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsafe { ms.get_page_table_mut().activate_as_kernel() }
|
|
|
|
info!("kernel remap end");
|
|
|
|
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
|
|
|
|
/// Returns the (start address, end address) of the available memory on this
|
|
|
|
/// system if it can be determined. If it cannot, `None` is returned.
|
|
|
|
/// system if it can be determined. If it cannot, `None` is returned.
|
|
|
|
///
|
|
|
|
///
|
|
|
@ -131,7 +153,7 @@ fn memory_map() -> Option<(usize, usize)> {
|
|
|
|
None
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern {
|
|
|
|
extern "C" {
|
|
|
|
fn bootstacktop();
|
|
|
|
fn bootstacktop();
|
|
|
|
fn stext();
|
|
|
|
fn stext();
|
|
|
|
fn etext();
|
|
|
|
fn etext();
|
|
|
|