xref: /DragonOS/kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs (revision 453452cc02e2766a28d87dd47bdee37caddc4c44)
1 use core::hint::spin_loop;
2 
3 use alloc::{
4     string::ToString,
5     sync::{Arc, Weak},
6 };
7 use kdepends::ringbuffer::{AllocRingBuffer, RingBuffer};
8 use system_error::SystemError;
9 use unified_init::macros::unified_init;
10 
11 use crate::{
12     arch::{io::PortIOArch, CurrentIrqArch, CurrentPortIOArch},
13     driver::{
14         base::{
15             class::Class,
16             device::{
17                 bus::Bus, device_manager, device_number::DeviceNumber, driver::Driver, Device,
18                 DeviceType, IdTable,
19             },
20             kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
21             kset::KSet,
22         },
23         input::serio::serio_device::{serio_device_manager, SerioDevice},
24     },
25     exception::InterruptArch,
26     filesystem::{
27         devfs::{devfs_register, DevFS, DeviceINode},
28         kernfs::KernFSInode,
29         vfs::{
30             core::generate_inode_id, syscall::ModeType, FilePrivateData, FileSystem, FileType,
31             IndexNode, Metadata,
32         },
33     },
34     init::initcall::INITCALL_DEVICE,
35     libs::{
36         rwlock::{RwLockReadGuard, RwLockWriteGuard},
37         spinlock::SpinLock,
38     },
39     time::TimeSpec,
40 };
41 
42 static mut PS2_MOUSE_DEVICE: Option<Arc<Ps2MouseDevice>> = None;
43 
44 pub fn ps2_mouse_device() -> Option<Arc<Ps2MouseDevice>> {
45     unsafe { PS2_MOUSE_DEVICE.clone() }
46 }
47 
48 const ADDRESS_PORT_ADDRESS: u16 = 0x64;
49 const DATA_PORT_ADDRESS: u16 = 0x60;
50 
51 const KEYBOARD_COMMAND_ENABLE_PS2_MOUSE_PORT: u8 = 0xa8;
52 const KEYBOARD_COMMAND_SEND_TO_PS2_MOUSE: u8 = 0xd4;
53 
54 const MOUSE_BUFFER_CAPACITY: usize = 15;
55 
56 bitflags! {
57     /// Represents the flags currently set for the mouse.
58     #[derive(Default)]
59     pub struct MouseFlags: u8 {
60         /// Whether or not the left mouse button is pressed.
61         const LEFT_BUTTON = 0b0000_0001;
62 
63         /// Whether or not the right mouse button is pressed.
64         const RIGHT_BUTTON = 0b0000_0010;
65 
66         /// Whether or not the middle mouse button is pressed.
67         const MIDDLE_BUTTON = 0b0000_0100;
68 
69         /// Whether or not the packet is valid or not.
70         const ALWAYS_ONE = 0b0000_1000;
71 
72         /// Whether or not the x delta is negative.
73         const X_SIGN = 0b0001_0000;
74 
75         /// Whether or not the y delta is negative.
76         const Y_SIGN = 0b0010_0000;
77 
78         /// Whether or not the x delta overflowed.
79         const X_OVERFLOW = 0b0100_0000;
80 
81         /// Whether or not the y delta overflowed.
82         const Y_OVERFLOW = 0b1000_0000;
83     }
84 }
85 
86 #[derive(Debug)]
87 enum PsMouseCommand {
88     SampleRate(u8),
89     EnablePacketStreaming,
90     // SetDefaults = 0xF6,
91     InitKeyboard,
92     GetMouseId,
93     SetSampleRate,
94 }
95 
96 impl Into<u8> for PsMouseCommand {
97     fn into(self) -> u8 {
98         match self {
99             Self::SampleRate(x) => x,
100             Self::EnablePacketStreaming => 0xf4,
101             Self::InitKeyboard => 0x47,
102             Self::GetMouseId => 0xf2,
103             Self::SetSampleRate => 0xf3,
104         }
105     }
106 }
107 
108 #[derive(Debug)]
109 pub struct MouseState {
110     flags: MouseFlags,
111     x: i16,
112     y: i16,
113 }
114 
115 #[allow(dead_code)]
116 impl MouseState {
117     /// Returns a new `MouseState`.
118     pub const fn new() -> MouseState {
119         MouseState {
120             flags: MouseFlags::empty(),
121             x: 0,
122             y: 0,
123         }
124     }
125 
126     /// Returns true if the left mouse button is currently down.
127     pub fn left_button_down(&self) -> bool {
128         self.flags.contains(MouseFlags::LEFT_BUTTON)
129     }
130 
131     /// Returns true if the left mouse button is currently up.
132     pub fn left_button_up(&self) -> bool {
133         !self.flags.contains(MouseFlags::LEFT_BUTTON)
134     }
135 
136     /// Returns true if the right mouse button is currently down.
137     pub fn right_button_down(&self) -> bool {
138         self.flags.contains(MouseFlags::RIGHT_BUTTON)
139     }
140 
141     /// Returns true if the right mouse button is currently up.
142     pub fn right_button_up(&self) -> bool {
143         !self.flags.contains(MouseFlags::RIGHT_BUTTON)
144     }
145 
146     /// Returns true if the x axis has moved.
147     pub fn x_moved(&self) -> bool {
148         self.x != 0
149     }
150 
151     /// Returns true if the y axis has moved.
152     pub fn y_moved(&self) -> bool {
153         self.y != 0
154     }
155 
156     /// Returns true if the x or y axis has moved.
157     pub fn moved(&self) -> bool {
158         self.x_moved() || self.y_moved()
159     }
160 
161     /// Returns the x delta of the mouse state.
162     pub fn get_x(&self) -> i16 {
163         self.x
164     }
165 
166     /// Returns the y delta of the mouse state.
167     pub fn get_y(&self) -> i16 {
168         self.y
169     }
170 }
171 
172 #[derive(Debug)]
173 #[cast_to([sync] Device, SerioDevice)]
174 pub struct Ps2MouseDevice {
175     inner: SpinLock<InnerPs2MouseDevice>,
176     kobj_state: LockedKObjectState,
177 }
178 
179 impl Ps2MouseDevice {
180     pub const NAME: &'static str = "psmouse";
181     pub fn new() -> Self {
182         let r = Self {
183             inner: SpinLock::new(InnerPs2MouseDevice {
184                 bus: None,
185                 class: None,
186                 driver: None,
187                 kern_inode: None,
188                 parent: None,
189                 kset: None,
190                 kobj_type: None,
191                 current_packet: 0,
192                 current_state: MouseState::new(),
193                 buf: AllocRingBuffer::new(MOUSE_BUFFER_CAPACITY),
194                 devfs_metadata: Metadata {
195                     dev_id: 1,
196                     inode_id: generate_inode_id(),
197                     size: 4096,
198                     blk_size: 0,
199                     blocks: 0,
200                     atime: TimeSpec::default(),
201                     mtime: TimeSpec::default(),
202                     ctime: TimeSpec::default(),
203                     file_type: FileType::CharDevice, // 文件夹,block设备,char设备
204                     mode: ModeType::from_bits_truncate(0o644),
205                     nlinks: 1,
206                     uid: 0,
207                     gid: 0,
208                     raw_dev: DeviceNumber::default(), // 这里用来作为device number
209                 },
210                 device_inode_fs: None,
211             }),
212             kobj_state: LockedKObjectState::new(None),
213         };
214         return r;
215     }
216 
217     pub fn init(&self) -> Result<(), SystemError> {
218         let _irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
219 
220         self.write_control_port(KEYBOARD_COMMAND_ENABLE_PS2_MOUSE_PORT)?;
221         for _i in 0..1000 {
222             for _j in 0..1000 {
223                 spin_loop();
224             }
225         }
226         self.read_data_port().ok();
227 
228         self.send_command_to_ps2mouse(PsMouseCommand::EnablePacketStreaming)
229             .map_err(|e| {
230                 kerror!("ps2 mouse init error: {:?}", e);
231                 e
232             })?;
233         self.read_data_port().ok();
234         for _i in 0..1000 {
235             for _j in 0..1000 {
236                 spin_loop();
237             }
238         }
239 
240         // self.send_command_to_ps2mouse(PsMouseCommand::InitKeyboard)?;
241         self.do_send_command(DATA_PORT_ADDRESS as u8, PsMouseCommand::InitKeyboard.into())?;
242         self.read_data_port().ok();
243         for _i in 0..1000 {
244             for _j in 0..1000 {
245                 spin_loop();
246             }
247         }
248 
249         self.set_sample_rate(20)?;
250         // self.get_mouse_id()?;
251         Ok(())
252     }
253 
254     #[allow(dead_code)]
255     pub fn get_mouse_id(&self) -> Result<(), SystemError> {
256         self.send_command_to_ps2mouse(PsMouseCommand::GetMouseId)?;
257         let _mouse_id = self.read_data_port()?;
258         Ok(())
259     }
260 
261     /// 设置鼠标采样率
262     ///
263     /// `hz` 合法值为 10,20,40,60,80,100,200
264     pub fn set_sample_rate(&self, hz: u8) -> Result<(), SystemError> {
265         const SAMPLE_RATE: [u8; 7] = [10, 20, 40, 60, 80, 100, 200];
266         if !SAMPLE_RATE.contains(&hz) {
267             return Err(SystemError::EINVAL);
268         }
269 
270         self.send_command_to_ps2mouse(PsMouseCommand::SetSampleRate)?;
271         self.read_data_port().ok();
272         for _i in 0..1000 {
273             for _j in 0..1000 {
274                 spin_loop();
275             }
276         }
277 
278         self.send_command_to_ps2mouse(PsMouseCommand::SampleRate(hz))?;
279         for _i in 0..1000 {
280             for _j in 0..1000 {
281                 spin_loop();
282             }
283         }
284         self.read_data_port().ok();
285         Ok(())
286     }
287 
288     /// # 函数的功能
289     /// 鼠标设备处理数据包
290     pub fn process_packet(&self) -> Result<(), SystemError> {
291         let packet = self.read_data_port()?;
292         let mut guard = self.inner.lock();
293         guard.buf.push(packet); // 更新缓冲区
294         match guard.current_packet {
295             0 => {
296                 let flags: MouseFlags = MouseFlags::from_bits_truncate(packet);
297                 if !flags.contains(MouseFlags::ALWAYS_ONE) {
298                     return Ok(());
299                 }
300                 guard.current_state.flags = flags;
301             }
302             1 => {
303                 let flags = guard.current_state.flags.clone();
304                 if !flags.contains(MouseFlags::X_OVERFLOW) {
305                     guard.current_state.x = self.get_x_movement(packet, flags);
306                 }
307             }
308             2 => {
309                 let flags = guard.current_state.flags.clone();
310                 if !flags.contains(MouseFlags::Y_OVERFLOW) {
311                     guard.current_state.y = self.get_y_movement(packet, flags);
312                 }
313 
314                 // kdebug!(
315                 //     "Ps2MouseDevice packet : flags:{}, x:{}, y:{}\n",
316                 //     guard.current_state.flags.bits,
317                 //     guard.current_state.x,
318                 //     guard.current_state.y
319                 // )
320             }
321             _ => unreachable!(),
322         }
323         guard.current_packet = (guard.current_packet + 1) % 3;
324         Ok(())
325     }
326 
327     fn get_x_movement(&self, packet: u8, flags: MouseFlags) -> i16 {
328         if flags.contains(MouseFlags::X_SIGN) {
329             return self.sign_extend(packet);
330         } else {
331             return packet as i16;
332         }
333     }
334 
335     fn get_y_movement(&self, packet: u8, flags: MouseFlags) -> i16 {
336         if flags.contains(MouseFlags::Y_SIGN) {
337             return self.sign_extend(packet);
338         } else {
339             return packet as i16;
340         }
341     }
342 
343     fn sign_extend(&self, packet: u8) -> i16 {
344         ((packet as u16) | 0xFF00) as i16
345     }
346 
347     fn read_data_port(&self) -> Result<u8, SystemError> {
348         self.wait_for_write()?;
349         let cmd = unsafe { CurrentPortIOArch::in8(ADDRESS_PORT_ADDRESS) };
350         if (cmd & 0x21) == 0x21 {
351             let data = unsafe { CurrentPortIOArch::in8(DATA_PORT_ADDRESS) };
352             return Ok(data);
353         } else {
354             return Err(SystemError::ENODATA);
355         }
356     }
357 
358     #[inline(never)]
359     fn send_command_to_ps2mouse(&self, command: PsMouseCommand) -> Result<(), SystemError> {
360         self.do_send_command(KEYBOARD_COMMAND_SEND_TO_PS2_MOUSE, command.into())?;
361         Ok(())
362     }
363 
364     #[inline(never)]
365     fn do_send_command(&self, ctrl: u8, command: u8) -> Result<(), SystemError> {
366         self.write_control_port(ctrl)?;
367         self.write_data_port(command)?;
368         return Ok(());
369     }
370 
371     fn write_data_port(&self, data: u8) -> Result<(), SystemError> {
372         self.wait_for_write()?;
373         unsafe {
374             CurrentPortIOArch::out8(DATA_PORT_ADDRESS, data);
375         }
376         Ok(())
377     }
378 
379     fn write_control_port(&self, command: u8) -> Result<(), SystemError> {
380         self.wait_for_write()?;
381         unsafe {
382             CurrentPortIOArch::out8(ADDRESS_PORT_ADDRESS, command);
383         }
384         Ok(())
385     }
386 
387     fn wait_for_read(&self) -> Result<(), SystemError> {
388         let timeout = 100_000;
389         for _ in 0..timeout {
390             let value = unsafe { CurrentPortIOArch::in8(ADDRESS_PORT_ADDRESS) };
391             if (value & 0x1) == 0x1 {
392                 return Ok(());
393             }
394         }
395         Err(SystemError::ETIMEDOUT)
396     }
397 
398     fn wait_for_write(&self) -> Result<(), SystemError> {
399         let timeout = 100_000;
400         for _ in 0..timeout {
401             let value = unsafe { CurrentPortIOArch::in8(ADDRESS_PORT_ADDRESS) };
402             if (value & 0x2) == 0 {
403                 return Ok(());
404             }
405         }
406         Err(SystemError::ETIMEDOUT)
407     }
408 }
409 
410 #[derive(Debug)]
411 struct InnerPs2MouseDevice {
412     bus: Option<Weak<dyn Bus>>,
413     class: Option<Arc<dyn Class>>,
414     driver: Option<Weak<dyn Driver>>,
415     kern_inode: Option<Arc<KernFSInode>>,
416     parent: Option<Weak<dyn KObject>>,
417     kset: Option<Arc<KSet>>,
418     kobj_type: Option<&'static dyn KObjType>,
419 
420     /// 鼠标数据
421     current_state: MouseState,
422     current_packet: u8,
423     /// 鼠标数据环形缓冲区
424     buf: AllocRingBuffer<u8>,
425 
426     /// device inode要求的字段
427     device_inode_fs: Option<Weak<DevFS>>,
428     devfs_metadata: Metadata,
429 }
430 
431 impl Device for Ps2MouseDevice {
432     fn is_dead(&self) -> bool {
433         false
434     }
435 
436     fn dev_type(&self) -> DeviceType {
437         DeviceType::Char
438     }
439 
440     fn id_table(&self) -> IdTable {
441         IdTable::new(self.name().to_string(), None)
442     }
443 
444     fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn Bus>>) {
445         self.inner.lock_irqsave().bus = bus;
446     }
447 
448     fn set_class(&self, class: Option<alloc::sync::Arc<dyn Class>>) {
449         self.inner.lock_irqsave().class = class;
450     }
451 
452     fn driver(&self) -> Option<alloc::sync::Arc<dyn Driver>> {
453         self.inner.lock_irqsave().driver.clone()?.upgrade()
454     }
455 
456     fn set_driver(&self, driver: Option<alloc::sync::Weak<dyn Driver>>) {
457         self.inner.lock_irqsave().driver = driver;
458     }
459 
460     fn can_match(&self) -> bool {
461         true
462     }
463 
464     fn set_can_match(&self, _can_match: bool) {}
465 
466     fn state_synced(&self) -> bool {
467         true
468     }
469 
470     fn bus(&self) -> Option<alloc::sync::Weak<dyn Bus>> {
471         self.inner.lock_irqsave().bus.clone()
472     }
473 
474     fn class(&self) -> Option<Arc<dyn Class>> {
475         self.inner.lock_irqsave().class.clone()
476     }
477 }
478 
479 impl SerioDevice for Ps2MouseDevice {
480     fn write(
481         &self,
482         _device: &alloc::sync::Arc<dyn SerioDevice>,
483         _data: u8,
484     ) -> Result<(), system_error::SystemError> {
485         todo!()
486     }
487 
488     fn open(
489         &self,
490         _device: &alloc::sync::Arc<dyn SerioDevice>,
491     ) -> Result<(), system_error::SystemError> {
492         todo!()
493     }
494 
495     fn close(
496         &self,
497         _device: &alloc::sync::Arc<dyn SerioDevice>,
498     ) -> Result<(), system_error::SystemError> {
499         todo!()
500     }
501 
502     fn start(
503         &self,
504         _device: &alloc::sync::Arc<dyn SerioDevice>,
505     ) -> Result<(), system_error::SystemError> {
506         todo!()
507     }
508 
509     fn stop(
510         &self,
511         _device: &alloc::sync::Arc<dyn SerioDevice>,
512     ) -> Result<(), system_error::SystemError> {
513         todo!()
514     }
515 }
516 
517 impl KObject for Ps2MouseDevice {
518     fn as_any_ref(&self) -> &dyn core::any::Any {
519         self
520     }
521 
522     fn set_inode(&self, inode: Option<alloc::sync::Arc<KernFSInode>>) {
523         self.inner.lock_irqsave().kern_inode = inode;
524     }
525 
526     fn inode(&self) -> Option<alloc::sync::Arc<KernFSInode>> {
527         self.inner.lock_irqsave().kern_inode.clone()
528     }
529 
530     fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
531         self.inner.lock_irqsave().parent.clone()
532     }
533 
534     fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
535         self.inner.lock_irqsave().parent = parent
536     }
537 
538     fn kset(&self) -> Option<alloc::sync::Arc<KSet>> {
539         self.inner.lock_irqsave().kset.clone()
540     }
541 
542     fn set_kset(&self, kset: Option<alloc::sync::Arc<KSet>>) {
543         self.inner.lock_irqsave().kset = kset;
544     }
545 
546     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
547         self.inner.lock_irqsave().kobj_type.clone()
548     }
549 
550     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
551         self.inner.lock_irqsave().kobj_type = ktype;
552     }
553 
554     fn name(&self) -> alloc::string::String {
555         Self::NAME.to_string()
556     }
557 
558     fn set_name(&self, _name: alloc::string::String) {}
559 
560     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
561         self.kobj_state.read()
562     }
563 
564     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
565         self.kobj_state.write()
566     }
567 
568     fn set_kobj_state(&self, state: KObjectState) {
569         *self.kobj_state.write() = state;
570     }
571 }
572 
573 impl DeviceINode for Ps2MouseDevice {
574     fn set_fs(&self, fs: Weak<DevFS>) {
575         self.inner.lock_irqsave().device_inode_fs = Some(fs);
576     }
577 }
578 
579 impl IndexNode for Ps2MouseDevice {
580     fn open(
581         &self,
582         _data: &mut FilePrivateData,
583         _mode: &crate::filesystem::vfs::file::FileMode,
584     ) -> Result<(), SystemError> {
585         let mut guard = self.inner.lock_irqsave();
586         guard.buf.clear();
587         Ok(())
588     }
589 
590     fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
591         let mut guard = self.inner.lock_irqsave();
592         guard.buf.clear();
593         Ok(())
594     }
595 
596     fn read_at(
597         &self,
598         _offset: usize,
599         _len: usize,
600         buf: &mut [u8],
601         _data: &mut FilePrivateData,
602     ) -> Result<usize, SystemError> {
603         let mut guard = self.inner.lock_irqsave();
604 
605         if guard.buf.len() >= 3 {
606             for i in 0..3 {
607                 buf[i] = guard.buf.dequeue().unwrap();
608             }
609             return Ok(3);
610         } else {
611             return Ok(0);
612         }
613     }
614 
615     fn write_at(
616         &self,
617         _offset: usize,
618         _len: usize,
619         _buf: &[u8],
620         _data: &mut FilePrivateData,
621     ) -> Result<usize, SystemError> {
622         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
623     }
624 
625     fn fs(&self) -> Arc<dyn FileSystem> {
626         self.inner
627             .lock_irqsave()
628             .device_inode_fs
629             .as_ref()
630             .unwrap()
631             .upgrade()
632             .unwrap()
633     }
634 
635     fn as_any_ref(&self) -> &dyn core::any::Any {
636         self
637     }
638 
639     fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
640         todo!()
641     }
642 
643     fn metadata(&self) -> Result<Metadata, SystemError> {
644         Ok(self.inner.lock_irqsave().devfs_metadata.clone())
645     }
646 
647     fn resize(&self, _len: usize) -> Result<(), SystemError> {
648         Ok(())
649     }
650 }
651 
652 #[unified_init(INITCALL_DEVICE)]
653 fn rs_ps2_mouse_device_int() -> Result<(), SystemError> {
654     kdebug!("ps2_mouse_device initializing...");
655     let psmouse = Arc::new(Ps2MouseDevice::new());
656 
657     device_manager().device_default_initialize(&(psmouse.clone() as Arc<dyn Device>));
658     serio_device_manager().register_port(psmouse.clone())?;
659 
660     devfs_register(&psmouse.name(), psmouse.clone()).map_err(|e| {
661         kerror!(
662             "register psmouse device '{}' to devfs failed: {:?}",
663             psmouse.name(),
664             e
665         );
666         device_manager().remove(&(psmouse.clone() as Arc<dyn Device>));
667         e
668     })?;
669 
670     unsafe { PS2_MOUSE_DEVICE = Some(psmouse) };
671     return Ok(());
672 }
673