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,
30dfe53cf0SGnoCiYeH libs::{
31dfe53cf0SGnoCiYeH keyboard_parser::TypeOneFSM,
32dfe53cf0SGnoCiYeH rwlock::RwLock,
33dfe53cf0SGnoCiYeH spinlock::{SpinLock, SpinLockGuard},
34dfe53cf0SGnoCiYeH },
356fc066acSJomo time::PosixTimeSpec,
36004e86ffSlogin };
3791e9d4abSLoGin use system_error::SystemError;
38e2841179SLoGin
39e2841179SLoGin /// PS2键盘的中断向量号
40e2841179SLoGin const PS2_KEYBOARD_INTR_VECTOR: IrqNumber = IrqNumber::new(0x21);
41e2841179SLoGin
42e2841179SLoGin const PORT_PS2_KEYBOARD_DATA: u8 = 0x60;
43e2841179SLoGin const PORT_PS2_KEYBOARD_STATUS: u8 = 0x64;
44e2841179SLoGin const PORT_PS2_KEYBOARD_CONTROL: u8 = 0x64;
45e2841179SLoGin
46e2841179SLoGin /// 向键盘发送配置命令
47e2841179SLoGin const PS2_KEYBOARD_COMMAND_WRITE: u8 = 0x60;
48e2841179SLoGin
49e2841179SLoGin /// 读取键盘的配置值
50e2841179SLoGin #[allow(dead_code)]
51e2841179SLoGin const PS2_KEYBOARD_COMMAND_READ: u8 = 0x20;
52e2841179SLoGin /// 初始化键盘控制器的配置值
53e2841179SLoGin const PS2_KEYBOARD_PARAM_INIT: u8 = 0x47;
54e2841179SLoGin
55004e86ffSlogin #[derive(Debug)]
56e2841179SLoGin pub struct LockedPS2KeyBoardInode(RwLock<PS2KeyBoardInode>);
57004e86ffSlogin
585fb12ce4SGou Ngai lazy_static! {
5952da9a59SGnoCiYeH static ref PS2_KEYBOARD_FSM: SpinLock<TypeOneFSM> = SpinLock::new(TypeOneFSM::new());
605fb12ce4SGou Ngai }
615fb12ce4SGou Ngai
62004e86ffSlogin #[derive(Debug)]
63004e86ffSlogin pub struct PS2KeyBoardInode {
64004e86ffSlogin /// uuid 暂时不知道有什么用(x
65004e86ffSlogin // uuid: Uuid,
66004e86ffSlogin /// 指向自身的弱引用
67004e86ffSlogin self_ref: Weak<LockedPS2KeyBoardInode>,
68004e86ffSlogin /// 指向inode所在的文件系统对象的指针
69004e86ffSlogin fs: Weak<DevFS>,
70004e86ffSlogin /// INode 元数据
71004e86ffSlogin metadata: Metadata,
72004e86ffSlogin }
73004e86ffSlogin
74004e86ffSlogin impl LockedPS2KeyBoardInode {
new() -> Arc<Self>75e2841179SLoGin pub fn new() -> Arc<Self> {
76004e86ffSlogin let inode = PS2KeyBoardInode {
77004e86ffSlogin // uuid: Uuid::new_v5(),
78004e86ffSlogin self_ref: Weak::default(),
79004e86ffSlogin fs: Weak::default(),
80004e86ffSlogin metadata: Metadata {
81004e86ffSlogin dev_id: 1,
82004e86ffSlogin inode_id: generate_inode_id(),
83004e86ffSlogin size: 0,
84004e86ffSlogin blk_size: 0,
85004e86ffSlogin blocks: 0,
866fc066acSJomo atime: PosixTimeSpec::default(),
876fc066acSJomo mtime: PosixTimeSpec::default(),
886fc066acSJomo ctime: PosixTimeSpec::default(),
89004e86ffSlogin file_type: FileType::CharDevice, // 文件夹,block设备,char设备
906b4e7a29SLoGin mode: ModeType::from_bits_truncate(0o666),
91004e86ffSlogin nlinks: 1,
92004e86ffSlogin uid: 0,
93004e86ffSlogin gid: 0,
9402343d0bSLoGin raw_dev: DeviceNumber::new(Major::INPUT_MAJOR, 0), // 这里用来作为device number
95004e86ffSlogin },
96004e86ffSlogin };
97004e86ffSlogin
98e2841179SLoGin let result = Arc::new(LockedPS2KeyBoardInode(RwLock::new(inode)));
9964aea4b3SGou Ngai result.0.write().self_ref = Arc::downgrade(&result);
100004e86ffSlogin
101004e86ffSlogin return result;
102004e86ffSlogin }
103004e86ffSlogin }
104004e86ffSlogin
105004e86ffSlogin impl DeviceINode for LockedPS2KeyBoardInode {
set_fs(&self, fs: Weak<DevFS>)106004e86ffSlogin fn set_fs(&self, fs: Weak<DevFS>) {
10764aea4b3SGou Ngai self.0.write().fs = fs;
108004e86ffSlogin }
109004e86ffSlogin }
110004e86ffSlogin
ps2_keyboard_register()111e2841179SLoGin fn ps2_keyboard_register() {
112e2841179SLoGin devfs_register("ps2_keyboard", LockedPS2KeyBoardInode::new())
113004e86ffSlogin .expect("Failed to register ps/2 keyboard");
114004e86ffSlogin }
115004e86ffSlogin
116004e86ffSlogin impl IndexNode for LockedPS2KeyBoardInode {
read_at( &self, _offset: usize, _len: usize, _buf: &mut [u8], _data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, SystemError>117004e86ffSlogin fn read_at(
118004e86ffSlogin &self,
119004e86ffSlogin _offset: usize,
120e2841179SLoGin _len: usize,
121e2841179SLoGin _buf: &mut [u8],
122dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>,
123676b8ef6SMork ) -> Result<usize, SystemError> {
124e2841179SLoGin return Err(SystemError::ENOSYS);
125004e86ffSlogin }
126004e86ffSlogin
write_at( &self, _offset: usize, _len: usize, _buf: &[u8], _data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, SystemError>127004e86ffSlogin fn write_at(
128004e86ffSlogin &self,
129004e86ffSlogin _offset: usize,
130004e86ffSlogin _len: usize,
131004e86ffSlogin _buf: &[u8],
132dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>,
133676b8ef6SMork ) -> Result<usize, SystemError> {
134e2841179SLoGin return Err(SystemError::ENOSYS);
135004e86ffSlogin }
136004e86ffSlogin
open( &self, _data: SpinLockGuard<FilePrivateData>, _mode: &FileMode, ) -> Result<(), SystemError>137dfe53cf0SGnoCiYeH fn open(
138dfe53cf0SGnoCiYeH &self,
139dfe53cf0SGnoCiYeH _data: SpinLockGuard<FilePrivateData>,
140dfe53cf0SGnoCiYeH _mode: &FileMode,
141dfe53cf0SGnoCiYeH ) -> Result<(), SystemError> {
142004e86ffSlogin return Ok(());
143004e86ffSlogin }
144004e86ffSlogin
close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError>145dfe53cf0SGnoCiYeH fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
146004e86ffSlogin return Ok(());
147004e86ffSlogin }
148004e86ffSlogin
metadata(&self) -> Result<Metadata, SystemError>149676b8ef6SMork fn metadata(&self) -> Result<Metadata, SystemError> {
15064aea4b3SGou Ngai return Ok(self.0.read().metadata.clone());
151004e86ffSlogin }
152004e86ffSlogin
set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError>153676b8ef6SMork fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
15464aea4b3SGou Ngai let mut inode = self.0.write();
155004e86ffSlogin inode.metadata.atime = metadata.atime;
156004e86ffSlogin inode.metadata.mtime = metadata.mtime;
157004e86ffSlogin inode.metadata.ctime = metadata.ctime;
158004e86ffSlogin inode.metadata.mode = metadata.mode;
159004e86ffSlogin inode.metadata.uid = metadata.uid;
160004e86ffSlogin inode.metadata.gid = metadata.gid;
161004e86ffSlogin
162004e86ffSlogin return Ok(());
163004e86ffSlogin }
164004e86ffSlogin
fs(&self) -> alloc::sync::Arc<dyn FileSystem>1654ad52e57S裕依2439 fn fs(&self) -> alloc::sync::Arc<dyn FileSystem> {
16664aea4b3SGou Ngai return self.0.read().fs.upgrade().unwrap();
167004e86ffSlogin }
168004e86ffSlogin
as_any_ref(&self) -> &dyn core::any::Any169004e86ffSlogin fn as_any_ref(&self) -> &dyn core::any::Any {
170004e86ffSlogin self
171004e86ffSlogin }
172004e86ffSlogin
list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError>173676b8ef6SMork fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
174*1074eb34SSamuel Dai return Err(SystemError::ENOSYS);
175004e86ffSlogin }
176004e86ffSlogin }
1775fb12ce4SGou Ngai
178e2841179SLoGin #[derive(Debug)]
179e2841179SLoGin struct Ps2KeyboardIrqHandler;
180e2841179SLoGin
181e2841179SLoGin impl IrqHandler for Ps2KeyboardIrqHandler {
handle( &self, _irq: IrqNumber, _static_data: Option<&dyn IrqHandlerData>, _dev_id: Option<Arc<dyn IrqHandlerData>>, ) -> Result<IrqReturn, SystemError>182e2841179SLoGin fn handle(
183e2841179SLoGin &self,
184e2841179SLoGin _irq: IrqNumber,
185e2841179SLoGin _static_data: Option<&dyn IrqHandlerData>,
186e2841179SLoGin _dev_id: Option<Arc<dyn IrqHandlerData>>,
187e2841179SLoGin ) -> Result<IrqReturn, SystemError> {
188e2841179SLoGin // 先检查状态寄存器,看看是否有数据
189e2841179SLoGin let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) };
190e2841179SLoGin let status = Ps2StatusRegister::from(status);
191e2841179SLoGin if !status.outbuf_full() {
1928cb2e9b3SLoGin return Ok(IrqReturn::Handled);
193e2841179SLoGin }
194e2841179SLoGin
195e2841179SLoGin let input = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) };
196e2841179SLoGin // wait_ps2_keyboard_read();
1975fb12ce4SGou Ngai PS2_KEYBOARD_FSM.lock().parse(input);
198e2841179SLoGin
199e2841179SLoGin return Ok(IrqReturn::Handled);
200e2841179SLoGin }
201e2841179SLoGin }
202e2841179SLoGin
203e2841179SLoGin impl Ps2KeyboardIrqHandler {
204e2841179SLoGin const INTR_HANDLE_FLAGS: IrqHandleFlags =
205e2841179SLoGin IrqHandleFlags::from_bits_truncate(IrqHandleFlags::IRQF_TRIGGER_RISING.bits());
206e2841179SLoGin }
207e2841179SLoGin
208e2841179SLoGin /// 等待 PS/2 键盘的输入缓冲区为空
wait_ps2_keyboard_write()209e2841179SLoGin fn wait_ps2_keyboard_write() {
210e2841179SLoGin let mut status: Ps2StatusRegister;
211e2841179SLoGin loop {
212e2841179SLoGin status = Ps2StatusRegister::from(unsafe {
213e2841179SLoGin CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into())
214e2841179SLoGin });
215e2841179SLoGin if !status.inbuf_full() {
216e2841179SLoGin break;
217e2841179SLoGin }
218e2841179SLoGin
219e2841179SLoGin spin_loop();
220e2841179SLoGin }
221e2841179SLoGin }
222e2841179SLoGin #[unified_init(INITCALL_DEVICE)]
ps2_keyboard_init() -> Result<(), SystemError>223e2841179SLoGin fn ps2_keyboard_init() -> Result<(), SystemError> {
224e2841179SLoGin // ======== 初始化键盘控制器,写入配置值 =========
225e2841179SLoGin wait_ps2_keyboard_write();
226e2841179SLoGin unsafe {
227e2841179SLoGin CurrentPortIOArch::out8(PORT_PS2_KEYBOARD_CONTROL.into(), PS2_KEYBOARD_COMMAND_WRITE);
228e2841179SLoGin wait_ps2_keyboard_write();
229e2841179SLoGin CurrentPortIOArch::out8(PORT_PS2_KEYBOARD_DATA.into(), PS2_KEYBOARD_PARAM_INIT);
230e2841179SLoGin wait_ps2_keyboard_write();
231e2841179SLoGin }
232e2841179SLoGin
233e2841179SLoGin // 执行一百万次nop,等待键盘控制器把命令执行完毕
234e2841179SLoGin for _ in 0..1000000 {
235e2841179SLoGin spin_loop();
236e2841179SLoGin }
237e2841179SLoGin
238e2841179SLoGin irq_manager()
239e2841179SLoGin .request_irq(
240e2841179SLoGin PS2_KEYBOARD_INTR_VECTOR,
241e2841179SLoGin "ps2keyboard".to_string(),
242e2841179SLoGin &Ps2KeyboardIrqHandler,
243e2841179SLoGin Ps2KeyboardIrqHandler::INTR_HANDLE_FLAGS,
244e2841179SLoGin None,
245e2841179SLoGin )
246e2841179SLoGin .expect("Failed to request irq for ps2 keyboard");
247e2841179SLoGin
248e2841179SLoGin // 先读一下键盘的数据,防止由于在键盘初始化之前,由于按键被按下从而导致接收不到中断。
249e2841179SLoGin let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) };
250e2841179SLoGin let status = Ps2StatusRegister::from(status);
251e2841179SLoGin if status.outbuf_full() {
252e2841179SLoGin unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) };
253e2841179SLoGin }
254e2841179SLoGin
255e2841179SLoGin // 将设备挂载到devfs
256e2841179SLoGin ps2_keyboard_register();
257e2841179SLoGin
258e2841179SLoGin Ok(())
2595fb12ce4SGou Ngai }
260