Repository navigation
System Architecture
xemu models the original Xbox as a collection of QEMU devices connected through the machine's memory, PCI, interrupt, DMA, and timing infrastructure. The important architectural boundary is between guest-visible hardware state and host-side implementations used to realize that state.
The Xbox machine is assembled primarily from hw/xbox/xbox.c. The machine class selects a Pentium III x86 CPU and permits one guest CPU. The rest of the platform is constructed around PC-compatible infrastructure plus Xbox-specific chipset, storage, input, audio, and NV2A devices.
| Area | Guest-facing role | Representative source area |
|---|---|---|
| CPU | Single x86 Pentium III-compatible processor |
hw/xbox/xbox.c, target/i386, accel/tcg
|
| Main memory | Guest system RAM and address-space mappings | QEMU memory subsystem, Xbox machine setup |
| PCI / LPC | Device discovery, configuration, legacy platform services |
hw/xbox, QEMU PCI/LPC infrastructure |
| PIT / RTC | PC-compatible timer and real-time-clock devices used by the Xbox platform | Xbox machine initialization + common device models |
| NV2A | Graphics processor, VRAM-visible behavior, command submission, timers, display and reports | hw/xbox/nv2a |
| Storage | IDE/ATA-style Xbox disk and optical-device behavior | Xbox machine and storage device models |
| Audio | MCPX APU and related audio path |
hw/xbox/mcpx / Xbox audio code |
| Input / USB | Xbox controllers and USB-facing behavior | Xbox/USB device models |
The machine intentionally tolerates some failed memory transactions because real software can probe absent or partially implemented PCI/ISA regions. A failed probe is therefore not automatically equivalent to a fatal emulator error.
flowchart TD
A[Guest application / Xbox kernel] --> B[x86 guest CPU state]
B --> C[TCG vCPU execution]
C --> D{Operation type}
D -->|Normal guest instruction| C
D -->|RAM access| E[Guest memory regions]
D -->|MMIO / port I/O| F[Emulated device]
F --> G{Device family}
G --> H[Chipset / storage / USB / audio]
G --> I[NV2A]
I --> J[PFIFO]
J --> K[PGRAPH]
K --> L{Renderer backend}
L --> M[OpenGL]
L --> N[Vulkan]
O[QEMU clocks / timers] --> F
O --> I
F --> P[Interrupt state]
I --> P
P --> B
A guest instruction that only changes CPU registers can remain inside translated host code. An I/O instruction, an MMIO access, an interrupt, an exception, a translated-code invalidation, or another asynchronous condition can force control back into emulator code so the corresponding device or scheduler work can run.
xemu is easier to reason about when the program is divided into execution domains rather than files.
The Xbox has one guest CPU. xemu creates one guest CPU object and the MTTCG path runs it on a dedicated vCPU thread. The thread repeatedly enters the TCG execution engine, executes translated blocks, then handles exits such as interrupts, exceptions, debug events, or waits.
See CPU & vCPU Execution.
QEMU infrastructure handles event-loop work, timers, host I/O notifications, UI integration, and coordination that is not owned by the vCPU thread. A timer callback is not a guest instruction: it is host-side emulation work scheduled against a particular QEMU clock domain.
See Clocks & Timers.
The guest writes command data and GPU state through memory/MMIO. PFIFO consumes pushbuffer/channel work and feeds methods toward PGRAPH. PGRAPH maintains the backend-independent NV2A graphics state. The selected renderer translates that state into OpenGL or Vulkan operations.
See NV2A Graphics Architecture.
The guest does not directly submit OpenGL or Vulkan calls. PGRAPH exposes a renderer interface and backend code owns the host graphics API objects. This is why a state change can have very different host-side cost between OpenGL and Vulkan while representing the same guest-visible NV2A operation.
See OpenGL Renderer, Vulkan Renderer, and OpenGL vs Vulkan.
Several kinds of time coexist:
- Host time drives the process and operating-system waits.
- Virtual time advances according to the emulated machine's execution policy.
- Device clocks derive guest-visible counters or deadlines from emulated hardware state.
- Presentation/frame cadence is an observation of GPU/display progress and is not interchangeable with guest CPU time.
The NV2A PTIMER is a good example: its visible counter derives from QEMU virtual time and NV2A clock configuration, then an alarm can schedule a host callback that eventually asserts a guest-visible interrupt. Changing host waiting precision does not directly change the emulated PTIMER frequency.
Devices interact with guest memory through QEMU memory regions, DMA mappings, and device-specific ownership rules. For graphics this is especially important because data may exist in several forms at once:
Guest RAM / VRAM
↓
backend mirror or staging resource
↓
host GPU resource
↓
possible GPU-written result
↓
readback / coherency operation
↓
guest-visible RAM / VRAM
The direction of the newest authoritative copy matters. A backend optimization is correct only if it preserves that ownership. This is why vertex uploads, surfaces, report/query results, and snapshot restore all need explicit lifetime reasoning rather than simply copying fewer bytes.
At a high level, device state becomes CPU-visible through interrupt controllers and CPU interrupt delivery:
sequenceDiagram
participant D as Emulated device
participant I as Interrupt routing
participant C as vCPU / x86 CPU
participant T as TCG dispatcher
D->>I: Assert or clear interrupt condition
I->>C: Update CPU-visible interrupt state
T->>T: Observe exit/request boundary
T->>C: Deliver interrupt at legal guest boundary
C->>T: Continue guest execution
TCG cannot blindly run translated guest instructions forever. It has explicit exit paths so asynchronous device state can become visible at the correct architectural boundary.
Save/restore is a cross-subsystem operation. Guest RAM and device state can be replaced while host resources such as GL/Vulkan objects cannot simply be serialized as guest state. Each subsystem therefore needs a lifecycle contract:
| Phase | Requirement |
|---|---|
| Save preparation | Flush or expose guest-visible state that currently exists only in host-side resources |
| Save | Serialize guest/device state, not opaque host GPU handles |
| Restore | Reconstruct derived host-side state from restored guest/device state |
| Shutdown | Stop producers, retire or cancel asynchronous work, then destroy owned resources |
Renderer pre_savevm_* and pre_shutdown_* hooks exist because renderer-owned state participates in those global lifecycle transitions.
The machine is best understood as a chain of observable contracts, not a schematic simulator.
flowchart LR
A[Guest software] --> B[CPU / PCI / MMIO / I/O contract]
B --> C[Emulated device state]
C --> D{Implementation boundary}
D --> E[Pure device logic]
D --> F[Generic QEMU device]
D --> G[Host service]
D --> H[Compatibility shortcut]
E --> I[Guest-visible result]
F --> I
G --> I
H --> I
Important current examples:
| Area | Current implementation boundary | Why it matters |
|---|---|---|
| Pentium III CPU | Architectural x86 through TCG, not cycle-accurate P6 pipeline/cache simulation | Host CPU time cannot be converted directly into Xbox CPU cycles |
| LPC/PCI/SMBus | Logical buses and callbacks, not motherboard wire edges | Port/MMIO timing is emulator timing, not bus propagation time |
| PIT/RTC/OHCI/IDE | Reused QEMU PC-compatible devices where suitable | Guest semantics are inherited from mature generic device models |
| PC speaker | QEMU pcspk is linked to PIT and realized even though a retail console does not normally expose a populated speaker |
Source presence is not proof of a physical user-facing device |
| SMC | Software-facing register/event model, not PIC firmware execution | Fan/LED/security/timing details can be absent while normal kernel behavior works |
| Video encoder | Current SMBus models are mainly register arrays | Analog encoder cost/behavior is not represented by those callbacks |
| APU | Dedicated worker + host SDL queue pacing | Host audio backpressure can appear as emulator timing |
| NV2A | Register/DMA/PFIFO/PGRAPH semantics translated to GL/Vulkan | Host render passes/pipelines are implementation artifacts, not NV2A objects |
| Memory controller | Current PCI function is explicitly a pci-testdev stub |
Undocumented register probing can expose missing hardware |
For motherboard-level examples and source FIXME boundaries, see Hardware Fidelity & Emulation Boundaries.
The main performance regions do not all represent the same kind of work:
| Region | Typical cost source |
|---|---|
| vCPU / TCG | Translation-block dispatch, guest instruction execution, exits, memory helpers |
| Timers | Timer-list operations, wakeups, callback frequency, guest IRQ work |
| PFIFO/PGRAPH | Method decoding, guest GPU state changes, locking, command preparation |
| Shader translation | Guest shader/combiner state → GLSL → compiled host shader representation |
| OpenGL | Driver validation, implicit synchronization, shader/program/state updates |
| Vulkan | Explicit command recording, pipeline creation, descriptors, barriers, submissions, fences |
| Memory coherency | RAM/VRAM mirrors, surface readback, vertex/texture upload, report publication |
A profile should first identify which boundary owns the time before changing code. See Performance Methodology.
| File / area | Why start there |
|---|---|
hw/xbox/xbox.c |
Machine construction and CPU/platform setup |
accel/tcg/cpu-exec.c |
Central translated guest execution loop |
accel/tcg/tcg-accel-ops-mttcg.c |
vCPU thread creation and MTTCG run loop |
util/qemu-timer.c |
QEMU clock and timer-list implementation |
hw/xbox/nv2a/nv2a.c |
NV2A device integration and lifecycle |
hw/xbox/nv2a/pfifo.c |
Pushbuffer/channel command processing |
hw/xbox/nv2a/pgraph/pgraph.c |
Shared NV2A graphics state/method behavior |
hw/xbox/nv2a/pgraph/pgraph.h |
Shared renderer interface and PGRAPH ownership |
hw/xbox/nv2a/pgraph/gl/* |
OpenGL renderer implementation |
hw/xbox/nv2a/pgraph/vk/* |
Vulkan renderer implementation |
- Hardware Oddities — a separate research index cross-referenced from the affected subsystems.
- CPU & vCPU Execution
- Clocks & Timers
- NV2A Graphics Architecture
- Performance
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