kernel/devices/keyboard_mouse/
mod.rs1mod 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 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
67pub 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 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 }
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#[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}