kernel/cpu/interrupts/
mod.rs1pub mod apic;
2mod handlers;
3
4use crate::sync::{once::OnceLock, spin::mutex::Mutex};
5
6use super::{
7 gdt::USER_RING,
8 idt::{BasicInterruptHandler, InterruptDescriptorTable, InterruptHandlerWithAllState},
9};
10
11static INTERRUPTS: OnceLock<Mutex<Interrupts>> = OnceLock::new();
12
13pub(super) mod stack_index {
14 pub const FAULTS_STACK: u8 = 0;
15 pub const DOUBLE_FAULT_STACK: u8 = 1;
16}
17
18const USER_INTERRUPTS_START: u8 = 0x20;
19const MAX_USER_INTERRUPTS: u8 = 0xe0 - 0x10;
20pub const SPECIAL_SCHEDULER_INTERRUPT: u8 = 0xdf; pub const SPECIAL_SYSCALL_INTERRUPT: u8 =
22 kernel_user_link::syscalls::SYSCALL_INTERRUPT_NUMBER - USER_INTERRUPTS_START;
23
24struct Interrupts {
25 idt: InterruptDescriptorTable,
26 last_used_user_interrupt: u16,
27}
28
29impl Interrupts {
30 fn init(&'static mut self) {
32 self.idt.init_default_handlers();
33
34 self.idt.apply_idt();
36 }
37
38 fn get_next_interrupt(&mut self) -> u8 {
39 if self.last_used_user_interrupt >= MAX_USER_INTERRUPTS as u16 {
40 panic!("No more user interrupts available");
41 }
42
43 let interrupt = self.last_used_user_interrupt;
44 self.last_used_user_interrupt += 1;
45
46 interrupt as u8
47 }
48
49 fn allocate_basic_user_interrupt(&mut self, handler: BasicInterruptHandler) -> u8 {
50 let interrupt = self.get_next_interrupt();
51
52 self.idt.user_defined[interrupt as usize].set_handler(handler);
53
54 interrupt + USER_INTERRUPTS_START
55 }
56
57 fn allocate_user_interrupt_all_saved(&mut self, handler: InterruptHandlerWithAllState) -> u8 {
58 let interrupt = self.get_next_interrupt();
59
60 self.idt.user_defined[interrupt as usize]
61 .set_handler_with_number(handler, interrupt + USER_INTERRUPTS_START);
62
63 interrupt + USER_INTERRUPTS_START
64 }
65}
66
67pub fn init_interrupts() {
68 if INTERRUPTS.try_get().is_some() {
69 panic!("Interrupts already initialized");
70 }
71
72 INTERRUPTS
73 .get_or_init(|| {
74 let interrupts = Interrupts {
75 idt: InterruptDescriptorTable::empty(),
76 last_used_user_interrupt: 0,
77 };
78 Mutex::new(interrupts)
79 })
80 .run_with_mut(|interrupts| {
81 interrupts.init();
82 });
83}
84
85pub trait InterruptHandler {
87 fn allocate_and_set_handler(val: Self) -> u8;
88}
89
90impl InterruptHandler for BasicInterruptHandler {
91 fn allocate_and_set_handler(handler: Self) -> u8 {
92 INTERRUPTS
93 .get()
94 .lock()
95 .allocate_basic_user_interrupt(handler)
96 }
97}
98
99impl InterruptHandler for InterruptHandlerWithAllState {
100 fn allocate_and_set_handler(handler: Self) -> u8 {
101 INTERRUPTS
102 .get()
103 .lock()
104 .allocate_user_interrupt_all_saved(handler)
105 }
106}
107
108pub(super) fn allocate_user_interrupt<F: InterruptHandler>(handler: F) -> u8 {
110 F::allocate_and_set_handler(handler)
111}
112
113pub(super) fn allocate_basic_user_interrupt(handler: BasicInterruptHandler) -> u8 {
115 BasicInterruptHandler::allocate_and_set_handler(handler)
116}
117
118pub(super) fn allocate_user_interrupt_all_saved(handler: InterruptHandlerWithAllState) -> u8 {
120 InterruptHandlerWithAllState::allocate_and_set_handler(handler)
121}
122
123pub fn create_scheduler_interrupt(handler: InterruptHandlerWithAllState) {
124 let mut interrupts = INTERRUPTS.get().lock();
125 interrupts.idt.user_defined[SPECIAL_SCHEDULER_INTERRUPT as usize]
126 .set_handler_with_number(handler, SPECIAL_SCHEDULER_INTERRUPT + USER_INTERRUPTS_START)
127 .set_disable_interrupts(true);
128}
129
130pub fn create_syscall_interrupt(handler: InterruptHandlerWithAllState) {
131 let mut interrupts = INTERRUPTS.get().lock();
132 interrupts.idt.user_defined[SPECIAL_SYSCALL_INTERRUPT as usize]
133 .set_handler_with_number(handler, SPECIAL_SYSCALL_INTERRUPT + USER_INTERRUPTS_START)
134 .set_privilege_level(USER_RING)
135 .set_disable_interrupts(false);
136}