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