使用rust编写中断/异常的入口 (#509)

* 使用rust编写中断/异常的入口
This commit is contained in:
LoGin 2024-02-07 13:29:47 +08:00 committed by GitHub
parent d14e28a8a9
commit f2022a8a1c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 1161 additions and 904 deletions

View File

@ -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",

View File

@ -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时使用下面的依赖

View File

@ -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();
}

View File

@ -143,7 +143,7 @@ __entry_err_code_to_ret_from_exception:
// 0 #DE
ENTRY(divide_error)
ENTRY(trap_divide_error)
pushq $0 //#DE0
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 //

View File

@ -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
*

View File

@ -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);

View File

@ -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();
}

View 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;
}

View File

@ -67,6 +67,7 @@ impl Into<ApicId> for ArchIpiTarget {
}
impl ArchIpiTarget {
#[allow(dead_code)]
pub fn shorthand(&self) -> u8 {
match self {
ArchIpiTarget::Specified(_) => 0,

View File

@ -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();
}

View 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.");
}

View File

@ -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);
}
}

View File

@ -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(());
}

View File

@ -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

View File

@ -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 PDPLTYPE的属性
* @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中的第几项
* 3GDT每项占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=1DPL=0, type=E
// set_gate((ul *)phys_2_virt(IDT_Table + n), 0x8E, ist, (ul *)(addr)); // p=1DPL=0, type=E
}
/**
* @brief 64DPL=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=1DPL=0, type=F
_set_gate(phys_2_virt(IDT_Table + n), 0x8F, ist, addr); // p=1DPL=0, type=F
}
/**
* @brief 64DPL=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=1DPL=3, type=F
_set_gate(phys_2_virt(IDT_Table + n), 0xEF, ist, addr); // p=1DPL=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

View 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(());
}

View File

@ -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 10IPI消息处理程序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")

View File

@ -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);
}

View File

@ -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
}

View File

@ -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();

View File

@ -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>

View File

@ -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");

View File

@ -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);
}

View File

@ -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() {

View File

@ -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();

View File

@ -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;
}

View File

@ -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);

View File

@ -1,2 +0,0 @@
// ================= Rust 实现 =============
extern void kvm_init();