diff --git a/crate/process/src/interrupt.rs b/crate/process/src/interrupt.rs index f75102e..e0f2283 100644 --- a/crate/process/src/interrupt.rs +++ b/crate/process/src/interrupt.rs @@ -26,4 +26,19 @@ pub unsafe fn restore(flags: usize) { #[cfg(target_arch = "riscv32")] pub unsafe fn restore(flags: usize) { asm!("csrs 0x100, $0" :: "r"(flags)); -} \ No newline at end of file +} + +#[inline(always)] +#[cfg(target_arch = "aarch64")] +pub unsafe fn disable_and_store() -> usize { + let daif: u32; + asm!("mrs $0, DAIF": "=r"(daif) ::: "volatile"); + asm!("msr daifset, #2"); + daif as usize +} + +#[inline(always)] +#[cfg(target_arch = "aarch64")] +pub unsafe fn restore(flags: usize) { + asm!("msr DAIF, $0" :: "r"(flags as u32) :: "volatile"); +} diff --git a/kernel/Makefile b/kernel/Makefile index 6a26d8c..0e1a2e8 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -4,7 +4,7 @@ # make justrun Run the last build # make doc Generate docs # make asm Open the deassemble file of the last build -# make elf-h Open 'objdump -h' of the last build +# make header Open 'objdump -h' of the last build # make clean Clean # # Options: @@ -18,7 +18,6 @@ arch ?= riscv32 board ?= raspi3 -prefix ?= $(arch)-none-elf mode ?= debug LOG ?= debug smp ?= 4 @@ -83,12 +82,22 @@ endif ### prefix ### -ld := $(prefix)-ld -objdump := $(prefix)-objdump -objcopy := $(prefix)-objcopy -cc := $(prefix)-gcc -as := $(prefix)-as -gdb := $(prefix)-gdb +ifeq ($(arch), x86_64) +ifeq ($(uname), Darwin) +prefix := x86_64-elf- +endif +else ifeq ($(arch), riscv32) +prefix := riscv64-unknown-elf- +else ifeq ($(arch), aarch64) +prefix ?= aarch64-none-elf- +endif + +ld := $(prefix)ld +objdump := $(prefix)objdump +objcopy := $(prefix)objcopy +cc := $(prefix)gcc +as := $(prefix)as +gdb := $(prefix)gdb .PHONY: all clean run build asm doc justrun kernel @@ -144,7 +153,7 @@ else cp bbl ../../kernel/$@ endif else ifeq ($(arch), aarch64) - $(objcopy) $(kernel) --strip-all -O binary $@ + @$(objcopy) $(kernel) --strip-all -O binary $@ endif kernel: diff --git a/kernel/src/arch/aarch64/board/raspi3/irq.rs b/kernel/src/arch/aarch64/board/raspi3/irq.rs index e01a2c3..c78b651 100644 --- a/kernel/src/arch/aarch64/board/raspi3/irq.rs +++ b/kernel/src/arch/aarch64/board/raspi3/irq.rs @@ -1,11 +1,11 @@ -use arch::interrupt::TrapFrame; -use super::bcm2837::timer::Timer; -use super::bcm2837::interrupt::{Controller, Interrupt}; +use crate::arch::interrupt::TrapFrame; +use bcm2837::timer::Timer; +use bcm2837::interrupt::{Controller, Interrupt}; pub fn handle_irq(tf: &mut TrapFrame) { let controller = Timer::new(); if controller.is_pending() { super::timer::set_next(); - ::trap::timer(); + crate::trap::timer(); } } diff --git a/kernel/src/arch/aarch64/board/raspi3/mod.rs b/kernel/src/arch/aarch64/board/raspi3/mod.rs index 2b32a10..4276dd9 100644 --- a/kernel/src/arch/aarch64/board/raspi3/mod.rs +++ b/kernel/src/arch/aarch64/board/raspi3/mod.rs @@ -1,7 +1,5 @@ //! Raspberry PI 3 Model B/B+ -extern crate bcm2837; - pub mod irq; pub mod timer; pub mod serial; diff --git a/kernel/src/arch/aarch64/board/raspi3/serial.rs b/kernel/src/arch/aarch64/board/raspi3/serial.rs index 5434071..5170195 100644 --- a/kernel/src/arch/aarch64/board/raspi3/serial.rs +++ b/kernel/src/arch/aarch64/board/raspi3/serial.rs @@ -1,5 +1,4 @@ -use super::bcm2837::mini_uart::MiniUart; - +use bcm2837::mini_uart::MiniUart; use core::fmt; use spin::Mutex; diff --git a/kernel/src/arch/aarch64/board/raspi3/timer.rs b/kernel/src/arch/aarch64/board/raspi3/timer.rs index 4cc0be0..9a51d31 100644 --- a/kernel/src/arch/aarch64/board/raspi3/timer.rs +++ b/kernel/src/arch/aarch64/board/raspi3/timer.rs @@ -1,5 +1,6 @@ -use super::bcm2837::timer; -use super::bcm2837::interrupt::{Controller, Interrupt}; +use bcm2837::timer; +use bcm2837::interrupt::{Controller, Interrupt}; +use log::*; pub fn init() { timer::init(); diff --git a/kernel/src/arch/aarch64/cpu.rs b/kernel/src/arch/aarch64/cpu.rs new file mode 100644 index 0000000..8dd916f --- /dev/null +++ b/kernel/src/arch/aarch64/cpu.rs @@ -0,0 +1,8 @@ +pub fn halt() { + unsafe { asm!("wfi" :::: "volatile") } +} + +pub fn id() -> usize { + // TODO: cpu id + 0 +} \ No newline at end of file diff --git a/kernel/src/arch/aarch64/interrupt/context.rs b/kernel/src/arch/aarch64/interrupt/context.rs index df2b5b3..e494453 100644 --- a/kernel/src/arch/aarch64/interrupt/context.rs +++ b/kernel/src/arch/aarch64/interrupt/context.rs @@ -148,4 +148,10 @@ impl Context { }, }.push_at(kstack_top) } + /// Called at a new user context + /// To get the init TrapFrame in sys_exec + pub unsafe fn get_init_tf(&self) -> TrapFrame { + (*(self.0 as *const InitStack)).tf.clone() + } + } diff --git a/kernel/src/arch/aarch64/interrupt/handler.rs b/kernel/src/arch/aarch64/interrupt/handler.rs index 85d1faf..e4a768c 100644 --- a/kernel/src/arch/aarch64/interrupt/handler.rs +++ b/kernel/src/arch/aarch64/interrupt/handler.rs @@ -1,8 +1,9 @@ //! Trap handler -use arch::board::irq::handle_irq; +use crate::arch::board::irq::handle_irq; use super::context::TrapFrame; use super::syndrome::Syndrome; +use log::*; global_asm!(include_str!("trap.S")); global_asm!(include_str!("vector.S")); @@ -46,13 +47,12 @@ pub extern "C" fn rust_trap(info: Info, esr: u32, tf: &mut TrapFrame) { match syndrome { Syndrome::Brk(brk) => handle_break(brk, tf), Syndrome::Svc(_) => handle_syscall(tf), - _ => ::trap::error(tf), + _ => crate::trap::error(tf), } } Kind::Irq => handle_irq(tf), - _ => ::trap::error(tf), + _ => crate::trap::error(tf), } - ::trap::before_return(); trace!("Interrupt end"); } @@ -63,7 +63,7 @@ fn handle_break(num: u16, tf: &mut TrapFrame) { fn handle_syscall(tf: &mut TrapFrame) { // svc instruction has been skipped in syscall (ref: J1.1.2, page 6152) - let ret = ::syscall::syscall( + let ret = crate::syscall::syscall( tf.x1to29[7] as usize, [ tf.x0, diff --git a/kernel/src/arch/aarch64/interrupt/mod.rs b/kernel/src/arch/aarch64/interrupt/mod.rs index 140e9b8..606654a 100644 --- a/kernel/src/arch/aarch64/interrupt/mod.rs +++ b/kernel/src/arch/aarch64/interrupt/mod.rs @@ -4,7 +4,7 @@ mod handler; mod context; mod syndrome; -use super::cortex_a::regs::*; +use cortex_a::regs::*; pub use self::context::*; pub use self::handler::*; diff --git a/kernel/src/arch/aarch64/memory.rs b/kernel/src/arch/aarch64/memory.rs index bf55354..edc1d5b 100644 --- a/kernel/src/arch/aarch64/memory.rs +++ b/kernel/src/arch/aarch64/memory.rs @@ -1,8 +1,9 @@ //! Memory initialization for aarch64. use ucore_memory::PAGE_SIZE; -use super::atags::atags::Atags; -use super::super::HEAP_ALLOCATOR; +use atags::atags::Atags; +use crate::HEAP_ALLOCATOR; +use log::*; /// Memory initialization. pub fn init() { diff --git a/kernel/src/arch/aarch64/mod.rs b/kernel/src/arch/aarch64/mod.rs index 58aa784..de86725 100644 --- a/kernel/src/arch/aarch64/mod.rs +++ b/kernel/src/arch/aarch64/mod.rs @@ -1,13 +1,11 @@ //! Entrance and initialization for aarch64. -extern crate atags; -extern crate cortex_a; - pub mod io; pub mod paging; pub mod memory; pub mod interrupt; pub mod consts; +pub mod cpu; #[cfg(feature = "board_raspi3")] #[path = "board/raspi3/mod.rs"] @@ -15,16 +13,87 @@ pub mod board; pub use self::board::timer; +global_asm!(include_str!("boot/boot.S")); + /// The entry point of kernel #[no_mangle] // don't mangle the name of this function pub extern "C" fn rust_main() -> ! { // Init board to enable serial port. board::init(); - ::logging::init(); // FIXME + crate::logging::init(); // FIXME interrupt::init(); memory::init(); timer::init(); - ::kmain(); + + use crate::process::{processor, ContextImpl}; + crate::process::init(); + processor().manager().add(ContextImpl::new_kernel(kernel_proc2, 2333), 0); + processor().manager().add(ContextImpl::new_user_test(kernel_proc3), 0); + + crate::kmain(); } -global_asm!(include_str!("boot/boot.S")); +extern fn kernel_proc2(arg: usize) -> ! { + use alloc::format; + test_shell(&format!("proc2-{}>> ", arg)); +} + +extern fn kernel_proc3(arg: usize) -> ! { + use alloc::format; + test_shell(&format!("proc3-{}$ ", arg)); +} + +const LOGO: &str = r#" + ____ __ ____ _____ + / __ \ __ __ _____ / /_ / __ \/ ___/ + / /_/ // / / // ___// __// / / /\__ \ + / _, _// /_/ /(__ )/ /_ / /_/ /___/ / +/_/ |_| \__,_//____/ \__/ \____//____/ +"#; + +pub fn show_logo() { + println!("{}", LOGO); +} + +#[inline(always)] +fn sys_call(id: usize, arg0: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> i32 { + let ret: i32; + unsafe { + asm!("svc 0" + : "={x0}" (ret) + : "{x8}" (id), "{x0}" (arg0), "{x1}" (arg1), "{x2}" (arg2), "{x3}" (arg3), "{x4}" (arg4), "{x5}" (arg5) + : "memory" + : "volatile"); + } + ret +} + +pub fn test_shell(prefix: &str) -> ! { + show_logo(); + loop { + print!("{}", prefix); + loop { + let c = io::getchar(); + match c { + '\u{7f}' => { + print!("\u{7f}"); + } + 'c' => unsafe { + print!("sys_putc: "); + sys_call(30, 'A' as usize, 0, 0, 0, 0, 0); + }, + 't' => unsafe { + println!("sys_get_time: {}", sys_call(17, 0, 0, 0, 0, 0, 0)); + }, + ' '...'\u{7e}' => { + print!("{}", c); + } + '\n' | '\r' => { + print!("\n"); + break; + } + _ => {} + } + } + } +} diff --git a/kernel/src/arch/aarch64/paging.rs b/kernel/src/arch/aarch64/paging.rs index e9cc43e..53b9045 100644 --- a/kernel/src/arch/aarch64/paging.rs +++ b/kernel/src/arch/aarch64/paging.rs @@ -7,7 +7,7 @@ type VirtAddr = usize; type PhysAddr = usize; use alloc::alloc::{alloc, Layout}; -use memory::{active_table, alloc_frame, alloc_stack, dealloc_frame}; +use crate::memory::{active_table, alloc_frame, dealloc_frame}; /// TODO pub struct ActivePageTable { @@ -19,6 +19,10 @@ impl ActivePageTable { pub unsafe fn new() -> Self { unimplemented!() } + + pub fn token() -> usize { + unimplemented!() + } } impl PageTable for ActivePageTable { @@ -31,7 +35,7 @@ impl PageTable for ActivePageTable { unimplemented!() } - fn get_entry(&mut self, addr: VirtAddr) -> &mut Self::Entry { + fn get_entry(&mut self, addr: VirtAddr) -> Option<&mut Self::Entry> { unimplemented!() } @@ -200,7 +204,7 @@ impl InactivePageTable for InactivePageTable0 { unimplemented!() } - unsafe fn with(&self, f: impl FnOnce()) { + unsafe fn with(&self, f: impl FnOnce() -> T) -> T { unimplemented!() } @@ -215,8 +219,4 @@ impl InactivePageTable for InactivePageTable0 { fn dealloc_frame(target: PhysAddr) { dealloc_frame(target) } - - fn alloc_stack() -> Stack { - alloc_stack() - } } diff --git a/kernel/src/fs.rs b/kernel/src/fs.rs index fb3a6a8..9fea7d7 100644 --- a/kernel/src/fs.rs +++ b/kernel/src/fs.rs @@ -34,6 +34,8 @@ lazy_static! { }; #[cfg(target_arch = "x86_64")] let device = Box::new(ide::IDE::new(1)); + #[cfg(target_arch = "aarch64")] + let device = unimplemented!(); let sfs = SimpleFileSystem::open(device).expect("failed to open SFS"); sfs.root_inode() diff --git a/kernel/src/process/context.rs b/kernel/src/process/context.rs index c377f63..14b78b7 100644 --- a/kernel/src/process/context.rs +++ b/kernel/src/process/context.rs @@ -51,13 +51,18 @@ impl ContextImpl { }) } - pub fn new_user_test(entry: extern fn(usize) -> !) -> Self { - let ms = MemorySet::new(); - let user_stack = ::memory::alloc_stack(); - Context { - arch: unsafe { ArchContext::new_user_thread(entry as usize, user_stack.top - 8, ms.kstack_top(), false, ms.token()) }, - memory_set: ms, - } + /// Temp for aarch64 + pub fn new_user_test(entry: extern fn(usize) -> !) -> Box { + let memory_set = MemorySet::new(); + let kstack = KernelStack::new(); + let ustack = KernelStack::new(); + Box::new(ContextImpl { + arch: unsafe { ArchContext::new_user_thread(entry as usize, ustack.top(), kstack.top(), false, memory_set.token()) }, + memory_set, + kstack, + files: BTreeMap::default(), + cwd: String::new(), + }) } /// Make a new user thread from ELF data diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index 1d2147d..cb9c41e 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -9,6 +9,7 @@ use core::sync::atomic::*; use log::*; pub mod context; + pub fn init() { // NOTE: max_time_slice <= 5 to ensure 'priority' test pass let scheduler = Box::new(scheduler::RRScheduler::new(5)); @@ -26,6 +27,7 @@ pub fn init() { for i in 0..4 { manager.add(ContextImpl::new_kernel(idle, i), 0); } + #[cfg(not(target_arch = "aarch64"))] crate::shell::run_user_shell(); info!("process init end");