kernel/devices/keyboard_mouse/
ps2.rs

1use crate::cpu;
2
3const PS2_STATUS_PORT: u16 = 0x64;
4const PS2_DATA_PORT: u16 = 0x60;
5
6#[allow(dead_code)]
7pub mod status {
8    pub const DATA_READY: u8 = 1 << 0;
9    pub const INPUT_BUFFER_FULL: u8 = 1 << 1;
10    pub const SYSTEM_FLAG: u8 = 1 << 2;
11    pub const COMMAND_DATA: u8 = 1 << 3;
12    pub const KEYBOARD_LOCKED: u8 = 1 << 4;
13    pub const KEYBOARD_TIMEOUT_MOUSE_DATA: u8 = 1 << 5;
14    pub const RECEIVE_TIMEOUT: u8 = 1 << 6;
15    pub const PARITY_ERROR: u8 = 1 << 7;
16}
17
18#[derive(Debug, Clone, Copy)]
19pub struct Ps2;
20
21impl Ps2 {
22    pub fn read_data(&self) -> u8 {
23        unsafe { cpu::io_in(PS2_DATA_PORT) }
24    }
25
26    // returns (success, resend)
27    fn wait_for_ack(&self) -> (bool, bool) {
28        let mut timeout = 1000;
29        while timeout > 0 {
30            if self.read_status() & status::DATA_READY != 0 {
31                let data = self.read_data();
32                match data {
33                    0xFA => return (true, false),
34                    0xFE => return (false, true),
35                    _ => {}
36                }
37                panic!("unexpected data from mouse: {:#X}, waiting for ack", data)
38            }
39            timeout -= 1;
40        }
41        (false, false)
42    }
43
44    pub fn read_status(&self) -> u8 {
45        unsafe { cpu::io_in(PS2_STATUS_PORT) }
46    }
47
48    pub fn has_data(&self) -> bool {
49        self.read_status() & status::DATA_READY != 0
50    }
51
52    pub fn write_prefix(&self, prefix: u8) {
53        self.wait_for_command_clear();
54        unsafe { cpu::io_out(PS2_STATUS_PORT, prefix) }
55    }
56
57    fn write_data(&self, data: u8) {
58        unsafe { cpu::io_out(PS2_DATA_PORT, data) }
59    }
60
61    pub fn wait_read_data(&self) -> u8 {
62        loop {
63            if self.read_status() & status::DATA_READY != 0 {
64                return self.read_data();
65            }
66        }
67    }
68
69    pub fn wait_read_data_slice(&self, data: &mut [u8]) {
70        for byte in data.iter_mut() {
71            *byte = self.wait_read_data();
72        }
73    }
74
75    #[must_use]
76    pub fn write_command_data(&self, data: u8) -> Option<()> {
77        let mut attempts = 3;
78        loop {
79            self.wait_for_command_clear();
80            self.write_data(data);
81            let (ack, resend) = self.wait_for_ack();
82
83            if resend {
84                attempts -= 1;
85                if attempts == 0 {
86                    return None;
87                }
88                continue;
89            }
90
91            if ack {
92                return Some(());
93            }
94        }
95    }
96
97    pub fn wait_for_command_clear(&self) {
98        while self.read_status() & status::DATA_READY != 0 {
99            // flush the buffer
100            self.read_data();
101        }
102        while self.read_status() & status::INPUT_BUFFER_FULL != 0 {
103            // wait for the buffer to be empty
104            core::hint::spin_loop();
105        }
106    }
107
108    pub fn reset_system(&self) -> ! {
109        self.write_prefix(0xFE);
110        loop {
111            unsafe { cpu::halt() };
112        }
113    }
114}