feat: add lower kernel identity-mapping
This commit is contained in:
parent
455f6deec3
commit
70490c9aa8
135
Cargo.lock
generated
135
Cargo.lock
generated
@ -2,6 +2,12 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@ -17,10 +23,38 @@ dependencies = [
|
||||
"tock-registers",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "endian-type-rs"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6419a5c75e40011b9fe0174db3fe24006ab122fbe1b7e9cc5974b338a755c76"
|
||||
|
||||
[[package]]
|
||||
name = "error"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||
|
||||
[[package]]
|
||||
name = "fdt-rs"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99a40cabc11c8258822a593f5c51f2d9f4923e715ca9e2a0630cf77ae15f390b"
|
||||
dependencies = [
|
||||
"endian-type-rs",
|
||||
"fallible-iterator",
|
||||
"memoffset",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"rustc_version",
|
||||
"static_assertions",
|
||||
"unsafe_unwrap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel"
|
||||
version = "0.1.0"
|
||||
@ -28,15 +62,116 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"cortex-a",
|
||||
"error",
|
||||
"fdt-rs",
|
||||
"tock-registers",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "osdev5"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tock-registers"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ee8fba06c1f4d0b396ef61a54530bb6b28f0dc61c38bc8bc5a5a48161e6282e"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe_unwrap"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1230ec65f13e0f9b28d789da20d2d419511893ea9dac2c1f4ef67b8b14e5da80"
|
||||
|
@ -22,6 +22,11 @@ SECTIONS {
|
||||
*(.data*)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
.tables : AT(. - KERNEL_OFFSET) {
|
||||
*(.tables)
|
||||
}
|
||||
|
||||
. = ALIGN(4K);
|
||||
.bss : AT(. - KERNEL_OFFSET) {
|
||||
PROVIDE(__bss_start = .);
|
||||
|
@ -13,6 +13,7 @@ test = false
|
||||
cfg-if = "1.x.x"
|
||||
error = { path = "../error" }
|
||||
tock-registers = "0.7.x"
|
||||
fdt-rs = { version = "0.x.x", default-features = false }
|
||||
|
||||
[target.'cfg(target_arch = "aarch64")'.dependencies]
|
||||
cortex-a = { version = "6.x.x" }
|
||||
|
@ -8,6 +8,9 @@
|
||||
.section .text._entry
|
||||
.global _entry
|
||||
_entry:
|
||||
// Preserve FDT base address
|
||||
mov x8, x0
|
||||
|
||||
mrs x1, mpidr_el1
|
||||
and x1, x1, #3
|
||||
beq 2f
|
||||
@ -30,6 +33,7 @@ _entry:
|
||||
ADR_REL x0, bsp_stack_top
|
||||
mov sp, x0
|
||||
|
||||
mov x0, x8
|
||||
b __aa64_bsp_main
|
||||
|
||||
.section .bss
|
||||
|
@ -1,13 +1,14 @@
|
||||
//! aarch64 common boot logic
|
||||
|
||||
use crate::arch::{aarch64::asm::CPACR_EL1, machine};
|
||||
use crate::dev::Device;
|
||||
use crate::dev::{Device, fdt::DeviceTree};
|
||||
use crate::mem::virt;
|
||||
use cortex_a::asm::barrier::{self, dsb, isb};
|
||||
use cortex_a::registers::{DAIF, SCTLR_EL1, VBAR_EL1};
|
||||
use tock_registers::interfaces::{ReadWriteable, Writeable};
|
||||
|
||||
#[no_mangle]
|
||||
fn __aa64_bsp_main() {
|
||||
fn __aa64_bsp_main(fdt_base: usize) {
|
||||
// Disable FP instruction trapping
|
||||
CPACR_EL1.modify(CPACR_EL1::FPEN::TrapNone);
|
||||
|
||||
@ -28,7 +29,14 @@ fn __aa64_bsp_main() {
|
||||
isb(barrier::SY);
|
||||
}
|
||||
|
||||
// Enable MMU
|
||||
virt::enable().expect("Failed to initialize virtual memory");
|
||||
|
||||
machine::init_board().unwrap();
|
||||
|
||||
let fdt = DeviceTree::from_phys(fdt_base).expect("Failed to obtain a device tree");
|
||||
fdt.dump();
|
||||
|
||||
unsafe {
|
||||
machine::local_timer().enable().unwrap();
|
||||
}
|
||||
|
88
kernel/src/dev/fdt.rs
Normal file
88
kernel/src/dev/fdt.rs
Normal file
@ -0,0 +1,88 @@
|
||||
use error::Errno;
|
||||
use fdt_rs::prelude::*;
|
||||
use fdt_rs::{
|
||||
base::DevTree,
|
||||
index::{DevTreeIndex, DevTreeIndexNode},
|
||||
};
|
||||
|
||||
#[repr(align(16))]
|
||||
struct Wrap {
|
||||
data: [u8; 16384],
|
||||
}
|
||||
|
||||
static mut INDEX_BUFFER: Wrap = Wrap { data: [0; 16384] };
|
||||
|
||||
type INode<'a> = DevTreeIndexNode<'a, 'a, 'a>;
|
||||
|
||||
pub struct DeviceTree {
|
||||
tree: DevTree<'static>,
|
||||
index: DevTreeIndex<'static, 'static>,
|
||||
}
|
||||
|
||||
fn tab(depth: usize) {
|
||||
for _ in 0..depth {
|
||||
debug!("\t");
|
||||
}
|
||||
}
|
||||
|
||||
fn dump_node(node: &INode, depth: usize) {
|
||||
if node.name().unwrap().starts_with("virtio_mmio@") {
|
||||
return;
|
||||
}
|
||||
|
||||
tab(depth);
|
||||
debugln!("{:?} {{", node.name().unwrap());
|
||||
|
||||
for prop in node.props() {
|
||||
tab(depth + 1);
|
||||
let name = prop.name().unwrap();
|
||||
debug!("{:?} = ", name);
|
||||
|
||||
match name {
|
||||
"compatible" => debug!("{:?}", prop.str().unwrap()),
|
||||
"#address-cells" | "#size-cells" => debug!("{}", prop.u32(0).unwrap()),
|
||||
"reg" => {
|
||||
debug!("<");
|
||||
let len = prop.length() / 4;
|
||||
for i in 0..len {
|
||||
debug!("{:#010x}", prop.u32(i).unwrap());
|
||||
if i < len - 1 {
|
||||
debug!(", ");
|
||||
}
|
||||
}
|
||||
debug!(">");
|
||||
},
|
||||
_ => debug!("..."),
|
||||
}
|
||||
debugln!(";");
|
||||
}
|
||||
|
||||
if node.children().next().is_some() {
|
||||
debugln!("");
|
||||
}
|
||||
|
||||
for child in node.children() {
|
||||
dump_node(&child, depth + 1);
|
||||
}
|
||||
|
||||
tab(depth);
|
||||
debugln!("}}");
|
||||
}
|
||||
|
||||
impl DeviceTree {
|
||||
pub fn dump(&self) {
|
||||
dump_node(&self.index.root(), 0);
|
||||
}
|
||||
|
||||
pub fn from_phys(base: usize) -> Result<DeviceTree, Errno> {
|
||||
// TODO virtualize address
|
||||
let tree = unsafe { DevTree::from_raw_pointer(base as *const _) }.unwrap();
|
||||
let layout = DevTreeIndex::get_layout(&tree).unwrap();
|
||||
let index = DevTreeIndex::new(tree, unsafe {
|
||||
&mut INDEX_BUFFER.data[0..layout.size() + layout.align()]
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Ok(DeviceTree { tree, index })
|
||||
}
|
||||
}
|
@ -3,6 +3,8 @@
|
||||
use error::Errno;
|
||||
|
||||
// Device classes
|
||||
#[allow(missing_docs)]
|
||||
pub mod fdt;
|
||||
pub mod gpio;
|
||||
pub mod irq;
|
||||
pub mod pci;
|
||||
|
@ -1,5 +1,7 @@
|
||||
//! Memory management and functions module
|
||||
|
||||
pub mod virt;
|
||||
|
||||
/// See memcpy(3p).
|
||||
///
|
||||
/// # Safety
|
||||
|
69
kernel/src/mem/virt/mod.rs
Normal file
69
kernel/src/mem/virt/mod.rs
Normal file
@ -0,0 +1,69 @@
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use cortex_a::asm::barrier::{self, dsb, isb};
|
||||
use cortex_a::registers::{ID_AA64MMFR0_EL1, MAIR_EL1, SCTLR_EL1, TCR_EL1, TTBR0_EL1, TTBR1_EL1};
|
||||
use error::Errno;
|
||||
use tock_registers::interfaces::{ReadWriteable, Readable, Writeable};
|
||||
|
||||
const PTE_BLOCK_AF: u64 = 1 << 10;
|
||||
const PTE_BLOCK_ISH: u64 = 3 << 8;
|
||||
const PTE_BLOCK_OSH: u64 = 2 << 8;
|
||||
const PTE_PRESENT: u64 = 1 << 0;
|
||||
|
||||
#[no_mangle]
|
||||
static mut KERNEL_TTBR0: [u64; 512] = {
|
||||
let mut table = [0; 512];
|
||||
// TODO fine-grained mapping
|
||||
table[0] = (0 << 30) | PTE_BLOCK_AF | PTE_BLOCK_ISH | PTE_PRESENT;
|
||||
table[1] = (1 << 30) | PTE_BLOCK_AF | PTE_BLOCK_ISH | PTE_PRESENT;
|
||||
|
||||
table
|
||||
};
|
||||
|
||||
pub struct DeviceMemory {
|
||||
base: usize,
|
||||
count: usize,
|
||||
}
|
||||
|
||||
impl DeviceMemory {
|
||||
pub fn map(phys: usize, count: usize) -> Result<Self, Errno> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DeviceMemory {
|
||||
fn drop(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enable() -> Result<(), Errno> {
|
||||
MAIR_EL1.write(
|
||||
MAIR_EL1::Attr0_Normal_Outer::NonCacheable + MAIR_EL1::Attr0_Normal_Inner::NonCacheable,
|
||||
);
|
||||
TTBR0_EL1.set(unsafe { &mut KERNEL_TTBR0 as *mut _ as u64 });
|
||||
|
||||
if ID_AA64MMFR0_EL1.matches_all(ID_AA64MMFR0_EL1::TGran4::NotSupported) {
|
||||
return Err(Errno::InvalidArgument);
|
||||
}
|
||||
let parange = ID_AA64MMFR0_EL1.read(ID_AA64MMFR0_EL1::PARange);
|
||||
|
||||
unsafe {
|
||||
dsb(barrier::ISH);
|
||||
isb(barrier::SY);
|
||||
}
|
||||
|
||||
TCR_EL1.write(
|
||||
TCR_EL1::IPS.val(parange)
|
||||
+ TCR_EL1::T0SZ.val(25)
|
||||
+ TCR_EL1::TG0::KiB_4
|
||||
+ TCR_EL1::SH0::Outer
|
||||
+ TCR_EL1::IRGN0::NonCacheable
|
||||
+ TCR_EL1::ORGN0::NonCacheable
|
||||
+ TCR_EL1::EPD1::SET
|
||||
);
|
||||
|
||||
SCTLR_EL1.modify(SCTLR_EL1::M::SET);
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user