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