(
&mut self,
reg_idx: usize,
data: &[u8],
)
| 970 | } |
| 971 | |
| 972 | fn detect_bar_reprogramming( |
| 973 | &mut self, |
| 974 | reg_idx: usize, |
| 975 | data: &[u8], |
| 976 | ) -> Option<BarReprogrammingParams> { |
| 977 | if data.len() != 4 { |
| 978 | return None; |
| 979 | } |
| 980 | |
| 981 | let value = LittleEndian::read_u32(data); |
| 982 | |
| 983 | let mask = self.writable_bits[reg_idx]; |
| 984 | if (BAR0_REG..BAR0_REG + NUM_BAR_REGS).contains(®_idx) { |
| 985 | // Ignore the case where the BAR size is being asked for. |
| 986 | if value == 0xffff_ffff { |
| 987 | return None; |
| 988 | } |
| 989 | |
| 990 | let bar_idx = reg_idx - BAR0_REG; |
| 991 | // Handle special case where the address being written is |
| 992 | // different from the address initially provided. This is a |
| 993 | // BAR reprogramming case which needs to be properly caught. |
| 994 | if let Some(bar_type) = self.bars[bar_idx].r#type { |
| 995 | // In case of 64 bits memory BAR, we don't do anything until |
| 996 | // the upper BAR is modified, otherwise we would be moving the |
| 997 | // BAR to a wrong location in memory. |
| 998 | if bar_type == PciBarRegionType::Memory64BitRegion { |
| 999 | return None; |
| 1000 | } |
| 1001 | |
| 1002 | // Ignore the case where the value is unchanged. |
| 1003 | if (value & mask) == (self.bars[bar_idx].addr & mask) { |
| 1004 | return None; |
| 1005 | } |
| 1006 | |
| 1007 | info!( |
| 1008 | "Detected BAR reprogramming: (BAR {}) 0x{:x}->0x{:x}", |
| 1009 | bar_idx, self.bars[bar_idx].addr, value |
| 1010 | ); |
| 1011 | let old_base = u64::from(self.bars[bar_idx].addr & mask); |
| 1012 | let new_base = u64::from(value & mask); |
| 1013 | let len = u64::from( |
| 1014 | decode_32_bits_bar_size(self.bars[bar_idx].size) |
| 1015 | .ok_or(Error::Decode32BarSize) |
| 1016 | .unwrap(), |
| 1017 | ); |
| 1018 | let region_type = bar_type; |
| 1019 | |
| 1020 | self.bars[bar_idx].addr = value; |
| 1021 | |
| 1022 | return Some(BarReprogrammingParams { |
| 1023 | old_base, |
| 1024 | new_base, |
| 1025 | len, |
| 1026 | region_type, |
| 1027 | }); |
| 1028 | } else if (bar_idx > 0) |
| 1029 | && ((self.registers[reg_idx - 1] & self.writable_bits[reg_idx - 1]) |
no test coverage detected