xref: /DragonOS/kernel/src/driver/keyboard/ps2_keyboard.rs (revision 8cb2e9b344230227fe5f3ab3ebeb2522f1c5e289)
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,
305fb12ce4SGou Ngai     libs::{keyboard_parser::TypeOneFSM, rwlock::RwLock, spinlock::SpinLock},
315fb12ce4SGou Ngai     time::TimeSpec,
32004e86ffSlogin };
3391e9d4abSLoGin use system_error::SystemError;
34e2841179SLoGin 
35e2841179SLoGin /// PS2键盘的中断向量号
36e2841179SLoGin const PS2_KEYBOARD_INTR_VECTOR: IrqNumber = IrqNumber::new(0x21);
37e2841179SLoGin 
38e2841179SLoGin const PORT_PS2_KEYBOARD_DATA: u8 = 0x60;
39e2841179SLoGin const PORT_PS2_KEYBOARD_STATUS: u8 = 0x64;
40e2841179SLoGin const PORT_PS2_KEYBOARD_CONTROL: u8 = 0x64;
41e2841179SLoGin 
42e2841179SLoGin /// 向键盘发送配置命令
43e2841179SLoGin const PS2_KEYBOARD_COMMAND_WRITE: u8 = 0x60;
44e2841179SLoGin 
45e2841179SLoGin /// 读取键盘的配置值
46e2841179SLoGin #[allow(dead_code)]
47e2841179SLoGin const PS2_KEYBOARD_COMMAND_READ: u8 = 0x20;
48e2841179SLoGin /// 初始化键盘控制器的配置值
49e2841179SLoGin const PS2_KEYBOARD_PARAM_INIT: u8 = 0x47;
50e2841179SLoGin 
51004e86ffSlogin #[derive(Debug)]
52e2841179SLoGin pub struct LockedPS2KeyBoardInode(RwLock<PS2KeyBoardInode>);
53004e86ffSlogin 
545fb12ce4SGou Ngai lazy_static! {
5552da9a59SGnoCiYeH     static ref PS2_KEYBOARD_FSM: SpinLock<TypeOneFSM> = SpinLock::new(TypeOneFSM::new());
565fb12ce4SGou Ngai }
575fb12ce4SGou Ngai 
58004e86ffSlogin #[derive(Debug)]
59004e86ffSlogin pub struct PS2KeyBoardInode {
60004e86ffSlogin     /// uuid 暂时不知道有什么用(x
61004e86ffSlogin     // uuid: Uuid,
62004e86ffSlogin     /// 指向自身的弱引用
63004e86ffSlogin     self_ref: Weak<LockedPS2KeyBoardInode>,
64004e86ffSlogin     /// 指向inode所在的文件系统对象的指针
65004e86ffSlogin     fs: Weak<DevFS>,
66004e86ffSlogin     /// INode 元数据
67004e86ffSlogin     metadata: Metadata,
68004e86ffSlogin }
69004e86ffSlogin 
70004e86ffSlogin impl LockedPS2KeyBoardInode {
71e2841179SLoGin     pub fn new() -> Arc<Self> {
72004e86ffSlogin         let inode = PS2KeyBoardInode {
73004e86ffSlogin             // uuid: Uuid::new_v5(),
74004e86ffSlogin             self_ref: Weak::default(),
75004e86ffSlogin             fs: Weak::default(),
76004e86ffSlogin             metadata: Metadata {
77004e86ffSlogin                 dev_id: 1,
78004e86ffSlogin                 inode_id: generate_inode_id(),
79004e86ffSlogin                 size: 0,
80004e86ffSlogin                 blk_size: 0,
81004e86ffSlogin                 blocks: 0,
82004e86ffSlogin                 atime: TimeSpec::default(),
83004e86ffSlogin                 mtime: TimeSpec::default(),
84004e86ffSlogin                 ctime: TimeSpec::default(),
85004e86ffSlogin                 file_type: FileType::CharDevice, // 文件夹,block设备,char设备
866b4e7a29SLoGin                 mode: ModeType::from_bits_truncate(0o666),
87004e86ffSlogin                 nlinks: 1,
88004e86ffSlogin                 uid: 0,
89004e86ffSlogin                 gid: 0,
9002343d0bSLoGin                 raw_dev: DeviceNumber::new(Major::INPUT_MAJOR, 0), // 这里用来作为device number
91004e86ffSlogin             },
92004e86ffSlogin         };
93004e86ffSlogin 
94e2841179SLoGin         let result = Arc::new(LockedPS2KeyBoardInode(RwLock::new(inode)));
9564aea4b3SGou Ngai         result.0.write().self_ref = Arc::downgrade(&result);
96004e86ffSlogin 
97004e86ffSlogin         return result;
98004e86ffSlogin     }
99004e86ffSlogin }
100004e86ffSlogin 
101004e86ffSlogin impl DeviceINode for LockedPS2KeyBoardInode {
102004e86ffSlogin     fn set_fs(&self, fs: Weak<DevFS>) {
10364aea4b3SGou Ngai         self.0.write().fs = fs;
104004e86ffSlogin     }
105004e86ffSlogin }
106004e86ffSlogin 
107e2841179SLoGin fn ps2_keyboard_register() {
108e2841179SLoGin     devfs_register("ps2_keyboard", LockedPS2KeyBoardInode::new())
109004e86ffSlogin         .expect("Failed to register ps/2 keyboard");
110004e86ffSlogin }
111004e86ffSlogin 
112004e86ffSlogin impl IndexNode for LockedPS2KeyBoardInode {
113004e86ffSlogin     fn read_at(
114004e86ffSlogin         &self,
115004e86ffSlogin         _offset: usize,
116e2841179SLoGin         _len: usize,
117e2841179SLoGin         _buf: &mut [u8],
1184ad52e57S裕依2439         _data: &mut FilePrivateData,
119676b8ef6SMork     ) -> Result<usize, SystemError> {
120e2841179SLoGin         return Err(SystemError::ENOSYS);
121004e86ffSlogin     }
122004e86ffSlogin 
123004e86ffSlogin     fn write_at(
124004e86ffSlogin         &self,
125004e86ffSlogin         _offset: usize,
126004e86ffSlogin         _len: usize,
127004e86ffSlogin         _buf: &[u8],
1284ad52e57S裕依2439         _data: &mut FilePrivateData,
129676b8ef6SMork     ) -> Result<usize, SystemError> {
130e2841179SLoGin         return Err(SystemError::ENOSYS);
131004e86ffSlogin     }
132004e86ffSlogin 
1334ad52e57S裕依2439     fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
134004e86ffSlogin         return Ok(());
135004e86ffSlogin     }
136004e86ffSlogin 
1374ad52e57S裕依2439     fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
138004e86ffSlogin         return Ok(());
139004e86ffSlogin     }
140004e86ffSlogin 
141676b8ef6SMork     fn metadata(&self) -> Result<Metadata, SystemError> {
14264aea4b3SGou Ngai         return Ok(self.0.read().metadata.clone());
143004e86ffSlogin     }
144004e86ffSlogin 
145676b8ef6SMork     fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
14664aea4b3SGou Ngai         let mut inode = self.0.write();
147004e86ffSlogin         inode.metadata.atime = metadata.atime;
148004e86ffSlogin         inode.metadata.mtime = metadata.mtime;
149004e86ffSlogin         inode.metadata.ctime = metadata.ctime;
150004e86ffSlogin         inode.metadata.mode = metadata.mode;
151004e86ffSlogin         inode.metadata.uid = metadata.uid;
152004e86ffSlogin         inode.metadata.gid = metadata.gid;
153004e86ffSlogin 
154004e86ffSlogin         return Ok(());
155004e86ffSlogin     }
156004e86ffSlogin 
1574ad52e57S裕依2439     fn fs(&self) -> alloc::sync::Arc<dyn FileSystem> {
15864aea4b3SGou Ngai         return self.0.read().fs.upgrade().unwrap();
159004e86ffSlogin     }
160004e86ffSlogin 
161004e86ffSlogin     fn as_any_ref(&self) -> &dyn core::any::Any {
162004e86ffSlogin         self
163004e86ffSlogin     }
164004e86ffSlogin 
165676b8ef6SMork     fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
16679a452ceShoumkh         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
167004e86ffSlogin     }
168004e86ffSlogin }
1695fb12ce4SGou Ngai 
170e2841179SLoGin #[derive(Debug)]
171e2841179SLoGin struct Ps2KeyboardIrqHandler;
172e2841179SLoGin 
173e2841179SLoGin impl IrqHandler for Ps2KeyboardIrqHandler {
174e2841179SLoGin     fn handle(
175e2841179SLoGin         &self,
176e2841179SLoGin         _irq: IrqNumber,
177e2841179SLoGin         _static_data: Option<&dyn IrqHandlerData>,
178e2841179SLoGin         _dev_id: Option<Arc<dyn IrqHandlerData>>,
179e2841179SLoGin     ) -> Result<IrqReturn, SystemError> {
180e2841179SLoGin         // 先检查状态寄存器,看看是否有数据
181e2841179SLoGin         let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) };
182e2841179SLoGin         let status = Ps2StatusRegister::from(status);
183e2841179SLoGin         if !status.outbuf_full() {
184*8cb2e9b3SLoGin             return Ok(IrqReturn::Handled);
185e2841179SLoGin         }
186e2841179SLoGin 
187e2841179SLoGin         let input = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) };
188e2841179SLoGin         // wait_ps2_keyboard_read();
1895fb12ce4SGou Ngai         PS2_KEYBOARD_FSM.lock().parse(input);
190e2841179SLoGin 
191e2841179SLoGin         return Ok(IrqReturn::Handled);
192e2841179SLoGin     }
193e2841179SLoGin }
194e2841179SLoGin 
195e2841179SLoGin impl Ps2KeyboardIrqHandler {
196e2841179SLoGin     const INTR_HANDLE_FLAGS: IrqHandleFlags =
197e2841179SLoGin         IrqHandleFlags::from_bits_truncate(IrqHandleFlags::IRQF_TRIGGER_RISING.bits());
198e2841179SLoGin }
199e2841179SLoGin 
200e2841179SLoGin /// 等待 PS/2 键盘的输入缓冲区为空
201e2841179SLoGin fn wait_ps2_keyboard_write() {
202e2841179SLoGin     let mut status: Ps2StatusRegister;
203e2841179SLoGin     loop {
204e2841179SLoGin         status = Ps2StatusRegister::from(unsafe {
205e2841179SLoGin             CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into())
206e2841179SLoGin         });
207e2841179SLoGin         if !status.inbuf_full() {
208e2841179SLoGin             break;
209e2841179SLoGin         }
210e2841179SLoGin 
211e2841179SLoGin         spin_loop();
212e2841179SLoGin     }
213e2841179SLoGin }
214e2841179SLoGin #[unified_init(INITCALL_DEVICE)]
215e2841179SLoGin fn ps2_keyboard_init() -> Result<(), SystemError> {
216e2841179SLoGin     // ======== 初始化键盘控制器,写入配置值 =========
217e2841179SLoGin     wait_ps2_keyboard_write();
218e2841179SLoGin     unsafe {
219e2841179SLoGin         CurrentPortIOArch::out8(PORT_PS2_KEYBOARD_CONTROL.into(), PS2_KEYBOARD_COMMAND_WRITE);
220e2841179SLoGin         wait_ps2_keyboard_write();
221e2841179SLoGin         CurrentPortIOArch::out8(PORT_PS2_KEYBOARD_DATA.into(), PS2_KEYBOARD_PARAM_INIT);
222e2841179SLoGin         wait_ps2_keyboard_write();
223e2841179SLoGin     }
224e2841179SLoGin 
225e2841179SLoGin     // 执行一百万次nop,等待键盘控制器把命令执行完毕
226e2841179SLoGin     for _ in 0..1000000 {
227e2841179SLoGin         spin_loop();
228e2841179SLoGin     }
229e2841179SLoGin 
230e2841179SLoGin     irq_manager()
231e2841179SLoGin         .request_irq(
232e2841179SLoGin             PS2_KEYBOARD_INTR_VECTOR,
233e2841179SLoGin             "ps2keyboard".to_string(),
234e2841179SLoGin             &Ps2KeyboardIrqHandler,
235e2841179SLoGin             Ps2KeyboardIrqHandler::INTR_HANDLE_FLAGS,
236e2841179SLoGin             None,
237e2841179SLoGin         )
238e2841179SLoGin         .expect("Failed to request irq for ps2 keyboard");
239e2841179SLoGin 
240e2841179SLoGin     // 先读一下键盘的数据,防止由于在键盘初始化之前,由于按键被按下从而导致接收不到中断。
241e2841179SLoGin     let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) };
242e2841179SLoGin     let status = Ps2StatusRegister::from(status);
243e2841179SLoGin     if status.outbuf_full() {
244e2841179SLoGin         unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) };
245e2841179SLoGin     }
246e2841179SLoGin 
247e2841179SLoGin     // 将设备挂载到devfs
248e2841179SLoGin     ps2_keyboard_register();
249e2841179SLoGin 
250e2841179SLoGin     Ok(())
2515fb12ce4SGou Ngai }
252