/// Reads all bar registers of specified device and returns vector of PciBar's containing addresses and sizes.
Reads all bar registers of specified device and returns vector of PciBar's containing addresses and sizes.
Reads all bar registers of specified device and returns vector of PciBar ' s containing addresses and sizes .
fn parse_bars(bus: u8, device: u8, vendor_id: u16, device_id: u16) -> Vec<PciBar> {
	let mut bar_idxs = 0..6;
	let mut bars = Vec::new();
	while let Some(i) = bar_idxs.next() {
		let register = PCI_BAR0_REGISTER + ((i as u32) << 2);
		let barword = read_config(bus, device, register);
		debug!(
			"Found bar{} @{:x}:{:x} as 0x{:x}",
			i, vendor_id, device_id, barword
		);
		// We assume BIOS or something similar has initialized the device already and set appropriate values into the bar registers
		// If barword is all 0, the bar is disabled
		if barword == 0 {
			continue;
		}
		// Determine if bar is IO-mapped or memory-mapped
		if barword & PCI_BASE_ADDRESS_IO_SPACE != 0 {
			// IO Mapped BAR
			debug!("Bar {} @{:x}:{:x} IO mapped!", i, vendor_id, device_id);
			let base_addr = barword & PCI_IO_BASE_ADDRESS_MASK;
			// determine size by writing 0xFFFFFFFF
			write_config(bus, device, register, u32::MAX);
			let sizebits = read_config(bus, device, register);
			// Restore original value of register
			write_config(bus, device, register, barword);
			let size = (!(sizebits & PCI_IO_BASE_ADDRESS_MASK) + 1) as usize;
			bars.push(PciBar::IO(IOBar {
				index: i as u8,
				addr: base_addr,
				size,
			}));
		} else {
			// Memory Mapped BAR
			let prefetchable = barword & PCI_MEM_PREFETCHABLE != 0;
			if barword & PCI_MEM_BASE_ADDRESS_64BIT != 0 {
				// 64-bit, load additional bar-word
				let register_high = PCI_BAR0_REGISTER + (bar_idxs.next().unwrap() << 2);
				let barword_high = read_config(bus, device, register_high);
				let base_addr = ((barword_high as usize) << 32) + (barword & 0xFFFF_FFF0) as usize;
				debug!(
					"64-bit memory bar, merged next barword. Addr: 0x{:x}",
					base_addr
				);
				// determine size by writing 0xFFFFFFFF
				write_config(bus, device, register, u32::MAX);
				let sizebits = read_config(bus, device, register);
				// Also read/write to register_high if needed
				let size = if sizebits == 0 {
					write_config(bus, device, register_high, u32::MAX);
					let sizebits = read_config(bus, device, register_high);
					// Restore original value of register_high
					write_config(bus, device, register_high, barword);
					((!sizebits + 1) as usize) << 32
				} else {
					(!(sizebits & PCI_MEM_BASE_ADDRESS_MASK) + 1) as usize
				};
				// Restore original value
				write_config(bus, device, register, barword);
				bars.push(PciBar::Memory(MemoryBar {
					index: i as u8,
					addr: base_addr,
					size,
					width: 64,
					prefetchable,
				}));
			} else {
				// 32-bit
				let base_addr = (barword & 0xFFFF_FFF0) as usize;
				// determine size by writing 0xFFFFFFFF
				write_config(bus, device, register, u32::MAX);
				let size = !(read_config(bus, device, register) & PCI_MEM_BASE_ADDRESS_MASK) + 1;
				// Restore original value
				write_config(bus, device, register, barword);
				bars.push(PciBar::Memory(MemoryBar {
					index: i as u8,
					addr: base_addr,
					size: size.try_into().unwrap(),
					width: 32,
					prefetchable,
				}));
			}
		}
	}
	bars
}
fn parse_bars ( bus : u8 , device : u8 , vendor_id : u16 , device_id : u16 ) -> Vec < PciBar > { let mut bar_idxs = 0 .. 6 ; let mut bars = Vec :: new ( ) ; while let Some ( i ) = bar_idxs . next ( ) { let register = PCI_BAR0_REGISTER + ( ( i as u32 ) << 2 ) ; let barword = read_config ( bus , device , register ) ; debug ! ( " " i vendor_id device_id barword ) ; // We assume BIOS or something similar has initialized the device already and set appropriate values into the bar registers // If barword is all 0, the bar is disabled if barword == 0 { continue ; } // Determine if bar is IO-mapped or memory-mapped if barword & PCI_BASE_ADDRESS_IO_SPACE != 0 { // IO Mapped BAR debug ! ( " " i vendor_id device_id ) ; let base_addr = barword & PCI_IO_BASE_ADDRESS_MASK ; // determine size by writing 0xFFFFFFFF write_config ( bus , device , register , u32 :: MAX ) ; let sizebits = read_config ( bus , device , register ) ; // Restore original value of register write_config ( bus , device , register , barword ) ; let size = ( ! ( sizebits & PCI_IO_BASE_ADDRESS_MASK ) + 1 ) as usize ; bars . push ( PciBar :: IO ( IOBar { index : i as u8 , addr : base_addr , size , } ) ) ; } else { // Memory Mapped BAR let prefetchable = barword & PCI_MEM_PREFETCHABLE != 0 ; if barword & PCI_MEM_BASE_ADDRESS_64BIT != 0 { // 64-bit, load additional bar-word let register_high = PCI_BAR0_REGISTER + ( bar_idxs . next ( ) . unwrap ( ) << 2 ) ; let barword_high = read_config ( bus , device , register_high ) ; let base_addr = ( ( barword_high as usize ) << 32 ) + ( barword & 0xFFFF_FFF0 ) as usize ; debug ! ( " " base_addr ) ; // determine size by writing 0xFFFFFFFF write_config ( bus , device , register , u32 :: MAX ) ; let sizebits = read_config ( bus , device , register ) ; // Also read/write to register_high if needed let size = if sizebits == 0 { write_config ( bus , device , register_high , u32 :: MAX ) ; let sizebits = read_config ( bus , device , register_high ) ; // Restore original value of register_high write_config ( bus , device , register_high , barword ) ; ( ( ! sizebits + 1 ) as usize ) << 32 } else { ( ! ( sizebits & PCI_MEM_BASE_ADDRESS_MASK ) + 1 ) as usize } ; // Restore original value write_config ( bus , device , register , barword ) ; bars . push ( PciBar :: Memory ( MemoryBar { index : i as u8 , addr : base_addr , size , width : 64 , prefetchable , } ) ) ; } else { // 32-bit let base_addr = ( barword & 0xFFFF_FFF0 ) as usize ; // determine size by writing 0xFFFFFFFF write_config ( bus , device , register , u32 :: MAX ) ; let size = ! ( read_config ( bus , device , register ) & PCI_MEM_BASE_ADDRESS_MASK ) + 1 ; // Restore original value write_config ( bus , device , register , barword ) ; bars . push ( PciBar :: Memory ( MemoryBar { index : i as u8 , addr : base_addr , size : size . try_into ( ) . unwrap ( ) , width : 32 , prefetchable , } ) ) ; } } } bars }
Reads all bar registers of specified device and returns vector of PciBar's containing addresses and sizes.
Reads all bar registers of specified device and returns vector of PciBar ' s containing addresses and sizes .
bus
u8
device
u8
vendor_id
u16
device_id
u16