Repository navigation
USB OHCI and XID Input
The Xbox controller ports are exposed to guest software through USB-compatible host-controller behavior and Xbox-specific XID devices. xemu reuses QEMU's OHCI controller model for the host controllers, then implements Xbox controller protocol/state in the XID device layer and bridges that to xemu's host input system.
xbox_init_common() creates two pci-ohci devices and configures each with four ports.
flowchart TD
A[Guest USB stack] --> B[OHCI controller 0 - 4 ports]
A --> C[OHCI controller 1 - 4 ports]
B --> D[QEMU USB bus/devices]
C --> D
D --> E[Xbox XID gamepad device]
E --> F[xemu ControllerState]
F --> G[Host controller/input backend]
E --> H[Rumble output]
H --> F
The physical Xbox front connector is electrically USB-derived, but xemu does not simulate connector voltages, differential D+/D− signaling or PHY timing. Guest software interacts with an OHCI and USB-device protocol model.
The original Xbox OHCI controllers are PC-compatible enough that xemu instantiates QEMU's generic pci-ohci implementation instead of maintaining an Xbox-only host-controller core.
This is an important implementation boundary:
Xbox-specific machine wiring / IRQ route
↓
generic QEMU OHCI controller semantics
↓
Xbox-specific USB device (XID)
A controller problem can therefore live in three different places: Xbox PCI/IRQ wiring, QEMU OHCI behavior, or XID device behavior.
hw/xbox/xid.c maps xemu's host-neutral ControllerState into the report format expected by Xbox software.
A/B/X/Y/Black/White are represented as analog values by the Xbox controller protocol. xemu currently maps a host digital press to either 0x00 or 0xff.
Host trigger axes are shifted into the Xbox report's 8-bit analog trigger fields.
Host stick axes are copied into the signed Xbox thumbstick fields.
Back, Start, thumbstick clicks and D-pad directions are packed into wButtons.
flowchart LR
A[Host input backend] --> B[ControllerState]
B --> C[update_input]
C --> D[Analog button bytes]
C --> E[Trigger bytes]
C --> F[Thumbstick int16 values]
C --> G[wButtons bitmask]
D --> H[XID input report]
E --> H
F --> H
G --> H
H --> I[Guest USB request/interrupt transfer]
The host controller's native deadzones, calibration and polling behavior are therefore separate from the guest XID report format.
Both update_input() and update_output() return early when xemu_input_get_test_mode() is active. This prevents the running guest from receiving changes while the UI is testing a controller.
That is a host/UI policy layer, not Xbox hardware behavior. If input appears frozen only while controller-test UI is active, the XID USB model may be functioning correctly.
Guest rumble arrives as an XID output report. xemu copies the left/right actuator strengths into the bound ControllerState and calls xemu_input_update_rumble().
sequenceDiagram
participant G as Guest
participant X as XID device
participant C as xemu ControllerState
participant H as Host controller
G->>X: HID SET_REPORT output
X->>X: Validate/copy XID output state
X->>C: left/right actuator strength
C->>H: xemu_input_update_rumble()
Physical motor inertia/current draw is not simulated. The guest-visible command is translated into a host haptic request.
usb_xid_handle_control() first gives standard requests to QEMU's descriptor helper, then handles Xbox/HID-specific cases.
Implemented requests include:
- HID
GET_REPORTfor input state; - HID
SET_REPORTfor rumble/output state; - vendor XID descriptor
0x4200; - XID input/output capabilities.
Unsupported requests normally set USB_RET_STALL, which is the correct USB-level concept for many invalid requests.
Several unsupported or malformed request paths also contain assert() calls. Examples include unexpected report/descriptor values and the default unknown-request path.
unusual guest USB request
↓
USB_RET_STALL set
↓
assert() may also fire in assertion-enabled build
That is stronger than physical hardware behavior. Real hardware would not terminate the emulator process because software sent an unsupported request. It is therefore a known robustness boundary useful for fuzzing/homebrew qualification.
One SET_REPORT path also contains a source comment saying an invalid output-length condition should be a STALL rather than relying on the current assertion expectation.
The current descriptor strings identify the device as:
Manufacturer: QEMU
Product: Microsoft Xbox Controller
Serial: 1
Those strings are emulator-generated identity. Games normally depend more on USB/XID descriptors and report structure than on an electrical reproduction of the physical controller.
usb_xid_handle_reset() currently only emits debug output. There is no complex controller-internal reset state machine in that callback.
A title that depends on undocumented controller state surviving or clearing across USB reset therefore deserves a focused test rather than assuming physical behavior is reproduced.
Controller input is sampled when xemu updates the XID report from its host input state; the physical USB bus waveform is not simulated.
Relevant timing layers are:
flowchart LR
A[Host OS/controller polling] --> B[xemu input state update]
B --> C[XID report generation]
C --> D[QEMU USB/OHCI scheduling]
D --> E[Guest USB driver]
If an input-latency change is being measured, identify which layer changed. Lower host controller polling latency is different from OHCI scheduling, which is different from game-side input sampling.
The two OHCI PCI devices are mapped through the Xbox LPC interrupt-routing model. In the current machine mapping the two controller slots route to different legacy PIC IRQs. USB device events therefore still become guest CPU work through the PCI/OHCI interrupt model; XID does not directly call a guest input handler.
| Area | Current abstraction | Consequence |
|---|---|---|
| USB electrical layer | Not simulated | No D+/D− waveform/PHY timing cost |
| Host controller | Generic QEMU OHCI | Reuses PC-compatible USB scheduling semantics |
| Controller protocol | Xbox-specific XID | Guest report/capability behavior implemented directly |
| Host input |
ControllerState abstraction |
Physical controller type can differ from virtual Xbox controller |
| Face-button pressure | Digital host button → 0/255 | Intermediate analog pressure absent for digital inputs |
| Rumble | Strength → host haptic API | Motor/electrical dynamics absent |
| Invalid requests | STALL + some asserts | Debug/assert builds can fail harder than hardware |
flowchart TD
A[Controller bug] --> B{Guest sees OHCI device?}
B -->|No| C[PCI/OHCI/IRQ wiring]
B -->|Yes| D{XID enumerates?}
D -->|No| E[USB descriptor/control requests]
D -->|Yes| F{Input report wrong?}
F -->|Yes| G[ControllerState → XID mapping]
F -->|No| H{Rumble/output wrong?}
H -->|Yes| I[SET_REPORT → host haptic path]
H -->|No| J[Game/input timing or host backend]
| Source | Responsibility |
|---|---|
hw/xbox/xbox.c |
Creates two four-port PCI OHCI controllers |
| QEMU OHCI/USB core | Host-controller scheduling, transfers and USB bus behavior |
hw/xbox/xid.c |
Xbox controller reports, requests, capabilities and rumble mapping |
hw/xbox/xid.h |
XID structures/descriptors/state |
| xemu input subsystem | Host controller enumeration/state/rumble backend |
hw/xbox/xbox_pci.c |
PCI interrupt routing for OHCI devices |
DSP tooling guide and navigation updated November 2, 2026 for experimental PR #384, source 8f51d237. Capture/replay usage and limits.
The earlier wiki-wide review was published November 1, 2026. Emulator source: b7140848. Reviewed wiki content: 1d2b671. Current status · Release availability · Publication process.
- Home
- Current status
- Stable versus main
- Implemented mechanisms
- Controls and defaults
- Measured results and limits
- Complete change register
- System
- CPU and vCPU
- Memory and DMA
- Graphics / NV2A
- APU and audio
- Timing and timers
- Platform and I/O
- Hardware observations
- Fidelity boundaries
- Methodology
- PGR2 routes
- Debugging lag / hot paths
- Tools and commands
- DSP capture, replay and fuzzing
- HLE readiness and public XISO proof
- Concurrent DSP shadow and OpenAL proof
- DSP HLE operation inventory
- DSP HLE fix examples and testing
- Development
- Upstream shortlist
- Wiki maintenance
- Research / retired work
- Optimization catalog
- Hot-path shortcuts
- Researched experiments
- Unproven proposal directory
- PR lessons
- September26 snapshot
Repository · PRs · Issues