feat: xHCI NKRO keyboard fix, CC=12 resolution, verbose logging cleanup#240
Merged
feat: xHCI NKRO keyboard fix, CC=12 resolution, verbose logging cleanup#240
Conversation
…workarounds Snapshot of CC=12 debugging work. Key changes: Loader (parallels-loader): - Add UEFI DisconnectController for xHCI device at PCI 00:03.0 to prevent UEFI cleanup from resetting the controller during EBS - Add post-EBS PCI BAR re-enable safety fallback - Minimal PciIoProtocol binding via #[unsafe_protocol] for GetLocation - HardwareConfig gains xhci_hcrst_done sentinel + xhci_bar_phys fields Kernel: - xHCI driver: pre-HCRST delay for Parallels hypervisor settling - xHCI driver: ARM64 delay_ms() using CNTPCT_EL0/CNTFRQ_EL0 - xHCI driver: extensive DMA/context/doorbell diagnostics - PCI: MSI capability parsing, enhanced BAR handling - platform_config: atomic xhci_hcrst_done_raw() accessor - procfs: /proc/xhci status endpoint - btrace: periodic boot tracing utility Boot infrastructure: - boot.S: HHDM-aware page table setup - Heap: enlarged to 16MB for xHCI DMA buffers Findings: DisconnectController prevents UEFI's cleanup HCRST, but phymemrange_disable still fires during EBS. Delay approach (3s, 10s) does not produce ep create events in host log. linux-probe comparison shows its post-EBS HCRST at +29.5s DOES get ep creates — difference is NOT timing. Root cause remains under investigation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Root cause of CC=12 (Endpoint Not Enabled): explicit port reset on SuperSpeed ports that were already enabled (PED=1) after HCRST confused the Parallels hypervisor's USB device model. The hypervisor never processed SetConfiguration or created endpoint state, so all interrupt transfers immediately failed with CC=12. Key fixes: - Skip port reset when PED=1, matching Linux kernel module behavior. After HCRST, SuperSpeed ports auto-enable; AddressDevice internally triggers the device reset the hypervisor needs. - Fix Status Stage TRB direction per xHCI spec 4.11.2.2: IN for no-data/OUT-data transfers, OUT for IN-data transfers. - Rate-limit poll_hid_events to 10 Hz (every 20th timer tick). Full 200 Hz MMIO reads from timer interrupt context starved the Parallels hypervisor, locking up the system at fork+exit. Also includes: - Linux kernel module (linux_xhci_module/) used as reference for byte-for-byte comparison of xHCI TRB encoding and enumeration flow. - DisconnectController disabled in loader (matches linux-probe). - DMA buffers moved from .dma (NC) to .bss (WB-cacheable). - Event ring expanded to 256 entries (matching Linux). - PCI config space dump utility for debugging. - DSB barriers tightened: dsb st for clean, dsb ld for invalidate. Result: first working USB HID input on Parallels — keyboard keystrokes and mouse events delivered through the full xHCI pipeline. Co-Authored-By: Ryan Breen <rbreen@gmail.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Parallels virtual keyboard sends NKRO reports with layout [report_id=1, modifier, key1, key2, ..., key7] — no reserved byte. The code was passing this directly to process_keyboard_report() which expects boot keyboard format [modifier, reserved=0, key1, ..., key6], causing every keycode to land in the ignored "reserved" byte position. Fix: construct a properly formatted boot keyboard report by inserting a zero reserved byte before the keycodes in both the MSI handler and poll code paths. Also increase xHCI poll rate from 10 Hz (100ms latency) to 50 Hz (20ms latency) for responsive keyboard input. Cleanup: remove verbose CC=12 investigation logging from xhci.rs, re-enable VirtIO GPU PCI init, strip diagnostic logging from gpu_pci.rs and mod.rs, remove btrace periodic spawning from init. Co-Authored-By: Ryan Breen <ryanbreen@gmail.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
[report_id, modifier, key1, ...]), but code expected boot keyboard format ([modifier, reserved=0, key1, ...]). Every keycode was landing in the ignored reserved byte position. Fix: insert a zero reserved byte when reformatting NKRO reports for both MSI and poll paths.Test plan
🤖 Generated with Claude Code