From 174e0da3b6d41db589e5606253582d351c5b848b Mon Sep 17 00:00:00 2001 From: equation314 Date: Fri, 26 Oct 2018 11:21:43 +0800 Subject: [PATCH] aarch64: basic framework --- kernel/src/arch/aarch64/board/raspi3/mod.rs | 5 + kernel/src/arch/aarch64/context.rs | 62 ++++++ kernel/src/arch/aarch64/interrupt.rs | 42 +++++ kernel/src/arch/aarch64/io.rs | 13 ++ kernel/src/arch/aarch64/memory.rs | 8 + kernel/src/arch/aarch64/mod.rs | 34 ++++ kernel/src/arch/aarch64/paging.rs | 199 ++++++++++++++++++++ kernel/src/consts.rs | 19 +- kernel/src/fs.rs | 6 + kernel/src/lib.rs | 4 + kernel/src/memory.rs | 4 + 11 files changed, 395 insertions(+), 1 deletion(-) create mode 100644 kernel/src/arch/aarch64/board/raspi3/mod.rs create mode 100644 kernel/src/arch/aarch64/context.rs create mode 100644 kernel/src/arch/aarch64/interrupt.rs create mode 100644 kernel/src/arch/aarch64/io.rs create mode 100644 kernel/src/arch/aarch64/memory.rs create mode 100644 kernel/src/arch/aarch64/mod.rs create mode 100644 kernel/src/arch/aarch64/paging.rs diff --git a/kernel/src/arch/aarch64/board/raspi3/mod.rs b/kernel/src/arch/aarch64/board/raspi3/mod.rs new file mode 100644 index 0000000..db63357 --- /dev/null +++ b/kernel/src/arch/aarch64/board/raspi3/mod.rs @@ -0,0 +1,5 @@ +//! Raspberry PI 3 Model B/B+ + +pub fn init() { + // TODO +} diff --git a/kernel/src/arch/aarch64/context.rs b/kernel/src/arch/aarch64/context.rs new file mode 100644 index 0000000..4ca8b56 --- /dev/null +++ b/kernel/src/arch/aarch64/context.rs @@ -0,0 +1,62 @@ +//! Trapframe and context definitions for aarch64. + +/// TODO +#[repr(C)] +#[derive(Debug)] +pub struct TrapFrame { + // TODO +} + +///TODO +#[derive(Debug)] +pub struct Context { + // TODO +} + +impl Context { + /// TODO + #[inline(never)] + pub unsafe extern fn switch(&mut self, target: &mut Self) { + unimplemented!() + } + + /// TODO + pub unsafe fn null() -> Self { + unimplemented!() + } + + /// TODO + pub unsafe fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, kstack_top: usize, cr3: usize) -> Self { + unimplemented!() + } + + /// TODO + pub unsafe fn new_user_thread(entry_addr: usize, ustack_top: usize, kstack_top: usize, is32: bool, cr3: usize) -> Self { + unimplemented!() + } + + /// TODO + pub unsafe fn new_fork(tf: &TrapFrame, kstack_top: usize, cr3: usize) -> Self { + unimplemented!() + } +} + +#[inline(always)] +pub unsafe fn enable() { + unimplemented!() +} + +#[inline(always)] +pub unsafe fn disable() { + unimplemented!() +} + +#[inline(always)] +pub unsafe fn disable_and_store() -> usize { + unimplemented!() +} + +#[inline(always)] +pub unsafe fn restore(flags: usize) { + unimplemented!() +} diff --git a/kernel/src/arch/aarch64/interrupt.rs b/kernel/src/arch/aarch64/interrupt.rs new file mode 100644 index 0000000..1566afd --- /dev/null +++ b/kernel/src/arch/aarch64/interrupt.rs @@ -0,0 +1,42 @@ +//! Interrupt handler implementation on raspi3. + +pub use self::context::*; + +#[path = "context.rs"] +mod context; + +/// Initialize the trap to enable the interrupt. +pub fn init() { + // TODO + // info!("interrupt: init end"); +} + +/// Enable the interrupt. +#[inline(always)] +pub unsafe fn enable() { + // TODO +} + +/// Disable the interrupt. +#[inline(always)] +pub unsafe fn disable() { + // TODO +} + +/// Disable the interrupt and store the status. +/// +/// return: status(usize) +#[inline(always)] +pub unsafe fn disable_and_store() -> usize { + // TODO + 0 +} + +/// Use the original status to restore the process +/// +/// Arguments: +/// * flags: original status(usize) +#[inline(always)] +pub unsafe fn restore(flags: usize) { + // TODO +} diff --git a/kernel/src/arch/aarch64/io.rs b/kernel/src/arch/aarch64/io.rs new file mode 100644 index 0000000..70f4035 --- /dev/null +++ b/kernel/src/arch/aarch64/io.rs @@ -0,0 +1,13 @@ +//! Serial driver for aarch64. + +use core::fmt::{Arguments}; + +/// TODO +pub fn getchar() -> char { + unimplemented!() +} + +/// TODO +pub fn putfmt(fmt: Arguments<'_>) { + unimplemented!() +} diff --git a/kernel/src/arch/aarch64/memory.rs b/kernel/src/arch/aarch64/memory.rs new file mode 100644 index 0000000..05fff9d --- /dev/null +++ b/kernel/src/arch/aarch64/memory.rs @@ -0,0 +1,8 @@ +//! Memory initialization for aarch64. + +use ucore_memory::PAGE_SIZE; + +/// Memory initialization. +pub fn init() { + // TODO +} diff --git a/kernel/src/arch/aarch64/mod.rs b/kernel/src/arch/aarch64/mod.rs new file mode 100644 index 0000000..c19cd97 --- /dev/null +++ b/kernel/src/arch/aarch64/mod.rs @@ -0,0 +1,34 @@ +//! Entrance and initialization for aarch64. + +pub mod io; +pub mod paging; +pub mod memory; +pub mod interrupt; + +#[cfg(feature = "board_raspi3")] +#[path = "board/raspi3/mod.rs"] +pub mod board; + +/// TODO +/// The entry point of kernel +#[no_mangle] // don't mangle the name of this function +pub extern fn rust_main() -> ! { + println!("Hello ARM64!"); + + // First init log mod, so that we can print log info. + // ::logging::init(); + // Init trap handling. + // interrupt::init(); + // Init physical memory management and heap. + // memory::init(); + // Now heap is available + // timer::init(); + + // Init board. + board::init(); + ::kmain(); +} + +// global_asm!(include_str!("boot/boot.asm")); +// global_asm!(include_str!("boot/entry.asm")); +// global_asm!(include_str!("boot/trap.asm")); diff --git a/kernel/src/arch/aarch64/paging.rs b/kernel/src/arch/aarch64/paging.rs new file mode 100644 index 0000000..6c21839 --- /dev/null +++ b/kernel/src/arch/aarch64/paging.rs @@ -0,0 +1,199 @@ +//! Page table implementations for aarch64. + +use ucore_memory::memory_set::*; +use ucore_memory::paging::*; + +type VirtAddr = usize; +type PhysAddr = usize; + +/// TODO +pub struct ActivePageTable { + // TODO +} + +impl ActivePageTable { + /// TODO + pub unsafe fn new() -> Self { + unimplemented!() + } +} + +impl PageTable for ActivePageTable { + type Entry = PageEntry; + + fn map(&mut self, addr: VirtAddr, target: PhysAddr) -> &mut Self::Entry { + unimplemented!() + } + fn unmap(&mut self, addr: VirtAddr) { + unimplemented!() + } + + fn get_entry(&mut self, addr: VirtAddr) -> &mut Self::Entry { + unimplemented!() + } + + // For testing with mock + fn get_page_slice_mut<'a,'b>(&'a mut self, addr: VirtAddr) -> &'b mut [u8] { + unimplemented!() + } + + fn read(&mut self, addr: VirtAddr) -> u8 { + unimplemented!() + } + + fn write(&mut self, addr: VirtAddr, data: u8) { + unimplemented!() + } +} + +/// TODO +pub struct PageEntry { + // TODO +} + +impl Entry for PageEntry { + /// IMPORTANT! + /// This must be called after any change to ensure it become effective. + /// Usually this will make a flush to TLB/MMU. + fn update(&mut self) { + unimplemented!() + } + + /// Will be set when accessed + fn accessed(&self) -> bool { + unimplemented!() + } + + /// Will be set when written + fn dirty(&self) -> bool { + unimplemented!() + } + + /// Will PageFault when try to write page where writable=0 + fn writable(&self) -> bool { + unimplemented!() + } + + /// Will PageFault when try to access page where present=0 + fn present(&self) -> bool { + unimplemented!() + } + + + fn clear_accessed(&mut self) { + unimplemented!() + } + + fn clear_dirty(&mut self) { + unimplemented!() + } + + fn set_writable(&mut self, value: bool) { + unimplemented!() + } + + fn set_present(&mut self, value: bool) { + unimplemented!() + } + + + fn target(&self) -> PhysAddr { + unimplemented!() + } + + fn set_target(&mut self, target: PhysAddr) { + unimplemented!() + } + + + // For Copy-on-write extension + fn writable_shared(&self) -> bool { + unimplemented!() + } + + fn readonly_shared(&self) -> bool { + unimplemented!() + } + + fn set_shared(&mut self, writable: bool) { + unimplemented!() + } + + fn clear_shared(&mut self) { + unimplemented!() + } + + + // For Swap extension + fn swapped(&self) -> bool { + unimplemented!() + } + + fn set_swapped(&mut self, value: bool) { + unimplemented!() + } + + + fn user(&self) -> bool { + unimplemented!() + } + + fn set_user(&mut self, value: bool) { + unimplemented!() + } + + fn execute(&self) -> bool { + unimplemented!() + } + + fn set_execute(&mut self, value: bool) { + unimplemented!() + } + +} + +/// TODO +pub struct InactivePageTable0 { + // TODO +} + +/// TODO +impl InactivePageTable for InactivePageTable0 { + type Active = ActivePageTable; + + fn new() -> Self { + unimplemented!() + } + + fn new_bare() -> Self { + unimplemented!() + } + + fn edit(&mut self, f: impl FnOnce(&mut Self::Active)) { + unimplemented!() + } + + unsafe fn activate(&self) { + unimplemented!() + } + + unsafe fn with(&self, f: impl FnOnce()) { + unimplemented!() + } + + fn token(&self) -> usize { + unimplemented!() + } + + fn alloc_frame() -> Option { + unimplemented!() + } + + fn dealloc_frame(target: PhysAddr) { + unimplemented!() + } + + fn alloc_stack() -> Stack { + unimplemented!() + } +} diff --git a/kernel/src/consts.rs b/kernel/src/consts.rs index 4dddae0..b2cdefe 100644 --- a/kernel/src/consts.rs +++ b/kernel/src/consts.rs @@ -4,6 +4,8 @@ pub use self::riscv::*; #[cfg(target_arch = "x86_64")] pub use self::x86_64::*; +#[cfg(target_arch = "aarch64")] +pub use self::aarch64::*; pub const MAX_CPU_NUM: usize = 8; pub const MAX_PROCESS_NUM: usize = 48; @@ -125,4 +127,19 @@ mod x86_64 { /// Offset for usage in other temporary pages pub const USER_TMP_MISC_OFFSET: usize = USER_TMP_TLS_OFFSET + PML4_SIZE; pub const USER_TMP_MISC_PML4: usize = (USER_TMP_MISC_OFFSET & PML4_MASK) / PML4_SIZE; -} \ No newline at end of file +} + +#[cfg(target_arch = "aarch64")] +mod aarch64 { + //! TODO: replace unmiplemented consts with real value + const UNIMPLEMENTED: usize = 0; + pub const KERNEL_OFFSET: usize = UNIMPLEMENTED; + pub const KERNEL_PML4: usize = UNIMPLEMENTED; + pub const KERNEL_HEAP_OFFSET: usize = UNIMPLEMENTED; + pub const KERNEL_HEAP_SIZE: usize = 8 * 1024 * 1024; + pub const MEMORY_OFFSET: usize = UNIMPLEMENTED; + pub const MEMORY_END: usize = UNIMPLEMENTED; + pub const USER_STACK_OFFSET: usize = UNIMPLEMENTED; + pub const USER_STACK_SIZE: usize = UNIMPLEMENTED; + pub const USER32_STACK_OFFSET: usize = UNIMPLEMENTED; +} diff --git a/kernel/src/fs.rs b/kernel/src/fs.rs index fe20c6c..4dcaa14 100644 --- a/kernel/src/fs.rs +++ b/kernel/src/fs.rs @@ -23,8 +23,14 @@ pub fn shell() { } Box::new(unsafe { MemBuf::new(_binary_user_riscv_img_start, _binary_user_riscv_img_end) }) }; + #[cfg(target_arch = "x86_64")] let device = Box::new(&ide::DISK1); + + #[cfg(target_arch = "aarch64")] + // TODO + let device: Box = unimplemented!(); + let sfs = SimpleFileSystem::open(device).expect("failed to open SFS"); let root = sfs.root_inode(); let files = root.borrow().list().unwrap(); diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 4a23294..8305a77 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -60,6 +60,10 @@ pub mod arch; #[path = "arch/riscv32/mod.rs"] pub mod arch; +#[cfg(target_arch = "aarch64")] +#[path = "arch/aarch64/mod.rs"] +pub mod arch; + pub fn kmain() -> ! { process::init(); unsafe { arch::interrupt::enable(); } diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index 0f203f3..bbe78db 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -17,6 +17,10 @@ pub type FrameAlloc = BitAlloc64K; #[cfg(target_arch = "riscv32")] pub type FrameAlloc = BitAlloc4K; +// Raspberry Pi 3 has 1G memory +#[cfg(target_arch = "aarch64")] +pub type FrameAlloc = BitAlloc64K; + lazy_static! { pub static ref FRAME_ALLOCATOR: Mutex = Mutex::new(FrameAlloc::default()); }