diff --git a/kernel/src/arch/aarch64/board/raspi3/irq.rs b/kernel/src/arch/aarch64/board/raspi3/irq.rs index d7d43b2..e01a2c3 100644 --- a/kernel/src/arch/aarch64/board/raspi3/irq.rs +++ b/kernel/src/arch/aarch64/board/raspi3/irq.rs @@ -5,8 +5,7 @@ use super::bcm2837::interrupt::{Controller, Interrupt}; pub fn handle_irq(tf: &mut TrapFrame) { let controller = Timer::new(); if controller.is_pending() { - println!("Timer tick {}...", super::timer::get_cycle()); super::timer::set_next(); - // ::trap::timer(); + ::trap::timer(); } } diff --git a/kernel/src/arch/aarch64/board/raspi3/timer.rs b/kernel/src/arch/aarch64/board/raspi3/timer.rs index 2e54fb3..4cc0be0 100644 --- a/kernel/src/arch/aarch64/board/raspi3/timer.rs +++ b/kernel/src/arch/aarch64/board/raspi3/timer.rs @@ -12,6 +12,6 @@ pub fn get_cycle() -> u64 { } pub fn set_next() { - // 1000 ms - timer::tick_in(1000 * 1000); + // 10 ms + timer::tick_in(10 * 1000); } diff --git a/kernel/src/arch/aarch64/boot/boot.S b/kernel/src/arch/aarch64/boot/boot.S index 1740a20..b8a142e 100644 --- a/kernel/src/arch/aarch64/boot/boot.S +++ b/kernel/src/arch/aarch64/boot/boot.S @@ -18,6 +18,9 @@ setup: # store the desired EL1 stack pointer in x1 adr x1, _start + # use SP_ELx for Exception level ELx + msr SPsel, #1 + # read the current exception level into x0 (ref: C5.2.1) mrs x0, CurrentEL and x0, x0, #0b1100 diff --git a/kernel/src/arch/aarch64/interrupt/context.rs b/kernel/src/arch/aarch64/interrupt/context.rs index 9bc2e77..df2b5b3 100644 --- a/kernel/src/arch/aarch64/interrupt/context.rs +++ b/kernel/src/arch/aarch64/interrupt/context.rs @@ -116,6 +116,8 @@ impl Context { tlbi vmalle1is // invalidate the TLB entry for the entry that changes dsb ish // ensure TLB invalidation is complete isb // synchronize context on this processor + + str xzr, [x1] ret" : : : : "volatile" ); } diff --git a/kernel/src/arch/aarch64/interrupt/mod.rs b/kernel/src/arch/aarch64/interrupt/mod.rs index 2ced283..140e9b8 100644 --- a/kernel/src/arch/aarch64/interrupt/mod.rs +++ b/kernel/src/arch/aarch64/interrupt/mod.rs @@ -4,6 +4,7 @@ mod handler; mod context; mod syndrome; +use super::cortex_a::regs::*; pub use self::context::*; pub use self::handler::*; @@ -34,8 +35,9 @@ pub unsafe fn disable() { /// return: status(usize) #[inline(always)] pub unsafe fn disable_and_store() -> usize { - // TODO - 0 + let daif = DAIF.get() as usize; + disable(); + daif } /// Use the original status to restore the process @@ -44,5 +46,5 @@ pub unsafe fn disable_and_store() -> usize { /// * flags: original status(usize) #[inline(always)] pub unsafe fn restore(flags: usize) { - // TODO + DAIF.set(flags as u32); } diff --git a/kernel/src/arch/aarch64/mod.rs b/kernel/src/arch/aarch64/mod.rs index 8c9585d..35613ab 100644 --- a/kernel/src/arch/aarch64/mod.rs +++ b/kernel/src/arch/aarch64/mod.rs @@ -1,6 +1,7 @@ //! Entrance and initialization for aarch64. extern crate atags; +extern crate cortex_a; pub mod io; pub mod paging; @@ -13,72 +14,16 @@ pub mod board; pub use self::board::timer; -/// TODO /// 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(); - - // First init log mod, so that we can print log info. - // FIXME - ::logging::init(); - - let (start, end) = memory::memory_map().expect("failed to find memory map"); - println!("The value of start is: {:#x?}, end is {:#x?}", start, end); - + ::logging::init(); // FIXME interrupt::init(); memory::init(); timer::init(); - - //let mut v = vec![]; - //for i in 0..1000 { - // v.push(i); - // println!("{:?}", v); - //} - - ::process::init(); - - unsafe { interrupt::enable(); } - - super::fs::show_logo(); - - loop { - print!(">> "); - loop { - let c = io::getchar(); - match c { - '\u{7f}' => { - print!("\u{7f}"); - } - 'b' => unsafe { - println!("brk 233"); - asm!("brk 233"); - }, - 'c' => unsafe { - println!("sys_putc"); - asm!( - "mov x8, #30 - mov x0, #65 - svc 0" - ); - }, - 't' => unsafe { - println!("{}", timer::get_cycle()); - }, - ' '...'\u{7e}' => { - print!("{}", c); - } - '\n' | '\r' => { - print!("\n"); - break; - } - _ => {} - } - } - } - - // ::kmain(); + ::kmain(); } global_asm!(include_str!("boot/boot.S")); diff --git a/kernel/src/fs.rs b/kernel/src/fs.rs index d682236..6e4e0a3 100644 --- a/kernel/src/fs.rs +++ b/kernel/src/fs.rs @@ -26,6 +26,62 @@ 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 { + #[cfg(target_arch = "riscv32")] + asm!("ecall" + : "={x10}" (ret) + : "{x10}" (id), "{x11}" (arg0), "{x12}" (arg1), "{x13}" (arg2), "{x14}" (arg3), "{x15}" (arg4), "{x16}" (arg5) + : "memory" + : "volatile"); + #[cfg(target_arch = "x86_64")] + asm!("int 0x40" + : "={rax}" (ret) + : "{rax}" (id), "{rdi}" (arg0), "{rsi}" (arg1), "{rdx}" (arg2), "{rcx}" (arg3), "{r8}" (arg4), "{r9}" (arg5) + : "memory" + : "intel" "volatile"); + #[cfg(target_arch = "aarch64")] + 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 = super::arch::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; + } + _ => {} + } + } + } +} + pub fn shell() { show_logo(); diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 8305a77..4474c9c 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -66,9 +66,14 @@ pub mod arch; pub fn kmain() -> ! { process::init(); + + use process::*; + processor().add(Context::new_kernel(kernel_proc2, 2333)); + processor().add(Context::new_user_test(kernel_proc3)); + unsafe { arch::interrupt::enable(); } - fs::shell(); + // fs::shell(); // thread::test::local_key(); // thread::test::unpack(); @@ -86,3 +91,12 @@ pub fn kmain() -> ! { /// It should be defined in memory mod, but in Rust `global_allocator` must be in root mod. #[global_allocator] static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty(); + + +pub extern "C" fn kernel_proc2(arg: usize) -> ! { + fs::test_shell(&format!("proc2-{}>> ", arg)); +} + +pub extern "C" fn kernel_proc3(arg: usize) -> ! { + fs::test_shell(&format!("proc3-{}$ ", arg)); +} diff --git a/kernel/src/process/context.rs b/kernel/src/process/context.rs index d4ebd96..f20d209 100644 --- a/kernel/src/process/context.rs +++ b/kernel/src/process/context.rs @@ -33,6 +33,15 @@ impl Context { } } + 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, + } + } + /// Make a new user thread from ELF data pub fn new_user(data: &[u8]) -> Self { // Parse elf @@ -143,4 +152,4 @@ fn memory_attr_from(elf_flags: Flags) -> MemoryAttr { // TODO: handle readonly if elf_flags.is_execute() { flags = flags.execute(); } flags -} \ No newline at end of file +} diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index 09636cd..5ee8cd2 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -1,39 +1,32 @@ use spin::Once; -use sync::{SpinNoIrqLock, Mutex, MutexGuard, SpinNoIrq}; +use sync::{Mutex, MutexGuard, SpinNoIrq, SpinNoIrqLock}; pub use self::context::Context; pub use ucore_process::processor::{*, Context as _whatever}; pub use ucore_process::scheduler::*; pub use ucore_process::thread::*; -use arch::timer; - mod context; type Processor = Processor_; pub fn init() { - PROCESSOR.call_once(|| + PROCESSOR.call_once(|| { SpinNoIrqLock::new({ let mut processor = Processor::new( unsafe { Context::new_init() }, // NOTE: max_time_slice <= 5 to ensure 'priority' test pass StrideScheduler::new(5), ); - extern fn idle1(arg: usize) -> ! { - loop { - println!("idle 1 {}", timer::get_cycle()); - } - } - extern fn idle2(arg: usize) -> ! { + extern "C" fn idle(arg: usize) -> ! { loop { - println!("idle 2 {}", timer::get_cycle()); + #[cfg(target_arch = "aarch64")] + unsafe { asm!("wfi" :::: "volatile") } } } - processor.add(Context::new_kernel(idle1, 0)); - processor.add(Context::new_kernel(idle2, 0)); + processor.add(Context::new_kernel(idle, 0)); processor }) - ); + }); info!("process init end"); } diff --git a/kernel/src/sync/mutex.rs b/kernel/src/sync/mutex.rs index c8e62ea..6e4a24c 100644 --- a/kernel/src/sync/mutex.rs +++ b/kernel/src/sync/mutex.rs @@ -217,6 +217,8 @@ impl MutexSupport for Spin { asm!("pause" :::: "volatile"); #[cfg(target_arch = "riscv32")] asm!("nop" :::: "volatile"); + #[cfg(target_arch = "aarch64")] + asm!("yield" :::: "volatile"); } } fn before_lock() -> Self::GuardData {} @@ -247,6 +249,8 @@ impl MutexSupport for SpinNoIrq { asm!("pause" :::: "volatile"); #[cfg(target_arch = "riscv32")] asm!("nop" :::: "volatile"); + #[cfg(target_arch = "aarch64")] + asm!("yield" :::: "volatile"); } } fn before_lock() -> Self::GuardData { @@ -267,4 +271,4 @@ impl MutexSupport for Condvar { fn after_unlock(&self) { self.notify_one(); } -} \ No newline at end of file +}