Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions vm/devices/storage/ide/src/drive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,20 @@ impl DiskDrive {
DiskDrive::OpticalDevice(device) => device.interrupt_pending(),
}
}
// DIVERGENCE PROBE (temporary): pending & unmasked & not-in-reset but NOT selected.
pub fn probe_pending_unselected(&self) -> bool {
match self {
DiskDrive::HardDevice(device) => device.probe_pending_unselected(),
DiskDrive::OpticalDevice(device) => device.probe_pending_unselected(),
}
}
// DIVERGENCE PROBE (temporary): raw pending flag, regardless of gates.
pub fn probe_raw_pending(&self) -> bool {
match self {
DiskDrive::HardDevice(device) => device.probe_raw_pending(),
DiskDrive::OpticalDevice(device) => device.probe_raw_pending(),
}
}
pub fn dma_request(&self) -> Option<(&DmaType, usize)> {
match self {
DiskDrive::HardDevice(device) => device.dma_request(),
Expand Down
17 changes: 17 additions & 0 deletions vm/devices/storage/ide/src/drive/atapi_drive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,17 @@ impl AtapiDrive {
&& !self.state.pending_software_reset
}

// DIVERGENCE PROBES (temporary).
pub fn probe_pending_unselected(&self) -> bool {
self.state.pending_interrupt
&& !self.state.regs.device_control_reg.interrupt_mask()
&& !self.state.pending_software_reset
&& !self.is_selected()
}
pub fn probe_raw_pending(&self) -> bool {
self.state.pending_interrupt
}

pub fn dma_request(&self) -> Option<(&DmaType, usize)> {
if let Some(buffer) = &self.state.buffer {
buffer
Expand Down Expand Up @@ -627,6 +638,12 @@ impl AtapiDrive {
self.state.regs.error = ErrorReg::new().with_unknown_command(true);
}
command => {
if crate::probe::first_unknown_atapi(command.0) {
tracing::warn!(
opcode = command.0,
"IDEPROBE_C_UNKNOWN_CMD_ATAPI unimplemented command aborted"
);
}
tracing::debug!(?command, "unknown command");
self.state.regs.status.set_err(true);
self.state.regs.error = ErrorReg::new().with_unknown_command(true);
Expand Down
35 changes: 34 additions & 1 deletion vm/devices/storage/ide/src/drive/hard_drive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,14 @@ impl HardDrive {
// Initialize drive geometry
let read_only = disk.is_read_only();
let geometry = MediaGeometry::new(disk.sector_count(), disk.sector_size())?;
// IDEPROBE (temporary): non-512 sector disks expose the IDENTIFY word 106/117-118 gap.
if disk.sector_size() != 512 {
tracing::warn!(
sector_size = disk.sector_size(),
%disk_path,
"IDEPROBE_E_NON512_SECTOR non-512 sector IDE disk attached"
);
}
Ok(Self {
disk,
state: DriveState::new(),
Expand Down Expand Up @@ -565,7 +573,7 @@ impl HardDrive {
&& self.state.command.is_some()
{
tracing::warn!(
"Changing selected drive in the middle of operation. Resetting previously selected drive"
"IDEPROBE_F_DRIVE_CHANGE_MID_CMD Changing selected drive in the middle of operation. Resetting previously selected drive"
);
Comment on lines 575 to 577
self.reset();
}
Expand Down Expand Up @@ -629,6 +637,17 @@ impl HardDrive {
&& !self.state.pending_software_reset
}

// DIVERGENCE PROBES (temporary).
pub fn probe_pending_unselected(&self) -> bool {
self.state.pending_interrupt
&& !self.state.regs.device_control_reg.interrupt_mask()
&& !self.state.pending_software_reset
&& !self.is_selected()
}
pub fn probe_raw_pending(&self) -> bool {
self.state.pending_interrupt
}

pub fn dma_request(&self) -> Option<(&DmaType, usize)> {
if let Some(buffer) = &self.state.buffer {
buffer
Expand Down Expand Up @@ -946,6 +965,14 @@ impl HardDrive {
None
}
IdeCommand::SET_FEATURES => {
// IDEPROBE (temporary): detect guest write-cache control that UH silently ignores.
let sub = self.state.regs.features;
if sub == 0x02 || sub == 0x82 {
tracing::warn!(
subcommand = sub,
"IDEPROBE_D_SET_FEATURES_CACHE guest toggled write cache; UH ignores"
);
}
// TODO
//
// Saw in Gen 1 VM boot but this is likely not necessary because
Expand All @@ -959,6 +986,12 @@ impl HardDrive {
| IdeCommand::IDLE_IMMEDIATE
| IdeCommand::STANDBY_IMMEDIATE => None,
command => {
if crate::probe::first_unknown_hdd(command.0) {
tracing::warn!(
opcode = command.0,
"IDEPROBE_C_UNKNOWN_CMD_HDD unimplemented command aborted"
);
}
tracing::debug!(?command, "unknown command");
self.state.error_pending = true;
self.state.regs.error = ErrorReg::new().with_unknown_command(true);
Expand Down
Loading
Loading