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