IDE HDD/Optical

The IDE controller emulates the storage portion of an Intel PIIX4 (82371AB) PCI-to-ISA bridge. It provides two IDE channels (primary and secondary), each supporting up to two devices — four total. Devices are either ATA hard drives or ATAPI optical drives.

The controller connects to the storage stack through Disk for hard drives and AsyncScsiDisk (via SimpleScsiDvd) for optical drives. Interrupts use IRQ 14 (primary) and IRQ 15 (secondary). The emulator implements a subset of ATA/ATAPI-6 (48-bit LBA) and the ATAPI packet interface from ATA/ATAPI-4, with a PCI config space layout based on the Intel PIIX4 (82371AB) datasheet (PCI vendor/device ID 8086:7111).

I/O port layout

Command block registers (per channel):

Port (pri / sec)RegisterAccessPurpose
0x1F0 / 0x170DataR/W16-bit PIO data transfer
0x1F1 / 0x171Error (R) / Features (W)R/WError status / command parameters
0x1F2 / 0x172Sector countR/WTransfer size in sectors
0x1F3–0x1F5 / 0x173–0x175LBA low / mid / highR/WLBA address (28-bit or 48-bit with HOB)
0x1F6 / 0x176Device / headR/WDrive select + LBA[24:27] or head
0x1F7 / 0x177Status (R) / Command (W)R/WStatus flags / command issue
0x3F6 / 0x376Alt status (R) / Device control (W)R/WNon-interrupt status / reset + nIEN

The IDE controller claims port 0x3F6 (shared region with the floppy controller's 0x3F7).

Bus master DMA

The controller provides PCI bus master DMA via BAR4. Each channel has its own registers (primary at BAR4+0, secondary at BAR4+8):

OffsetRegisterPurpose
+0CommandStart DMA, read/write direction
+2StatusActive, DMA error, interrupt flags
+4PRD table pointerPhysical Region Descriptor table address

The PRD table is a scatter-gather list in guest memory. Each entry contains a 32-bit physical base address, a 16-bit byte count, and an end-of-table flag. DMA transfers iterate entries until the end-of-table bit or the requested byte count is reached.

PCI config space includes PIIX4-specific timing registers (PRIMARY_TIMING_REG_ADDR at 0x40, SECONDARY_TIMING_REG_ADDR at 0x44) and a UDMA control register (UDMA_CTL_REG_ADDR at 0x48).

ATA hard drives

The ATA (AT Attachment) protocol defines a register-based command interface for hard drives. The guest programs LBA, sector count, and command into the command block registers, then transfers data via PIO or DMA. The emulator implements the subset that OS drivers actually use:

  • Data transfer: READ SECTORS, WRITE SECTORS (PIO), READ DMA, WRITE DMA (DMA), plus 48-bit LBA extended variants.
  • WRITE DMA FUA EXT — force unit access, mapped to Disk::write_vectored with fua: true.
  • IDENTIFY DEVICE — returns 512 bytes of drive geometry, capabilities, and supported command sets.
  • FLUSH CACHE / FLUSH CACHE EXT — mapped to Disk::sync_cache.
  • SET FEATURES, SET MULTI BLOCK MODE, power management (STANDBY, IDLE, SLEEP, CHECK POWER MODE).

Commands not implemented (including SMART, security, and device configuration overlays) return an error. The emulator doesn't emulate PIO timing — transfers complete as fast as the backend can serve them.

ATAPI optical drives

The ATAPI (ATA Packet Interface) extension transports SCSI commands over the ATA register interface. The guest issues PACKET COMMAND (0xA0), then writes a 12-byte SCSI CDB through the data register. The controller forwards this CDB to SimpleScsiDvd, which handles optical-specific SCSI commands (READ, GET_CONFIGURATION, START_STOP_UNIT for eject, GET_EVENT_STATUS_NOTIFICATION for media change).

This layering means the ATAPI drive is a thin ATA-to-SCSI bridge — the same SimpleScsiDvd implementation serves both StorVSP (direct SCSI) and IDE (via ATAPI). See the storage pipeline — virtual optical / DVD section for the DVD model and eject behavior.

IDENTIFY PACKET DEVICE (0xA1) returns device identification with ATAPI-specific fields (general config word indicates removable media, ATAPI device type).

Enlightened I/O

The IDE controller supports a Microsoft-specific performance optimization: enlightened INT13 commands. Instead of the guest issuing a sequence of register writes to set up an ATA/ATAPI command (LBA, sector count, command register, then DMA start), the guest writes a single EnlightenedInt13Command packet to guest memory and writes the packet's GPA to the enlightened port.

Enlightened ports: 0x1E0 (primary channel), 0x160 (secondary channel).

The EnlightenedInt13Command struct contains the ATA command opcode, device/head select, full 48-bit LBA, block count, a GPA for the data buffer, byte count, skip-bytes for partial sector transfers, and a result status field written by the controller on completion.

This collapses the multi-exit register-programming sequence into a single VM exit, significantly reducing overhead for legacy IDE I/O. The enlightened path uses the same DeferredWrite async I/O mechanism — the I/O port write returns deferred, and the controller completes it when the disk operation finishes.

Both HDD and optical drives support enlightened commands, with separate completion paths.

IDE accelerator (StorVSP-backed)

OpenVMM offers an IDE accelerator that enhances Gen1 VM storage performance. The standard PCI-based IDE emulation path requires the guest to program ATA registers via port I/O, causing multiple VM exits per command. The accelerator provides a parallel VMBus-based data path using ring buffers — the same transport StorVSP uses for SCSI.

Both paths coexist: the emulation path always exists for control-plane operations, while the accelerator handles data-plane I/O when the guest supports it. The guest's storvsc driver recognizes the IDE accelerator VMBus offer and uses ring buffers instead of port I/O for data transfer. Under the hood, StorVSP builds the device with StorageDevice::build_ide(), which:

  • Constructs a ScsiController with a single disk at the matching (channel_id, device_id) path.
  • Generates a deterministic instance_id from the channel and device IDs.
  • Sets max_sub_channel_count = 0 — the accelerator uses only the primary channel. All I/O is serialized through one worker.

The accelerator exists for throughput (ring buffers avoid the multi-exit register-programming sequence), not for parallelism. It does not support subchannels or multi-queue I/O. For parallel storage I/O, use a SCSI controller with subchannels — see the StorVSP Channels & Subchannels page.

Note

The IDE accelerator and the standard IDE emulator coexist. The emulator handles control-plane operations (IDENTIFY, SET FEATURES, power management) while the accelerator handles data-plane I/O. If the guest doesn't support the accelerator, all I/O uses the PCI emulation path.

Limitations

  • No hot-add or hot-remove.
  • No online disk resize (IDE has no capacity-change notification).
  • Maximum four devices (two channels × two drives).
  • No native command queuing (NCQ) — one command at a time per channel.

Crate

ide. See also ide_resources for the GuestMedia enum and IdeDeviceConfig types. The storage pipeline page covers how IDE fits into the broader frontend-to-backend architecture.