mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 08:06:17 +04:00
Fix riscv interrupt
This commit is contained in:
parent
57d923c1f9
commit
b94b6aa09e
14
kernel/src/arch/riscv/interrupt/consts.rs
Normal file
14
kernel/src/arch/riscv/interrupt/consts.rs
Normal file
@ -0,0 +1,14 @@
|
||||
pub const Syscall: usize = 8;
|
||||
pub const InstructionPageFault: usize = 12;
|
||||
pub const LoadPageFault: usize = 13;
|
||||
pub const StorePageFault: usize = 15;
|
||||
|
||||
// highest bit set
|
||||
pub const IrqMin: usize = usize::MAX / 2;
|
||||
pub const IrqMax: usize = usize::MAX;
|
||||
|
||||
pub const Timer: usize = usize::MAX / 2 + 1 + 5;
|
||||
|
||||
pub fn is_page_fault(trap: usize) -> bool {
|
||||
trap == InstructionPageFault || trap == LoadPageFault || trap == StorePageFault
|
||||
}
|
@ -4,7 +4,7 @@ use log::*;
|
||||
use riscv::register::*;
|
||||
use trapframe::UserContext;
|
||||
|
||||
#[path = "context.rs"]
|
||||
pub mod consts;
|
||||
mod context;
|
||||
|
||||
/// Enable interrupt
|
||||
@ -87,7 +87,7 @@ fn ipi() {
|
||||
super::sbi::clear_ipi();
|
||||
}
|
||||
|
||||
fn timer() {
|
||||
pub fn timer() {
|
||||
super::timer::set_next();
|
||||
crate::trap::timer();
|
||||
}
|
@ -23,11 +23,12 @@ pub const SIMDFloatingPointException: usize = 19;
|
||||
pub const VirtualizationException: usize = 20;
|
||||
pub const SecurityException: usize = 30;
|
||||
|
||||
pub const IRQ0: usize = 32;
|
||||
pub const Syscall32: usize = 0x80;
|
||||
pub const IrqMin: usize = 0x20;
|
||||
pub const IrqMax: usize = 0x3f;
|
||||
pub const Syscall: usize = 0x100;
|
||||
|
||||
// IRQ
|
||||
pub const Timer: usize = 0;
|
||||
pub const Timer: usize = IrqMin + 0;
|
||||
pub const Error: usize = 19;
|
||||
pub const Spurious: usize = 31;
|
||||
|
||||
@ -44,3 +45,7 @@ pub const PIRQH: usize = 23;
|
||||
|
||||
// IPI constants
|
||||
pub const IPIFuncCall: usize = 0xfc;
|
||||
|
||||
pub fn is_page_fault(trap: usize) -> bool {
|
||||
trap == PageFault
|
||||
}
|
||||
|
@ -85,10 +85,10 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
|
||||
match tf.trap_num {
|
||||
DoubleFault => double_fault(tf),
|
||||
PageFault => page_fault(tf),
|
||||
IRQ0..=63 => {
|
||||
let irq = tf.trap_num - IRQ0;
|
||||
IrqMin..=IrqMax => {
|
||||
let irq = tf.trap_num - IrqMin;
|
||||
super::ack(irq); // must ack before switching
|
||||
match irq {
|
||||
match tf.trap_num {
|
||||
Timer => {
|
||||
crate::trap::timer();
|
||||
/*
|
||||
@ -107,7 +107,7 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
|
||||
}
|
||||
}
|
||||
IPIFuncCall => {
|
||||
let irq = tf.trap_num - IRQ0;
|
||||
let irq = tf.trap_num - IrqMin;
|
||||
super::ack(irq); // must ack before switching
|
||||
super::super::gdt::Cpu::current().handle_ipi();
|
||||
}
|
||||
|
@ -38,10 +38,14 @@ pub fn no_interrupt(f: impl FnOnce()) {
|
||||
#[inline(always)]
|
||||
pub fn enable_irq(irq: usize) {
|
||||
let mut ioapic = unsafe { IoApic::new(phys_to_virt(IOAPIC_ADDR as usize)) };
|
||||
ioapic.set_irq_vector(irq as u8, (consts::IRQ0 + irq) as u8);
|
||||
ioapic.set_irq_vector(irq as u8, (consts::IrqMin + irq) as u8);
|
||||
ioapic.enable(irq as u8, 0);
|
||||
}
|
||||
|
||||
pub fn timer() {
|
||||
crate::trap::timer();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn ack(_irq: usize) {
|
||||
let mut lapic = unsafe { XApic::new(phys_to_virt(LAPIC_ADDR)) };
|
||||
|
@ -2,6 +2,7 @@ use super::{
|
||||
abi::{self, ProcInitInfo},
|
||||
add_to_process_table, Pid, Process, PROCESSORS,
|
||||
};
|
||||
use crate::arch::interrupt::consts::{is_page_fault, IrqMax, IrqMin, Syscall, Timer};
|
||||
use crate::arch::interrupt::{get_trap_num, TrapFrame};
|
||||
use crate::arch::{
|
||||
cpu,
|
||||
@ -434,26 +435,24 @@ pub fn spawn(thread: Arc<Thread>) {
|
||||
|
||||
let mut exit = false;
|
||||
match trap_num {
|
||||
0x100 => exit = handle_syscall(&thread, &mut cx).await,
|
||||
0x20..=0x3f => {
|
||||
Syscall => exit = handle_syscall(&thread, &mut cx).await,
|
||||
IrqMin..=IrqMax => {
|
||||
crate::arch::interrupt::ack(trap_num);
|
||||
trace!("handle irq {}", trap_num);
|
||||
if trap_num == 0x20 {
|
||||
crate::trap::timer();
|
||||
} else if trap_num == 0x20 + 4 {
|
||||
//use crate::arch::driver::serial::*;
|
||||
info!("\nInterupt: COM1");
|
||||
//crate::trap::serial(COM1.lock().receive());
|
||||
if trap_num == Timer {
|
||||
crate::arch::interrupt::timer();
|
||||
}
|
||||
}
|
||||
0xe => {
|
||||
_ if is_page_fault(trap_num) => {
|
||||
// page fault
|
||||
let addr = get_page_fault_addr();
|
||||
debug!("page fault from user @ {:#x}", addr);
|
||||
|
||||
thread.vm.lock().handle_page_fault(addr as usize);
|
||||
}
|
||||
_ => {}
|
||||
_ => {
|
||||
warn!("unhandled trap {}", trap_num);
|
||||
}
|
||||
}
|
||||
thread.end_running(cx);
|
||||
if exit {
|
||||
|
Loading…
Reference in New Issue
Block a user