Skip to content

Conversation

@andreea-35
Copy link

Pull Request Overview

This PR wires the QEMU i486 “Q35” board to the PS/2 mouse:

Testing Strategy

This pull request was tested by running on QEMU.

TODO or Help Wanted

Mouse packets aren't getting displayed as they should. Scan codes don't get printed upon key press either.

Documentation Updated

  • Updated the relevant files in /docs, or no updates are required.

Formatting

  • Ran make prepush.

domnudragota and others added 26 commits August 1, 2025 15:17
step1: PS/2 controller self-test (clock & IRQ still disabled)

step2: enable keyboard clock (IRQ 1 still masked)

step3: full PS/2 driver – self-test, clock on, IRQ1 unmasked, single-byte buffering

step4: drain-loop IRQ handler; full ring-buffer active

step5: add send_with_ack() with RESEND retry; enable keyboard scanning (0xF4)

step7: implemented some unit tests to debug buffers

fix: readded comments from previous controller, moved ps2.init() to enable debug macro

feature: added IRQ1 self-test when init.
step1: PS/2 controller self-test (clock & IRQ still disabled)

step2: enable keyboard clock (IRQ 1 still masked)

step3: full PS/2 driver – self-test, clock on, IRQ1 unmasked, single-byte buffering

step4: drain-loop IRQ handler; full ring-buffer active

step5: add send_with_ack() with RESEND retry; enable keyboard scanning (0xF4)

step7: implemented some unit tests to debug buffers

fix: readded comments from previous controller, moved ps2.init() to enable debug macro

feature: added IRQ1 self-test when init.
workflow: rebased with upstream
…for init, reworked ISR to handle drop parity/timeout => make/break logs + prefixes
added content for dv_ms.rs must be revised in the future
initialisation of ms_buffer used the keyboard buffer's constant instead of the mouse's
@domnudragota
Copy link

If I recall correctly, I disabled the output of keycodes/ASCII a while ago on the controller. They still are sent/received, but not shown on VGA. You can enable them for testing in the controller plus add your debug packets messages for your driver. Let me check.

Comment on lines +207 to +211
// pub fn with_mouse(mut self, mouse: &'a crate::dv_ms::Mouse<'a>) -> Self {
// // ← new
// self.mouse = Some(mouse);
// self
// }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these lines commented ? Are they temporarily ?

Comment on lines +69 to +71
/// PS/2 Mouse
// pub ms: &'a crate::dv_ms::Mouse<'a>,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these lines commented ? Are they temporarily ?

Comment on lines +261 to +263
// PS/2 instance supplied via .with_ps2(...)
let ps2 = self.ps2.expect("PcComponent::with_ps2 was not called");
//let mouse = self.mouse.expect("PcComponent::with_mouse was not called"); // added new 4 the mouse

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from an older version of the PS/2 controller.

Comment on lines +161 to +167
// Build the PC chip and attach our
// PS/2 controller so that `service_pending_interrupts` will dispatch IRQ1.
let chip = PcComponent::new(
&mut *ptr::addr_of_mut!(PAGE_DIR),
&mut *ptr::addr_of_mut!(PAGE_TABLE),
)
.with_ps2(ps2)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was changed removed in the newest version of the controller.

Comment on lines +718 to +721
impl DeferredCallClient for Ps2Controller {
fn handle_deferred_call(&self) {
// drain and print MAKE/BREAKs
self.decode_and_log_stream();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're draining the BH twice by adding the keyboard and mouse bytes. You can write smth small that sends, receives and logs at the same time the mouse, in order to separate from keyboard.

Comment on lines +109 to +112
pub trait Ps2Client {
fn receive_scancode(&self, code: u8);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define a trait here for Ps2MouseClient, you're setting it below but not declaring it.

Comment on lines +353 to +360
ms_buffer: RefCell::new([[0; MOUSE_PACKET_SIZE]; MOUSE_BUFFER_SIZE]),
ms_head: Cell::new(0),
ms_tail: Cell::new(0),
ms_count: Cell::new(0),
ms_packet: Cell::new([0; MOUSE_PACKET_SIZE]),
ms_index: Cell::new(0),
ms_overruns: Cell::new(0),
mouse_client: OptionalCell::empty(), //added mouse client 4 cursor delete if needed, just for testing

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that the controller could only send bytes and leave the packaging job to the mouse driver ?

self.deferred_call.set();
}
}
pub fn handle_mouse_interrupt(&self) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can combine these 2 handle_interrupt functions into 1

Comment on lines +295 to +296
/// PS/2 controller driver (the “8042” peripheral)
pub struct Ps2Controller {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just before here, you can write a small helper function to init. in chip.rs

Comment on lines +321 to +330
ms_buffer: RefCell<[[u8; MOUSE_PACKET_SIZE]; MOUSE_BUFFER_SIZE]>,
ms_head: Cell<usize>,
ms_tail: Cell<usize>,
ms_count: Cell<usize>, // new field to track number of valid entries
ms_packet: Cell<[u8; MOUSE_PACKET_SIZE]>,
ms_index: Cell<usize>,
ms_overruns: Cell<usize>,

mouse_client: OptionalCell<&'static dyn Ps2MouseClient>, //added mouse client 4 cursor delete if needed, just for testing
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that the controller could only send bytes and leave the packaging job to the mouse driver ?

Comment on lines +187 to +189

ps2: Option<&'a crate::ps2::Ps2Controller>,
// mouse: Option<&'a crate::dv_ms::Mouse<'a>>, // added 4 mouse!!!!!!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed ?

Comment on lines +196 to +198
pt,
ps2: None,
// mouse: None,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these 2 needed here ?

Comment on lines +277 to +278
ps2,
// ms: mouse, // ← pass the mouse

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to add the mouse here, it's better to add it below under macro_rules

@domnudragota
Copy link

Rebase this with the latest ps2-incremental

Comment on lines +266 to +268

// controller bring-up owned by the chip (no logging here)
let _ = ps2.init_early();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you can init. the mouse, after the controller.

@andreea-35 andreea-35 self-assigned this Sep 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants