From f2022a8a1cc4a8e2a85e9061e036e9c491a2fa00 Mon Sep 17 00:00:00 2001 From: LoGin Date: Wed, 7 Feb 2024 13:29:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8rust=E7=BC=96=E5=86=99?= =?UTF-8?q?=E4=B8=AD=E6=96=AD/=E5=BC=82=E5=B8=B8=E7=9A=84=E5=85=A5?= =?UTF-8?q?=E5=8F=A3=20(#509)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 使用rust编写中断/异常的入口 --- .vscode/settings.json | 2 - kernel/Cargo.toml | 3 +- kernel/src/arch/riscv64/interrupt/mod.rs | 5 + kernel/src/arch/x86_64/asm/entry.S | 40 +- kernel/src/arch/x86_64/driver/apic/apic.c | 24 - kernel/src/arch/x86_64/driver/apic/apic.h | 10 +- kernel/src/arch/x86_64/init/mod.rs | 8 +- kernel/src/arch/x86_64/interrupt/entry.rs | 603 ++++++++++++++++++++++ kernel/src/arch/x86_64/interrupt/ipi.rs | 1 + kernel/src/arch/x86_64/interrupt/mod.rs | 25 +- kernel/src/arch/x86_64/interrupt/trap.rs | 438 ++++++++++++++++ kernel/src/arch/x86_64/sched.rs | 2 +- kernel/src/arch/x86_64/syscall/mod.rs | 10 +- kernel/src/exception/Makefile | 5 +- kernel/src/exception/gate.h | 199 ------- kernel/src/exception/init.rs | 15 + kernel/src/exception/irq.c | 196 ------- kernel/src/exception/mod.rs | 15 +- kernel/src/exception/trap.c | 344 ------------ kernel/src/exception/trap.h | 52 -- kernel/src/include/bindings/wrapper.h | 1 - kernel/src/init/init.rs | 4 +- kernel/src/libs/sys/wait.c | 2 +- kernel/src/process/mod.rs | 11 + kernel/src/smp/smp.c | 6 +- kernel/src/syscall/syscall.c | 40 +- kernel/src/syscall/syscall.h | 2 +- kernel/src/virt/kvm/kvm.h | 2 - 28 files changed, 1161 insertions(+), 904 deletions(-) create mode 100644 kernel/src/arch/x86_64/interrupt/entry.rs create mode 100644 kernel/src/arch/x86_64/interrupt/trap.rs delete mode 100644 kernel/src/exception/gate.h create mode 100644 kernel/src/exception/init.rs delete mode 100644 kernel/src/exception/trap.c delete mode 100644 kernel/src/exception/trap.h delete mode 100644 kernel/src/virt/kvm/kvm.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 6409ec20..04886d30 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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", diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index fe7179f2..7fe6b38b 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -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时,使用下面的依赖 diff --git a/kernel/src/arch/riscv64/interrupt/mod.rs b/kernel/src/arch/riscv64/interrupt/mod.rs index ae1dbf62..379f5ded 100644 --- a/kernel/src/arch/riscv64/interrupt/mod.rs +++ b/kernel/src/arch/riscv64/interrupt/mod.rs @@ -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(); } diff --git a/kernel/src/arch/x86_64/asm/entry.S b/kernel/src/arch/x86_64/asm/entry.S index abfc3d35..7b7c5758 100644 --- a/kernel/src/arch/x86_64/asm/entry.S +++ b/kernel/src/arch/x86_64/asm/entry.S @@ -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 // 获取中断服务程序的地址 diff --git a/kernel/src/arch/x86_64/driver/apic/apic.c b/kernel/src/arch/x86_64/driver/apic/apic.c index 31765c41..fbbb3fcb 100644 --- a/kernel/src/arch/x86_64/driver/apic/apic.c +++ b/kernel/src/arch/x86_64/driver/apic/apic.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -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 中断服务程序 * diff --git a/kernel/src/arch/x86_64/driver/apic/apic.h b/kernel/src/arch/x86_64/driver/apic/apic.h index 1d95dc69..c8c483a0 100644 --- a/kernel/src/arch/x86_64/driver/apic/apic.h +++ b/kernel/src/arch/x86_64/driver/apic/apic.h @@ -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); diff --git a/kernel/src/arch/x86_64/init/mod.rs b/kernel/src/arch/x86_64/init/mod.rs index d6ccb871..95bbf3c2 100644 --- a/kernel/src/arch/x86_64/init/mod.rs +++ b/kernel/src/arch/x86_64/init/mod.rs @@ -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(); } diff --git a/kernel/src/arch/x86_64/interrupt/entry.rs b/kernel/src/arch/x86_64/interrupt/entry.rs new file mode 100644 index 00000000..69ef92ca --- /dev/null +++ b/kernel/src/arch/x86_64/interrupt/entry.rs @@ -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 []() { + 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; +} diff --git a/kernel/src/arch/x86_64/interrupt/ipi.rs b/kernel/src/arch/x86_64/interrupt/ipi.rs index 5ec086d6..275cdf96 100644 --- a/kernel/src/arch/x86_64/interrupt/ipi.rs +++ b/kernel/src/arch/x86_64/interrupt/ipi.rs @@ -67,6 +67,7 @@ impl Into for ArchIpiTarget { } impl ArchIpiTarget { + #[allow(dead_code)] pub fn shorthand(&self) -> u8 { match self { ArchIpiTarget::Specified(_) => 0, diff --git a/kernel/src/arch/x86_64/interrupt/mod.rs b/kernel/src/arch/x86_64/interrupt/mod.rs index 3864f5c8..44dae4d1 100644 --- a/kernel/src/arch/x86_64/interrupt/mod.rs +++ b/kernel/src/arch/x86_64/interrupt/mod.rs @@ -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(); } diff --git a/kernel/src/arch/x86_64/interrupt/trap.rs b/kernel/src/arch/x86_64/interrupt/trap.rs new file mode 100644 index 00000000..8d567b78 --- /dev/null +++ b/kernel/src/arch/x86_64/interrupt/trap.rs @@ -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."); +} diff --git a/kernel/src/arch/x86_64/sched.rs b/kernel/src/arch/x86_64/sched.rs index b3860122..db4e7197 100644 --- a/kernel/src/arch/x86_64/sched.rs +++ b/kernel/src/arch/x86_64/sched.rs @@ -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); } } diff --git a/kernel/src/arch/x86_64/syscall/mod.rs b/kernel/src/arch/x86_64/syscall/mod.rs index 47adf1b3..489c3f08 100644 --- a/kernel/src/arch/x86_64/syscall/mod.rs +++ b/kernel/src/arch/x86_64/syscall/mod.rs @@ -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(()); } diff --git a/kernel/src/exception/Makefile b/kernel/src/exception/Makefile index e4bb9d8e..a9fac409 100644 --- a/kernel/src/exception/Makefile +++ b/kernel/src/exception/Makefile @@ -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 \ No newline at end of file diff --git a/kernel/src/exception/gate.h b/kernel/src/exception/gate.h deleted file mode 100644 index ae0666f4..00000000 --- a/kernel/src/exception/gate.h +++ /dev/null @@ -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 -#include - -// 描述符表的结构体 -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 \ No newline at end of file diff --git a/kernel/src/exception/init.rs b/kernel/src/exception/init.rs new file mode 100644 index 00000000..b96fcf0d --- /dev/null +++ b/kernel/src/exception/init.rs @@ -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(()); +} diff --git a/kernel/src/exception/irq.c b/kernel/src/exception/irq.c index a7c08221..54f70a27 100644 --- a/kernel/src/exception/irq.c +++ b/kernel/src/exception/irq.c @@ -2,196 +2,16 @@ #include "irq.h" #include -#if _INTR_8259A_ -#include -#else -#include -#endif -#include "gate.h" #include #include #include #include #include -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") diff --git a/kernel/src/exception/mod.rs b/kernel/src/exception/mod.rs index 5ab53bc4..78259c37 100644 --- a/kernel/src/exception/mod.rs +++ b/kernel/src/exception/mod.rs @@ -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); } diff --git a/kernel/src/exception/trap.c b/kernel/src/exception/trap.c deleted file mode 100644 index 34f8e555..00000000 --- a/kernel/src/exception/trap.c +++ /dev/null @@ -1,344 +0,0 @@ -#include "trap.h" -#include "gate.h" -#include -#include -#include -#include -#include -#include - -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 -} \ No newline at end of file diff --git a/kernel/src/exception/trap.h b/kernel/src/exception/trap.h deleted file mode 100644 index 83eba783..00000000 --- a/kernel/src/exception/trap.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file trap.h - * @author longjin@RinGoTek.cn - * @brief 异常捕获模块 - * @date 2022-01-24 - * - */ - -#pragma once - -#include -#include -#include - -/** - * @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(); \ No newline at end of file diff --git a/kernel/src/include/bindings/wrapper.h b/kernel/src/include/bindings/wrapper.h index 60f0858d..ef04a555 100644 --- a/kernel/src/include/bindings/wrapper.h +++ b/kernel/src/include/bindings/wrapper.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/kernel/src/init/init.rs b/kernel/src/init/init.rs index 6bffd802..8fb414ad 100644 --- a/kernel/src/init/init.rs +++ b/kernel/src/init/init.rs @@ -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"); diff --git a/kernel/src/libs/sys/wait.c b/kernel/src/libs/sys/wait.c index 9b1d1278..71d142c6 100644 --- a/kernel/src/libs/sys/wait.c +++ b/kernel/src/libs/sys/wait.c @@ -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); } \ No newline at end of file diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index f9e0ab44..f1965b61 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -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() { diff --git a/kernel/src/smp/smp.c b/kernel/src/smp/smp.c index eb52e364..12dda326 100644 --- a/kernel/src/smp/smp.c +++ b/kernel/src/smp/smp.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -10,7 +9,6 @@ #include #include #include -#include "exception/trap.h" #include "exception/irq.h" #include "ipi.h" #include @@ -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(); diff --git a/kernel/src/syscall/syscall.c b/kernel/src/syscall/syscall.c index 3b6bb661..8343692c 100644 --- a/kernel/src/syscall/syscall.c +++ b/kernel/src/syscall/syscall.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -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; } - - diff --git a/kernel/src/syscall/syscall.h b/kernel/src/syscall/syscall.h index 9c6a3499..0d1aeda2 100644 --- a/kernel/src/syscall/syscall.h +++ b/kernel/src/syscall/syscall.h @@ -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); diff --git a/kernel/src/virt/kvm/kvm.h b/kernel/src/virt/kvm/kvm.h deleted file mode 100644 index 0c75c5eb..00000000 --- a/kernel/src/virt/kvm/kvm.h +++ /dev/null @@ -1,2 +0,0 @@ -// ================= Rust 实现 ============= -extern void kvm_init(); \ No newline at end of file