diff --git a/local/recipes/drivers/redox-driver-sys/source/src/pci.rs b/local/recipes/drivers/redox-driver-sys/source/src/pci.rs index bd81bb14cb..e8c7259a6d 100644 --- a/local/recipes/drivers/redox-driver-sys/source/src/pci.rs +++ b/local/recipes/drivers/redox-driver-sys/source/src/pci.rs @@ -574,11 +574,16 @@ impl PciDevice { let is_io = (original & 0x01) != 0; let mask = if is_io { 0xFFFFFFFC } else { 0xFFFFFFF0 }; - let size_val = !(inverted & mask) & mask; - if size_val == 0 { + let masked = inverted & mask; + if masked == 0 { return Ok(0); } - Ok(size_val as u64) + // The lowest set bit in the readback IS the BAR size. + // This correctly handles non-zero base addresses because + // writable address bits above the size boundary are all 1s + // while hardwired size bits below are all 0s. + let size = masked & (!masked).wrapping_add(1); + Ok(size as u64) } fn probe_bar64_size(&mut self, offset: u64) -> Result { @@ -594,14 +599,16 @@ impl PciDevice { self.write_config_dword(offset, original_lo)?; self.write_config_dword(offset + 4, original_hi)?; - let lo = !(inverted_lo & 0xFFFFFFF0) & 0xFFFFFFF0; - let hi = !inverted_hi; + let masked_lo = inverted_lo & 0xFFFFFFF0; + let masked_hi = inverted_hi; + let masked = ((masked_hi as u64) << 32) | (masked_lo as u64); - if lo == 0 && hi == 0 { + if masked == 0 { return Ok(0); } - let size = ((hi as u64) << 32) | (lo as u64); + // The lowest set bit in the readback IS the BAR size. + let size = masked & (!masked).wrapping_add(1); Ok(size) }