xref: /DragonOS/kernel/src/driver/keyboard/ps2_keyboard.rs (revision c3dc6f2ff9169c309d1cbf47dcb9e4528d509b2f)
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::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 键盘的输入缓冲区为空
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