e1000_driver/
pci.rs

1// Simple PCI-Express for qemu and its e1000 ethernet
2use core::slice::from_raw_parts_mut;
3use volatile::Volatile;
4use log::*;
5
6// E1000 registers which were mapped
7pub const E1000_REGS: u32 = 0x40000000;
8// Qemu virt PCIe config space
9pub const ECAM: u32 = 0x30000000;
10
11pub fn pci_init() {
12    // Look at each PCI device on bus 0
13    for dev in 0..32 {
14        let bus = 0;
15        let func = 0;
16        let offset = 0;
17
18        let off: u32 = (bus << 16) | (dev << 11) | (func << 8) | offset;
19        let base = ECAM + off;
20        let pci_base = base as *mut Volatile<u32>;
21        let deve_id = unsafe{ (*pci_base).read() };
22        trace!("PCI device id: {:#x} @ {:#x}", deve_id, base);
23
24        // E1000 ID = 100e:8086
25        if deve_id == 0x100e8086 {
26            info!("PCI Found device id: {:#x}", deve_id);
27            let pci_config = unsafe { from_raw_parts_mut(base as *mut Volatile<u32>, 0xff / 4) };
28
29            // Enable I/O access, memory access, mastering
30            pci_config[1].write(0x7);
31            //sync
32
33            for bar in 0..6 {
34                let old: u32 = pci_config[4 + bar].read();
35
36                // Writing all 1's to the BAR causes it to be replaced with its size.
37                pci_config[4 + bar].write(0xffffffff);
38                //sync
39
40                pci_config[4 + bar].write(old);
41            }
42
43            // To reveal e1000 registers at E1000_REGS;
44            pci_config[4 + 0].write(E1000_REGS);
45
46            //e1000_init((*mut u32)E1000_REGS);
47        }
48    }
49}