So now I'm more confused then before. Does that mean the way I originally handled the interrupt is the correct way to do it? For every interrupt, read one and only one value from port 0x60? I also have an interrupt setup for the keyboard, which is working and continues to work even after the mouse packets get screwed up.Octocontrabass wrote:No, you should read only one byte at a time. The PS/2 controller is dumb and doesn't know how many bytes are in one packet.rkennedy9064 wrote:Currently every time an interrupt is fired, I read a byte from port 0x60, but now I'm wondering if I need to read 3 bytes at a time?
The PS/2 controller is shared by the keyboard as well, so a mistake there could interfere with your mouse driver.
You don't need to do this. The IRQ already indicates that you may read one byte from port 0x60.alexfru wrote:My reads wait for the data by polling port 0x64 before reading from port 0x60.
This sounds like a mistake due to poor understanding of the PS/2 controller. Those commands disable and enable the keyboard port, presumably to ensure that all bytes are being received from the mouse and not the keyboard, but you can receive from both devices at the same time. You can tell which device sent the byte by which IRQ was raised.alexfru wrote:I can also see multiple implementations issuing command 0xAD before those three reads and 0xAE afterwards (some kind of synchronization/acknowledgement?; the writes also poll port 0x64). I can't find where these two commands are coming from. You probably shouldn't send them until you know they're needed.
No, you should read one byte each time without polling port 0x64.alexfru wrote:So, yeah, read all 3 bytes every time you enter the ISR and use(poll) port 0x64 to know when you can read/write a byte of data.
If that is the correct way to do it, do you have any suggestions as to why the packets start to get screwed up? Here are both my interrupts for reference.
Code: Select all
extern "x86-interrupt" fn mouse_interrupt_handler(_stack_frame: &mut InterruptStackFrame) {
let mut port = PortReadOnly::new(0x60);
let packet: u8 = unsafe { port.read() };
println!("{:08b}", packet);
unsafe {
PICS.lock()
.notify_end_of_interrupt(InterruptIndex::Mouse.into());
}
}
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: &mut InterruptStackFrame) {
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
use x86_64::instructions::port::PortReadOnly;
static KEYBOARD: Lazy<Spinlock<Keyboard<layouts::Us104Key, ScancodeSet1>>> = Lazy::new(|| {
Spinlock::new(Keyboard::new(
layouts::Us104Key,
ScancodeSet1,
HandleControl::Ignore,
))
});
let mut keyboard = KEYBOARD.lock();
let mut port = PortReadOnly::new(0x60);
let scancode: u8 = unsafe { port.read() };
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
if let Some(key) = keyboard.process_keyevent(key_event) {
match key {
DecodedKey::Unicode(character) => print!("{}", character),
DecodedKey::RawKey(key) => print!("{:?}", key),
}
}
}
unsafe {
PICS.lock()
.notify_end_of_interrupt(InterruptIndex::Keyboard.into());
}
}