1e2841179SLoGin use core::hint::spin_loop; 264aea4b3SGou Ngai 3e2841179SLoGin use alloc::{ 4e2841179SLoGin string::ToString, 5e2841179SLoGin sync::{Arc, Weak}, 6e2841179SLoGin }; 7e2841179SLoGin 8e2841179SLoGin use unified_init::macros::unified_init; 9004e86ffSlogin 10004e86ffSlogin use crate::{ 11e2841179SLoGin arch::{io::PortIOArch, CurrentPortIOArch}, 12e2841179SLoGin driver::{ 13e2841179SLoGin base::device::device_number::{DeviceNumber, Major}, 14e2841179SLoGin input::ps2_dev::Ps2StatusRegister, 15e2841179SLoGin }, 16e2841179SLoGin exception::{ 17e2841179SLoGin irqdata::IrqHandlerData, 18e2841179SLoGin irqdesc::{IrqHandleFlags, IrqHandler, IrqReturn}, 19e2841179SLoGin manage::irq_manager, 20e2841179SLoGin IrqNumber, 21e2841179SLoGin }, 22004e86ffSlogin filesystem::{ 23004e86ffSlogin devfs::{devfs_register, DevFS, DeviceINode}, 246b4e7a29SLoGin vfs::{ 254ad52e57S裕依2439 core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, 264ad52e57S裕依2439 FileSystem, FileType, IndexNode, Metadata, 276b4e7a29SLoGin }, 28004e86ffSlogin }, 29e2841179SLoGin init::initcall::INITCALL_DEVICE, 30dfe53cf0SGnoCiYeH libs::{ 31dfe53cf0SGnoCiYeH keyboard_parser::TypeOneFSM, 32dfe53cf0SGnoCiYeH rwlock::RwLock, 33dfe53cf0SGnoCiYeH spinlock::{SpinLock, SpinLockGuard}, 34dfe53cf0SGnoCiYeH }, 356fc066acSJomo time::PosixTimeSpec, 36004e86ffSlogin }; 3791e9d4abSLoGin use system_error::SystemError; 38e2841179SLoGin 39e2841179SLoGin /// PS2键盘的中断向量号 40e2841179SLoGin const PS2_KEYBOARD_INTR_VECTOR: IrqNumber = IrqNumber::new(0x21); 41e2841179SLoGin 42e2841179SLoGin const PORT_PS2_KEYBOARD_DATA: u8 = 0x60; 43e2841179SLoGin const PORT_PS2_KEYBOARD_STATUS: u8 = 0x64; 44e2841179SLoGin const PORT_PS2_KEYBOARD_CONTROL: u8 = 0x64; 45e2841179SLoGin 46e2841179SLoGin /// 向键盘发送配置命令 47e2841179SLoGin const PS2_KEYBOARD_COMMAND_WRITE: u8 = 0x60; 48e2841179SLoGin 49e2841179SLoGin /// 读取键盘的配置值 50e2841179SLoGin #[allow(dead_code)] 51e2841179SLoGin const PS2_KEYBOARD_COMMAND_READ: u8 = 0x20; 52e2841179SLoGin /// 初始化键盘控制器的配置值 53e2841179SLoGin const PS2_KEYBOARD_PARAM_INIT: u8 = 0x47; 54e2841179SLoGin 55004e86ffSlogin #[derive(Debug)] 56e2841179SLoGin pub struct LockedPS2KeyBoardInode(RwLock<PS2KeyBoardInode>); 57004e86ffSlogin 585fb12ce4SGou Ngai lazy_static! { 5952da9a59SGnoCiYeH static ref PS2_KEYBOARD_FSM: SpinLock<TypeOneFSM> = SpinLock::new(TypeOneFSM::new()); 605fb12ce4SGou Ngai } 615fb12ce4SGou Ngai 62004e86ffSlogin #[derive(Debug)] 63004e86ffSlogin pub struct PS2KeyBoardInode { 64004e86ffSlogin /// uuid 暂时不知道有什么用(x 65004e86ffSlogin // uuid: Uuid, 66004e86ffSlogin /// 指向自身的弱引用 67004e86ffSlogin self_ref: Weak<LockedPS2KeyBoardInode>, 68004e86ffSlogin /// 指向inode所在的文件系统对象的指针 69004e86ffSlogin fs: Weak<DevFS>, 70004e86ffSlogin /// INode 元数据 71004e86ffSlogin metadata: Metadata, 72004e86ffSlogin } 73004e86ffSlogin 74004e86ffSlogin impl LockedPS2KeyBoardInode { 75e2841179SLoGin pub fn new() -> Arc<Self> { 76004e86ffSlogin let inode = PS2KeyBoardInode { 77004e86ffSlogin // uuid: Uuid::new_v5(), 78004e86ffSlogin self_ref: Weak::default(), 79004e86ffSlogin fs: Weak::default(), 80004e86ffSlogin metadata: Metadata { 81004e86ffSlogin dev_id: 1, 82004e86ffSlogin inode_id: generate_inode_id(), 83004e86ffSlogin size: 0, 84004e86ffSlogin blk_size: 0, 85004e86ffSlogin blocks: 0, 866fc066acSJomo atime: PosixTimeSpec::default(), 876fc066acSJomo mtime: PosixTimeSpec::default(), 886fc066acSJomo ctime: PosixTimeSpec::default(), 89004e86ffSlogin file_type: FileType::CharDevice, // 文件夹,block设备,char设备 906b4e7a29SLoGin mode: ModeType::from_bits_truncate(0o666), 91004e86ffSlogin nlinks: 1, 92004e86ffSlogin uid: 0, 93004e86ffSlogin gid: 0, 9402343d0bSLoGin raw_dev: DeviceNumber::new(Major::INPUT_MAJOR, 0), // 这里用来作为device number 95004e86ffSlogin }, 96004e86ffSlogin }; 97004e86ffSlogin 98e2841179SLoGin let result = Arc::new(LockedPS2KeyBoardInode(RwLock::new(inode))); 9964aea4b3SGou Ngai result.0.write().self_ref = Arc::downgrade(&result); 100004e86ffSlogin 101004e86ffSlogin return result; 102004e86ffSlogin } 103004e86ffSlogin } 104004e86ffSlogin 105004e86ffSlogin impl DeviceINode for LockedPS2KeyBoardInode { 106004e86ffSlogin fn set_fs(&self, fs: Weak<DevFS>) { 10764aea4b3SGou Ngai self.0.write().fs = fs; 108004e86ffSlogin } 109004e86ffSlogin } 110004e86ffSlogin 111e2841179SLoGin fn ps2_keyboard_register() { 112e2841179SLoGin devfs_register("ps2_keyboard", LockedPS2KeyBoardInode::new()) 113004e86ffSlogin .expect("Failed to register ps/2 keyboard"); 114004e86ffSlogin } 115004e86ffSlogin 116004e86ffSlogin impl IndexNode for LockedPS2KeyBoardInode { 117004e86ffSlogin fn read_at( 118004e86ffSlogin &self, 119004e86ffSlogin _offset: usize, 120e2841179SLoGin _len: usize, 121e2841179SLoGin _buf: &mut [u8], 122dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>, 123676b8ef6SMork ) -> Result<usize, SystemError> { 124e2841179SLoGin return Err(SystemError::ENOSYS); 125004e86ffSlogin } 126004e86ffSlogin 127004e86ffSlogin fn write_at( 128004e86ffSlogin &self, 129004e86ffSlogin _offset: usize, 130004e86ffSlogin _len: usize, 131004e86ffSlogin _buf: &[u8], 132dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>, 133676b8ef6SMork ) -> Result<usize, SystemError> { 134e2841179SLoGin return Err(SystemError::ENOSYS); 135004e86ffSlogin } 136004e86ffSlogin 137dfe53cf0SGnoCiYeH fn open( 138dfe53cf0SGnoCiYeH &self, 139dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>, 140dfe53cf0SGnoCiYeH _mode: &FileMode, 141dfe53cf0SGnoCiYeH ) -> Result<(), SystemError> { 142004e86ffSlogin return Ok(()); 143004e86ffSlogin } 144004e86ffSlogin 145dfe53cf0SGnoCiYeH fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 146004e86ffSlogin return Ok(()); 147004e86ffSlogin } 148004e86ffSlogin 149676b8ef6SMork fn metadata(&self) -> Result<Metadata, SystemError> { 15064aea4b3SGou Ngai return Ok(self.0.read().metadata.clone()); 151004e86ffSlogin } 152004e86ffSlogin 153676b8ef6SMork fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> { 15464aea4b3SGou Ngai let mut inode = self.0.write(); 155004e86ffSlogin inode.metadata.atime = metadata.atime; 156004e86ffSlogin inode.metadata.mtime = metadata.mtime; 157004e86ffSlogin inode.metadata.ctime = metadata.ctime; 158004e86ffSlogin inode.metadata.mode = metadata.mode; 159004e86ffSlogin inode.metadata.uid = metadata.uid; 160004e86ffSlogin inode.metadata.gid = metadata.gid; 161004e86ffSlogin 162004e86ffSlogin return Ok(()); 163004e86ffSlogin } 164004e86ffSlogin 1654ad52e57S裕依2439 fn fs(&self) -> alloc::sync::Arc<dyn FileSystem> { 16664aea4b3SGou Ngai return self.0.read().fs.upgrade().unwrap(); 167004e86ffSlogin } 168004e86ffSlogin 169004e86ffSlogin fn as_any_ref(&self) -> &dyn core::any::Any { 170004e86ffSlogin self 171004e86ffSlogin } 172004e86ffSlogin 173676b8ef6SMork fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> { 174*1074eb34SSamuel Dai return Err(SystemError::ENOSYS); 175004e86ffSlogin } 176004e86ffSlogin } 1775fb12ce4SGou Ngai 178e2841179SLoGin #[derive(Debug)] 179e2841179SLoGin struct Ps2KeyboardIrqHandler; 180e2841179SLoGin 181e2841179SLoGin impl IrqHandler for Ps2KeyboardIrqHandler { 182e2841179SLoGin fn handle( 183e2841179SLoGin &self, 184e2841179SLoGin _irq: IrqNumber, 185e2841179SLoGin _static_data: Option<&dyn IrqHandlerData>, 186e2841179SLoGin _dev_id: Option<Arc<dyn IrqHandlerData>>, 187e2841179SLoGin ) -> Result<IrqReturn, SystemError> { 188e2841179SLoGin // 先检查状态寄存器,看看是否有数据 189e2841179SLoGin let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) }; 190e2841179SLoGin let status = Ps2StatusRegister::from(status); 191e2841179SLoGin if !status.outbuf_full() { 1928cb2e9b3SLoGin return Ok(IrqReturn::Handled); 193e2841179SLoGin } 194e2841179SLoGin 195e2841179SLoGin let input = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) }; 196e2841179SLoGin // wait_ps2_keyboard_read(); 1975fb12ce4SGou Ngai PS2_KEYBOARD_FSM.lock().parse(input); 198e2841179SLoGin 199e2841179SLoGin return Ok(IrqReturn::Handled); 200e2841179SLoGin } 201e2841179SLoGin } 202e2841179SLoGin 203e2841179SLoGin impl Ps2KeyboardIrqHandler { 204e2841179SLoGin const INTR_HANDLE_FLAGS: IrqHandleFlags = 205e2841179SLoGin IrqHandleFlags::from_bits_truncate(IrqHandleFlags::IRQF_TRIGGER_RISING.bits()); 206e2841179SLoGin } 207e2841179SLoGin 208e2841179SLoGin /// 等待 PS/2 键盘的输入缓冲区为空 209e2841179SLoGin fn wait_ps2_keyboard_write() { 210e2841179SLoGin let mut status: Ps2StatusRegister; 211e2841179SLoGin loop { 212e2841179SLoGin status = Ps2StatusRegister::from(unsafe { 213e2841179SLoGin CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) 214e2841179SLoGin }); 215e2841179SLoGin if !status.inbuf_full() { 216e2841179SLoGin break; 217e2841179SLoGin } 218e2841179SLoGin 219e2841179SLoGin spin_loop(); 220e2841179SLoGin } 221e2841179SLoGin } 222e2841179SLoGin #[unified_init(INITCALL_DEVICE)] 223e2841179SLoGin fn ps2_keyboard_init() -> Result<(), SystemError> { 224e2841179SLoGin // ======== 初始化键盘控制器,写入配置值 ========= 225e2841179SLoGin wait_ps2_keyboard_write(); 226e2841179SLoGin unsafe { 227e2841179SLoGin CurrentPortIOArch::out8(PORT_PS2_KEYBOARD_CONTROL.into(), PS2_KEYBOARD_COMMAND_WRITE); 228e2841179SLoGin wait_ps2_keyboard_write(); 229e2841179SLoGin CurrentPortIOArch::out8(PORT_PS2_KEYBOARD_DATA.into(), PS2_KEYBOARD_PARAM_INIT); 230e2841179SLoGin wait_ps2_keyboard_write(); 231e2841179SLoGin } 232e2841179SLoGin 233e2841179SLoGin // 执行一百万次nop,等待键盘控制器把命令执行完毕 234e2841179SLoGin for _ in 0..1000000 { 235e2841179SLoGin spin_loop(); 236e2841179SLoGin } 237e2841179SLoGin 238e2841179SLoGin irq_manager() 239e2841179SLoGin .request_irq( 240e2841179SLoGin PS2_KEYBOARD_INTR_VECTOR, 241e2841179SLoGin "ps2keyboard".to_string(), 242e2841179SLoGin &Ps2KeyboardIrqHandler, 243e2841179SLoGin Ps2KeyboardIrqHandler::INTR_HANDLE_FLAGS, 244e2841179SLoGin None, 245e2841179SLoGin ) 246e2841179SLoGin .expect("Failed to request irq for ps2 keyboard"); 247e2841179SLoGin 248e2841179SLoGin // 先读一下键盘的数据,防止由于在键盘初始化之前,由于按键被按下从而导致接收不到中断。 249e2841179SLoGin let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) }; 250e2841179SLoGin let status = Ps2StatusRegister::from(status); 251e2841179SLoGin if status.outbuf_full() { 252e2841179SLoGin unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) }; 253e2841179SLoGin } 254e2841179SLoGin 255e2841179SLoGin // 将设备挂载到devfs 256e2841179SLoGin ps2_keyboard_register(); 257e2841179SLoGin 258e2841179SLoGin Ok(()) 2595fb12ce4SGou Ngai } 260