diff --git a/kernel/src/console/uart.rs b/kernel/src/console/uart.rs index fc6d353bc703fb5f1585e9a16b091f1122b2f934..5360fbadd66e1dfe1b7db4dfb6a8f85cb6f42c0d 100755 --- a/kernel/src/console/uart.rs +++ b/kernel/src/console/uart.rs @@ -2,6 +2,9 @@ use core::ptr; use core::convert::Into; use crate::define::memlayout::UART0; +use crate::lock::spinlock::*; + +static mut UART_TX_LOCK: Spinlock<()> = Spinlock::new((), "uart_tx_lock"); macro_rules! Reg { @@ -57,6 +60,30 @@ pub fn uartinit() { } pub fn uartputc(c: u8) { + let guard = unsafe{ UART_TX_LOCK.acquire() }; while (ReadReg!(LSR) & (1 << 5)) == 0 {} WriteReg!(THR, c); + drop(guard); +} + +// read one input character from the UART. +// return -1 if none is waiting. +pub fn uartgetc() -> u8 { + if ReadReg!(LSR) & 1 != 0 { + ReadReg!(RHR) + }else { + 1 + } +} + +// handle a uart interrupt, raised because input has +// arrived, or the uart is ready for more output, or +// both. called from trap.c. + +pub fn uartintr() { + // read and process incoming characters. + loop { + let c = uartgetc(); + + } } diff --git a/kernel/src/interrupt/handler.rs b/kernel/src/interrupt/handler.rs index f271e23149c138e1c3b5cb246421ed098511e4ab..9eff190628fe7238521bd88d577ddfc7639bdcaa 100644 --- a/kernel/src/interrupt/handler.rs +++ b/kernel/src/interrupt/handler.rs @@ -2,13 +2,18 @@ use crate::shutdown::*; use crate::kernel_syscall::*; use crate::register::satp; -pub fn handler_kernel_syscall(result: usize) { +pub fn handler_kernel_syscall( + _: usize, + _: usize, + _: usize, + which: usize +) { unsafe{ satp::write(0); } - match result { + match which { SHUTDOWN => { - println!("\x1b[1;31mshutdown! Bye~ \x1b[0m"); + println!("\x1b[1;31mshutdown! Bye~ \x1b[0m"); system_reset( RESET_TYPE_SHUTDOWN, RESET_REASON_NO_REASON diff --git a/kernel/src/interrupt/trap.rs b/kernel/src/interrupt/trap.rs index 9a07c68c4b5c20331d8b6b847deb9834b4b2b95b..29c1fe5c583cb6b8b3df12d2dd9687f6ad8474e4 100755 --- a/kernel/src/interrupt/trap.rs +++ b/kernel/src/interrupt/trap.rs @@ -9,7 +9,6 @@ use crate::process::*; use super::*; static mut TICKSLOCK:Spinlock<usize> = Spinlock::new(0, "time"); -// static mut TICKS:usize = 0; pub fn trapinit(){ println!("trap init......"); @@ -100,7 +99,7 @@ unsafe fn usertrap_ret() { fn userret(); } - let mut my_proc = CPU_MANAGER.myproc().unwrap(); + let my_proc = CPU_MANAGER.myproc().unwrap(); // we're about to switch the destination of traps from // kerneltrap() to usertrap(), so turn off interrupts until @@ -139,11 +138,11 @@ unsafe fn usertrap_ret() { // jump to trampoline.S at the top of memory, which // switches to the user page table, restores user registers, // and switches to user mode with sret. - let func = TRAMPOLINE + (userret as usize - trampoline as usize); - let func: extern "C" fn(usize, usize) -> ! = - core::mem::transmute(func); + let userret_virt = TRAMPOLINE + (userret as usize - trampoline as usize); + let userret_virt: extern "C" fn(usize, usize) -> ! = + core::mem::transmute(userret_virt); - func(TRAMPOLINE, satp); + userret_virt(TRAMPOLINE, satp); } @@ -154,8 +153,8 @@ unsafe fn usertrap_ret() { // on whatever the current kernel stack is. #[no_mangle] pub unsafe fn kerneltrap( - _: usize, _: usize, _: usize, _: usize, - _: usize, _: usize, _: usize, arg7: usize + arg0: usize, arg1: usize, arg2: usize, _: usize, + _: usize, _: usize, _: usize, which: usize ) { let mut sepc = sepc::read(); @@ -167,7 +166,7 @@ pub unsafe fn kerneltrap( // } if sstatus::intr_get() { - panic!("kerneltrap: interrupts enabled"); + panic!("kerneltrap(): interrupts enabled"); } let which_dev = devintr(); @@ -183,13 +182,13 @@ pub unsafe fn kerneltrap( Trap::Exception(Exception::LoadFault) => panic!("Load Fault!"), - Trap::Exception(Exception::UserEnvCall) => panic!("User System Call!"), + // Trap::Exception(Exception::UserEnvCall) => panic!("User System Call!"), Trap::Exception(Exception::LoadPageFault) => panic!("Load Page Fault!"), Trap::Exception(Exception::StorePageFault) => panic!("Store Page Fault!"), - Trap::Exception(Exception::KernelEnvCall) => handler_kernel_syscall(arg7), + Trap::Exception(Exception::KernelEnvCall) => handler_kernel_syscall(arg0, arg1, arg2, which), _ => panic!("Unresolved Trap!") } @@ -246,10 +245,10 @@ unsafe fn devintr() -> usize { let irq = plic::plic_claim(); if irq == UART0_IRQ as usize{ - // TODO: uartinit + // TODO: uartintr println!("uart interrupt") }else if irq == VIRTIO0_IRQ as usize{ - // TODO: virtio_disk_init + // TODO: virtio_disk_intr println!("virtio0 interrupt") }else if irq != 0{ println!("unexpected intrrupt, irq={}", irq); @@ -263,7 +262,7 @@ unsafe fn devintr() -> usize { } Trap::Interrupt(Interrupt::SupervisorSoft) => { - // println!("Timer Interupt Occures!"); + // software interrupt from a machine-mode timer interrupt, // forwarded by timervec in kernelvec.S. @@ -281,7 +280,6 @@ unsafe fn devintr() -> usize { } _ => { - println!("Exception and other Interrupts Occurs!"); 0 } } diff --git a/kernel/src/process/scheduler.rs b/kernel/src/process/scheduler.rs index b15fb44fff8040fc58b2204f4206fcdc551d72d2..8cb86f807349f4784c1c07027d171a279603eb22 100644 --- a/kernel/src/process/scheduler.rs +++ b/kernel/src/process/scheduler.rs @@ -81,15 +81,16 @@ impl ProcManager{ // for p in self.proc.iter_mut() { // let mut guard = p.data.acquire(); - // let extern_data = p.extern_data.get_mut(); + // // let extern_data = p.extern_data.get_mut(); // if guard.state == Procstate::UNUSED { // guard.pid = alloc_pid(); // guard.set_state(Procstate::USED); + // let extern_data = p.extern_data.get_mut(); // // Allocate a trapframe page. // match unsafe { kalloc() } { - // Some(pa) => { - // extern_data.set_trapframe(pa as *mut Trapframe); + // Some(ptr) => { + // extern_data.set_trapframe(ptr as *mut Trapframe); // // An empty user page table // if let Some(page_table) = unsafe { extern_data.proc_pagetable() } { @@ -107,14 +108,14 @@ impl ProcManager{ // return Some(guard) // } else { - // p.freeproc(); + // // p.freeproc(); // drop(guard); // return None // } // } // None => { - // p.freeproc(); + // // p.freeproc(); // drop(guard); // return None // } @@ -128,6 +129,7 @@ impl ProcManager{ // None // } + // Wake up all processes sleeping on chan. // Must be called without any p->lock. pub fn wakeup(&self, channel: usize) {