intr subscriber
Some checks failed
Check / Build ISO (nightly-2025-04-27) (push) Failing after 46s

This commit is contained in:
Masato Imai
2025-08-22 09:51:20 +00:00
parent fc93be3043
commit 7fb000f5ce
3 changed files with 115 additions and 1 deletions

View File

@ -5,6 +5,7 @@ use crate::{
interrupt::{
apic::{EOI, LAPIC},
gdt,
subscriber::InterruptContext,
},
time, warn,
};
@ -40,6 +41,17 @@ pub fn init_idt() {
}
extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
let context = InterruptContext {
vector: 3,
instruction_pointer: stack_frame.instruction_pointer.as_u64(),
code_segment: stack_frame.code_segment.0 as u64,
cpu_flags: stack_frame.cpu_flags.bits(),
stack_pointer: stack_frame.stack_pointer.as_u64(),
stack_segment: stack_frame.stack_segment.0 as u64,
};
crate::interrupt::subscriber::dispatch_to_subscribers(&context);
warn!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
}
@ -47,6 +59,17 @@ extern "x86-interrupt" fn double_fault_handler(
stack_frame: InterruptStackFrame,
_error_code: u64,
) -> ! {
let context = InterruptContext {
vector: 8,
instruction_pointer: stack_frame.instruction_pointer.as_u64(),
code_segment: stack_frame.code_segment.0 as u64,
cpu_flags: stack_frame.cpu_flags.bits(),
stack_pointer: stack_frame.stack_pointer.as_u64(),
stack_segment: stack_frame.stack_segment.0 as u64,
};
crate::interrupt::subscriber::dispatch_to_subscribers(&context);
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
}
@ -56,6 +79,17 @@ extern "x86-interrupt" fn page_fault_handler(
) {
use x86_64::registers::control::Cr2;
let context = InterruptContext {
vector: 14,
instruction_pointer: stack_frame.instruction_pointer.as_u64(),
code_segment: stack_frame.code_segment.0 as u64,
cpu_flags: stack_frame.cpu_flags.bits(),
stack_pointer: stack_frame.stack_pointer.as_u64(),
stack_segment: stack_frame.stack_segment.0 as u64,
};
crate::interrupt::subscriber::dispatch_to_subscribers(&context);
panic!(
"EXCEPTION: PAGE FAULT\n{:#?}\nAccessed address: {:#x}",
stack_frame,
@ -63,7 +97,18 @@ extern "x86-interrupt" fn page_fault_handler(
);
}
extern "x86-interrupt" fn timer_handler(_stack_frame: InterruptStackFrame) {
extern "x86-interrupt" fn timer_handler(stack_frame: InterruptStackFrame) {
let context = InterruptContext {
vector: IRQ_TIMER as u8,
instruction_pointer: stack_frame.instruction_pointer.as_u64(),
code_segment: stack_frame.code_segment.0 as u64,
cpu_flags: stack_frame.cpu_flags.bits(),
stack_pointer: stack_frame.stack_pointer.as_u64(),
stack_segment: stack_frame.stack_segment.0 as u64,
};
crate::interrupt::subscriber::dispatch_to_subscribers(&context);
time::tick();
LAPIC.get().unwrap().write(EOI, 0);
}

View File

@ -1,3 +1,4 @@
pub mod apic;
pub mod gdt;
pub mod idt;
pub mod subscriber;

View File

@ -0,0 +1,68 @@
use spin::Mutex;
#[derive(Debug)]
pub struct InterruptContext {
pub vector: u8,
pub instruction_pointer: u64,
pub code_segment: u64,
pub cpu_flags: u64,
pub stack_pointer: u64,
pub stack_segment: u64,
}
pub type SubscriberCallback = fn(*mut core::ffi::c_void, &InterruptContext);
#[derive(Debug, Clone, Copy)]
pub struct Subscriber {
pub callback: SubscriberCallback,
pub context: *mut core::ffi::c_void,
}
unsafe impl Send for Subscriber {}
unsafe impl Sync for Subscriber {}
const MAX_SUBSCRIBERS: usize = 10;
static SUBSCRIBERS: Mutex<[Option<Subscriber>; MAX_SUBSCRIBERS]> =
Mutex::new([None; MAX_SUBSCRIBERS]);
pub fn subscribe(
callback: SubscriberCallback,
context: *mut core::ffi::c_void,
) -> Result<(), &'static str> {
let mut subscribers = SUBSCRIBERS.lock();
for slot in subscribers.iter_mut() {
if slot.is_none() {
*slot = Some(Subscriber { callback, context });
return Ok(());
}
}
Err("No available subscriber slots")
}
pub fn unsubscribe(callback: SubscriberCallback) -> Result<(), &'static str> {
let mut subscribers = SUBSCRIBERS.lock();
for slot in subscribers.iter_mut() {
if let Some(subscriber) = slot {
if subscriber.callback == callback {
*slot = None;
return Ok(());
}
}
}
Err("Subscriber not found")
}
pub fn dispatch_to_subscribers(context: &InterruptContext) {
let subscribers = SUBSCRIBERS.lock();
for subscriber in subscribers.iter() {
if let Some(subscriber) = subscriber {
(subscriber.callback)(subscriber.context, context);
}
}
}