pci: Fix detection of expansion ROM BAR reprogramming

The expansion ROM BAR reprogramming was being triggered for the wrong
reason and was causing the following error to be reported:

ERROR:pci/src/bus.rs:207 -- Failed moving device BAR: failed allocating
new 32 bits MMIO range

Following the PCI specification, here is what is defined:

Device independent configuration software can determine how much address
space the device requires by writing a value of all 1's to the address
portion of the register and then reading the value back.

This means we cannot expect 0xffffffff to be written, as the address
portion corresponds to the bits 31-11. That's why whenever the size of
this special BAR is being asked for, the value being written is
0xfffff800.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-01-08 17:59:21 +01:00
parent 0d2e38db25
commit 07bad79fd7

View File

@ -399,12 +399,17 @@ impl PciConfiguration {
pub fn write_reg(&mut self, reg_idx: usize, value: u32) {
let mut mask = self.writable_bits[reg_idx];
if value == 0xffff_ffff {
if reg_idx >= BAR0_REG && reg_idx < BAR0_REG + NUM_BAR_REGS {
// Handle very specific case where the BAR is being written with
// all 1's to retrieve the BAR size on next BAR reading.
if reg_idx >= BAR0_REG && reg_idx < BAR0_REG + NUM_BAR_REGS {
// Handle very specific case where the BAR is being written with
// all 1's to retrieve the BAR size during next BAR reading.
if value == 0xffff_ffff {
mask = self.bar_size[reg_idx - 4];
} else if reg_idx == ROM_BAR_REG {
}
} else if reg_idx == ROM_BAR_REG {
// Handle very specific case where the BAR is being written with
// all 1's on bits 31-11 to retrieve the BAR size during next BAR
// reading.
if value & ROM_BAR_ADDR_MASK == ROM_BAR_ADDR_MASK {
mask = self.rom_bar_size;
}
}
@ -731,6 +736,11 @@ impl PciConfiguration {
}
}
} else if reg_idx == ROM_BAR_REG && (value & mask) != (self.rom_bar_addr & mask) {
// Ignore the case where the BAR size is being asked for.
if value & ROM_BAR_ADDR_MASK == ROM_BAR_ADDR_MASK {
return None;
}
debug!(
"DETECT ROM BAR REPROG: current 0x{:x}, new 0x{:x}",
self.registers[reg_idx], value