1 use core::hint::spin_loop; 2 3 use alloc::{ 4 string::ToString, 5 sync::{Arc, Weak}, 6 }; 7 8 use unified_init::macros::unified_init; 9 10 use crate::{ 11 arch::{io::PortIOArch, CurrentPortIOArch}, 12 driver::{ 13 base::device::device_number::{DeviceNumber, Major}, 14 input::ps2_dev::Ps2StatusRegister, 15 }, 16 exception::{ 17 irqdata::IrqHandlerData, 18 irqdesc::{IrqHandleFlags, IrqHandler, IrqReturn}, 19 manage::irq_manager, 20 IrqNumber, 21 }, 22 filesystem::{ 23 devfs::{devfs_register, DevFS, DeviceINode}, 24 vfs::{ 25 core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, 26 FileSystem, FileType, IndexNode, Metadata, 27 }, 28 }, 29 init::initcall::INITCALL_DEVICE, 30 libs::{ 31 keyboard_parser::TypeOneFSM, 32 rwlock::RwLock, 33 spinlock::{SpinLock, SpinLockGuard}, 34 }, 35 time::PosixTimeSpec, 36 }; 37 use system_error::SystemError; 38 39 /// PS2键盘的中断向量号 40 const PS2_KEYBOARD_INTR_VECTOR: IrqNumber = IrqNumber::new(0x21); 41 42 const PORT_PS2_KEYBOARD_DATA: u8 = 0x60; 43 const PORT_PS2_KEYBOARD_STATUS: u8 = 0x64; 44 const PORT_PS2_KEYBOARD_CONTROL: u8 = 0x64; 45 46 /// 向键盘发送配置命令 47 const PS2_KEYBOARD_COMMAND_WRITE: u8 = 0x60; 48 49 /// 读取键盘的配置值 50 #[allow(dead_code)] 51 const PS2_KEYBOARD_COMMAND_READ: u8 = 0x20; 52 /// 初始化键盘控制器的配置值 53 const PS2_KEYBOARD_PARAM_INIT: u8 = 0x47; 54 55 #[derive(Debug)] 56 pub struct LockedPS2KeyBoardInode(RwLock<PS2KeyBoardInode>); 57 58 lazy_static! { 59 static ref PS2_KEYBOARD_FSM: SpinLock<TypeOneFSM> = SpinLock::new(TypeOneFSM::new()); 60 } 61 62 #[derive(Debug)] 63 pub struct PS2KeyBoardInode { 64 /// uuid 暂时不知道有什么用(x 65 // uuid: Uuid, 66 /// 指向自身的弱引用 67 self_ref: Weak<LockedPS2KeyBoardInode>, 68 /// 指向inode所在的文件系统对象的指针 69 fs: Weak<DevFS>, 70 /// INode 元数据 71 metadata: Metadata, 72 } 73 74 impl LockedPS2KeyBoardInode { 75 pub fn new() -> Arc<Self> { 76 let inode = PS2KeyBoardInode { 77 // uuid: Uuid::new_v5(), 78 self_ref: Weak::default(), 79 fs: Weak::default(), 80 metadata: Metadata { 81 dev_id: 1, 82 inode_id: generate_inode_id(), 83 size: 0, 84 blk_size: 0, 85 blocks: 0, 86 atime: PosixTimeSpec::default(), 87 mtime: PosixTimeSpec::default(), 88 ctime: PosixTimeSpec::default(), 89 file_type: FileType::CharDevice, // 文件夹,block设备,char设备 90 mode: ModeType::from_bits_truncate(0o666), 91 nlinks: 1, 92 uid: 0, 93 gid: 0, 94 raw_dev: DeviceNumber::new(Major::INPUT_MAJOR, 0), // 这里用来作为device number 95 }, 96 }; 97 98 let result = Arc::new(LockedPS2KeyBoardInode(RwLock::new(inode))); 99 result.0.write().self_ref = Arc::downgrade(&result); 100 101 return result; 102 } 103 } 104 105 impl DeviceINode for LockedPS2KeyBoardInode { 106 fn set_fs(&self, fs: Weak<DevFS>) { 107 self.0.write().fs = fs; 108 } 109 } 110 111 fn ps2_keyboard_register() { 112 devfs_register("ps2_keyboard", LockedPS2KeyBoardInode::new()) 113 .expect("Failed to register ps/2 keyboard"); 114 } 115 116 impl IndexNode for LockedPS2KeyBoardInode { 117 fn read_at( 118 &self, 119 _offset: usize, 120 _len: usize, 121 _buf: &mut [u8], 122 _data: SpinLockGuard<FilePrivateData>, 123 ) -> Result<usize, SystemError> { 124 return Err(SystemError::ENOSYS); 125 } 126 127 fn write_at( 128 &self, 129 _offset: usize, 130 _len: usize, 131 _buf: &[u8], 132 _data: SpinLockGuard<FilePrivateData>, 133 ) -> Result<usize, SystemError> { 134 return Err(SystemError::ENOSYS); 135 } 136 137 fn open( 138 &self, 139 _data: SpinLockGuard<FilePrivateData>, 140 _mode: &FileMode, 141 ) -> Result<(), SystemError> { 142 return Ok(()); 143 } 144 145 fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 146 return Ok(()); 147 } 148 149 fn metadata(&self) -> Result<Metadata, SystemError> { 150 return Ok(self.0.read().metadata.clone()); 151 } 152 153 fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> { 154 let mut inode = self.0.write(); 155 inode.metadata.atime = metadata.atime; 156 inode.metadata.mtime = metadata.mtime; 157 inode.metadata.ctime = metadata.ctime; 158 inode.metadata.mode = metadata.mode; 159 inode.metadata.uid = metadata.uid; 160 inode.metadata.gid = metadata.gid; 161 162 return Ok(()); 163 } 164 165 fn fs(&self) -> alloc::sync::Arc<dyn FileSystem> { 166 return self.0.read().fs.upgrade().unwrap(); 167 } 168 169 fn as_any_ref(&self) -> &dyn core::any::Any { 170 self 171 } 172 173 fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> { 174 return Err(SystemError::ENOSYS); 175 } 176 } 177 178 #[derive(Debug)] 179 struct Ps2KeyboardIrqHandler; 180 181 impl IrqHandler for Ps2KeyboardIrqHandler { 182 fn handle( 183 &self, 184 _irq: IrqNumber, 185 _static_data: Option<&dyn IrqHandlerData>, 186 _dev_id: Option<Arc<dyn IrqHandlerData>>, 187 ) -> Result<IrqReturn, SystemError> { 188 // 先检查状态寄存器,看看是否有数据 189 let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) }; 190 let status = Ps2StatusRegister::from(status); 191 if !status.outbuf_full() { 192 return Ok(IrqReturn::Handled); 193 } 194 195 let input = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) }; 196 // wait_ps2_keyboard_read(); 197 PS2_KEYBOARD_FSM.lock().parse(input); 198 199 return Ok(IrqReturn::Handled); 200 } 201 } 202 203 impl Ps2KeyboardIrqHandler { 204 const INTR_HANDLE_FLAGS: IrqHandleFlags = 205 IrqHandleFlags::from_bits_truncate(IrqHandleFlags::IRQF_TRIGGER_RISING.bits()); 206 } 207 208 /// 等待 PS/2 键盘的输入缓冲区为空 209 fn wait_ps2_keyboard_write() { 210 let mut status: Ps2StatusRegister; 211 loop { 212 status = Ps2StatusRegister::from(unsafe { 213 CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) 214 }); 215 if !status.inbuf_full() { 216 break; 217 } 218 219 spin_loop(); 220 } 221 } 222 #[unified_init(INITCALL_DEVICE)] 223 fn ps2_keyboard_init() -> Result<(), SystemError> { 224 // ======== 初始化键盘控制器,写入配置值 ========= 225 wait_ps2_keyboard_write(); 226 unsafe { 227 CurrentPortIOArch::out8(PORT_PS2_KEYBOARD_CONTROL.into(), PS2_KEYBOARD_COMMAND_WRITE); 228 wait_ps2_keyboard_write(); 229 CurrentPortIOArch::out8(PORT_PS2_KEYBOARD_DATA.into(), PS2_KEYBOARD_PARAM_INIT); 230 wait_ps2_keyboard_write(); 231 } 232 233 // 执行一百万次nop,等待键盘控制器把命令执行完毕 234 for _ in 0..1000000 { 235 spin_loop(); 236 } 237 238 irq_manager() 239 .request_irq( 240 PS2_KEYBOARD_INTR_VECTOR, 241 "ps2keyboard".to_string(), 242 &Ps2KeyboardIrqHandler, 243 Ps2KeyboardIrqHandler::INTR_HANDLE_FLAGS, 244 None, 245 ) 246 .expect("Failed to request irq for ps2 keyboard"); 247 248 // 先读一下键盘的数据,防止由于在键盘初始化之前,由于按键被按下从而导致接收不到中断。 249 let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) }; 250 let status = Ps2StatusRegister::from(status); 251 if status.outbuf_full() { 252 unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) }; 253 } 254 255 // 将设备挂载到devfs 256 ps2_keyboard_register(); 257 258 Ok(()) 259 } 260