1#![allow(dead_code)]
14
15use crate::arch::x86_64::{keyboard, mouse};
16use alloc::{sync::Arc, vec::Vec};
17use core::sync::atomic::{AtomicBool, Ordering};
18use spin::Mutex;
19
20pub const HID_BOOT_KEYBOARD: u8 = 0x01;
21pub const HID_BOOT_MOUSE: u8 = 0x02;
22
23const KBD_REPORT_SIZE: usize = 8;
25
26const MOUSE_REPORT_SIZE: usize = 3;
28
29const MOD_LCTRL: u8 = 0x01;
31const MOD_LSHIFT: u8 = 0x02;
32const MOD_LALT: u8 = 0x04;
33const MOD_LGUI: u8 = 0x08;
34const MOD_RCTRL: u8 = 0x10;
35const MOD_RSHIFT: u8 = 0x20;
36const MOD_RALT: u8 = 0x40;
37const MOD_RGUI: u8 = 0x80;
38
39#[derive(Clone, Copy, Debug)]
40pub struct KeyEvent {
41 pub keycode: u8,
42 pub pressed: bool,
43 pub modifiers: u8,
44}
45
46#[derive(Clone, Copy, Debug)]
47pub struct MouseEvent {
48 pub dx: i8,
49 pub dy: i8,
50 pub dz: i8,
51 pub buttons: u8,
52}
53
54const USB_TO_PS2: [u8; 128] = [
57 0x00, 0x00, 0x00, 0x00, 0x1C, 0x32, 0x21, 0x23, 0x1D, 0x24, 0x2B, 0x34, 0x33, 0x43, 0x35, 0x0E, 0x15, 0x16, 0x17, 0x1C, 0x18, 0x19, 0x14, 0x1A, 0x1B, 0x1D, 0x1E, 0x21, 0x22, 0x23, 0x24, 0x2B, 0x29, 0x2F, 0x2E, 0x30, 0x20, 0x31, 0x32, 0x33, 0x2C, 0x2D, 0x11, 0x12, 0x13, 0x3F, 0x3E, 0x46, 0x45, 0x5D, 0x4C, 0x36, 0x4A, 0x55, 0x37, 0x4E, 0x57, 0x5E, 0x5C, 0x41, 0x52, 0x4D, 0x4B, 0x5B, 0x5A, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
74
75fn usb_to_ps2(keycode: u8) -> u8 {
77 if keycode < USB_TO_PS2.len() as u8 {
78 USB_TO_PS2[keycode as usize]
79 } else {
80 0x00
81 }
82}
83
84pub struct HidKeyboard {
85 port: usize,
86 interface: u8,
87 endpoint: u8,
88 max_packet: u16,
89 interval: u8,
90 event_queue: Vec<KeyEvent>,
91 last_report: [u8; KBD_REPORT_SIZE],
92}
93
94unsafe impl Send for HidKeyboard {}
95unsafe impl Sync for HidKeyboard {}
96
97impl HidKeyboard {
98 pub fn new(port: usize, interface: u8, endpoint: u8, max_packet: u16, interval: u8) -> Self {
100 Self {
101 port,
102 interface,
103 endpoint,
104 max_packet,
105 interval,
106 event_queue: Vec::new(),
107 last_report: [0; KBD_REPORT_SIZE],
108 }
109 }
110
111 pub fn read_event(&mut self) -> Option<KeyEvent> {
113 if self.event_queue.is_empty() {
114 self.poll();
115 }
116 self.event_queue.pop()
117 }
118
119 pub fn poll(&mut self) {
121 }
125
126 pub fn process_report(&mut self, report: &[u8; KBD_REPORT_SIZE]) {
128 let modifiers = report[0];
133
134 for i in 2..8 {
135 let keycode = report[i];
136 if keycode == 0 {
137 continue;
138 }
139
140 let was_pressed = self.last_report[2..8].contains(&keycode);
142 if !was_pressed {
143 self.event_queue.push(KeyEvent {
144 keycode: usb_to_ps2(keycode),
145 pressed: true,
146 modifiers,
147 });
148 }
149 }
150
151 for i in 2..8 {
153 let keycode = self.last_report[i];
154 if keycode != 0 && !report[2..8].contains(&keycode) {
155 self.event_queue.push(KeyEvent {
156 keycode: usb_to_ps2(keycode),
157 pressed: false,
158 modifiers,
159 });
160 }
161 }
162
163 self.last_report = *report;
164 }
165
166 pub fn is_modifier_pressed(&self, modifier: u8) -> bool {
168 self.last_report[0] & modifier != 0
169 }
170
171 pub fn drain_into_unified(&mut self) {
173 while let Some(ev) = self.event_queue.pop() {
174 keyboard::inject_hid_scancode(ev.keycode, ev.pressed);
175 }
176 }
177}
178
179pub struct HidMouse {
180 port: usize,
181 interface: u8,
182 endpoint: u8,
183 max_packet: u16,
184 interval: u8,
185 event_queue: Vec<MouseEvent>,
186 last_buttons: u8,
187}
188
189unsafe impl Send for HidMouse {}
190unsafe impl Sync for HidMouse {}
191
192impl HidMouse {
193 pub fn new(port: usize, interface: u8, endpoint: u8, max_packet: u16, interval: u8) -> Self {
195 Self {
196 port,
197 interface,
198 endpoint,
199 max_packet,
200 interval,
201 event_queue: Vec::new(),
202 last_buttons: 0,
203 }
204 }
205
206 pub fn read_event(&mut self) -> Option<MouseEvent> {
208 if self.event_queue.is_empty() {
209 self.poll();
210 }
211 self.event_queue.pop()
212 }
213
214 pub fn poll(&mut self) {
216 }
219
220 pub fn process_report(&mut self, report: &[u8]) {
222 if report.len() < 3 {
223 return;
224 }
225
226 let buttons = report[0];
227 let dx = report[1] as i8;
228 let dy = report[2] as i8;
229 let dz = if report.len() > 3 { report[3] as i8 } else { 0 };
230
231 for i in 0..5 {
233 let mask = 1 << i;
234 let was_pressed = self.last_buttons & mask != 0;
235 let is_pressed = buttons & mask != 0;
236
237 if was_pressed != is_pressed {
238 self.event_queue.push(MouseEvent {
239 dx: 0,
240 dy: 0,
241 dz: 0,
242 buttons: if is_pressed { mask } else { 0 },
243 });
244 }
245 }
246
247 if dx != 0 || dy != 0 || dz != 0 {
249 self.event_queue.push(MouseEvent {
250 dx,
251 dy,
252 dz,
253 buttons,
254 });
255 }
256
257 self.last_buttons = buttons;
258 }
259
260 pub fn is_button_pressed(&self, button: u8) -> bool {
262 self.last_buttons & (1 << button) != 0
263 }
264
265 pub fn drain_into_unified(&mut self) {
267 while let Some(ev) = self.event_queue.pop() {
268 let left = ev.buttons & 0x01 != 0;
269 let right = ev.buttons & 0x02 != 0;
270 let middle = ev.buttons & 0x04 != 0;
271 mouse::push_event_from_hid(ev.dx as i16, ev.dy as i16, ev.dz, left, right, middle);
272 }
273 }
274}
275
276static KEYBOARDS: Mutex<Vec<Arc<Mutex<HidKeyboard>>>> = Mutex::new(Vec::new());
277static MICE: Mutex<Vec<Arc<Mutex<HidMouse>>>> = Mutex::new(Vec::new());
278static HID_INITIALIZED: AtomicBool = AtomicBool::new(false);
279
280pub fn init() {
282 log::info!("[USB-HID] Initializing HID drivers...");
283
284 if !crate::hardware::usb::xhci::is_available() {
285 log::warn!("[USB-HID] xHCI not available, skipping HID init");
286 return;
287 }
288
289 log::warn!("[USB-HID] xHCI enumeration not enabled yet, skipping HID probe");
293
294 HID_INITIALIZED.store(true, Ordering::SeqCst);
295 log::info!(
296 "[USB-HID] Initialized: {} keyboard(s), {} mouse/mice",
297 KEYBOARDS.lock().len(),
298 MICE.lock().len()
299 );
300}
301
302fn probe_hid_device(port: usize) {
304 if port == 0 {
305 let keyboard = HidKeyboard::new(port, 0, 0x81, 8, 10);
306 KEYBOARDS.lock().push(Arc::new(Mutex::new(keyboard)));
307 log::info!("[USB-HID] Found keyboard on port {}", port);
308 } else if port == 1 {
309 let mouse_dev = HidMouse::new(port, 0, 0x81, 4, 10);
310 MICE.lock().push(Arc::new(Mutex::new(mouse_dev)));
311 log::info!("[USB-HID] Found mouse on port {}", port);
312 }
313}
314
315pub fn enumerate_device(port: usize) {
316 if let Some(controller_arc) = crate::hardware::usb::xhci::get_controller(0) {
317 let mut controller = controller_arc.lock();
318
319 let mut dev_desc = [0u8; 18];
320 if controller.get_device_descriptor(1, &mut dev_desc).is_ok() {
321 log::info!(
322 "[USB-HID] Device: VID={:04x} PID={:04x}",
323 u16::from_le_bytes([dev_desc[2], dev_desc[3]]),
324 u16::from_le_bytes([dev_desc[4], dev_desc[5]])
325 );
326 }
327
328 let mut config_desc = [0u8; 256];
329 if controller
330 .get_configuration_descriptor(1, 0, &mut config_desc, 9)
331 .is_ok()
332 {
333 log::info!(
334 "[USB-HID] Config: total_len={}",
335 u16::from_le_bytes([config_desc[2], config_desc[3]])
336 );
337 }
338
339 controller.set_configuration(1, 1).ok();
340 }
341
342 probe_hid_device(port);
343}
344
345pub fn get_keyboard(index: usize) -> Option<Arc<Mutex<HidKeyboard>>> {
347 KEYBOARDS.lock().get(index).cloned()
348}
349
350pub fn get_mouse(index: usize) -> Option<Arc<Mutex<HidMouse>>> {
352 MICE.lock().get(index).cloned()
353}
354
355pub fn keyboard_count() -> usize {
357 KEYBOARDS.lock().len()
358}
359
360pub fn mouse_count() -> usize {
362 MICE.lock().len()
363}
364
365pub fn is_available() -> bool {
367 HID_INITIALIZED.load(Ordering::Relaxed)
368}
369
370pub fn poll_all() {
376 for kbd in KEYBOARDS.lock().iter() {
377 let mut k = kbd.lock();
378 k.drain_into_unified();
379 }
380 for m in MICE.lock().iter() {
381 let mut dev = m.lock();
382 dev.drain_into_unified();
383 }
384}
385
386pub fn notify_transfer_complete(_slot_id: u8, _ep_id: u8) {
390 poll_all();
391}