continuing work on interrupts - PIC doesn't work, probably switching to APIC
This commit is contained in:
@@ -9,6 +9,7 @@ spin = { version = "0.9.8", features = ["lazy"] }
|
||||
bitflags = { version = "2.4.0", default-features = false }
|
||||
lazy_static = { version = "1.5.0", features = ["spin_no_std"] }
|
||||
x86_64 = { version = "0.15.1" }
|
||||
pic8259 = "0.11.0"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ pub use sys::kernel::drivers::serial::{
|
||||
};
|
||||
|
||||
pub fn init() {
|
||||
sys::kernel::cpu::interrupts::init();
|
||||
sys::kernel::cpu::init();
|
||||
}
|
||||
|
||||
pub fn hcf() -> ! {
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
use x86_64::{
|
||||
instructions::tables::load_tss, registers::segmentation::{Segment, CS}, structures::{
|
||||
gdt::{
|
||||
Descriptor, GlobalDescriptorTable, SegmentSelector
|
||||
},
|
||||
tss::TaskStateSegment,
|
||||
}, VirtAddr
|
||||
};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use crate::println_log;
|
||||
|
||||
pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;
|
||||
|
||||
lazy_static! {
|
||||
static ref TSS: TaskStateSegment = {
|
||||
let mut tss = TaskStateSegment::new();
|
||||
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
|
||||
const STACK_SIZE: usize = 4096 * 5;
|
||||
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||
|
||||
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||
let stack_end = stack_start + STACK_SIZE.try_into().unwrap();
|
||||
stack_end
|
||||
};
|
||||
tss
|
||||
};
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref GDT: (GlobalDescriptorTable, Selectors) = {
|
||||
let mut gdt = GlobalDescriptorTable::new();
|
||||
let code_selector = gdt.append(Descriptor::kernel_code_segment());
|
||||
let tss_selector = gdt.append(Descriptor::tss_segment(&TSS));
|
||||
(gdt, Selectors { code_selector, tss_selector })
|
||||
};
|
||||
}
|
||||
|
||||
struct Selectors {
|
||||
code_selector: SegmentSelector,
|
||||
tss_selector: SegmentSelector
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
GDT.0.load();
|
||||
println_log!("Loaded GDT...");
|
||||
|
||||
unsafe {
|
||||
CS::set_reg(GDT.1.code_selector);
|
||||
load_tss(GDT.1.tss_selector);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,15 +4,20 @@ use lazy_static::lazy_static;
|
||||
use spin::lazy;
|
||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||
|
||||
use crate::{println_log, serial_println};
|
||||
use crate::{println_log, serial_println, sys::kernel::cpu::gdt};
|
||||
|
||||
use super::pics::ChainedPics;
|
||||
// use super::pics::ChainedPics;
|
||||
|
||||
use pic8259::ChainedPics;
|
||||
|
||||
pub const PIC_1_OFFSET: u8 = 32;
|
||||
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
|
||||
|
||||
pub static PICS: spin::Mutex<ChainedPics> =
|
||||
spin::Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });
|
||||
pub static PICS: spin::Mutex<ChainedPics> = spin::Mutex::new(
|
||||
unsafe {
|
||||
ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET)
|
||||
}
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
@@ -34,22 +39,35 @@ lazy_static! {
|
||||
static ref IDT: InterruptDescriptorTable = {
|
||||
let mut idt = InterruptDescriptorTable::new();
|
||||
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
||||
idt.double_fault.set_handler_fn(double_fault_handler);
|
||||
idt[InterruptIndex::Timer.as_u8()].set_handler_fn(clock_handler);
|
||||
|
||||
unsafe {
|
||||
idt.double_fault.set_handler_fn(double_fault_handler)
|
||||
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
|
||||
}
|
||||
|
||||
idt[InterruptIndex::Timer.as_u8()].set_handler_fn(timer_interrupt_handler);
|
||||
idt
|
||||
};
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
IDT.load();
|
||||
println_log!("Loaded IDT...");
|
||||
|
||||
unsafe {
|
||||
PICS.lock().initialize();
|
||||
}
|
||||
|
||||
x86_64::instructions::interrupts::enable();
|
||||
println_log!("Enabled interrupts...");
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn timer_interrupt_handler(stack_frame: InterruptStackFrame) {
|
||||
serial_println!("clock");
|
||||
println_log!("clock");
|
||||
|
||||
pub fn disable(func: impl Fn()) {
|
||||
unsafe {
|
||||
asm!("cli", options(nomem, nostack, preserves_flags));
|
||||
func();
|
||||
asm!("sti", options(nomem, nostack, preserves_flags));
|
||||
PICS.lock().notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,11 +81,8 @@ extern "x86-interrupt" fn double_fault_handler(stack_frame: InterruptStackFrame,
|
||||
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame)
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn clock_handler(stack_frame: InterruptStackFrame) {
|
||||
println_log!("EXCEPTION: CLOCK\n{:#?}", stack_frame);
|
||||
serial_println!("EXCEPTION: CLOCK\n{:#?}", stack_frame);
|
||||
|
||||
unsafe {
|
||||
PICS.lock().notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
||||
}
|
||||
pub fn disable(func: impl Fn()) {
|
||||
x86_64::instructions::interrupts::disable();
|
||||
func();
|
||||
x86_64::instructions::interrupts::enable();
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
pub mod interrupts;
|
||||
pub mod gdt;
|
||||
|
||||
mod pics;
|
||||
|
||||
pub use interrupts::*;
|
||||
pub fn init() {
|
||||
gdt::init();
|
||||
interrupts::init();
|
||||
}
|
||||
Reference in New Issue
Block a user