Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

domnudragota
Copy link
Contributor

@domnudragota domnudragota commented Sep 11, 2025

Pull Request Overview

This pull request adds an i8042 PS/2 controller for the x86_q35 platform and wires it into the board/chip (all was done according to https://wiki.osdev.org/I8042_PS/2_Controller)

  • Implements controller bring-up (init_early): disable ports, flush OB, self-test, typed config byte updates (translation OFF, clocks/IRQs as needed), keyboard port test/enable, and device init (F5, FF => AA, F0 02, F4).

  • Interrupt/top-half: reads OB, drops bytes with parity/timeout errors, enqueues scan codes, and schedules a deferred call.

  • Deferred/bottom-half: drains a ring buffer and currently logs Set-2 MAKE/BREAK lines; also exposes a client hook:
    pub trait Ps2Client { fn receive_scancode(&self, code: u8); }
    pub fn set_client(&self, client: &'static dyn Ps2Client)

  • Observability: adds Ps2Health { bytes_rx, overruns, parity_err, timeout_err, timeouts, resends } and health_snapshot(), with periodic debug logging.

  • Uses LocalRegisterCopy<u8, CONFIG::Register> for typed, safe CONFIG-byte manipulation.

  • Integrates with PcComponent: registers as a DeferredCallClient, dispatches IRQ1 to the controller, and runs bring-up during finalize.

Testing Strategy

This pull request was tested by running on QEMU

  • Verified IRQ1 fires, ISR queues bytes, and deferred call drains/logs MAKE/BREAK for key presses.

  • Observed bytes_rx increasing in health logs; no parity/timeout drops seen during normal typing.

  • Confirmed no regressions in PIT and serial console paths; kernel boots and services interrupts normally.

TODO or Help Wanted

  • Keyboard driver which connects to this controller, (x86_q35: add keyboard driver over i8042 controller #4595)
  • Keyboard capsule: consume Set-2 stream via Ps2Client, translate to key events, and plumb into the process console (soon!!!!)
  • Optional port 2 (mouse) probing/enable remains off by default; add probe + support in a follow-up.

Documentation Updated

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

Formatting

  • Ran make prepush.

Copy link
Contributor

@alexandruradovici alexandruradovici left a comment

Choose a reason for hiding this comment

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

I would suggest adding a _timeout to all wait_ functions.

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
Comment on lines 110 to 113
/// Client hook (future: keyboard capsule)
pub trait Ps2Client {
fn receive_scancode(&self, code: u8);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

We do have a keyboard HIL now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed the old P2Client and added the keyboard HIL. Will take a look to see how should I implement it in the keyboard driver.

Copy link
Contributor Author

@domnudragota domnudragota Sep 17, 2025

Choose a reason for hiding this comment

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

Edit regarding my previous message (prepare for a loong message :D )

We split the PS/2 stack into two layers:

Controller (transport): ps2.rs

  1. Owns the i8042 hardware: port I/O, status polling, bring-up (self-test, config, Set-2, enable IRQ1).

  2. IRQ top-half enqueues raw bytes; deferred call (bottom-half) drains a ring buffer and forwards bytes to a small, local hook:

Keyboard (device): keyboard.rs

  • Implements the new kernel::hil::keyboard::Keyboard<'a> and calls the HIL client via: c.keys_pressed(&[(linux_keycode, pressed)], Ok(()));

  • Implements Ps2Client so the controller can feed it raw bytes.

  • Provides a Set-2 decoder (E0/F0/E1) and emits MAKE/BREAK logs after prefix resolution.

  • Maps Set-2 - Linux keycodes (initial coverage: letters, digits, common modifiers, arrows).

  • Contains a small command engine (ACK/RESEND FIFO) for device commands (to move full init here later and to send commands).
    (i wrote this in x86_q35: add keyboard driver over i8042 controller #4595)

Now the big question :

Why keep Ps2Client if we have a keyboard HIL now ?

Ps2Client is not another HIL; it’s a tiny internal hook for the controller to deliver raw scancodes to some consumer (the keyboard device here, but could be a mouse/AUX later). The actual HIL interface is implemented in keyboard.rs (emitting Linux keycodes + press/release), which matches the new kernel/src/hil/keyboard.rs. We removed the old ASCII path and byte emission. We now rely solely on the HIL interface for key events.

This separation keeps responsibilities clean:

  • Controller = reusable i8042 transport (also future-proof for AUX/mouse).

  • Keyboard = device semantics (decode, mapping, HIL emission).

Comment on lines +286 to +289
// PS/2 inside the component
let ps2 =
unsafe { static_init!(crate::ps2::Ps2Controller, crate::ps2::Ps2Controller::new()) };
kernel::deferred_call::DeferredCallClient::register(ps2);
Copy link
Contributor

Choose a reason for hiding this comment

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

Now is not that time, but at some point we need to stop adding new static_init here, which shouldn't have ever been here.

@bradjc
Copy link
Contributor

bradjc commented Oct 2, 2025

Once we have #4595 ready and the PR which uses this stack we can start merging these.

@bradjc bradjc added the blocked Waiting on something, like a different PR or a dependency. label Oct 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blocked Waiting on something, like a different PR or a dependency.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants