Restore BAR address after a failed move. This undoes the premature address update in detect_bar_reprogramming() so that config space stays consistent with the actual MMIO mapping.
(&mut self, params: &BarReprogrammingParams)
| 1098 | /// address update in detect_bar_reprogramming() so that config space |
| 1099 | /// stays consistent with the actual MMIO mapping. |
| 1100 | pub fn restore_bar_addr(&mut self, params: &BarReprogrammingParams) { |
| 1101 | match params.region_type { |
| 1102 | PciBarRegionType::Memory64BitRegion => { |
| 1103 | // 64-bit BAR spans two slots: bars[i] (low, type Memory64BitRegion) |
| 1104 | // and bars[i+1] (high, type None). Mirror detect_bar_reprogramming |
| 1105 | // by matching the combined address and restoring both halves. |
| 1106 | for i in 0..NUM_BAR_REGS - 1 { |
| 1107 | if self.bars[i].r#type != Some(PciBarRegionType::Memory64BitRegion) { |
| 1108 | continue; |
| 1109 | } |
| 1110 | let low_mask = self.writable_bits[BAR0_REG + i]; |
| 1111 | let high_mask = self.writable_bits[BAR0_REG + i + 1]; |
| 1112 | let current = (u64::from(self.bars[i + 1].addr & high_mask) << 32) |
| 1113 | | u64::from(self.bars[i].addr & low_mask); |
| 1114 | if current == params.new_base { |
| 1115 | let old_low = params.old_base as u32; |
| 1116 | let old_high = (params.old_base >> 32) as u32; |
| 1117 | self.bars[i].addr = old_low; |
| 1118 | self.bars[i + 1].addr = old_high; |
| 1119 | self.registers[BAR0_REG + i] = |
| 1120 | (self.registers[BAR0_REG + i] & !low_mask) | (old_low & low_mask); |
| 1121 | self.registers[BAR0_REG + i + 1] = (self.registers[BAR0_REG + i + 1] |
| 1122 | & !high_mask) |
| 1123 | | (old_high & high_mask); |
| 1124 | return; |
| 1125 | } |
| 1126 | } |
| 1127 | } |
| 1128 | _ => { |
| 1129 | // 32-bit Memory or IO BAR |
| 1130 | for i in 0..NUM_BAR_REGS { |
| 1131 | let mask = self.writable_bits[BAR0_REG + i]; |
| 1132 | if self.bars[i].r#type == Some(params.region_type) |
| 1133 | && u64::from(self.bars[i].addr & mask) == params.new_base |
| 1134 | { |
| 1135 | let old = params.old_base as u32; |
| 1136 | self.bars[i].addr = old; |
| 1137 | self.registers[BAR0_REG + i] = |
| 1138 | (self.registers[BAR0_REG + i] & !mask) | (old & mask); |
| 1139 | return; |
| 1140 | } |
| 1141 | } |
| 1142 | } |
| 1143 | } |
| 1144 | } |
| 1145 | } |
| 1146 | |
| 1147 | impl Pausable for PciConfiguration {} |