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