kernel/devices/keyboard_mouse/
mod.rs

1mod keyboard;
2mod mouse;
3mod ps2;
4
5use alloc::sync::Arc;
6use core::fmt;
7
8use crate::{
9    cpu::{
10        self,
11        idt::{BasicInterruptHandler, InterruptStackFrame64},
12        interrupts::apic,
13    },
14    sync::{once::OnceLock, spin::mutex::Mutex},
15};
16
17pub use kernel_user_link::{keyboard::Key, mouse::MouseEvent};
18
19use self::{
20    keyboard::{Keyboard, KEYBOARD_INT_NUM},
21    mouse::{Mouse, MOUSE_INT_NUM},
22    ps2::status,
23};
24
25pub use self::{keyboard::KeyboardReader, mouse::MouseReader};
26
27use super::Device;
28
29static KEYBOARD_MOUSE: OnceLock<KeyboardMouse> = OnceLock::new();
30
31pub fn init_device() {
32    let device = KeyboardMouse::new();
33
34    KEYBOARD_MOUSE
35        .set(device)
36        .unwrap_or_else(|_| panic!("keyboard-mouse already initialized"));
37
38    // assign after we have assigned the device
39    apic::assign_io_irq(
40        ps2_interrupt_handler as BasicInterruptHandler,
41        KEYBOARD_INT_NUM,
42        cpu::cpu(),
43    );
44    apic::assign_io_irq(
45        ps2_interrupt_handler as BasicInterruptHandler,
46        MOUSE_INT_NUM,
47        cpu::cpu(),
48    );
49}
50
51pub fn poll_events() {
52    KEYBOARD_MOUSE.try_get().map(KeyboardMouse::read_all_events);
53}
54
55pub fn get_keyboard_reader() -> KeyboardReader {
56    KEYBOARD_MOUSE.get().get_keyboard_reader()
57}
58
59pub fn get_mouse_reader() -> MouseReader {
60    KEYBOARD_MOUSE.get().get_mouse_reader()
61}
62
63pub fn reset_system() -> ! {
64    KEYBOARD_MOUSE.get().ps2.reset_system();
65}
66
67// A mini keyboard driver/mapper
68pub struct KeyboardMouse {
69    keyboard: Keyboard,
70    mouse: Mouse,
71    ps2: ps2::Ps2,
72}
73
74impl fmt::Debug for KeyboardMouse {
75    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76        f.debug_struct("Keyboard").finish()
77    }
78}
79
80impl KeyboardMouse {
81    pub fn new() -> KeyboardMouse {
82        let ps2 = ps2::Ps2;
83        let keyboard = Keyboard::new(ps2);
84        let mouse = Mouse::new(ps2);
85
86        KeyboardMouse {
87            keyboard,
88            mouse,
89            ps2,
90        }
91    }
92
93    fn fetch_next_data(&self) -> bool {
94        let status = self.ps2.read_status();
95
96        if status & status::DATA_READY == 0 {
97            return false;
98        }
99
100        if status & status::PARITY_ERROR != 0 {
101            // ignore the data
102            self.ps2.read_data();
103            return false;
104        }
105
106        if status & status::KEYBOARD_TIMEOUT_MOUSE_DATA != 0 {
107            self.mouse.handle_mouse_data();
108        } else {
109            self.keyboard.handle_keyboard_data();
110        }
111
112        true
113    }
114
115    fn read_all_events(&self) {
116        while self.fetch_next_data() {
117            // keep fetching
118        }
119    }
120
121    pub fn get_keyboard_reader(&self) -> KeyboardReader {
122        self.keyboard.new_receiver()
123    }
124
125    #[allow(dead_code)]
126    pub fn get_mouse_reader(&self) -> MouseReader {
127        self.mouse.new_receiver()
128    }
129}
130
131extern "x86-interrupt" fn ps2_interrupt_handler(_stack_frame: InterruptStackFrame64) {
132    poll_events();
133    apic::return_from_interrupt();
134}
135
136// Virtual devices
137// -------------------
138
139/// This is just a helper definition, and should not be used directly in any file
140#[derive(Debug)]
141pub struct KeyboardDeviceCreator;
142
143impl Device for KeyboardDeviceCreator {
144    fn name(&self) -> &str {
145        "keyboard"
146    }
147
148    fn clone_device(&self) -> Result<(), crate::fs::FileSystemError> {
149        Err(crate::fs::FileSystemError::OperationNotSupported)
150    }
151
152    fn try_create(&self) -> Option<Result<Arc<dyn Device>, crate::fs::FileSystemError>> {
153        Some(Ok(Arc::new(KeyboardDevice {
154            reader: Mutex::new(get_keyboard_reader()),
155        })))
156    }
157}
158
159pub struct KeyboardDevice {
160    reader: Mutex<KeyboardReader>,
161}
162
163impl fmt::Debug for KeyboardDevice {
164    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165        write!(f, "KeyboardDevice")
166    }
167}
168
169impl Device for KeyboardDevice {
170    fn name(&self) -> &str {
171        "keyboard_instance"
172    }
173
174    fn read(&self, _offset: u64, buf: &mut [u8]) -> Result<u64, crate::fs::FileSystemError> {
175        if buf.len() < Key::BYTES_SIZE {
176            return Err(crate::fs::FileSystemError::BufferNotLargeEnough(
177                Key::BYTES_SIZE,
178            ));
179        }
180
181        let mut reader = self.reader.lock();
182
183        let mut i = 0;
184
185        while i + Key::BYTES_SIZE <= buf.len() {
186            if let Some(key) = reader.recv() {
187                let key_bytes = key.as_bytes();
188                buf[i..i + Key::BYTES_SIZE].copy_from_slice(&key_bytes);
189                i += Key::BYTES_SIZE;
190            } else {
191                break;
192            }
193        }
194
195        Ok(i as u64)
196    }
197}
198
199#[derive(Debug)]
200pub struct MouseDeviceCreator;
201
202impl Device for MouseDeviceCreator {
203    fn name(&self) -> &str {
204        "mouse"
205    }
206
207    fn clone_device(&self) -> Result<(), crate::fs::FileSystemError> {
208        Err(crate::fs::FileSystemError::OperationNotSupported)
209    }
210
211    fn try_create(&self) -> Option<Result<Arc<dyn Device>, crate::fs::FileSystemError>> {
212        Some(Ok(Arc::new(MouseDevice {
213            reader: Mutex::new(get_mouse_reader()),
214        })))
215    }
216}
217
218pub struct MouseDevice {
219    reader: Mutex<MouseReader>,
220}
221
222impl fmt::Debug for MouseDevice {
223    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
224        write!(f, "MouseDevice")
225    }
226}
227
228impl Device for MouseDevice {
229    fn name(&self) -> &str {
230        "mouse_instance"
231    }
232
233    fn read(&self, _offset: u64, buf: &mut [u8]) -> Result<u64, crate::fs::FileSystemError> {
234        if buf.len() < MouseEvent::BYTES_SIZE {
235            return Err(crate::fs::FileSystemError::BufferNotLargeEnough(
236                MouseEvent::BYTES_SIZE,
237            ));
238        }
239
240        let mut reader = self.reader.lock();
241
242        let mut i = 0;
243
244        while i + MouseEvent::BYTES_SIZE <= buf.len() {
245            if let Some(mouse_event) = reader.recv() {
246                let event_bytes = mouse_event.as_bytes();
247                buf[i..i + MouseEvent::BYTES_SIZE].copy_from_slice(&event_bytes);
248                i += MouseEvent::BYTES_SIZE;
249            } else {
250                break;
251            }
252        }
253
254        Ok(i as u64)
255    }
256}