Commit 15675ea9 authored by Jeremy Soller's avatar Jeremy Soller

Allow retry of commands, allow failure of commands

parent d3c29d0f
...@@ -64,7 +64,7 @@ impl<'pci> PciIter<'pci> { ...@@ -64,7 +64,7 @@ impl<'pci> PciIter<'pci> {
impl<'pci> Iterator for PciIter<'pci> { impl<'pci> Iterator for PciIter<'pci> {
type Item = PciBus<'pci>; type Item = PciBus<'pci>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if self.num < 256 { if self.num < 255 { /* TODO: Do not ignore 0xFF bus */
let bus = PciBus { let bus = PciBus {
pci: self.pci, pci: self.pci,
num: self.num as u8 num: self.num as u8
......
...@@ -50,6 +50,7 @@ enum Command { ...@@ -50,6 +50,7 @@ enum Command {
#[allow(dead_code)] #[allow(dead_code)]
enum KeyboardCommand { enum KeyboardCommand {
EnableReporting = 0xF4, EnableReporting = 0xF4,
SetDefaultsDisable = 0xF5,
SetDefaults = 0xF6, SetDefaults = 0xF6,
Reset = 0xFF Reset = 0xFF
} }
...@@ -64,6 +65,7 @@ enum KeyboardCommandData { ...@@ -64,6 +65,7 @@ enum KeyboardCommandData {
enum MouseCommand { enum MouseCommand {
GetDeviceId = 0xF2, GetDeviceId = 0xF2,
EnableReporting = 0xF4, EnableReporting = 0xF4,
SetDefaultsDisable = 0xF5,
SetDefaults = 0xF6, SetDefaults = 0xF6,
Reset = 0xFF Reset = 0xFF
} }
...@@ -100,9 +102,9 @@ impl Ps2 { ...@@ -100,9 +102,9 @@ impl Ps2 {
while ! self.status().contains(OUTPUT_FULL) {} while ! self.status().contains(OUTPUT_FULL) {}
} }
fn flush_read(&mut self) { fn flush_read(&mut self, message: &str) {
while self.status().contains(OUTPUT_FULL) { while self.status().contains(OUTPUT_FULL) {
print!("FLUSH: {:X}\n", self.data.read()); print!("ps2d: flush {}: {:X}\n", message, self.data.read());
} }
} }
...@@ -131,28 +133,57 @@ impl Ps2 { ...@@ -131,28 +133,57 @@ impl Ps2 {
self.write(config.bits()); self.write(config.bits());
} }
fn keyboard_command_inner(&mut self, command: u8) -> u8 {
let mut ret = 0xFE;
for i in 0..4 {
self.write(command as u8);
ret = self.read();
if ret == 0xFE {
println!("ps2d: retry keyboard command {:X}: {}", command, i);
} else {
break;
}
}
ret
}
fn keyboard_command(&mut self, command: KeyboardCommand) -> u8 { fn keyboard_command(&mut self, command: KeyboardCommand) -> u8 {
self.write(command as u8); self.keyboard_command_inner(command as u8)
self.read()
} }
fn keyboard_command_data(&mut self, command: KeyboardCommandData, data: u8) -> u8 { fn keyboard_command_data(&mut self, command: KeyboardCommandData, data: u8) -> u8 {
self.write(command as u8); let res = self.keyboard_command_inner(command as u8);
assert_eq!(self.read(), 0xFA); if res != 0xFA {
return res;
}
self.write(data as u8); self.write(data as u8);
self.read() self.read()
} }
fn mouse_command_inner(&mut self, command: u8) -> u8 {
let mut ret = 0xFE;
for i in 0..4 {
self.command(Command::WriteSecond);
self.write(command as u8);
ret = self.read();
if ret == 0xFE {
println!("ps2d: retry mouse command {:X}: {}", command, i);
} else {
break;
}
}
ret
}
fn mouse_command(&mut self, command: MouseCommand) -> u8 { fn mouse_command(&mut self, command: MouseCommand) -> u8 {
self.command(Command::WriteSecond); self.mouse_command_inner(command as u8)
self.write(command as u8);
self.read()
} }
fn mouse_command_data(&mut self, command: MouseCommandData, data: u8) -> u8 { fn mouse_command_data(&mut self, command: MouseCommandData, data: u8) -> u8 {
self.command(Command::WriteSecond); let res = self.mouse_command_inner(command as u8);
self.write(command as u8); if res != 0xFA {
assert_eq!(self.read(), 0xFA); return res;
}
self.command(Command::WriteSecond); self.command(Command::WriteSecond);
self.write(data as u8); self.write(data as u8);
self.read() self.read()
...@@ -169,12 +200,15 @@ impl Ps2 { ...@@ -169,12 +200,15 @@ impl Ps2 {
} }
pub fn init(&mut self) -> bool { pub fn init(&mut self) -> bool {
// Clear remaining data
self.flush_read("init start");
// Disable devices // Disable devices
self.command(Command::DisableFirst); self.command(Command::DisableFirst);
self.command(Command::DisableSecond); self.command(Command::DisableSecond);
// Clear remaining data // Clear remaining data
self.flush_read(); self.flush_read("disable");
// Disable clocks, disable interrupts, and disable translate // Disable clocks, disable interrupts, and disable translate
{ {
...@@ -195,35 +229,70 @@ impl Ps2 { ...@@ -195,35 +229,70 @@ impl Ps2 {
self.command(Command::EnableFirst); self.command(Command::EnableFirst);
self.command(Command::EnableSecond); self.command(Command::EnableSecond);
// Clear remaining data
self.flush_read("enable");
// Reset keyboard // Reset keyboard
assert_eq!(self.keyboard_command(KeyboardCommand::Reset), 0xFA); if self.keyboard_command(KeyboardCommand::Reset) == 0xFA {
assert_eq!(self.read(), 0xAA); if self.read() != 0xAA {
self.flush_read(); println!("ps2d: keyboard failed self test");
}
} else {
println!("ps2d: keyboard failed to reset");
}
// Clear remaining data
self.flush_read("keyboard defaults");
// Set scancode set to 2 // Set scancode set to 2
assert_eq!(self.keyboard_command_data(KeyboardCommandData::ScancodeSet, 2), 0xFA); let scancode_set = 2;
if self.keyboard_command_data(KeyboardCommandData::ScancodeSet, scancode_set) != 0xFA {
println!("ps2d: keyboard failed to set scancode set {}", scancode_set);
}
// Enable data reporting
if self.keyboard_command(KeyboardCommand::EnableReporting) != 0xFA {
println!("ps2d: keyboard failed to enable reporting");
}
// Reset mouse and set up scroll // Reset mouse and set up scroll
// TODO: Check for ack if self.mouse_command(MouseCommand::Reset) == 0xFA {
assert_eq!(self.mouse_command(MouseCommand::Reset), 0xFA); let a = self.read();
assert_eq!(self.read(), 0xAA); let b = self.read();
assert_eq!(self.read(), 0x00); if a != 0xAA || b != 0x00 {
self.flush_read(); println!("ps2d: mouse failed self test");
}
} else {
println!("ps2d: mouse failed to reset");
}
// Clear remaining data
self.flush_read("mouse defaults");
// Enable extra packet on mouse // Enable extra packet on mouse
assert_eq!(self.mouse_command_data(MouseCommandData::SetSampleRate, 200), 0xFA); if self.mouse_command_data(MouseCommandData::SetSampleRate, 200) != 0xFA
assert_eq!(self.mouse_command_data(MouseCommandData::SetSampleRate, 100), 0xFA); || self.mouse_command_data(MouseCommandData::SetSampleRate, 100) != 0xFA
assert_eq!(self.mouse_command_data(MouseCommandData::SetSampleRate, 80), 0xFA); || self.mouse_command_data(MouseCommandData::SetSampleRate, 80) != 0xFA {
assert_eq!(self.mouse_command(MouseCommand::GetDeviceId), 0xFA); println!("ps2d: mouse failed to enable extra packet");
let mouse_id = self.read(); }
let mouse_extra = mouse_id == 3;
let mouse_extra = if self.mouse_command(MouseCommand::GetDeviceId) == 0xFA {
self.read() == 3
} else {
println!("ps2d: mouse failed to get device id");
false
};
// Set sample rate to maximum // Set sample rate to maximum
assert_eq!(self.mouse_command_data(MouseCommandData::SetSampleRate, 200), 0xFA); let sample_rate = 200;
if self.mouse_command_data(MouseCommandData::SetSampleRate, sample_rate) != 0xFA {
println!("ps2d: mouse failed to set sample rate to {}", sample_rate);
}
// Enable data reporting // Enable data reporting
assert_eq!(self.keyboard_command(KeyboardCommand::EnableReporting), 0xFA); if self.mouse_command(MouseCommand::EnableReporting) != 0xFA {
assert_eq!(self.mouse_command(MouseCommand::EnableReporting), 0xFA); println!("ps2d: mouse failed to enable reporting");
}
// Enable clocks and interrupts // Enable clocks and interrupts
{ {
...@@ -236,7 +305,8 @@ impl Ps2 { ...@@ -236,7 +305,8 @@ impl Ps2 {
self.set_config(config); self.set_config(config);
} }
self.flush_read(); // Clear remaining data
self.flush_read("init finish");
mouse_extra mouse_extra
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment