1use core::fmt;
2
3pub mod ctx;
4pub use self::ctx::Context;
5
6pub trait Control {
8 type Registers: fmt::Debug + fmt::Display;
9
10 unsafe fn disable(&mut self);
18
19 unsafe fn enable(&mut self);
26
27 fn is_enabled(&self) -> bool;
29
30 fn register_handlers<H>(&mut self) -> Result<(), RegistrationError>
31 where
32 H: Handlers<Self::Registers>;
33
34 fn enter_critical(&mut self) -> CriticalGuard<'_, Self> {
36 unsafe {
37 self.disable();
38 }
39 CriticalGuard { ctrl: self }
40 }
41}
42
43pub trait Handlers<R: fmt::Debug + fmt::Display> {
44 fn page_fault<C>(cx: C)
45 where
46 C: ctx::Context<Registers = R> + ctx::PageFault;
47
48 fn code_fault<C>(cx: C)
49 where
50 C: ctx::Context<Registers = R> + ctx::CodeFault;
51
52 fn double_fault<C>(cx: C)
53 where
54 C: ctx::Context<Registers = R>;
55
56 fn timer_tick();
57
58 fn ps2_keyboard(scancode: u8);
61
62 fn serial_input(port: u8, byte: u8);
64
65 fn test_interrupt<C>(_cx: C)
66 where
67 C: ctx::Context<Registers = R>,
68 {
69 }
71}
72
73#[derive(Clone, Eq, PartialEq, thiserror::Error)]
75#[error("{kind}")]
76pub struct RegistrationError {
77 kind: RegistrationErrorKind,
78}
79
80#[derive(Debug)]
81pub struct CriticalGuard<'a, C: Control + ?Sized> {
82 ctrl: &'a mut C,
83}
84
85#[derive(Debug, Clone, Eq, PartialEq, thiserror::Error)]
86enum RegistrationErrorKind {
87 #[error("the provided interrupt vector does not exist")]
88 Nonexistant,
89 #[error("an interrupt handler is already registered for this vector")]
90 AlreadyRegistered,
91 #[error("{0}")]
92 Other(&'static str),
93}
94
95impl<C: Control + ?Sized> Drop for CriticalGuard<'_, C> {
98 fn drop(&mut self) {
99 unsafe {
100 self.ctrl.enable();
101 }
102 }
103}
104
105impl RegistrationError {
107 pub fn nonexistant() -> Self {
110 Self {
111 kind: RegistrationErrorKind::Nonexistant,
112 }
113 }
114
115 pub fn already_registered() -> Self {
118 Self {
119 kind: RegistrationErrorKind::AlreadyRegistered,
120 }
121 }
122
123 pub fn other(message: &'static str) -> Self {
125 Self {
126 kind: RegistrationErrorKind::Other(message),
127 }
128 }
129
130 pub fn is_nonexistant(&self) -> bool {
131 matches!(self.kind, RegistrationErrorKind::Nonexistant)
132 }
133
134 pub fn is_already_registered(&self) -> bool {
135 matches!(self.kind, RegistrationErrorKind::AlreadyRegistered)
136 }
137}
138
139impl fmt::Debug for RegistrationError {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 let Self { kind } = self;
142 f.debug_struct("RegistrationError")
143 .field("kind", kind)
144 .finish()
145 }
146}