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