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 {
new() -> Arc<Self>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 {
set_fs(&self, fs: Weak<DevFS>)102 fn set_fs(&self, fs: Weak<DevFS>) {
103 self.0.write().fs = fs;
104 }
105 }
106
ps2_keyboard_register()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 {
read_at( &self, _offset: usize, _len: usize, _buf: &mut [u8], _data: &mut FilePrivateData, ) -> Result<usize, SystemError>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
write_at( &self, _offset: usize, _len: usize, _buf: &[u8], _data: &mut FilePrivateData, ) -> Result<usize, SystemError>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
open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError>133 fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
134 return Ok(());
135 }
136
close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError>137 fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
138 return Ok(());
139 }
140
metadata(&self) -> Result<Metadata, SystemError>141 fn metadata(&self) -> Result<Metadata, SystemError> {
142 return Ok(self.0.read().metadata.clone());
143 }
144
set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError>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
fs(&self) -> alloc::sync::Arc<dyn FileSystem>157 fn fs(&self) -> alloc::sync::Arc<dyn FileSystem> {
158 return self.0.read().fs.upgrade().unwrap();
159 }
160
as_any_ref(&self) -> &dyn core::any::Any161 fn as_any_ref(&self) -> &dyn core::any::Any {
162 self
163 }
164
list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError>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 {
handle( &self, _irq: IrqNumber, _static_data: Option<&dyn IrqHandlerData>, _dev_id: Option<Arc<dyn IrqHandlerData>>, ) -> Result<IrqReturn, SystemError>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::NotHandled);
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 键盘的输入缓冲区为空
wait_ps2_keyboard_write()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)]
ps2_keyboard_init() -> Result<(), SystemError>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