From fba204e2f5017091a0b2d6f7d9179016b2e4e96c Mon Sep 17 00:00:00 2001 From: Vasilito Date: Fri, 15 May 2026 07:23:11 +0100 Subject: [PATCH] fix: correct BAR size probing for non-zero base addresses The previous BAR size calculation used !(inverted & mask) & mask which\nproduces incorrect results when the BAR has a non-zero base address.\nUse lowest-set-bit extraction (masked & (!masked + 1)) to correctly\ncompute the BAR size from the writable bit pattern read back from hardware. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- .../redox-driver-sys/source/src/pci.rs | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) 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) }