1#![allow(dead_code)]
15
16use crate::arch::x86_64::{keyboard, mouse};
17use alloc::{sync::Arc, vec::Vec};
18use core::sync::atomic::{AtomicBool, Ordering};
19use spin::Mutex;
20
21pub const HID_BOOT_KEYBOARD: u8 = 0x01;
22pub const HID_BOOT_MOUSE: u8 = 0x02;
23
24const KBD_REPORT_SIZE: usize = 8;
25const MOUSE_REPORT_SIZE: usize = 4;
26
27#[derive(Clone, Copy, Debug)]
28pub struct KeyEvent {
29 pub keycode: u8,
30 pub pressed: bool,
31 pub modifiers: u8,
32}
33
34#[derive(Clone, Copy, Debug)]
35pub struct MouseEvent {
36 pub dx: i8,
37 pub dy: i8,
38 pub dz: i8,
39 pub buttons: u8,
40}
41
42const USB_TO_PS2: [u8; 128] = [
43 0x00, 0x00, 0x00, 0x00, 0x1C, 0x32, 0x21, 0x23, 0x1D, 0x24, 0x2B, 0x34, 0x33, 0x43, 0x35, 0x0E,
44 0x15, 0x16, 0x17, 0x1C, 0x18, 0x19, 0x14, 0x1A, 0x1B, 0x1D, 0x1E, 0x21, 0x22, 0x23, 0x24, 0x2B,
45 0x29, 0x2F, 0x2E, 0x30, 0x20, 0x31, 0x32, 0x33, 0x2C, 0x2D, 0x11, 0x12, 0x13, 0x3F, 0x3E, 0x46,
46 0x45, 0x5D, 0x4C, 0x36, 0x4A, 0x55, 0x37, 0x4E, 0x57, 0x5E, 0x5C, 0x41, 0x52, 0x4D, 0x4B, 0x5B,
47 0x5A, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
48 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51];
52
53fn usb_to_ps2(keycode: u8) -> u8 {
54 if keycode < USB_TO_PS2.len() as u8 {
55 USB_TO_PS2[keycode as usize]
56 } else {
57 0x00
58 }
59}
60
61pub struct HidKeyboard {
62 port: usize,
63 slot_id: u8,
64 interface: u8,
65 endpoint: u8,
66 max_packet: u16,
67 interval: u8,
68 event_queue: Vec<KeyEvent>,
69 last_report: [u8; KBD_REPORT_SIZE],
70 report_buf: *mut u8,
71}
72
73unsafe impl Send for HidKeyboard {}
74unsafe impl Sync for HidKeyboard {}
75
76impl HidKeyboard {
77 pub fn new(
78 port: usize,
79 slot_id: u8,
80 interface: u8,
81 endpoint: u8,
82 max_packet: u16,
83 interval: u8,
84 ) -> Self {
85 Self {
86 port,
87 slot_id,
88 interface,
89 endpoint,
90 max_packet,
91 interval,
92 event_queue: Vec::new(),
93 last_report: [0; KBD_REPORT_SIZE],
94 report_buf: core::ptr::null_mut(),
95 }
96 }
97
98 pub fn read_event(&mut self) -> Option<KeyEvent> {
99 self.event_queue.pop()
100 }
101
102 pub fn process_report(&mut self, report: &[u8]) {
103 if report.len() < KBD_REPORT_SIZE {
104 return;
105 }
106 let modifiers = report[0];
107
108 for i in 2..8 {
109 let keycode = report[i];
110 if keycode == 0 {
111 continue;
112 }
113 let was_pressed = self.last_report[2..8].contains(&keycode);
114 if !was_pressed {
115 self.event_queue.push(KeyEvent {
116 keycode: usb_to_ps2(keycode),
117 pressed: true,
118 modifiers,
119 });
120 }
121 }
122
123 for i in 2..8 {
124 let keycode = self.last_report[i];
125 if keycode != 0 && !report[2..8].contains(&keycode) {
126 self.event_queue.push(KeyEvent {
127 keycode: usb_to_ps2(keycode),
128 pressed: false,
129 modifiers,
130 });
131 }
132 }
133
134 for i in 0..8 {
135 self.last_report[i] = report[i];
136 }
137 }
138
139 pub fn is_modifier_pressed(&self, modifier: u8) -> bool {
140 self.last_report[0] & modifier != 0
141 }
142
143 pub fn drain_into_unified(&mut self) {
144 while let Some(ev) = self.event_queue.pop() {
145 keyboard::inject_hid_scancode(ev.keycode, ev.pressed);
146 }
147 }
148}
149
150pub struct HidMouse {
151 port: usize,
152 slot_id: u8,
153 interface: u8,
154 endpoint: u8,
155 max_packet: u16,
156 interval: u8,
157 event_queue: Vec<MouseEvent>,
158 last_buttons: u8,
159 report_buf: *mut u8,
160}
161
162unsafe impl Send for HidMouse {}
163unsafe impl Sync for HidMouse {}
164
165impl HidMouse {
166 pub fn new(
167 port: usize,
168 slot_id: u8,
169 interface: u8,
170 endpoint: u8,
171 max_packet: u16,
172 interval: u8,
173 ) -> Self {
174 Self {
175 port,
176 slot_id,
177 interface,
178 endpoint,
179 max_packet,
180 interval,
181 event_queue: Vec::new(),
182 last_buttons: 0,
183 report_buf: core::ptr::null_mut(),
184 }
185 }
186
187 pub fn read_event(&mut self) -> Option<MouseEvent> {
188 self.event_queue.pop()
189 }
190
191 pub fn process_report(&mut self, report: &[u8]) {
192 if report.len() < 3 {
193 return;
194 }
195
196 let buttons = report[0];
197 let dx = report[1] as i8;
198 let dy = report[2] as i8;
199 let dz = if report.len() > 3 { report[3] as i8 } else { 0 };
200
201 for i in 0..5 {
202 let mask = 1 << i;
203 let was_pressed = self.last_buttons & mask != 0;
204 let is_pressed = buttons & mask != 0;
205
206 if was_pressed != is_pressed {
207 self.event_queue.push(MouseEvent {
208 dx: 0,
209 dy: 0,
210 dz: 0,
211 buttons: if is_pressed { mask } else { 0 },
212 });
213 }
214 }
215
216 if dx != 0 || dy != 0 || dz != 0 {
217 self.event_queue.push(MouseEvent {
218 dx,
219 dy,
220 dz,
221 buttons,
222 });
223 }
224
225 self.last_buttons = buttons;
226 }
227
228 pub fn is_button_pressed(&self, button: u8) -> bool {
229 self.last_buttons & (1 << button) != 0
230 }
231
232 pub fn drain_into_unified(&mut self) {
233 while let Some(ev) = self.event_queue.pop() {
234 let left = ev.buttons & 0x01 != 0;
235 let right = ev.buttons & 0x02 != 0;
236 let middle = ev.buttons & 0x04 != 0;
237 mouse::push_event_from_hid(ev.dx as i16, ev.dy as i16, ev.dz, left, right, middle);
238 }
239 }
240}
241
242static KEYBOARDS: Mutex<Vec<Arc<Mutex<HidKeyboard>>>> = Mutex::new(Vec::new());
243static MICE: Mutex<Vec<Arc<Mutex<HidMouse>>>> = Mutex::new(Vec::new());
244static HID_INITIALIZED: AtomicBool = AtomicBool::new(false);
245
246pub fn init() {
247 log::info!("[USB-HID] Initializing HID drivers...");
248 HID_INITIALIZED.store(true, Ordering::SeqCst);
249 log::info!(
250 "[USB-HID] Initialized: {} keyboard(s), {} mouse/mice",
251 KEYBOARDS.lock().len(),
252 MICE.lock().len()
253 );
254}
255
256pub fn enumerate_device(port: usize, slot_id: u8, dev_desc: &[u8; 18]) {
257 let dev_class = dev_desc[4];
258
259 if dev_class == 0x03 {
260 let protocol = dev_desc[6];
261 log::info!(
262 "[USB-HID] HID device: port={} slot={} class=03 protocol={:02x}",
263 port,
264 slot_id,
265 protocol
266 );
267
268 if let Some(controller_arc) = crate::hardware::usb::xhci::get_controller(0) {
269 let mut controller = controller_arc.lock();
270
271 if protocol == 1 {
272 controller.set_protocol(port as u8, 0, 0).ok();
273 } else if protocol == 2 {
274 controller.set_protocol(port as u8, 0, 1).ok();
275 }
276
277 let mut config_desc = [0u8; 256];
278 if controller
279 .get_configuration_descriptor(slot_id, 0, &mut config_desc, 9)
280 .is_ok()
281 {
282 let total_len = u16::from_le_bytes([config_desc[2], config_desc[3]]) as usize;
283 if total_len > 9 && total_len <= 256 {
284 controller
285 .get_configuration_descriptor(slot_id, 0, &mut config_desc, total_len)
286 .ok();
287 }
288
289 let mut offset = 9;
290 while offset + 9 <= total_len {
291 let b_length = config_desc[offset];
292 let b_descriptor_type = config_desc[offset + 1];
293 if b_length < 9 || offset + b_length as usize > total_len {
294 break;
295 }
296 if b_descriptor_type == 4 {
297 let b_interface_class = config_desc[offset + 5];
298 let b_interface_protocol = config_desc[offset + 7];
299
300 if b_interface_class == 0x03 {
301 let mut ep_offset = offset + 9;
302 while ep_offset + 7 <= offset + b_length as usize {
303 let ep_b_length = config_desc[ep_offset];
304 let ep_b_descriptor_type = config_desc[ep_offset + 1];
305 if ep_b_length < 7 || ep_b_descriptor_type != 5 {
306 break;
307 }
308 let ep_addr = config_desc[ep_offset + 2];
309 let ep_max_packet = u16::from_le_bytes([
310 config_desc[ep_offset + 4],
311 config_desc[ep_offset + 5],
312 ]);
313 let ep_interval = config_desc[ep_offset + 6];
314
315 if (ep_addr & 0x80) != 0 {
316 let ep_num = ep_addr & 0x0F;
317 let ep_type = 7;
318
319 controller
320 .setup_endpoint(
321 slot_id,
322 ep_num,
323 ep_max_packet as u32,
324 ep_type,
325 ep_interval as u32,
326 0,
327 )
328 .ok();
329
330 let buf_size = ep_max_packet as usize;
331 if let Ok((_buf_virt, _buf_phys)) =
332 controller.alloc_interrupt_buffer(slot_id, ep_num, buf_size)
333 {
334 if b_interface_protocol == 1 {
335 let mut keyboard = HidKeyboard::new(
336 port,
337 slot_id,
338 config_desc[offset + 2],
339 ep_addr,
340 ep_max_packet,
341 ep_interval,
342 );
343 keyboard.report_buf = _buf_virt;
344 log::info!(
345 "[USB-HID] Keyboard: port={} slot={} ep={:02x} max_pkt={} interval={}",
346 port,
347 slot_id,
348 ep_addr,
349 ep_max_packet,
350 ep_interval
351 );
352 KEYBOARDS.lock().push(Arc::new(Mutex::new(keyboard)));
353
354 controller
355 .submit_interrupt_transfer(slot_id, ep_num)
356 .ok();
357 } else if b_interface_protocol == 2 {
358 let mut mouse_dev = HidMouse::new(
359 port,
360 slot_id,
361 config_desc[offset + 2],
362 ep_addr,
363 ep_max_packet,
364 ep_interval,
365 );
366 mouse_dev.report_buf = _buf_virt;
367 log::info!(
368 "[USB-HID] Mouse: port={} slot={} ep={:02x} max_pkt={} interval={}",
369 port,
370 slot_id,
371 ep_addr,
372 ep_max_packet,
373 ep_interval
374 );
375 MICE.lock().push(Arc::new(Mutex::new(mouse_dev)));
376
377 controller
378 .submit_interrupt_transfer(slot_id, ep_num)
379 .ok();
380 }
381 }
382 }
383 ep_offset += ep_b_length as usize;
384 }
385 }
386 }
387 offset += b_length as usize;
388 }
389 }
390
391 controller.set_configuration(slot_id, 1).ok();
392 }
393 } else {
394 log::info!(
395 "[USB-HID] Non-HID device: port={} slot={} class={:02x}",
396 port,
397 slot_id,
398 dev_class
399 );
400 }
401}
402
403pub fn receive_interrupt_report(slot_id: u8, ep_id: u8, buf: *const u8, len: usize) {
404 if buf.is_null() || len == 0 {
405 return;
406 }
407
408 let report = unsafe { core::slice::from_raw_parts(buf, len) };
409
410 for kbd in KEYBOARDS.lock().iter() {
411 let mut k = kbd.lock();
412 if k.slot_id == slot_id && (k.endpoint & 0x0F) == ep_id {
413 k.process_report(report);
414 k.drain_into_unified();
415 return;
416 }
417 }
418
419 for m in MICE.lock().iter() {
420 let mut dev = m.lock();
421 if dev.slot_id == slot_id && (dev.endpoint & 0x0F) == ep_id {
422 dev.process_report(report);
423 dev.drain_into_unified();
424 return;
425 }
426 }
427}
428
429pub fn get_keyboard(index: usize) -> Option<Arc<Mutex<HidKeyboard>>> {
430 KEYBOARDS.lock().get(index).cloned()
431}
432
433pub fn get_mouse(index: usize) -> Option<Arc<Mutex<HidMouse>>> {
434 MICE.lock().get(index).cloned()
435}
436
437pub fn keyboard_count() -> usize {
438 KEYBOARDS.lock().len()
439}
440
441pub fn mouse_count() -> usize {
442 MICE.lock().len()
443}
444
445pub fn is_available() -> bool {
446 HID_INITIALIZED.load(Ordering::Relaxed)
447}
448
449pub fn poll_all() {
450 for kbd in KEYBOARDS.lock().iter() {
451 let mut k = kbd.lock();
452 k.drain_into_unified();
453 }
454 for m in MICE.lock().iter() {
455 let mut dev = m.lock();
456 dev.drain_into_unified();
457 }
458}
459
460pub fn notify_transfer_complete(_slot_id: u8, _ep_id: u8) {
461 poll_all();
462}