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 test_interrupt<C>(_cx: C)
63 where
64 C: ctx::Context<Registers = R>,
65 {
66 }
68}
69
70#[derive(Clone, Eq, PartialEq, thiserror::Error)]
72#[error("{kind}")]
73pub struct RegistrationError {
74 kind: RegistrationErrorKind,
75}
76
77#[derive(Debug)]
78pub struct CriticalGuard<'a, C: Control + ?Sized> {
79 ctrl: &'a mut C,
80}
81
82#[derive(Debug, Clone, Eq, PartialEq, thiserror::Error)]
83enum RegistrationErrorKind {
84 #[error("the provided interrupt vector does not exist")]
85 Nonexistant,
86 #[error("an interrupt handler is already registered for this vector")]
87 AlreadyRegistered,
88 #[error("{0}")]
89 Other(&'static str),
90}
91
92impl<C: Control + ?Sized> Drop for CriticalGuard<'_, C> {
95 fn drop(&mut self) {
96 unsafe {
97 self.ctrl.enable();
98 }
99 }
100}
101
102impl RegistrationError {
104 pub fn nonexistant() -> Self {
107 Self {
108 kind: RegistrationErrorKind::Nonexistant,
109 }
110 }
111
112 pub fn already_registered() -> Self {
115 Self {
116 kind: RegistrationErrorKind::AlreadyRegistered,
117 }
118 }
119
120 pub fn other(message: &'static str) -> Self {
122 Self {
123 kind: RegistrationErrorKind::Other(message),
124 }
125 }
126
127 pub fn is_nonexistant(&self) -> bool {
128 matches!(self.kind, RegistrationErrorKind::Nonexistant)
129 }
130
131 pub fn is_already_registered(&self) -> bool {
132 matches!(self.kind, RegistrationErrorKind::AlreadyRegistered)
133 }
134}
135
136impl fmt::Debug for RegistrationError {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 let Self { kind } = self;
139 f.debug_struct("RegistrationError")
140 .field("kind", kind)
141 .finish()
142 }
143}