mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
parent
d14e28a8a9
commit
f2022a8a1c
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -4,8 +4,6 @@
|
||||
"stdbool.h": "c",
|
||||
"printk.h": "c",
|
||||
"stdarg.h": "c",
|
||||
"trap.h": "c",
|
||||
"gate.h": "c",
|
||||
"process.h": "c",
|
||||
"cpu.h": "c",
|
||||
"mm.h": "c",
|
||||
|
@ -16,7 +16,7 @@ members = [
|
||||
]
|
||||
|
||||
[features]
|
||||
default = ["backtrace"]
|
||||
default = ["backtrace", "kvm"]
|
||||
# 内核栈回溯
|
||||
backtrace = []
|
||||
# kvm
|
||||
@ -50,6 +50,7 @@ virtio-drivers = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community
|
||||
fdt = "0.1.5"
|
||||
uefi = { version = "0.26.0", features = ["alloc"] }
|
||||
uefi-raw = "0.5.0"
|
||||
paste = "1.0.14"
|
||||
|
||||
|
||||
# target为x86_64时,使用下面的依赖
|
||||
|
@ -1,3 +1,5 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard};
|
||||
|
||||
pub mod ipi;
|
||||
@ -5,6 +7,9 @@ pub mod ipi;
|
||||
pub struct RiscV64InterruptArch;
|
||||
|
||||
impl InterruptArch for RiscV64InterruptArch {
|
||||
unsafe fn arch_irq_init() -> Result<(), SystemError> {
|
||||
todo!("RiscV64InterruptArch::arch_irq_init")
|
||||
}
|
||||
unsafe fn interrupt_enable() {
|
||||
riscv::interrupt::enable();
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ __entry_err_code_to_ret_from_exception:
|
||||
|
||||
|
||||
// 0 #DE 除法错误
|
||||
ENTRY(divide_error)
|
||||
ENTRY(trap_divide_error)
|
||||
|
||||
pushq $0 //由于#DE不会产生错误码,但是为了保持弹出结构的一致性,故也压入一个错误码0
|
||||
pushq %rax // 先将rax入栈
|
||||
@ -153,7 +153,7 @@ ENTRY(divide_error)
|
||||
jmp Err_Code
|
||||
|
||||
// 1 #DB 调试异常
|
||||
ENTRY(debug)
|
||||
ENTRY(trap_debug)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_debug(%rip), %rax // 获取中断服务程序的地址
|
||||
@ -161,7 +161,7 @@ ENTRY(debug)
|
||||
jmp Err_Code
|
||||
|
||||
// 2 不可屏蔽中断
|
||||
ENTRY(nmi)
|
||||
ENTRY(trap_nmi)
|
||||
// 不可屏蔽中断不是异常,而是一个外部中断,不会产生错误码
|
||||
// 应执行中断处理流程
|
||||
pushq $0 //占位err_code
|
||||
@ -172,7 +172,7 @@ ENTRY(nmi)
|
||||
jmp Err_Code
|
||||
|
||||
// 3 #BP 断点异常
|
||||
ENTRY(int3)
|
||||
ENTRY(trap_int3)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_int3(%rip), %rax // 获取中断服务程序的地址
|
||||
@ -180,7 +180,7 @@ ENTRY(int3)
|
||||
jmp Err_Code
|
||||
|
||||
// 4 #OF 溢出异常
|
||||
ENTRY(overflow)
|
||||
ENTRY(trap_overflow)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_overflow(%rip), %rax // 获取中断服务程序的地址
|
||||
@ -188,7 +188,7 @@ ENTRY(overflow)
|
||||
jmp Err_Code
|
||||
|
||||
// 5 #BR 越界异常
|
||||
ENTRY(bounds)
|
||||
ENTRY(trap_bounds)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_bounds(%rip), %rax // 获取中断服务程序的地址
|
||||
@ -196,7 +196,7 @@ ENTRY(bounds)
|
||||
jmp Err_Code
|
||||
|
||||
// 6 #UD 无效/未定义的机器码
|
||||
ENTRY(undefined_opcode)
|
||||
ENTRY(trap_undefined_opcode)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_undefined_opcode(%rip), %rax // 获取中断服务程序的地址
|
||||
@ -204,7 +204,7 @@ ENTRY(undefined_opcode)
|
||||
jmp Err_Code
|
||||
|
||||
// 7 #NM 设备异常(FPU不存在)
|
||||
ENTRY(dev_not_avaliable)
|
||||
ENTRY(trap_dev_not_avaliable)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_dev_not_avaliable(%rip), %rax // 获取中断服务程序的地址
|
||||
@ -212,14 +212,14 @@ ENTRY(dev_not_avaliable)
|
||||
jmp Err_Code
|
||||
|
||||
// 8 #DF 双重错误
|
||||
ENTRY(double_fault)
|
||||
ENTRY(trap_double_fault)
|
||||
pushq %rax
|
||||
leaq do_double_fault(%rip), %rax // 获取中断服务程序的地址
|
||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||
jmp Err_Code
|
||||
|
||||
// 9 协处理器越界(保留)
|
||||
ENTRY(coprocessor_segment_overrun)
|
||||
ENTRY(trap_coprocessor_segment_overrun)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_coprocessor_segment_overrun(%rip), %rax // 获取中断服务程序的地址
|
||||
@ -227,7 +227,7 @@ ENTRY(coprocessor_segment_overrun)
|
||||
jmp Err_Code
|
||||
|
||||
// 10 #TS 无效的TSS段
|
||||
ENTRY(invalid_TSS)
|
||||
ENTRY(trap_invalid_TSS)
|
||||
// === 不正确的任务状态段 #TS ==
|
||||
// 有错误码,处理器已经自动在异常处理程序栈中压入错误码
|
||||
pushq %rax
|
||||
@ -236,28 +236,28 @@ ENTRY(invalid_TSS)
|
||||
jmp Err_Code
|
||||
|
||||
// 11 #NP 段不存在
|
||||
ENTRY(segment_not_exists)
|
||||
ENTRY(trap_segment_not_exists)
|
||||
pushq %rax
|
||||
leaq do_segment_not_exists(%rip), %rax // 获取中断服务程序的地址
|
||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||
jmp Err_Code
|
||||
|
||||
// 12 #SS 段错误
|
||||
ENTRY(stack_segment_fault)
|
||||
ENTRY(trap_stack_segment_fault)
|
||||
pushq %rax
|
||||
leaq do_stack_segment_fault(%rip), %rax // 获取中断服务程序的地址
|
||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||
jmp Err_Code
|
||||
|
||||
// 13 #GP 通用保护性异常
|
||||
ENTRY(general_protection)
|
||||
ENTRY(trap_general_protection)
|
||||
pushq %rax
|
||||
leaq do_general_protection(%rip), %rax // 获取中断服务程序的地址
|
||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||
jmp Err_Code
|
||||
|
||||
// 14 #PF 页错误
|
||||
ENTRY(page_fault)
|
||||
ENTRY(trap_page_fault)
|
||||
// === 页故障 #PF ==
|
||||
// 有错误码
|
||||
pushq %rax
|
||||
@ -268,7 +268,7 @@ ENTRY(page_fault)
|
||||
// 15 Intel保留,请勿使用
|
||||
|
||||
// 16 #MF X87 FPU错误(计算错误)
|
||||
ENTRY(x87_FPU_error)
|
||||
ENTRY(trap_x87_FPU_error)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_x87_FPU_error(%rip), %rax // 获取中断服务程序的地址
|
||||
@ -276,14 +276,14 @@ ENTRY(x87_FPU_error)
|
||||
jmp Err_Code
|
||||
|
||||
// 17 #AC 对齐检测
|
||||
ENTRY(alignment_check)
|
||||
ENTRY(trap_alignment_check)
|
||||
pushq %rax
|
||||
leaq do_alignment_check(%rip), %rax // 获取中断服务程序的地址
|
||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||
jmp Err_Code
|
||||
|
||||
// 18 #MC 机器检测
|
||||
ENTRY(machine_check)
|
||||
ENTRY(trap_machine_check)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_machine_check(%rip), %rax // 获取中断服务程序的地址
|
||||
@ -291,7 +291,7 @@ ENTRY(machine_check)
|
||||
jmp Err_Code
|
||||
|
||||
// 19 #XM SIMD浮点异常
|
||||
ENTRY(SIMD_exception)
|
||||
ENTRY(trap_SIMD_exception)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_SIMD_exception(%rip), %rax // 获取中断服务程序的地址
|
||||
@ -299,7 +299,7 @@ ENTRY(SIMD_exception)
|
||||
jmp Err_Code
|
||||
|
||||
// 20 #VE 虚拟化异常
|
||||
ENTRY(virtualization_exception)
|
||||
ENTRY(trap_virtualization_exception)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_virtualization_exception(%rip), %rax // 获取中断服务程序的地址
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <common/kprint.h>
|
||||
#include <common/printk.h>
|
||||
#include <driver/acpi/acpi.h>
|
||||
#include <exception/gate.h>
|
||||
#include <exception/softirq.h>
|
||||
#include <process/process.h>
|
||||
#include <sched/sched.h>
|
||||
@ -26,29 +25,6 @@ extern void rs_ioapic_uninstall(uint8_t irq_num);
|
||||
extern void rs_ioapic_enable(uint8_t irq_num);
|
||||
extern void rs_ioapic_disable(uint8_t irq_num);
|
||||
|
||||
/**
|
||||
* @brief 初始化apic控制器
|
||||
*
|
||||
*/
|
||||
int apic_init()
|
||||
{
|
||||
cli();
|
||||
kinfo("Initializing APIC...");
|
||||
// 初始化中断门, 中断使用rsp0防止在软中断时发生嵌套,然后处理器重新加载导致数据被抹掉
|
||||
for (int i = 32; i <= 57; ++i)
|
||||
set_intr_gate(i, 0, interrupt_table[i - 32]);
|
||||
|
||||
// 设置local apic中断门
|
||||
for (int i = 150; i < 160; ++i)
|
||||
set_intr_gate(i, 0, local_apic_interrupt_table[i - 150]);
|
||||
|
||||
// 初始化BSP的APIC
|
||||
rs_apic_init_bsp();
|
||||
|
||||
kinfo("APIC initialized.");
|
||||
// sti();
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief 中断服务程序
|
||||
*
|
||||
|
@ -217,16 +217,10 @@ struct apic_IO_APIC_RTE_entry
|
||||
void do_IRQ(struct pt_regs *rsp, ul number);
|
||||
void rs_apic_init_ap();
|
||||
|
||||
/**
|
||||
* @brief 初始化apic控制器
|
||||
*
|
||||
*/
|
||||
int apic_init();
|
||||
|
||||
#if ARCH(I386) || ARCH(X86_64)
|
||||
|
||||
// =========== 中断控制操作接口 ============
|
||||
void apic_ioapic_enable(ul irq_num);
|
||||
// =========== 中断控制操作接口 ============
|
||||
void apic_ioapic_enable(ul irq_num);
|
||||
void apic_ioapic_disable(ul irq_num);
|
||||
ul apic_ioapic_install(ul irq_num, void *arg);
|
||||
void apic_ioapic_uninstall(ul irq_num);
|
||||
|
@ -4,9 +4,9 @@ use system_error::SystemError;
|
||||
use x86::dtables::DescriptorTablePointer;
|
||||
|
||||
use crate::{
|
||||
arch::process::table::TSSManager,
|
||||
arch::{interrupt::trap::arch_trap_init, process::table::TSSManager},
|
||||
driver::pci::pci::pci_init,
|
||||
include::bindings::bindings::{cpu_init, irq_init},
|
||||
include::bindings::bindings::cpu_init,
|
||||
init::init::start_kernel,
|
||||
kdebug,
|
||||
mm::{MemoryManagementArch, PhysAddr},
|
||||
@ -34,7 +34,6 @@ extern "C" {
|
||||
|
||||
fn multiboot2_init(mb2_info: u64, mb2_magic: u32) -> bool;
|
||||
fn __init_set_cpu_stack_start(cpu: u32, stack_start: u64);
|
||||
fn sys_vector_init();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -83,7 +82,7 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
|
||||
set_current_core_tss(stack_start, 0);
|
||||
unsafe { TSSManager::load_tr() };
|
||||
unsafe { __init_set_cpu_stack_start(0, stack_start as u64) };
|
||||
unsafe { sys_vector_init() };
|
||||
arch_trap_init().expect("arch_trap_init failed");
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
@ -92,7 +91,6 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
|
||||
#[inline(never)]
|
||||
pub fn setup_arch() -> Result<(), SystemError> {
|
||||
unsafe {
|
||||
irq_init();
|
||||
cpu_init();
|
||||
}
|
||||
|
||||
|
603
kernel/src/arch/x86_64/interrupt/entry.rs
Normal file
603
kernel/src/arch/x86_64/interrupt/entry.rs
Normal file
@ -0,0 +1,603 @@
|
||||
use crate::{
|
||||
arch::MMArch,
|
||||
mm::{MemoryManagementArch, PhysAddr, VirtAddr},
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
static mut IDT_Table: [usize; 0usize];
|
||||
}
|
||||
macro_rules! save_all_regs {
|
||||
() => {
|
||||
"
|
||||
cld
|
||||
push rax
|
||||
push rax
|
||||
mov rax, es
|
||||
push rax
|
||||
mov rax, ds
|
||||
push rax
|
||||
xor rax, rax
|
||||
push rbp
|
||||
push rdi
|
||||
push rsi
|
||||
push rdx
|
||||
push rcx
|
||||
push rbx
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
mov rdx, 0x10
|
||||
mov ds, rdx
|
||||
mov es, rdx
|
||||
"
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! interrupt_handler {
|
||||
($name:expr) => {
|
||||
paste::paste! {
|
||||
|
||||
#[naked]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn [<irq_handler $name>]() {
|
||||
core::arch::asm!(
|
||||
concat!(
|
||||
"
|
||||
push 0x0
|
||||
",
|
||||
save_all_regs!(),
|
||||
"\n",
|
||||
"
|
||||
mov rdi, rsp
|
||||
lea rax, ret_from_intr[rip]
|
||||
push rax
|
||||
mov rsi, {irqnum}
|
||||
jmp do_IRQ
|
||||
"
|
||||
),
|
||||
irqnum = const($name),
|
||||
options(noreturn)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
interrupt_handler!(32);
|
||||
interrupt_handler!(33);
|
||||
interrupt_handler!(34);
|
||||
interrupt_handler!(35);
|
||||
interrupt_handler!(36);
|
||||
interrupt_handler!(37);
|
||||
interrupt_handler!(38);
|
||||
interrupt_handler!(39);
|
||||
interrupt_handler!(40);
|
||||
interrupt_handler!(41);
|
||||
interrupt_handler!(42);
|
||||
interrupt_handler!(43);
|
||||
interrupt_handler!(44);
|
||||
interrupt_handler!(45);
|
||||
interrupt_handler!(46);
|
||||
interrupt_handler!(47);
|
||||
interrupt_handler!(48);
|
||||
interrupt_handler!(49);
|
||||
interrupt_handler!(50);
|
||||
interrupt_handler!(51);
|
||||
interrupt_handler!(52);
|
||||
interrupt_handler!(53);
|
||||
interrupt_handler!(54);
|
||||
interrupt_handler!(55);
|
||||
interrupt_handler!(56);
|
||||
interrupt_handler!(57);
|
||||
interrupt_handler!(58);
|
||||
interrupt_handler!(59);
|
||||
interrupt_handler!(60);
|
||||
interrupt_handler!(61);
|
||||
interrupt_handler!(62);
|
||||
interrupt_handler!(63);
|
||||
interrupt_handler!(64);
|
||||
interrupt_handler!(65);
|
||||
interrupt_handler!(66);
|
||||
interrupt_handler!(67);
|
||||
interrupt_handler!(68);
|
||||
interrupt_handler!(69);
|
||||
interrupt_handler!(70);
|
||||
interrupt_handler!(71);
|
||||
interrupt_handler!(72);
|
||||
interrupt_handler!(73);
|
||||
interrupt_handler!(74);
|
||||
interrupt_handler!(75);
|
||||
interrupt_handler!(76);
|
||||
interrupt_handler!(77);
|
||||
interrupt_handler!(78);
|
||||
interrupt_handler!(79);
|
||||
interrupt_handler!(80);
|
||||
interrupt_handler!(81);
|
||||
interrupt_handler!(82);
|
||||
interrupt_handler!(83);
|
||||
interrupt_handler!(84);
|
||||
interrupt_handler!(85);
|
||||
interrupt_handler!(86);
|
||||
interrupt_handler!(87);
|
||||
interrupt_handler!(88);
|
||||
interrupt_handler!(89);
|
||||
interrupt_handler!(90);
|
||||
interrupt_handler!(91);
|
||||
interrupt_handler!(92);
|
||||
interrupt_handler!(93);
|
||||
interrupt_handler!(94);
|
||||
interrupt_handler!(95);
|
||||
interrupt_handler!(96);
|
||||
interrupt_handler!(97);
|
||||
interrupt_handler!(98);
|
||||
interrupt_handler!(99);
|
||||
interrupt_handler!(100);
|
||||
interrupt_handler!(101);
|
||||
interrupt_handler!(102);
|
||||
interrupt_handler!(103);
|
||||
interrupt_handler!(104);
|
||||
interrupt_handler!(105);
|
||||
interrupt_handler!(106);
|
||||
interrupt_handler!(107);
|
||||
interrupt_handler!(108);
|
||||
interrupt_handler!(109);
|
||||
interrupt_handler!(110);
|
||||
interrupt_handler!(111);
|
||||
interrupt_handler!(112);
|
||||
interrupt_handler!(113);
|
||||
interrupt_handler!(114);
|
||||
interrupt_handler!(115);
|
||||
interrupt_handler!(116);
|
||||
interrupt_handler!(117);
|
||||
interrupt_handler!(118);
|
||||
interrupt_handler!(119);
|
||||
interrupt_handler!(120);
|
||||
interrupt_handler!(121);
|
||||
interrupt_handler!(122);
|
||||
interrupt_handler!(123);
|
||||
interrupt_handler!(124);
|
||||
interrupt_handler!(125);
|
||||
interrupt_handler!(126);
|
||||
interrupt_handler!(127);
|
||||
// 128号为系统调用,因此不需要设置中断处理函数
|
||||
interrupt_handler!(129);
|
||||
interrupt_handler!(130);
|
||||
interrupt_handler!(131);
|
||||
interrupt_handler!(132);
|
||||
interrupt_handler!(133);
|
||||
interrupt_handler!(134);
|
||||
interrupt_handler!(135);
|
||||
interrupt_handler!(136);
|
||||
interrupt_handler!(137);
|
||||
interrupt_handler!(138);
|
||||
interrupt_handler!(139);
|
||||
interrupt_handler!(140);
|
||||
interrupt_handler!(141);
|
||||
interrupt_handler!(142);
|
||||
interrupt_handler!(143);
|
||||
interrupt_handler!(144);
|
||||
interrupt_handler!(145);
|
||||
interrupt_handler!(146);
|
||||
interrupt_handler!(147);
|
||||
interrupt_handler!(148);
|
||||
interrupt_handler!(149);
|
||||
interrupt_handler!(150);
|
||||
interrupt_handler!(151);
|
||||
interrupt_handler!(152);
|
||||
interrupt_handler!(153);
|
||||
interrupt_handler!(154);
|
||||
interrupt_handler!(155);
|
||||
interrupt_handler!(156);
|
||||
interrupt_handler!(157);
|
||||
interrupt_handler!(158);
|
||||
interrupt_handler!(159);
|
||||
interrupt_handler!(160);
|
||||
interrupt_handler!(161);
|
||||
interrupt_handler!(162);
|
||||
interrupt_handler!(163);
|
||||
interrupt_handler!(164);
|
||||
interrupt_handler!(165);
|
||||
interrupt_handler!(166);
|
||||
interrupt_handler!(167);
|
||||
interrupt_handler!(168);
|
||||
interrupt_handler!(169);
|
||||
interrupt_handler!(170);
|
||||
interrupt_handler!(171);
|
||||
interrupt_handler!(172);
|
||||
interrupt_handler!(173);
|
||||
interrupt_handler!(174);
|
||||
interrupt_handler!(175);
|
||||
interrupt_handler!(176);
|
||||
interrupt_handler!(177);
|
||||
interrupt_handler!(178);
|
||||
interrupt_handler!(179);
|
||||
interrupt_handler!(180);
|
||||
interrupt_handler!(181);
|
||||
interrupt_handler!(182);
|
||||
interrupt_handler!(183);
|
||||
interrupt_handler!(184);
|
||||
interrupt_handler!(185);
|
||||
interrupt_handler!(186);
|
||||
interrupt_handler!(187);
|
||||
interrupt_handler!(188);
|
||||
interrupt_handler!(189);
|
||||
interrupt_handler!(190);
|
||||
interrupt_handler!(191);
|
||||
interrupt_handler!(192);
|
||||
interrupt_handler!(193);
|
||||
interrupt_handler!(194);
|
||||
interrupt_handler!(195);
|
||||
interrupt_handler!(196);
|
||||
interrupt_handler!(197);
|
||||
interrupt_handler!(198);
|
||||
interrupt_handler!(199);
|
||||
interrupt_handler!(200);
|
||||
interrupt_handler!(201);
|
||||
interrupt_handler!(202);
|
||||
interrupt_handler!(203);
|
||||
interrupt_handler!(204);
|
||||
interrupt_handler!(205);
|
||||
interrupt_handler!(206);
|
||||
interrupt_handler!(207);
|
||||
interrupt_handler!(208);
|
||||
interrupt_handler!(209);
|
||||
interrupt_handler!(210);
|
||||
interrupt_handler!(211);
|
||||
interrupt_handler!(212);
|
||||
interrupt_handler!(213);
|
||||
interrupt_handler!(214);
|
||||
interrupt_handler!(215);
|
||||
interrupt_handler!(216);
|
||||
interrupt_handler!(217);
|
||||
interrupt_handler!(218);
|
||||
interrupt_handler!(219);
|
||||
interrupt_handler!(220);
|
||||
interrupt_handler!(221);
|
||||
interrupt_handler!(222);
|
||||
interrupt_handler!(223);
|
||||
interrupt_handler!(224);
|
||||
interrupt_handler!(225);
|
||||
interrupt_handler!(226);
|
||||
interrupt_handler!(227);
|
||||
interrupt_handler!(228);
|
||||
interrupt_handler!(229);
|
||||
interrupt_handler!(230);
|
||||
interrupt_handler!(231);
|
||||
interrupt_handler!(232);
|
||||
interrupt_handler!(233);
|
||||
interrupt_handler!(234);
|
||||
interrupt_handler!(235);
|
||||
interrupt_handler!(236);
|
||||
interrupt_handler!(237);
|
||||
interrupt_handler!(238);
|
||||
interrupt_handler!(239);
|
||||
interrupt_handler!(240);
|
||||
interrupt_handler!(241);
|
||||
interrupt_handler!(242);
|
||||
interrupt_handler!(243);
|
||||
interrupt_handler!(244);
|
||||
interrupt_handler!(245);
|
||||
interrupt_handler!(246);
|
||||
interrupt_handler!(247);
|
||||
interrupt_handler!(248);
|
||||
interrupt_handler!(249);
|
||||
interrupt_handler!(250);
|
||||
interrupt_handler!(251);
|
||||
interrupt_handler!(252);
|
||||
interrupt_handler!(253);
|
||||
interrupt_handler!(254);
|
||||
interrupt_handler!(255);
|
||||
|
||||
#[inline(never)]
|
||||
pub(super) unsafe fn setup_interrupt_gate() {
|
||||
set_intr_gate(32, 0, VirtAddr::new(irq_handler32 as usize));
|
||||
set_intr_gate(33, 0, VirtAddr::new(irq_handler33 as usize));
|
||||
set_intr_gate(34, 0, VirtAddr::new(irq_handler34 as usize));
|
||||
set_intr_gate(35, 0, VirtAddr::new(irq_handler35 as usize));
|
||||
set_intr_gate(36, 0, VirtAddr::new(irq_handler36 as usize));
|
||||
set_intr_gate(37, 0, VirtAddr::new(irq_handler37 as usize));
|
||||
set_intr_gate(38, 0, VirtAddr::new(irq_handler38 as usize));
|
||||
set_intr_gate(39, 0, VirtAddr::new(irq_handler39 as usize));
|
||||
set_intr_gate(40, 0, VirtAddr::new(irq_handler40 as usize));
|
||||
|
||||
set_intr_gate(41, 0, VirtAddr::new(irq_handler41 as usize));
|
||||
set_intr_gate(42, 0, VirtAddr::new(irq_handler42 as usize));
|
||||
set_intr_gate(43, 0, VirtAddr::new(irq_handler43 as usize));
|
||||
set_intr_gate(44, 0, VirtAddr::new(irq_handler44 as usize));
|
||||
set_intr_gate(45, 0, VirtAddr::new(irq_handler45 as usize));
|
||||
set_intr_gate(46, 0, VirtAddr::new(irq_handler46 as usize));
|
||||
set_intr_gate(47, 0, VirtAddr::new(irq_handler47 as usize));
|
||||
set_intr_gate(48, 0, VirtAddr::new(irq_handler48 as usize));
|
||||
set_intr_gate(49, 0, VirtAddr::new(irq_handler49 as usize));
|
||||
set_intr_gate(50, 0, VirtAddr::new(irq_handler50 as usize));
|
||||
|
||||
set_intr_gate(51, 0, VirtAddr::new(irq_handler51 as usize));
|
||||
set_intr_gate(52, 0, VirtAddr::new(irq_handler52 as usize));
|
||||
set_intr_gate(53, 0, VirtAddr::new(irq_handler53 as usize));
|
||||
set_intr_gate(54, 0, VirtAddr::new(irq_handler54 as usize));
|
||||
set_intr_gate(55, 0, VirtAddr::new(irq_handler55 as usize));
|
||||
set_intr_gate(56, 0, VirtAddr::new(irq_handler56 as usize));
|
||||
set_intr_gate(57, 0, VirtAddr::new(irq_handler57 as usize));
|
||||
set_intr_gate(58, 0, VirtAddr::new(irq_handler58 as usize));
|
||||
set_intr_gate(59, 0, VirtAddr::new(irq_handler59 as usize));
|
||||
set_intr_gate(60, 0, VirtAddr::new(irq_handler60 as usize));
|
||||
|
||||
set_intr_gate(61, 0, VirtAddr::new(irq_handler61 as usize));
|
||||
set_intr_gate(62, 0, VirtAddr::new(irq_handler62 as usize));
|
||||
set_intr_gate(63, 0, VirtAddr::new(irq_handler63 as usize));
|
||||
set_intr_gate(64, 0, VirtAddr::new(irq_handler64 as usize));
|
||||
set_intr_gate(65, 0, VirtAddr::new(irq_handler65 as usize));
|
||||
set_intr_gate(66, 0, VirtAddr::new(irq_handler66 as usize));
|
||||
set_intr_gate(67, 0, VirtAddr::new(irq_handler67 as usize));
|
||||
set_intr_gate(68, 0, VirtAddr::new(irq_handler68 as usize));
|
||||
set_intr_gate(69, 0, VirtAddr::new(irq_handler69 as usize));
|
||||
set_intr_gate(70, 0, VirtAddr::new(irq_handler70 as usize));
|
||||
|
||||
set_intr_gate(71, 0, VirtAddr::new(irq_handler71 as usize));
|
||||
set_intr_gate(72, 0, VirtAddr::new(irq_handler72 as usize));
|
||||
set_intr_gate(73, 0, VirtAddr::new(irq_handler73 as usize));
|
||||
set_intr_gate(74, 0, VirtAddr::new(irq_handler74 as usize));
|
||||
set_intr_gate(75, 0, VirtAddr::new(irq_handler75 as usize));
|
||||
set_intr_gate(76, 0, VirtAddr::new(irq_handler76 as usize));
|
||||
set_intr_gate(77, 0, VirtAddr::new(irq_handler77 as usize));
|
||||
set_intr_gate(78, 0, VirtAddr::new(irq_handler78 as usize));
|
||||
set_intr_gate(79, 0, VirtAddr::new(irq_handler79 as usize));
|
||||
set_intr_gate(80, 0, VirtAddr::new(irq_handler80 as usize));
|
||||
|
||||
set_intr_gate(81, 0, VirtAddr::new(irq_handler81 as usize));
|
||||
set_intr_gate(82, 0, VirtAddr::new(irq_handler82 as usize));
|
||||
set_intr_gate(83, 0, VirtAddr::new(irq_handler83 as usize));
|
||||
set_intr_gate(84, 0, VirtAddr::new(irq_handler84 as usize));
|
||||
set_intr_gate(85, 0, VirtAddr::new(irq_handler85 as usize));
|
||||
set_intr_gate(86, 0, VirtAddr::new(irq_handler86 as usize));
|
||||
set_intr_gate(87, 0, VirtAddr::new(irq_handler87 as usize));
|
||||
set_intr_gate(88, 0, VirtAddr::new(irq_handler88 as usize));
|
||||
set_intr_gate(89, 0, VirtAddr::new(irq_handler89 as usize));
|
||||
set_intr_gate(90, 0, VirtAddr::new(irq_handler90 as usize));
|
||||
|
||||
set_intr_gate(91, 0, VirtAddr::new(irq_handler91 as usize));
|
||||
set_intr_gate(92, 0, VirtAddr::new(irq_handler92 as usize));
|
||||
set_intr_gate(93, 0, VirtAddr::new(irq_handler93 as usize));
|
||||
set_intr_gate(94, 0, VirtAddr::new(irq_handler94 as usize));
|
||||
set_intr_gate(95, 0, VirtAddr::new(irq_handler95 as usize));
|
||||
set_intr_gate(96, 0, VirtAddr::new(irq_handler96 as usize));
|
||||
set_intr_gate(97, 0, VirtAddr::new(irq_handler97 as usize));
|
||||
set_intr_gate(98, 0, VirtAddr::new(irq_handler98 as usize));
|
||||
set_intr_gate(99, 0, VirtAddr::new(irq_handler99 as usize));
|
||||
set_intr_gate(100, 0, VirtAddr::new(irq_handler100 as usize));
|
||||
|
||||
set_intr_gate(101, 0, VirtAddr::new(irq_handler101 as usize));
|
||||
set_intr_gate(102, 0, VirtAddr::new(irq_handler102 as usize));
|
||||
set_intr_gate(103, 0, VirtAddr::new(irq_handler103 as usize));
|
||||
set_intr_gate(104, 0, VirtAddr::new(irq_handler104 as usize));
|
||||
set_intr_gate(105, 0, VirtAddr::new(irq_handler105 as usize));
|
||||
set_intr_gate(106, 0, VirtAddr::new(irq_handler106 as usize));
|
||||
set_intr_gate(107, 0, VirtAddr::new(irq_handler107 as usize));
|
||||
set_intr_gate(108, 0, VirtAddr::new(irq_handler108 as usize));
|
||||
set_intr_gate(109, 0, VirtAddr::new(irq_handler109 as usize));
|
||||
set_intr_gate(110, 0, VirtAddr::new(irq_handler110 as usize));
|
||||
|
||||
set_intr_gate(111, 0, VirtAddr::new(irq_handler111 as usize));
|
||||
set_intr_gate(112, 0, VirtAddr::new(irq_handler112 as usize));
|
||||
set_intr_gate(113, 0, VirtAddr::new(irq_handler113 as usize));
|
||||
set_intr_gate(114, 0, VirtAddr::new(irq_handler114 as usize));
|
||||
set_intr_gate(115, 0, VirtAddr::new(irq_handler115 as usize));
|
||||
set_intr_gate(116, 0, VirtAddr::new(irq_handler116 as usize));
|
||||
set_intr_gate(117, 0, VirtAddr::new(irq_handler117 as usize));
|
||||
set_intr_gate(118, 0, VirtAddr::new(irq_handler118 as usize));
|
||||
set_intr_gate(119, 0, VirtAddr::new(irq_handler119 as usize));
|
||||
set_intr_gate(120, 0, VirtAddr::new(irq_handler120 as usize));
|
||||
|
||||
set_intr_gate(121, 0, VirtAddr::new(irq_handler121 as usize));
|
||||
set_intr_gate(122, 0, VirtAddr::new(irq_handler122 as usize));
|
||||
set_intr_gate(123, 0, VirtAddr::new(irq_handler123 as usize));
|
||||
set_intr_gate(124, 0, VirtAddr::new(irq_handler124 as usize));
|
||||
set_intr_gate(125, 0, VirtAddr::new(irq_handler125 as usize));
|
||||
set_intr_gate(126, 0, VirtAddr::new(irq_handler126 as usize));
|
||||
set_intr_gate(127, 0, VirtAddr::new(irq_handler127 as usize));
|
||||
set_intr_gate(129, 0, VirtAddr::new(irq_handler129 as usize));
|
||||
set_intr_gate(130, 0, VirtAddr::new(irq_handler130 as usize));
|
||||
|
||||
set_intr_gate(131, 0, VirtAddr::new(irq_handler131 as usize));
|
||||
set_intr_gate(132, 0, VirtAddr::new(irq_handler132 as usize));
|
||||
set_intr_gate(133, 0, VirtAddr::new(irq_handler133 as usize));
|
||||
set_intr_gate(134, 0, VirtAddr::new(irq_handler134 as usize));
|
||||
set_intr_gate(135, 0, VirtAddr::new(irq_handler135 as usize));
|
||||
set_intr_gate(136, 0, VirtAddr::new(irq_handler136 as usize));
|
||||
set_intr_gate(137, 0, VirtAddr::new(irq_handler137 as usize));
|
||||
set_intr_gate(138, 0, VirtAddr::new(irq_handler138 as usize));
|
||||
set_intr_gate(139, 0, VirtAddr::new(irq_handler139 as usize));
|
||||
set_intr_gate(140, 0, VirtAddr::new(irq_handler140 as usize));
|
||||
|
||||
set_intr_gate(141, 0, VirtAddr::new(irq_handler141 as usize));
|
||||
set_intr_gate(142, 0, VirtAddr::new(irq_handler142 as usize));
|
||||
set_intr_gate(143, 0, VirtAddr::new(irq_handler143 as usize));
|
||||
set_intr_gate(144, 0, VirtAddr::new(irq_handler144 as usize));
|
||||
set_intr_gate(145, 0, VirtAddr::new(irq_handler145 as usize));
|
||||
set_intr_gate(146, 0, VirtAddr::new(irq_handler146 as usize));
|
||||
set_intr_gate(147, 0, VirtAddr::new(irq_handler147 as usize));
|
||||
set_intr_gate(148, 0, VirtAddr::new(irq_handler148 as usize));
|
||||
set_intr_gate(149, 0, VirtAddr::new(irq_handler149 as usize));
|
||||
set_intr_gate(150, 0, VirtAddr::new(irq_handler150 as usize));
|
||||
|
||||
set_intr_gate(151, 0, VirtAddr::new(irq_handler151 as usize));
|
||||
set_intr_gate(152, 0, VirtAddr::new(irq_handler152 as usize));
|
||||
set_intr_gate(153, 0, VirtAddr::new(irq_handler153 as usize));
|
||||
set_intr_gate(154, 0, VirtAddr::new(irq_handler154 as usize));
|
||||
set_intr_gate(155, 0, VirtAddr::new(irq_handler155 as usize));
|
||||
set_intr_gate(156, 0, VirtAddr::new(irq_handler156 as usize));
|
||||
set_intr_gate(157, 0, VirtAddr::new(irq_handler157 as usize));
|
||||
set_intr_gate(158, 0, VirtAddr::new(irq_handler158 as usize));
|
||||
set_intr_gate(159, 0, VirtAddr::new(irq_handler159 as usize));
|
||||
set_intr_gate(160, 0, VirtAddr::new(irq_handler160 as usize));
|
||||
|
||||
set_intr_gate(161, 0, VirtAddr::new(irq_handler161 as usize));
|
||||
set_intr_gate(162, 0, VirtAddr::new(irq_handler162 as usize));
|
||||
set_intr_gate(163, 0, VirtAddr::new(irq_handler163 as usize));
|
||||
set_intr_gate(164, 0, VirtAddr::new(irq_handler164 as usize));
|
||||
set_intr_gate(165, 0, VirtAddr::new(irq_handler165 as usize));
|
||||
set_intr_gate(166, 0, VirtAddr::new(irq_handler166 as usize));
|
||||
set_intr_gate(167, 0, VirtAddr::new(irq_handler167 as usize));
|
||||
set_intr_gate(168, 0, VirtAddr::new(irq_handler168 as usize));
|
||||
set_intr_gate(169, 0, VirtAddr::new(irq_handler169 as usize));
|
||||
set_intr_gate(170, 0, VirtAddr::new(irq_handler170 as usize));
|
||||
|
||||
set_intr_gate(171, 0, VirtAddr::new(irq_handler171 as usize));
|
||||
set_intr_gate(172, 0, VirtAddr::new(irq_handler172 as usize));
|
||||
set_intr_gate(173, 0, VirtAddr::new(irq_handler173 as usize));
|
||||
set_intr_gate(174, 0, VirtAddr::new(irq_handler174 as usize));
|
||||
set_intr_gate(175, 0, VirtAddr::new(irq_handler175 as usize));
|
||||
set_intr_gate(176, 0, VirtAddr::new(irq_handler176 as usize));
|
||||
set_intr_gate(177, 0, VirtAddr::new(irq_handler177 as usize));
|
||||
set_intr_gate(178, 0, VirtAddr::new(irq_handler178 as usize));
|
||||
set_intr_gate(179, 0, VirtAddr::new(irq_handler179 as usize));
|
||||
set_intr_gate(180, 0, VirtAddr::new(irq_handler180 as usize));
|
||||
|
||||
set_intr_gate(181, 0, VirtAddr::new(irq_handler181 as usize));
|
||||
set_intr_gate(182, 0, VirtAddr::new(irq_handler182 as usize));
|
||||
set_intr_gate(183, 0, VirtAddr::new(irq_handler183 as usize));
|
||||
set_intr_gate(184, 0, VirtAddr::new(irq_handler184 as usize));
|
||||
set_intr_gate(185, 0, VirtAddr::new(irq_handler185 as usize));
|
||||
set_intr_gate(186, 0, VirtAddr::new(irq_handler186 as usize));
|
||||
set_intr_gate(187, 0, VirtAddr::new(irq_handler187 as usize));
|
||||
set_intr_gate(188, 0, VirtAddr::new(irq_handler188 as usize));
|
||||
set_intr_gate(189, 0, VirtAddr::new(irq_handler189 as usize));
|
||||
set_intr_gate(190, 0, VirtAddr::new(irq_handler190 as usize));
|
||||
|
||||
set_intr_gate(191, 0, VirtAddr::new(irq_handler191 as usize));
|
||||
set_intr_gate(192, 0, VirtAddr::new(irq_handler192 as usize));
|
||||
set_intr_gate(193, 0, VirtAddr::new(irq_handler193 as usize));
|
||||
set_intr_gate(194, 0, VirtAddr::new(irq_handler194 as usize));
|
||||
set_intr_gate(195, 0, VirtAddr::new(irq_handler195 as usize));
|
||||
set_intr_gate(196, 0, VirtAddr::new(irq_handler196 as usize));
|
||||
set_intr_gate(197, 0, VirtAddr::new(irq_handler197 as usize));
|
||||
set_intr_gate(198, 0, VirtAddr::new(irq_handler198 as usize));
|
||||
set_intr_gate(199, 0, VirtAddr::new(irq_handler199 as usize));
|
||||
|
||||
set_intr_gate(200, 0, VirtAddr::new(irq_handler200 as usize));
|
||||
set_intr_gate(201, 0, VirtAddr::new(irq_handler201 as usize));
|
||||
set_intr_gate(202, 0, VirtAddr::new(irq_handler202 as usize));
|
||||
set_intr_gate(203, 0, VirtAddr::new(irq_handler203 as usize));
|
||||
set_intr_gate(204, 0, VirtAddr::new(irq_handler204 as usize));
|
||||
set_intr_gate(205, 0, VirtAddr::new(irq_handler205 as usize));
|
||||
set_intr_gate(206, 0, VirtAddr::new(irq_handler206 as usize));
|
||||
set_intr_gate(207, 0, VirtAddr::new(irq_handler207 as usize));
|
||||
set_intr_gate(208, 0, VirtAddr::new(irq_handler208 as usize));
|
||||
set_intr_gate(209, 0, VirtAddr::new(irq_handler209 as usize));
|
||||
set_intr_gate(210, 0, VirtAddr::new(irq_handler210 as usize));
|
||||
|
||||
set_intr_gate(211, 0, VirtAddr::new(irq_handler211 as usize));
|
||||
set_intr_gate(212, 0, VirtAddr::new(irq_handler212 as usize));
|
||||
set_intr_gate(213, 0, VirtAddr::new(irq_handler213 as usize));
|
||||
set_intr_gate(214, 0, VirtAddr::new(irq_handler214 as usize));
|
||||
set_intr_gate(215, 0, VirtAddr::new(irq_handler215 as usize));
|
||||
set_intr_gate(216, 0, VirtAddr::new(irq_handler216 as usize));
|
||||
set_intr_gate(217, 0, VirtAddr::new(irq_handler217 as usize));
|
||||
set_intr_gate(218, 0, VirtAddr::new(irq_handler218 as usize));
|
||||
set_intr_gate(219, 0, VirtAddr::new(irq_handler219 as usize));
|
||||
set_intr_gate(220, 0, VirtAddr::new(irq_handler220 as usize));
|
||||
|
||||
set_intr_gate(221, 0, VirtAddr::new(irq_handler221 as usize));
|
||||
set_intr_gate(222, 0, VirtAddr::new(irq_handler222 as usize));
|
||||
set_intr_gate(223, 0, VirtAddr::new(irq_handler223 as usize));
|
||||
set_intr_gate(224, 0, VirtAddr::new(irq_handler224 as usize));
|
||||
set_intr_gate(225, 0, VirtAddr::new(irq_handler225 as usize));
|
||||
set_intr_gate(226, 0, VirtAddr::new(irq_handler226 as usize));
|
||||
set_intr_gate(227, 0, VirtAddr::new(irq_handler227 as usize));
|
||||
set_intr_gate(228, 0, VirtAddr::new(irq_handler228 as usize));
|
||||
set_intr_gate(229, 0, VirtAddr::new(irq_handler229 as usize));
|
||||
set_intr_gate(230, 0, VirtAddr::new(irq_handler230 as usize));
|
||||
|
||||
set_intr_gate(231, 0, VirtAddr::new(irq_handler231 as usize));
|
||||
set_intr_gate(232, 0, VirtAddr::new(irq_handler232 as usize));
|
||||
set_intr_gate(233, 0, VirtAddr::new(irq_handler233 as usize));
|
||||
set_intr_gate(234, 0, VirtAddr::new(irq_handler234 as usize));
|
||||
set_intr_gate(235, 0, VirtAddr::new(irq_handler235 as usize));
|
||||
set_intr_gate(236, 0, VirtAddr::new(irq_handler236 as usize));
|
||||
set_intr_gate(237, 0, VirtAddr::new(irq_handler237 as usize));
|
||||
set_intr_gate(238, 0, VirtAddr::new(irq_handler238 as usize));
|
||||
set_intr_gate(239, 0, VirtAddr::new(irq_handler239 as usize));
|
||||
set_intr_gate(240, 0, VirtAddr::new(irq_handler240 as usize));
|
||||
|
||||
set_intr_gate(241, 0, VirtAddr::new(irq_handler241 as usize));
|
||||
set_intr_gate(242, 0, VirtAddr::new(irq_handler242 as usize));
|
||||
set_intr_gate(243, 0, VirtAddr::new(irq_handler243 as usize));
|
||||
set_intr_gate(244, 0, VirtAddr::new(irq_handler244 as usize));
|
||||
set_intr_gate(245, 0, VirtAddr::new(irq_handler245 as usize));
|
||||
set_intr_gate(246, 0, VirtAddr::new(irq_handler246 as usize));
|
||||
set_intr_gate(247, 0, VirtAddr::new(irq_handler247 as usize));
|
||||
set_intr_gate(248, 0, VirtAddr::new(irq_handler248 as usize));
|
||||
set_intr_gate(249, 0, VirtAddr::new(irq_handler249 as usize));
|
||||
set_intr_gate(250, 0, VirtAddr::new(irq_handler250 as usize));
|
||||
|
||||
set_intr_gate(251, 0, VirtAddr::new(irq_handler251 as usize));
|
||||
set_intr_gate(252, 0, VirtAddr::new(irq_handler252 as usize));
|
||||
set_intr_gate(253, 0, VirtAddr::new(irq_handler253 as usize));
|
||||
set_intr_gate(254, 0, VirtAddr::new(irq_handler254 as usize));
|
||||
set_intr_gate(255, 0, VirtAddr::new(irq_handler255 as usize));
|
||||
}
|
||||
|
||||
/// 设置中断门(DPL=0)
|
||||
#[allow(dead_code)]
|
||||
pub unsafe fn set_intr_gate(irq: u32, ist: u8, vaddr: VirtAddr) {
|
||||
let idt_entry = get_idt_entry(irq);
|
||||
set_gate(idt_entry, 0x8E, ist, vaddr);
|
||||
}
|
||||
|
||||
/// 设置陷阱门(DPL=0)
|
||||
#[allow(dead_code)]
|
||||
pub unsafe fn set_trap_gate(irq: u32, ist: u8, vaddr: VirtAddr) {
|
||||
let idt_entry = get_idt_entry(irq);
|
||||
set_gate(idt_entry, 0x8F, ist, vaddr);
|
||||
}
|
||||
|
||||
/// 设置系统调用门(DPL=3)
|
||||
#[allow(dead_code)]
|
||||
pub unsafe fn set_system_trap_gate(irq: u32, ist: u8, vaddr: VirtAddr) {
|
||||
let idt_entry = get_idt_entry(irq);
|
||||
set_gate(idt_entry, 0xEF, ist, vaddr);
|
||||
}
|
||||
|
||||
unsafe fn get_idt_entry(irq: u32) -> &'static mut [u64] {
|
||||
assert!(irq < 256);
|
||||
let mut idt_vaddr =
|
||||
MMArch::phys_2_virt(PhysAddr::new(&IDT_Table as *const usize as usize)).unwrap();
|
||||
|
||||
idt_vaddr += irq as usize * 16;
|
||||
|
||||
let idt_entry = core::slice::from_raw_parts_mut(idt_vaddr.data() as *mut u64, 2);
|
||||
|
||||
idt_entry
|
||||
}
|
||||
unsafe fn set_gate(gate: &mut [u64], attr: u8, ist: u8, handler: VirtAddr) {
|
||||
assert_eq!(gate.len(), 2);
|
||||
let mut d0: u64 = 0;
|
||||
let mut d1: u64 = 0;
|
||||
|
||||
// 设置P、DPL、GateType
|
||||
d0 |= (attr as u64) << 40;
|
||||
// 设置IST
|
||||
d0 |= ((ist & 0x7) as u64) << 32;
|
||||
// 设置段选择子为0x10 ????
|
||||
d0 |= 0x8 << 16;
|
||||
|
||||
let mut handler = handler.data() as u64;
|
||||
// 设置偏移地址[0:15]
|
||||
|
||||
d0 |= handler & 0xFFFF;
|
||||
// 设置偏移地址[16:31]
|
||||
handler >>= 16;
|
||||
d0 |= (0xffff & handler) << 48;
|
||||
|
||||
// 设置偏移地址[32:63]
|
||||
handler >>= 16;
|
||||
d1 |= handler & 0xFFFFFFFF;
|
||||
|
||||
gate[0] = d0;
|
||||
gate[1] = d1;
|
||||
}
|
@ -67,6 +67,7 @@ impl Into<ApicId> for ArchIpiTarget {
|
||||
}
|
||||
|
||||
impl ArchIpiTarget {
|
||||
#[allow(dead_code)]
|
||||
pub fn shorthand(&self) -> u8 {
|
||||
match self {
|
||||
ArchIpiTarget::Specified(_) => 0,
|
||||
|
@ -1,16 +1,26 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
mod c_adapter;
|
||||
pub(super) mod entry;
|
||||
pub mod ipi;
|
||||
pub mod trap;
|
||||
|
||||
use core::{
|
||||
arch::asm,
|
||||
sync::atomic::{compiler_fence, Ordering},
|
||||
};
|
||||
|
||||
use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard};
|
||||
use system_error::SystemError;
|
||||
|
||||
use super::asm::irqflags::{local_irq_restore, local_irq_save};
|
||||
use crate::{
|
||||
arch::CurrentIrqArch,
|
||||
exception::{InterruptArch, IrqFlags, IrqFlagsGuard},
|
||||
};
|
||||
|
||||
use self::entry::setup_interrupt_gate;
|
||||
|
||||
use super::{
|
||||
asm::irqflags::{local_irq_restore, local_irq_save},
|
||||
driver::apic::{CurrentApic, LocalAPIC},
|
||||
};
|
||||
|
||||
/// @brief 关闭中断
|
||||
#[inline]
|
||||
@ -31,6 +41,13 @@ pub fn sti() {
|
||||
pub struct X86_64InterruptArch;
|
||||
|
||||
impl InterruptArch for X86_64InterruptArch {
|
||||
#[inline(never)]
|
||||
unsafe fn arch_irq_init() -> Result<(), SystemError> {
|
||||
CurrentIrqArch::interrupt_disable();
|
||||
setup_interrupt_gate();
|
||||
CurrentApic.init_current_cpu();
|
||||
return Ok(());
|
||||
}
|
||||
unsafe fn interrupt_enable() {
|
||||
sti();
|
||||
}
|
||||
|
438
kernel/src/arch/x86_64/interrupt/trap.rs
Normal file
438
kernel/src/arch/x86_64/interrupt/trap.rs
Normal file
@ -0,0 +1,438 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::CurrentIrqArch, exception::InterruptArch, kerror, kwarn, mm::VirtAddr, print,
|
||||
process::ProcessManager, smp::core::smp_get_processor_id,
|
||||
};
|
||||
|
||||
use super::{
|
||||
entry::{set_intr_gate, set_system_trap_gate},
|
||||
TrapFrame,
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
fn trap_divide_error();
|
||||
fn trap_debug();
|
||||
fn trap_nmi();
|
||||
fn trap_int3();
|
||||
fn trap_overflow();
|
||||
fn trap_bounds();
|
||||
fn trap_undefined_opcode();
|
||||
fn trap_dev_not_avaliable();
|
||||
fn trap_double_fault();
|
||||
fn trap_coprocessor_segment_overrun();
|
||||
fn trap_invalid_TSS();
|
||||
fn trap_segment_not_exists();
|
||||
fn trap_stack_segment_fault();
|
||||
fn trap_general_protection();
|
||||
fn trap_page_fault();
|
||||
fn trap_x87_FPU_error();
|
||||
fn trap_alignment_check();
|
||||
fn trap_machine_check();
|
||||
fn trap_SIMD_exception();
|
||||
fn trap_virtualization_exception();
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn arch_trap_init() -> Result<(), SystemError> {
|
||||
unsafe {
|
||||
set_intr_gate(0, 0, VirtAddr::new(trap_divide_error as usize));
|
||||
set_intr_gate(1, 0, VirtAddr::new(trap_debug as usize));
|
||||
set_intr_gate(2, 0, VirtAddr::new(trap_nmi as usize));
|
||||
set_system_trap_gate(3, 0, VirtAddr::new(trap_int3 as usize));
|
||||
set_system_trap_gate(4, 0, VirtAddr::new(trap_overflow as usize));
|
||||
set_system_trap_gate(5, 0, VirtAddr::new(trap_bounds as usize));
|
||||
set_intr_gate(6, 0, VirtAddr::new(trap_undefined_opcode as usize));
|
||||
set_intr_gate(7, 0, VirtAddr::new(trap_dev_not_avaliable as usize));
|
||||
set_intr_gate(8, 0, VirtAddr::new(trap_double_fault as usize));
|
||||
set_intr_gate(
|
||||
9,
|
||||
0,
|
||||
VirtAddr::new(trap_coprocessor_segment_overrun as usize),
|
||||
);
|
||||
set_intr_gate(10, 0, VirtAddr::new(trap_invalid_TSS as usize));
|
||||
set_intr_gate(11, 0, VirtAddr::new(trap_segment_not_exists as usize));
|
||||
set_intr_gate(12, 0, VirtAddr::new(trap_stack_segment_fault as usize));
|
||||
set_intr_gate(13, 0, VirtAddr::new(trap_general_protection as usize));
|
||||
set_intr_gate(14, 0, VirtAddr::new(trap_page_fault as usize));
|
||||
// 中断号15由Intel保留,不能使用
|
||||
set_intr_gate(16, 0, VirtAddr::new(trap_x87_FPU_error as usize));
|
||||
set_intr_gate(17, 0, VirtAddr::new(trap_alignment_check as usize));
|
||||
set_intr_gate(18, 0, VirtAddr::new(trap_machine_check as usize));
|
||||
set_intr_gate(19, 0, VirtAddr::new(trap_SIMD_exception as usize));
|
||||
set_intr_gate(20, 0, VirtAddr::new(trap_virtualization_exception as usize));
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
/// 处理除法错误 0 #DE
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_divide_error(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_divide_error(0), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Divide Error");
|
||||
}
|
||||
|
||||
/// 处理调试异常 1 #DB
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_debug(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_debug(1), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Debug Exception");
|
||||
}
|
||||
|
||||
/// 处理NMI中断 2 NMI
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_nmi(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_nmi(2), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("NMI Interrupt");
|
||||
}
|
||||
|
||||
/// 处理断点异常 3 #BP
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_int3(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_int3(3), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Int3");
|
||||
}
|
||||
|
||||
/// 处理溢出异常 4 #OF
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_overflow(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_overflow(4), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Overflow Exception");
|
||||
}
|
||||
|
||||
/// 处理BOUND指令检查异常 5 #BR
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_bounds(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_bounds(5), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Bounds Check");
|
||||
}
|
||||
|
||||
/// 处理未定义操作码异常 6 #UD
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_undefined_opcode(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_undefined_opcode(6), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Undefined Opcode");
|
||||
}
|
||||
|
||||
/// 处理设备不可用异常(FPU不存在) 7 #NM
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_dev_not_avaliable(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_dev_not_avaliable(7), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Device Not Available");
|
||||
}
|
||||
|
||||
/// 处理双重错误 8 #DF
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_double_fault(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_double_fault(8), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Double Fault");
|
||||
}
|
||||
|
||||
/// 处理协处理器段越界 9 #MF
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_coprocessor_segment_overrun(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_coprocessor_segment_overrun(9), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Coprocessor Segment Overrun");
|
||||
}
|
||||
|
||||
/// 处理无效TSS 10 #TS
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_invalid_TSS(regs: &'static TrapFrame, error_code: u64) {
|
||||
const ERR_MSG_1: &str =
|
||||
"The exception occurred during delivery of an event external to the program.\n";
|
||||
const ERR_MSG_2: &str = "Refers to a descriptor in the IDT.\n";
|
||||
const ERR_MSG_3: &str = "Refers to a descriptor in the current LDT.\n";
|
||||
const ERR_MSG_4: &str = "Refers to a descriptor in the GDT.\n";
|
||||
|
||||
let msg1: &str;
|
||||
if (error_code & 0x1) != 0 {
|
||||
msg1 = ERR_MSG_1;
|
||||
} else {
|
||||
msg1 = "";
|
||||
}
|
||||
|
||||
let msg2: &str;
|
||||
if (error_code & 0x02) != 0 {
|
||||
msg2 = ERR_MSG_2;
|
||||
} else {
|
||||
if (error_code & 0x04) != 0 {
|
||||
msg2 = ERR_MSG_3;
|
||||
} else {
|
||||
msg2 = ERR_MSG_4;
|
||||
}
|
||||
}
|
||||
kerror!(
|
||||
"do_invalid_TSS(10), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}\n{}{}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid(),
|
||||
msg1,
|
||||
msg2
|
||||
);
|
||||
panic!("Invalid TSS");
|
||||
}
|
||||
|
||||
/// 处理段不存在 11 #NP
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_segment_not_exists(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_segment_not_exists(11), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Segment Not Exists");
|
||||
}
|
||||
|
||||
/// 处理栈段错误 12 #SS
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_stack_segment_fault(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_stack_segment_fault(12), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Stack Segment Fault");
|
||||
}
|
||||
|
||||
/// 处理一般保护异常 13 #GP
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_general_protection(regs: &'static TrapFrame, error_code: u64) {
|
||||
const ERR_MSG_1: &str = "The exception occurred during delivery of an event external to the program, such as an interrupt or an earlier exception.";
|
||||
const ERR_MSG_2: &str = "Refers to a gate descriptor in the IDT;\n";
|
||||
const ERR_MSG_3: &str = "Refers to a descriptor in the GDT or the current LDT;\n";
|
||||
const ERR_MSG_4: &str = "Refers to a segment or gate descriptor in the LDT;\n";
|
||||
const ERR_MSG_5: &str = "Refers to a descriptor in the current GDT;\n";
|
||||
|
||||
let msg1: &str;
|
||||
if (error_code & 0x1) != 0 {
|
||||
msg1 = ERR_MSG_1;
|
||||
} else {
|
||||
msg1 = "";
|
||||
}
|
||||
|
||||
let msg2: &str;
|
||||
if (error_code & 0x02) != 0 {
|
||||
msg2 = ERR_MSG_2;
|
||||
} else {
|
||||
msg2 = ERR_MSG_3;
|
||||
}
|
||||
|
||||
let msg3: &str;
|
||||
if (error_code & 0x02) == 0 {
|
||||
if (error_code & 0x04) != 0 {
|
||||
msg3 = ERR_MSG_4;
|
||||
} else {
|
||||
msg3 = ERR_MSG_5;
|
||||
}
|
||||
} else {
|
||||
msg3 = "";
|
||||
}
|
||||
kerror!(
|
||||
"do_general_protection(13), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}
|
||||
{}{}{}
|
||||
Segment Selector Index: {:#x}\n
|
||||
",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid(),
|
||||
msg1, msg2, msg3,
|
||||
error_code & 0xfff8
|
||||
);
|
||||
panic!("General Protection");
|
||||
}
|
||||
|
||||
/// 处理页错误 14 #PF
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_page_fault(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_page_fault(14), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}, \nFault Address: {:#x}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid(),
|
||||
x86::controlregs::cr2()
|
||||
);
|
||||
|
||||
if (error_code & 0x01) == 0 {
|
||||
print!("Page Not Present,\t");
|
||||
}
|
||||
if (error_code & 0x02) != 0 {
|
||||
print!("Write Access,\t");
|
||||
} else {
|
||||
print!("Read Access,\t");
|
||||
}
|
||||
|
||||
if (error_code & 0x04) != 0 {
|
||||
print!("Fault in user(3),\t");
|
||||
} else {
|
||||
print!("Fault in supervisor(0,1,2),\t");
|
||||
}
|
||||
|
||||
if (error_code & 0x08) != 0 {
|
||||
print!("Reserved bit violation cause fault,\t");
|
||||
}
|
||||
|
||||
if (error_code & 0x10) != 0 {
|
||||
print!("Instruction fetch cause fault,\t");
|
||||
}
|
||||
print!("\n");
|
||||
|
||||
CurrentIrqArch::interrupt_enable();
|
||||
panic!("Page Fault");
|
||||
}
|
||||
|
||||
/// 处理x87 FPU错误 16 #MF
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_x87_FPU_error(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_x87_FPU_error(16), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("x87 FPU Error");
|
||||
}
|
||||
|
||||
/// 处理对齐检查 17 #AC
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_alignment_check(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_alignment_check(17), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Alignment Check");
|
||||
}
|
||||
|
||||
/// 处理机器检查 18 #MC
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_machine_check(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_machine_check(18), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Machine Check");
|
||||
}
|
||||
|
||||
/// 处理SIMD异常 19 #XM
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_SIMD_exception(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_SIMD_exception(19), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("SIMD Exception");
|
||||
}
|
||||
|
||||
/// 处理虚拟化异常 20 #VE
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn do_virtualization_exception(regs: &'static TrapFrame, error_code: u64) {
|
||||
kerror!(
|
||||
"do_virtualization_exception(20), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
|
||||
error_code,
|
||||
regs.rsp,
|
||||
regs.rip,
|
||||
smp_get_processor_id(),
|
||||
ProcessManager::current_pid()
|
||||
);
|
||||
panic!("Virtualization Exception");
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn ignore_int_handler(_regs: &'static TrapFrame, _error_code: u64) {
|
||||
kwarn!("Unknown interrupt.");
|
||||
}
|
@ -10,7 +10,7 @@ use super::CurrentIrqArch;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sched() {
|
||||
unsafe {
|
||||
enter_syscall_int(SYS_SCHED as u64, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
enter_syscall_int(SYS_SCHED as u64, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
use core::ffi::c_void;
|
||||
|
||||
use crate::{
|
||||
arch::{
|
||||
ipc::signal::X86_64SignalArch,
|
||||
@ -7,7 +5,6 @@ use crate::{
|
||||
CurrentIrqArch,
|
||||
},
|
||||
exception::InterruptArch,
|
||||
include::bindings::bindings::set_system_trap_gate,
|
||||
ipc::signal_types::SignalArch,
|
||||
libs::align::SafeForZero,
|
||||
mm::VirtAddr,
|
||||
@ -17,7 +14,10 @@ use crate::{
|
||||
use alloc::string::String;
|
||||
use system_error::SystemError;
|
||||
|
||||
use super::{interrupt::TrapFrame, mm::barrier::mfence};
|
||||
use super::{
|
||||
interrupt::{entry::set_system_trap_gate, TrapFrame},
|
||||
mm::barrier::mfence,
|
||||
};
|
||||
|
||||
pub mod nr;
|
||||
|
||||
@ -128,7 +128,7 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () {
|
||||
/// 系统调用初始化
|
||||
pub fn arch_syscall_init() -> Result<(), SystemError> {
|
||||
// kinfo!("arch_syscall_init\n");
|
||||
unsafe { set_system_trap_gate(0x80, 0, syscall_int as *mut c_void) }; // 系统调用门
|
||||
unsafe { set_system_trap_gate(0x80, 0, VirtAddr::new(syscall_int as usize)) }; // 系统调用门
|
||||
unsafe { init_syscall_64() };
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -2,10 +2,7 @@
|
||||
CFLAGS += -I .
|
||||
|
||||
|
||||
all: irq.o trap.o
|
||||
|
||||
trap.o: trap.c
|
||||
$(CC) $(CFLAGS) -c trap.c -o trap.o
|
||||
all: irq.o
|
||||
|
||||
irq.o: irq.c
|
||||
$(CC) $(CFLAGS) -c irq.c -o irq.o
|
@ -1,199 +0,0 @@
|
||||
/**
|
||||
* @file gate.h
|
||||
* @author longjin
|
||||
* @brief 门定义
|
||||
* @date 2022-01-24
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GATE_H__
|
||||
#define __GATE_H__
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
|
||||
#if ARCH(I386) || ARCH(X86_64)
|
||||
#include <common/kprint.h>
|
||||
#include <mm/mm.h>
|
||||
|
||||
// 描述符表的结构体
|
||||
struct desc_struct
|
||||
{
|
||||
unsigned char x[8];
|
||||
};
|
||||
|
||||
// 门的结构体
|
||||
struct gate_struct
|
||||
{
|
||||
unsigned char x[16];
|
||||
};
|
||||
|
||||
extern struct desc_struct GDT_Table[]; // GDT_Table是head.S中的GDT_Table
|
||||
extern struct gate_struct IDT_Table[]; // IDT_Table是head.S中的IDT_Table
|
||||
// extern unsigned int TSS64_Table[26];
|
||||
|
||||
struct gdtr
|
||||
{
|
||||
uint16_t size;
|
||||
uint64_t gdt_vaddr;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct idtr
|
||||
{
|
||||
uint16_t size;
|
||||
uint64_t idt_vaddr;
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* @brief 初始化中段描述符表内的门描述符(每个16B)
|
||||
* @param gate_selector_addr IDT表项的地址
|
||||
* @param attr P、DPL、TYPE的属性
|
||||
* @param ist 中断栈表号
|
||||
* @param code_addr 指向中断服务程序的指针的地址
|
||||
*/
|
||||
|
||||
void set_gate(ul *gate_selector_addr, ul attr, unsigned char ist, ul *code_addr)
|
||||
{
|
||||
ul __d0 = 0, __d1 = 0;
|
||||
ul tmp_code_addr = *code_addr;
|
||||
__d0 = attr << 40; // 设置P、DPL、Type
|
||||
|
||||
__d0 |= ((ul)(ist) << 32); // 设置ist
|
||||
|
||||
__d0 |= 8 << 16; // 设置段选择子为0x1000
|
||||
|
||||
__d0 |= (0xffff & tmp_code_addr); // 设置段内偏移的[15:00]
|
||||
|
||||
tmp_code_addr >>= 16;
|
||||
__d0 |= (0xffff & tmp_code_addr) << 48; // 设置段内偏移[31:16]
|
||||
|
||||
tmp_code_addr >>= 16;
|
||||
|
||||
__d1 = (0xffffffff & tmp_code_addr); // 设置段内偏移[63:32]
|
||||
|
||||
*gate_selector_addr = __d0;
|
||||
*(gate_selector_addr + 1) = __d1;
|
||||
}
|
||||
|
||||
#define _set_gate(gate_selector_addr, attr, ist, code_addr) \
|
||||
do \
|
||||
{ \
|
||||
unsigned long __d0, __d1; \
|
||||
__asm__ __volatile__("movw %%dx, %%ax \n\t" \
|
||||
"andq $0x7, %%rcx \n\t" \
|
||||
"addq %4, %%rcx \n\t" \
|
||||
"shlq $32, %%rcx \n\t" \
|
||||
"addq %%rcx, %%rax \n\t" \
|
||||
"xorq %%rcx, %%rcx \n\t" \
|
||||
"movl %%edx, %%ecx \n\t" \
|
||||
"shrq $16, %%rcx \n\t" \
|
||||
"shlq $48, %%rcx \n\t" \
|
||||
"addq %%rcx, %%rax \n\t" \
|
||||
"movq %%rax, %0 \n\t" \
|
||||
"shrq $32, %%rdx \n\t" \
|
||||
"movq %%rdx, %1 \n\t" \
|
||||
: "=m"(*((unsigned long *)(gate_selector_addr))), \
|
||||
"=m"(*(1 + (unsigned long *)(gate_selector_addr))), "=&a"(__d0), "=&d"(__d1) \
|
||||
: "i"(attr << 8), \
|
||||
"3"((unsigned long *)(code_addr)), "2"(0x8 << 16), "c"(ist) \
|
||||
: "memory"); \
|
||||
} while (0)
|
||||
|
||||
void set_tss_descriptor(unsigned int n, void *addr)
|
||||
{
|
||||
|
||||
unsigned long limit = 103;
|
||||
|
||||
*(unsigned long *)(phys_2_virt(GDT_Table + n)) = (limit & 0xffff) | (((unsigned long)addr & 0xffff) << 16) | ((((unsigned long)addr >> 16) & 0xff) << 32) | ((unsigned long)0x89 << 40) | ((limit >> 16 & 0xf) << 48) | (((unsigned long)addr >> 24 & 0xff) << 56); /////89 is attribute
|
||||
*(unsigned long *)(phys_2_virt(GDT_Table + n + 1)) = (((unsigned long)addr >> 32) & 0xffffffff) | 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 加载任务状态段寄存器
|
||||
* @param n TSS基地址在GDT中的第几项
|
||||
* 左移3位的原因是GDT每项占8字节
|
||||
*/
|
||||
#define load_TR(n) \
|
||||
do \
|
||||
{ \
|
||||
__asm__ __volatile__("ltr %%ax" ::"a"((n) << 3)); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief 设置中断门
|
||||
*
|
||||
* @param n 中断号
|
||||
* @param ist ist
|
||||
* @param addr 服务程序的地址
|
||||
*/
|
||||
void set_intr_gate(unsigned int n, unsigned char ist, void *addr)
|
||||
{
|
||||
_set_gate(phys_2_virt(IDT_Table + n), 0x8E, ist, addr); // p=1,DPL=0, type=E
|
||||
|
||||
// set_gate((ul *)phys_2_virt(IDT_Table + n), 0x8E, ist, (ul *)(addr)); // p=1,DPL=0, type=E
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置64位,DPL=0的陷阱门
|
||||
*
|
||||
* @param n 中断号
|
||||
* @param ist ist
|
||||
* @param addr 服务程序的地址
|
||||
*/
|
||||
void set_trap_gate(unsigned int n, unsigned char ist, void *addr)
|
||||
{
|
||||
// kdebug("addr=%#018lx", (ul)(addr));
|
||||
|
||||
// set_gate((ul *)phys_2_virt(IDT_Table + n), 0x8F, ist, (ul *)(addr)); // p=1,DPL=0, type=F
|
||||
_set_gate(phys_2_virt(IDT_Table + n), 0x8F, ist, addr); // p=1,DPL=0, type=F
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置64位,DPL=3的陷阱门
|
||||
*
|
||||
* @param n 中断号
|
||||
* @param ist ist
|
||||
* @param addr 服务程序的地址
|
||||
*/
|
||||
void set_system_trap_gate(unsigned int n, unsigned char ist, void *addr)
|
||||
{
|
||||
// kdebug("addr=%#018lx", (ul)(addr));
|
||||
|
||||
// set_gate((ul *)phys_2_virt(IDT_Table + n), 0xEF, ist, (ul *)(addr)); // p=1,DPL=3, type=F
|
||||
_set_gate(phys_2_virt(IDT_Table + n), 0xEF, ist, addr); // p=1,DPL=3, type=F
|
||||
}
|
||||
|
||||
static inline void set_system_intr_gate(unsigned int n, unsigned char ist, void *addr) // int3
|
||||
{
|
||||
_set_gate(phys_2_virt(IDT_Table + n), 0xEE, ist, addr); // P,DPL=3,TYPE=E
|
||||
}
|
||||
/**
|
||||
* @brief 初始化TSS表的内容
|
||||
*
|
||||
*/
|
||||
|
||||
void set_tss64(unsigned int *Table, unsigned long rsp0, unsigned long rsp1, unsigned long rsp2, unsigned long ist1, unsigned long ist2, unsigned long ist3,
|
||||
unsigned long ist4, unsigned long ist5, unsigned long ist6, unsigned long ist7)
|
||||
{
|
||||
*(unsigned long *)(Table + 1) = rsp0;
|
||||
*(unsigned long *)(Table + 3) = rsp1;
|
||||
*(unsigned long *)(Table + 5) = rsp2;
|
||||
|
||||
*(unsigned long *)(Table + 9) = ist1;
|
||||
*(unsigned long *)(Table + 11) = ist2;
|
||||
*(unsigned long *)(Table + 13) = ist3;
|
||||
*(unsigned long *)(Table + 15) = ist4;
|
||||
*(unsigned long *)(Table + 17) = ist5;
|
||||
*(unsigned long *)(Table + 19) = ist6;
|
||||
*(unsigned long *)(Table + 21) = ist7;
|
||||
}
|
||||
|
||||
#else
|
||||
void set_intr_gate(unsigned int n, unsigned char ist, void *addr)
|
||||
{
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma GCC pop_options
|
||||
#endif
|
15
kernel/src/exception/init.rs
Normal file
15
kernel/src/exception/init.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::arch::CurrentIrqArch;
|
||||
|
||||
use super::InterruptArch;
|
||||
|
||||
/// 初始化中断
|
||||
#[inline(never)]
|
||||
pub fn irq_init() -> Result<(), SystemError> {
|
||||
// todo: 通用初始化
|
||||
|
||||
// 初始化架构相关的中断
|
||||
unsafe { CurrentIrqArch::arch_irq_init() }?;
|
||||
return Ok(());
|
||||
}
|
@ -2,196 +2,16 @@
|
||||
#include "irq.h"
|
||||
#include <common/errno.h>
|
||||
|
||||
#if _INTR_8259A_
|
||||
#include <driver/interrupt/8259A/8259A.h>
|
||||
#else
|
||||
#include <arch/x86_64/driver/apic/apic.h>
|
||||
#endif
|
||||
|
||||
#include "gate.h"
|
||||
#include <common/asm.h>
|
||||
#include <common/printk.h>
|
||||
#include <common/string.h>
|
||||
#include <mm/slab.h>
|
||||
#include <arch/arch.h>
|
||||
extern void ignore_int();
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
|
||||
// 定义IRQ处理函数的名字格式:IRQ+中断号+interrupt
|
||||
#define IRQ_NAME2(name1) name1##interrupt(void)
|
||||
#define IRQ_NAME(number) IRQ_NAME2(IRQ##number)
|
||||
|
||||
#if ARCH(I386) || ARCH(X86_64)
|
||||
|
||||
// 保存函数调用现场的寄存器
|
||||
#define SAVE_ALL_REGS \
|
||||
"cld; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"movq %es, %rax; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"movq %ds, %rax; \n\t" \
|
||||
"pushq %rax; \n\t" \
|
||||
"xorq %rax, %rax;\n\t" \
|
||||
"pushq %rbp; \n\t" \
|
||||
"pushq %rdi; \n\t" \
|
||||
"pushq %rsi; \n\t" \
|
||||
"pushq %rdx; \n\t" \
|
||||
"pushq %rcx; \n\t" \
|
||||
"pushq %rbx; \n\t" \
|
||||
"pushq %r8 ; \n\t" \
|
||||
"pushq %r9 ; \n\t" \
|
||||
"pushq %r10; \n\t" \
|
||||
"pushq %r11; \n\t" \
|
||||
"pushq %r12; \n\t" \
|
||||
"pushq %r13; \n\t" \
|
||||
"pushq %r14; \n\t" \
|
||||
"pushq %r15; \n\t" \
|
||||
"movq $0x10, %rdx;\n\t" \
|
||||
"movq %rdx, %ds; \n\t" \
|
||||
"movq %rdx, %es; \n\t"
|
||||
|
||||
|
||||
|
||||
// 构造中断entry
|
||||
// 为了复用返回函数的代码,需要压入一个错误码0
|
||||
// todo: 将这里改为volatile,也许能解决编译选项为O1时,系统崩溃的问题
|
||||
#define Build_IRQ(number) \
|
||||
void IRQ_NAME(number); \
|
||||
__asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt: \n\t" \
|
||||
"pushq $0x00 \n\t" SAVE_ALL_REGS "movq %rsp, %rdi \n\t" \
|
||||
"leaq ret_from_intr(%rip), %rax \n\t" \
|
||||
"pushq %rax \n\t" \
|
||||
"movq $" #number ", %rsi \n\t" \
|
||||
"jmp do_IRQ \n\t");
|
||||
#elif ARCH(riscv)
|
||||
#define Build_IRQ(number) \
|
||||
void IRQ_NAME(number); \
|
||||
__asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt: \n\t" \
|
||||
"loopirq_"#number":\n\t"\
|
||||
"j loopirq_"#number"\n\t");
|
||||
#else
|
||||
#define Build_IRQ(number) ()
|
||||
#endif
|
||||
// 构造中断入口
|
||||
Build_IRQ(0x20);
|
||||
Build_IRQ(0x21);
|
||||
Build_IRQ(0x22);
|
||||
Build_IRQ(0x23);
|
||||
Build_IRQ(0x24);
|
||||
Build_IRQ(0x25);
|
||||
Build_IRQ(0x26);
|
||||
Build_IRQ(0x27);
|
||||
Build_IRQ(0x28);
|
||||
Build_IRQ(0x29);
|
||||
Build_IRQ(0x2a);
|
||||
Build_IRQ(0x2b);
|
||||
Build_IRQ(0x2c);
|
||||
Build_IRQ(0x2d);
|
||||
Build_IRQ(0x2e);
|
||||
Build_IRQ(0x2f);
|
||||
Build_IRQ(0x30);
|
||||
Build_IRQ(0x31);
|
||||
Build_IRQ(0x32);
|
||||
Build_IRQ(0x33);
|
||||
Build_IRQ(0x34);
|
||||
Build_IRQ(0x35);
|
||||
Build_IRQ(0x36);
|
||||
Build_IRQ(0x37);
|
||||
Build_IRQ(0x38);
|
||||
Build_IRQ(0x39);
|
||||
|
||||
// 初始化中断数组
|
||||
void (*interrupt_table[IRQ_NUM])(void) = {
|
||||
IRQ0x20interrupt,
|
||||
IRQ0x21interrupt,
|
||||
IRQ0x22interrupt,
|
||||
IRQ0x23interrupt,
|
||||
IRQ0x24interrupt,
|
||||
IRQ0x25interrupt,
|
||||
IRQ0x26interrupt,
|
||||
IRQ0x27interrupt,
|
||||
IRQ0x28interrupt,
|
||||
IRQ0x29interrupt,
|
||||
IRQ0x2ainterrupt,
|
||||
IRQ0x2binterrupt,
|
||||
IRQ0x2cinterrupt,
|
||||
IRQ0x2dinterrupt,
|
||||
IRQ0x2einterrupt,
|
||||
IRQ0x2finterrupt,
|
||||
IRQ0x30interrupt,
|
||||
IRQ0x31interrupt,
|
||||
IRQ0x32interrupt,
|
||||
IRQ0x33interrupt,
|
||||
IRQ0x34interrupt,
|
||||
IRQ0x35interrupt,
|
||||
IRQ0x36interrupt,
|
||||
IRQ0x37interrupt,
|
||||
IRQ0x38interrupt,
|
||||
IRQ0x39interrupt,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 声明10个IPI消息处理程序,向量号从200(0xc8)开始
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
Build_IRQ(0xc8);
|
||||
Build_IRQ(0xc9);
|
||||
Build_IRQ(0xca);
|
||||
Build_IRQ(0xcb);
|
||||
Build_IRQ(0xcc);
|
||||
Build_IRQ(0xcd);
|
||||
Build_IRQ(0xce);
|
||||
Build_IRQ(0xcf);
|
||||
Build_IRQ(0xd0);
|
||||
Build_IRQ(0xd1);
|
||||
|
||||
Build_IRQ(0x80); // 系统调用入口
|
||||
void (*syscall_intr_table[1])(void) = {IRQ0x80interrupt};
|
||||
|
||||
// 初始化IPI中断服务程序数组
|
||||
void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) = {
|
||||
IRQ0xc8interrupt,
|
||||
IRQ0xc9interrupt,
|
||||
IRQ0xcainterrupt,
|
||||
IRQ0xcbinterrupt,
|
||||
IRQ0xccinterrupt,
|
||||
IRQ0xcdinterrupt,
|
||||
IRQ0xceinterrupt,
|
||||
IRQ0xcfinterrupt,
|
||||
IRQ0xd0interrupt,
|
||||
IRQ0xd1interrupt,
|
||||
};
|
||||
|
||||
// 初始化local apic中断服务程序数组
|
||||
Build_IRQ(0x96);
|
||||
Build_IRQ(0x97);
|
||||
Build_IRQ(0x98);
|
||||
Build_IRQ(0x99);
|
||||
Build_IRQ(0x9a);
|
||||
Build_IRQ(0x9b);
|
||||
Build_IRQ(0x9c);
|
||||
Build_IRQ(0x9d);
|
||||
Build_IRQ(0x9e);
|
||||
Build_IRQ(0x9f);
|
||||
void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) = {
|
||||
IRQ0x96interrupt,
|
||||
IRQ0x97interrupt,
|
||||
IRQ0x98interrupt,
|
||||
IRQ0x99interrupt,
|
||||
IRQ0x9ainterrupt,
|
||||
IRQ0x9binterrupt,
|
||||
IRQ0x9cinterrupt,
|
||||
IRQ0x9dinterrupt,
|
||||
IRQ0x9einterrupt,
|
||||
IRQ0x9finterrupt,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 中断注册函数
|
||||
*
|
||||
@ -261,20 +81,4 @@ int irq_unregister(ul irq_num)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化中断模块
|
||||
*/
|
||||
void irq_init()
|
||||
{
|
||||
#if _INTR_8259A_
|
||||
init_8259A();
|
||||
#else
|
||||
|
||||
#if ARCH(I386) || ARCH(X86_64)
|
||||
memset((void *)interrupt_desc, 0, sizeof(irq_desc_t) * IRQ_NUM);
|
||||
apic_init();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
#pragma GCC optimize("O0")
|
||||
|
@ -1,18 +1,23 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::arch::CurrentIrqArch;
|
||||
|
||||
pub mod init;
|
||||
pub mod ipi;
|
||||
pub mod softirq;
|
||||
|
||||
/// @brief 中断相关的操作
|
||||
/// 中断的架构相关的trait
|
||||
pub trait InterruptArch: Send + Sync {
|
||||
/// @brief 使能中断
|
||||
/// 架构相关的中断初始化
|
||||
unsafe fn arch_irq_init() -> Result<(), SystemError>;
|
||||
/// 使能中断
|
||||
unsafe fn interrupt_enable();
|
||||
/// @brief 禁止中断
|
||||
/// 禁止中断
|
||||
unsafe fn interrupt_disable();
|
||||
/// @brief 检查中断是否被禁止
|
||||
/// 检查中断是否被禁止
|
||||
fn is_irq_enabled() -> bool;
|
||||
|
||||
/// @brief 保存当前中断状态,并且禁止中断
|
||||
/// 保存当前中断状态,并且禁止中断
|
||||
unsafe fn save_and_disable_irq() -> IrqFlagsGuard;
|
||||
unsafe fn restore_irq(flags: IrqFlags);
|
||||
}
|
||||
|
@ -1,344 +0,0 @@
|
||||
#include "trap.h"
|
||||
#include "gate.h"
|
||||
#include <common/kprint.h>
|
||||
#include <debug/traceback/traceback.h>
|
||||
#include <process/process.h>
|
||||
#include <process/ptrace.h>
|
||||
#include <sched/sched.h>
|
||||
#include <arch/arch.h>
|
||||
|
||||
extern void ignore_int();
|
||||
|
||||
// 0 #DE 除法错误
|
||||
void do_divide_error(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
// kerror("do_divide_error(0)");
|
||||
kerror("do_divide_error(0),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\t pid=%d\n", error_code,
|
||||
regs->rsp, regs->rip, rs_current_cpu_id(), rs_current_pcb_pid());
|
||||
traceback(regs);
|
||||
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 1 #DB 调试异常
|
||||
void do_debug(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
printk("[ ");
|
||||
printk_color(RED, BLACK, "ERROR / TRAP");
|
||||
printk(" ] do_debug(1),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid:%d\n", error_code, regs->rsp, regs->rip,
|
||||
rs_current_pcb_cpuid(), rs_current_pcb_pid());
|
||||
|
||||
while (1)
|
||||
hlt();
|
||||
}
|
||||
|
||||
// 2 不可屏蔽中断
|
||||
void do_nmi(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
printk("[ ");
|
||||
printk_color(BLUE, BLACK, "INT");
|
||||
printk(" ] do_nmi(2),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip,
|
||||
rs_current_pcb_cpuid());
|
||||
|
||||
while (1)
|
||||
hlt();
|
||||
}
|
||||
|
||||
// 3 #BP 断点异常
|
||||
void do_int3(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
printk("[ ");
|
||||
printk_color(YELLOW, BLACK, "TRAP");
|
||||
printk(" ] do_int3(3),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip,
|
||||
rs_current_pcb_cpuid());
|
||||
|
||||
while (1)
|
||||
hlt();
|
||||
}
|
||||
|
||||
// 4 #OF 溢出异常
|
||||
void do_overflow(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
printk("[ ");
|
||||
printk_color(YELLOW, BLACK, "TRAP");
|
||||
printk(" ] do_overflow(4),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, rs_current_pcb_cpuid());
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 5 #BR 越界异常
|
||||
void do_bounds(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_bounds(5),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip,
|
||||
rs_current_pcb_cpuid());
|
||||
|
||||
while (1)
|
||||
hlt();
|
||||
}
|
||||
|
||||
// 6 #UD 无效/未定义的机器码
|
||||
void do_undefined_opcode(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_undefined_opcode(6),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid:%ld", error_code,
|
||||
regs->rsp, regs->rip, rs_current_pcb_cpuid(), rs_current_pcb_pid());
|
||||
traceback(regs);
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 7 #NM 设备异常(FPU不存在)
|
||||
void do_dev_not_avaliable(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_dev_not_avaliable(7),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid=%d\n", error_code, regs->rsp,
|
||||
regs->rip, rs_current_pcb_cpuid(), rs_current_pcb_pid());
|
||||
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 8 #DF 双重错误
|
||||
void do_double_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
printk("[ ");
|
||||
printk_color(RED, BLACK, "Terminate");
|
||||
printk(" ] do_double_fault(8),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, rs_current_pcb_cpuid());
|
||||
traceback(regs);
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 9 协处理器越界(保留)
|
||||
void do_coprocessor_segment_overrun(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_coprocessor_segment_overrun(9),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code,
|
||||
regs->rsp, regs->rip, rs_current_pcb_cpuid());
|
||||
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 10 #TS 无效的TSS段
|
||||
void do_invalid_TSS(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
printk("[");
|
||||
printk_color(RED, BLACK, "ERROR");
|
||||
printk("] do_invalid_TSS(10),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, rs_current_pcb_cpuid());
|
||||
|
||||
printk_color(YELLOW, BLACK, "Information:\n");
|
||||
// 解析错误码
|
||||
if (error_code & 0x01)
|
||||
printk("The exception occurred during delivery of an event external to the program.\n");
|
||||
|
||||
if (error_code & 0x02)
|
||||
printk("Refers to a descriptor in the IDT.\n");
|
||||
else
|
||||
{
|
||||
if (error_code & 0x04)
|
||||
printk("Refers to a descriptor in the current LDT.\n");
|
||||
else
|
||||
printk("Refers to a descriptor in the GDT.\n");
|
||||
}
|
||||
|
||||
printk("Segment Selector Index:%10x\n", error_code & 0xfff8);
|
||||
|
||||
printk("\n");
|
||||
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 11 #NP 段不存在
|
||||
void do_segment_not_exists(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_segment_not_exists(11),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, rs_current_pcb_cpuid());
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 12 #SS SS段错误
|
||||
void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_stack_segment_fault(12),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, rs_current_pcb_cpuid());
|
||||
// kinfo("cs=%#04x, ds=%#04x, ss=%#04x", regs->cs, regs->ds, regs->ss);
|
||||
traceback(regs);
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 13 #GP 通用保护性异常
|
||||
void do_general_protection(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\tpid=%ld\n", error_code,
|
||||
regs->rsp, regs->rip, rs_current_pcb_cpuid(), rs_current_pcb_pid());
|
||||
if (error_code & 0x01)
|
||||
printk_color(RED, BLACK,
|
||||
"The exception occurred during delivery of an event external to the program,such as an interrupt "
|
||||
"or an earlier exception.\n");
|
||||
|
||||
if (error_code & 0x02)
|
||||
printk_color(RED, BLACK, "Refers to a gate descriptor in the IDT;\n");
|
||||
else
|
||||
printk_color(RED, BLACK, "Refers to a descriptor in the GDT or the current LDT;\n");
|
||||
|
||||
if ((error_code & 0x02) == 0)
|
||||
if (error_code & 0x04)
|
||||
printk_color(RED, BLACK, "Refers to a segment or gate descriptor in the LDT;\n");
|
||||
else
|
||||
printk_color(RED, BLACK, "Refers to a descriptor in the current GDT;\n");
|
||||
|
||||
printk_color(RED, BLACK, "Segment Selector Index:%#010x\n", error_code & 0xfff8);
|
||||
traceback(regs);
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 14 #PF 页故障
|
||||
void do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
cli();
|
||||
unsigned long cr2 = 0;
|
||||
#if ARCH(I386) || ARCH(X86_64)
|
||||
__asm__ __volatile__("movq %%cr2, %0" : "=r"(cr2)::"memory");
|
||||
#endif
|
||||
kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx, RBP=%#018lx, RIP:%#018lx CPU:%d, pid=%d\n", error_code,
|
||||
regs->rsp, regs->rbp, regs->rip, rs_current_pcb_cpuid(), rs_current_pcb_pid());
|
||||
kerror("regs->rax = %#018lx\n", regs->rax);
|
||||
if (!(error_code & 0x01))
|
||||
printk_color(RED, BLACK, "Page Not-Present,\t");
|
||||
|
||||
if (error_code & 0x02)
|
||||
printk_color(RED, BLACK, "Write Cause Fault,\t");
|
||||
else
|
||||
printk_color(RED, BLACK, "Read Cause Fault,\t");
|
||||
|
||||
if (error_code & 0x04)
|
||||
printk_color(RED, BLACK, "Fault in user(3)\t");
|
||||
else
|
||||
printk_color(RED, BLACK, "Fault in supervisor(0,1,2)\t");
|
||||
|
||||
if (error_code & 0x08)
|
||||
printk_color(RED, BLACK, ",Reserved Bit Cause Fault\t");
|
||||
|
||||
if (error_code & 0x10)
|
||||
printk_color(RED, BLACK, ",Instruction fetch Cause Fault");
|
||||
|
||||
printk_color(RED, BLACK, "\n");
|
||||
|
||||
printk_color(RED, BLACK, "CR2:%#018lx\n", cr2);
|
||||
|
||||
traceback(regs);
|
||||
sti();
|
||||
rs_process_do_exit(-1);
|
||||
// current_pcb->state = PROC_STOPPED;
|
||||
// sched();
|
||||
}
|
||||
|
||||
// 15 Intel保留,请勿使用
|
||||
|
||||
// 16 #MF x87FPU错误
|
||||
void do_x87_FPU_error(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_x87_FPU_error(16),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, rs_current_pcb_cpuid());
|
||||
|
||||
while (1)
|
||||
hlt();
|
||||
}
|
||||
|
||||
// 17 #AC 对齐检测
|
||||
void do_alignment_check(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_alignment_check(17),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, rs_current_pcb_cpuid());
|
||||
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 18 #MC 机器检测
|
||||
void do_machine_check(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_machine_check(18),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, rs_current_pcb_cpuid());
|
||||
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 19 #XM SIMD浮点异常
|
||||
void do_SIMD_exception(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_SIMD_exception(19),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp,
|
||||
regs->rip, rs_current_pcb_cpuid());
|
||||
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 20 #VE 虚拟化异常
|
||||
void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
|
||||
kerror("do_virtualization_exception(20),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code,
|
||||
regs->rsp, regs->rip, rs_current_pcb_cpuid());
|
||||
|
||||
rs_process_do_exit(-1);
|
||||
}
|
||||
|
||||
// 21-21 Intel保留,请勿使用
|
||||
|
||||
/**
|
||||
* @brief 当系统收到未知的中断时,执行此处理函数
|
||||
*
|
||||
* @param regs
|
||||
* @param error_code
|
||||
*/
|
||||
void ignore_int_handler(struct pt_regs *regs, unsigned long error_code)
|
||||
{
|
||||
kwarn("Unknown interrupt or fault at RIP.\n");
|
||||
}
|
||||
|
||||
void sys_vector_init()
|
||||
{
|
||||
|
||||
#if ARCH(I386) || ARCH(X86_64)
|
||||
// 将idt重置为新的ignore_int入点(此前在head.S中有设置,
|
||||
// 但是那个不完整,某些版本的编译器的输出,在真机运行时会破坏进程执行环境,从而导致#GP
|
||||
for (int i = 0; i < 256; ++i)
|
||||
set_intr_gate(i, 0, ignore_int);
|
||||
|
||||
set_intr_gate(0, 0, divide_error);
|
||||
set_intr_gate(1, 0, debug);
|
||||
set_intr_gate(2, 0, nmi);
|
||||
set_system_trap_gate(3, 0, int3);
|
||||
set_system_trap_gate(4, 0, overflow);
|
||||
set_system_trap_gate(5, 0, bounds);
|
||||
set_intr_gate(6, 0, undefined_opcode);
|
||||
set_intr_gate(7, 0, dev_not_avaliable);
|
||||
set_intr_gate(8, 0, double_fault);
|
||||
set_intr_gate(9, 0, coprocessor_segment_overrun);
|
||||
set_intr_gate(10, 0, invalid_TSS);
|
||||
set_intr_gate(11, 0, segment_not_exists);
|
||||
set_intr_gate(12, 0, stack_segment_fault);
|
||||
set_intr_gate(13, 0, general_protection);
|
||||
set_intr_gate(14, 0, page_fault);
|
||||
// 中断号15由Intel保留,不能使用
|
||||
set_intr_gate(16, 0, x87_FPU_error);
|
||||
set_intr_gate(17, 0, alignment_check);
|
||||
set_intr_gate(18, 0, machine_check);
|
||||
set_intr_gate(19, 0, SIMD_exception);
|
||||
set_intr_gate(20, 0, virtualization_exception);
|
||||
// 中断号21-31由Intel保留,不能使用
|
||||
|
||||
// 32-255为用户自定义中断内部
|
||||
#endif
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/**
|
||||
* @file trap.h
|
||||
* @author longjin@RinGoTek.cn
|
||||
* @brief 异常捕获模块
|
||||
* @date 2022-01-24
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <common/printk.h>
|
||||
#include <common/glib.h>
|
||||
#include <common/asm.h>
|
||||
|
||||
/**
|
||||
* @brief 初始化系统中断表
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
//除法错误
|
||||
void divide_error();
|
||||
// 调试
|
||||
void debug();
|
||||
// 不可屏蔽中断
|
||||
void nmi();
|
||||
//
|
||||
void int3();
|
||||
// 溢出
|
||||
void overflow();
|
||||
// 边界问题
|
||||
void bounds();
|
||||
// 未定义的操作数
|
||||
void undefined_opcode();
|
||||
// 设备不可用
|
||||
void dev_not_avaliable();
|
||||
void double_fault();
|
||||
void coprocessor_segment_overrun();
|
||||
void invalid_TSS();
|
||||
void segment_not_exists();
|
||||
void stack_segment_fault();
|
||||
void general_protection();
|
||||
// 缺页异常
|
||||
void page_fault();
|
||||
void x87_FPU_error();
|
||||
void alignment_check();
|
||||
void machine_check();
|
||||
void SIMD_exception();
|
||||
void virtualization_exception();
|
||||
|
||||
void syscall_int(); // 系统调用门
|
||||
void sys_vector_init();
|
@ -27,7 +27,6 @@
|
||||
#include <common/time.h>
|
||||
#include <common/unistd.h>
|
||||
#include <driver/multiboot2/multiboot2.h>
|
||||
#include <exception/gate.h>
|
||||
#include <include/DragonOS/refcount.h>
|
||||
#include <libs/lib_ui/textui.h>
|
||||
#include <mm/mm.h>
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
CurrentIrqArch, CurrentSMPArch, CurrentSchedArch,
|
||||
},
|
||||
driver::{base::init::driver_init, tty::init::tty_early_init, video::VideoRefreshManager},
|
||||
exception::{softirq::softirq_init, InterruptArch},
|
||||
exception::{init::irq_init, softirq::softirq_init, InterruptArch},
|
||||
filesystem::vfs::core::vfs_init,
|
||||
include::bindings::bindings::acpi_init,
|
||||
init::init_intertrait,
|
||||
@ -52,9 +52,11 @@ fn do_start_kernel() {
|
||||
vfs_init().expect("vfs init failed");
|
||||
driver_init().expect("driver init failed");
|
||||
unsafe { acpi_init() };
|
||||
irq_init().expect("irq init failed");
|
||||
CurrentSMPArch::prepare_cpus().expect("prepare_cpus failed");
|
||||
|
||||
setup_arch().expect("setup_arch failed");
|
||||
|
||||
process_init();
|
||||
sched_init();
|
||||
softirq_init().expect("softirq init failed");
|
||||
|
@ -11,5 +11,5 @@
|
||||
*/
|
||||
pid_t waitpid(pid_t pid, int *stat_loc, int options)
|
||||
{
|
||||
return (pid_t)enter_syscall_int(SYS_WAIT4, (uint64_t)pid, (uint64_t)stat_loc, options, 0, 0, 0, 0, 0);
|
||||
return (pid_t)enter_syscall_int(SYS_WAIT4, (uint64_t)pid, (uint64_t)stat_loc, options, 0, 0, 0);
|
||||
}
|
@ -138,6 +138,17 @@ impl ProcessManager {
|
||||
return ProcessControlBlock::arch_current_pcb();
|
||||
}
|
||||
|
||||
/// 获取当前进程的pid
|
||||
///
|
||||
/// 如果进程管理器未初始化完成,那么返回0
|
||||
pub fn current_pid() -> Pid {
|
||||
if unlikely(unsafe { !__PROCESS_MANAGEMENT_INIT_DONE }) {
|
||||
return Pid(0);
|
||||
}
|
||||
|
||||
return ProcessManager::current_pcb().pid();
|
||||
}
|
||||
|
||||
/// 增加当前进程的锁持有计数
|
||||
#[inline(always)]
|
||||
pub fn preempt_disable() {
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include <common/cpu.h>
|
||||
#include <common/kprint.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <exception/gate.h>
|
||||
#include <mm/slab.h>
|
||||
#include <process/process.h>
|
||||
#include <arch/x86_64/driver/apic/apic_timer.h>
|
||||
@ -10,7 +9,6 @@
|
||||
#include <process/preempt.h>
|
||||
#include <sched/sched.h>
|
||||
#include <driver/acpi/acpi.h>
|
||||
#include "exception/trap.h"
|
||||
#include "exception/irq.h"
|
||||
#include "ipi.h"
|
||||
#include <arch/arch.h>
|
||||
@ -69,9 +67,7 @@ void smp_init()
|
||||
memcpy((unsigned char *)phys_2_virt(0x20000), _apu_boot_start,
|
||||
(unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start);
|
||||
io_mfence();
|
||||
// 设置多核IPI中断门
|
||||
for (int i = 200; i < 210; ++i)
|
||||
set_intr_gate(i, 0, SMP_interrupt_table[i - 200]);
|
||||
|
||||
memset((void *)SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM);
|
||||
|
||||
io_mfence();
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include <common/errno.h>
|
||||
#include <common/fcntl.h>
|
||||
#include <common/string.h>
|
||||
#include <exception/gate.h>
|
||||
#include <exception/irq.h>
|
||||
#include <filesystem/vfs/VFS.h>
|
||||
#include <mm/slab.h>
|
||||
@ -29,33 +28,30 @@ extern void syscall_int(void);
|
||||
* @return long
|
||||
*/
|
||||
|
||||
long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7)
|
||||
long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5)
|
||||
{
|
||||
long err_code;
|
||||
__asm__ __volatile__("movq %2, %%r8 \n\t"
|
||||
"movq %3, %%r9 \n\t"
|
||||
"movq %4, %%r10 \n\t"
|
||||
"movq %5, %%r11 \n\t"
|
||||
"movq %6, %%r12 \n\t"
|
||||
"movq %7, %%r13 \n\t"
|
||||
"movq %8, %%r14 \n\t"
|
||||
"movq %9, %%r15 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(syscall_id), "m"(arg0), "m"(arg1), "m"(arg2), "m"(arg3), "m"(arg4), "m"(arg5), "m"(arg6),
|
||||
"m"(arg7)
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||
long err_code;
|
||||
__asm__ __volatile__("movq %2, %%rdi \n\t"
|
||||
"movq %3, %%rsi \n\t"
|
||||
"movq %4, %%rdx \n\t"
|
||||
"movq %5, %%r10 \n\t"
|
||||
"movq %6, %%r8 \n\t"
|
||||
"movq %7, %%r9 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(syscall_id), "m"(arg0), "m"(arg1), "m"(arg2), "m"(arg3), "m"(arg4), "m"(arg5)
|
||||
: "memory", "r8", "r9", "r10", "rdi", "rsi", "rdx");
|
||||
|
||||
return err_code;
|
||||
return err_code;
|
||||
}
|
||||
|
||||
#else
|
||||
long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7){
|
||||
long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
/* code */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -74,8 +70,6 @@ long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg
|
||||
ul do_put_string(char *s, uint32_t front_color, uint32_t background_color)
|
||||
{
|
||||
|
||||
printk_color(front_color, background_color, s);
|
||||
return 0;
|
||||
printk_color(front_color, background_color, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,5 +17,5 @@ extern int syscall_init();
|
||||
* @param syscall_id 系统调用id
|
||||
* @return long 错误码
|
||||
*/
|
||||
long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7);
|
||||
long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5);
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
// ================= Rust 实现 =============
|
||||
extern void kvm_init();
|
Loading…
x
Reference in New Issue
Block a user