OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 10:52 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: PCI: info qtree v/s brute force enumeration
PostPosted: Mon Oct 19, 2020 2:34 am 
Offline
Member
Member

Joined: Sat Feb 08, 2020 11:11 am
Posts: 106
I have written a simple PCI driver (nothing fancy... Just reads and writes to PCI config space and a function for brute force enumeration).

My brute force enumeration gives me this (I do the bus*device loops, and ignore reads which give me all 1s):
Code:
Bus: 0x0   Slot: 0x0   Vendor: 0x8086   Device: 0x1237   Class: 0x6   Subclass: 0x0   Header: 0x0
Bus: 0x0   Slot: 0x1   Vendor: 0x8086   Device: 0x7000   Class: 0x6   Subclass: 0x1   Header: 0x80
Bus: 0x0   Slot: 0x2   Vendor: 0x1234   Device: 0x1111   Class: 0x3   Subclass: 0x0   Header: 0x0
Bus: 0x0   Slot: 0x3   Vendor: 0x8086   Device: 0x100E   Class: 0x2   Subclass: 0x0   Header: 0x0


I wanted to check the validity of this, and did a `info qtree` on my qemu console.
Code:
bus: main-system-bus
  type System
  dev: hpet, id ""
    gpio-in "" 2
    gpio-out "" 1
    gpio-out "sysbus-irq" 32
    timers = 3 (0x3)
    msi = false
    hpet-intcap = 4 (0x4)
    hpet-offset-saved = true
    mmio 00000000fed00000/0000000000000400
  dev: ioapic, id ""
    gpio-in "" 24
    version = 32 (0x20)
    mmio 00000000fec00000/0000000000001000
  dev: i440FX-pcihost, id ""
    pci-hole64-size = 2147483648 (2 GiB)
    short_root_bus = 0 (0x0)
    x-pci-hole64-fix = true
    x-config-reg-migration-enabled = true
    bus: pci.0
      type PCI
      dev: PIIX4_PM, id ""
        smb_io_base = 1792 (0x700)
        disable_s3 = 0 (0x0)
        disable_s4 = 0 (0x0)
        s4_val = 2 (0x2)
        acpi-pci-hotplug-with-bridge-support = true
        memory-hotplug-support = true
        addr = 01.3
        romfile = ""
        rombar = 1 (0x1)
        multifunction = false
        x-pcie-lnksta-dllla = true
        x-pcie-extcap-init = true
        failover_pair_id = ""
        class Bridge, addr 00:01.3, pci id 8086:7113 (sub 1af4:1100)
        bus: i2c
          type i2c-bus
          dev: smbus-eeprom, id ""
            address = 87 (0x57)
          dev: smbus-eeprom, id ""
            address = 86 (0x56)
          dev: smbus-eeprom, id ""
            address = 85 (0x55)
          dev: smbus-eeprom, id ""
            address = 84 (0x54)
          dev: smbus-eeprom, id ""
            address = 83 (0x53)
          dev: smbus-eeprom, id ""
            address = 82 (0x52)
          dev: smbus-eeprom, id ""
            address = 81 (0x51)
          dev: smbus-eeprom, id ""
            address = 80 (0x50)
      dev: piix3-ide, id ""
        addr = 01.1
        romfile = ""
        rombar = 1 (0x1)
        multifunction = false
        x-pcie-lnksta-dllla = true
        x-pcie-extcap-init = true
        failover_pair_id = ""
        class IDE controller, addr 00:01.1, pci id 8086:7010 (sub 1af4:1100)
        bar 4: i/o at 0xc040 [0xc04f]
        bus: ide.1
          type IDE
          dev: ide-cd, id ""
            drive = "ide1-cd0"
            logical_block_size = 512 (512 B)
            physical_block_size = 512 (512 B)
            min_io_size = 0 (0 B)
            opt_io_size = 0 (0 B)
            discard_granularity = 512 (512 B)
            write-cache = "auto"
            share-rw = false
            rerror = "auto"
            werror = "auto"
            ver = "2.5+"
            wwn = 0 (0x0)
            serial = "QM00003"
            model = ""
            unit = 0 (0x0)
        bus: ide.0
          type IDE
      dev: e1000, id ""
        mac = "52:54:00:12:34:56"
        netdev = "hub0port0"
        autonegotiation = true
        mitigation = true
        extra_mac_registers = true
        migrate_tso_props = true
        addr = 03.0
        romfile = "efi-e1000.rom"
        rombar = 1 (0x1)
        multifunction = false
        x-pcie-lnksta-dllla = true
        x-pcie-extcap-init = true
        failover_pair_id = ""
        class Ethernet controller, addr 00:03.0, pci id 8086:100e (sub 1af4:1100)
        bar 0: mem at 0xfebc0000 [0xfebdffff]
        bar 1: i/o at 0xc000 [0xc03f]
        bar 6: mem at 0xffffffffffffffff [0x3fffe]
      dev: VGA, id ""
        vgamem_mb = 16 (0x10)
        mmio = true
        qemu-extended-regs = true
        edid = true
        xres = 1024 (0x400)
        yres = 768 (0x300)
        xmax = 0 (0x0)
        ymax = 0 (0x0)
        global-vmstate = false
        addr = 02.0
        romfile = "vgabios-stdvga.bin"
        rombar = 1 (0x1)
        multifunction = false
        x-pcie-lnksta-dllla = true
        x-pcie-extcap-init = true
        failover_pair_id = ""
        class VGA controller, addr 00:02.0, pci id 1234:1111 (sub 1af4:1100)
        bar 0: mem at 0xfd000000 [0xfdffffff]
        bar 2: mem at 0xfebf0000 [0xfebf0fff]
        bar 6: mem at 0xffffffffffffffff [0xfffe]
      dev: PIIX3, id ""
        addr = 01.0
        romfile = ""
        rombar = 1 (0x1)
        multifunction = true
        x-pcie-lnksta-dllla = true
        x-pcie-extcap-init = true
        failover_pair_id = ""
        class ISA bridge, addr 00:01.0, pci id 8086:7000 (sub 1af4:1100)
        bus: isa.0
          type ISA
          dev: port92, id ""
            gpio-out "a20" 1
          dev: vmmouse, id ""
          dev: vmport, id ""
            x-read-set-eax = true
            x-signal-unsupported-cmd = true
            x-report-vmx-type = true
            x-cmds-v2 = true
            vmware-vmx-version = 6 (0x6)
            vmware-vmx-type = 2 (0x2)
          dev: i8042, id ""
            gpio-out "a20" 1
            isa irqs 1,12
          dev: isa-fdc, id ""
            iobase = 1008 (0x3f0)
            irq = 6 (0x6)
            dma = 2 (0x2)
            driveA = ""
            driveB = ""
            check_media_rate = true
            fdtypeA = "auto"
            fdtypeB = "auto"
            fallback = "288"
            isa irq 6
            bus: floppy-bus.0
              type floppy-bus
              dev: floppy, id ""
                unit = 0 (0x0)
                drive = "floppy0"
                logical_block_size = 512 (512 B)
                physical_block_size = 512 (512 B)
                min_io_size = 0 (0 B)
                opt_io_size = 0 (0 B)
                discard_granularity = 4294967295 (4 GiB)
                write-cache = "auto"
                share-rw = false
                drive-type = "288"
          dev: isa-parallel, id ""
            index = 0 (0x0)
            iobase = 888 (0x378)
            irq = 7 (0x7)
            chardev = "parallel0"
            isa irq 7
          dev: isa-serial, id ""
            index = 0 (0x0)
            iobase = 1016 (0x3f8)
            irq = 4 (0x4)
            chardev = "serial0"
            wakeup = 0 (0x0)
            isa irq 4
          dev: i8257, id ""
            base = 192 (0xc0)
            page-base = 136 (0x88)
            pageh-base = -1 (0xffffffffffffffff)
            dshift = 1 (0x1)
          dev: i8257, id ""
            base = 0 (0x0)
            page-base = 128 (0x80)
            pageh-base = -1 (0xffffffffffffffff)
            dshift = 0 (0x0)
          dev: isa-pcspk, id ""
            audiodev = ""
            iobase = 97 (0x61)
            migrate = true
          dev: isa-pit, id ""
            gpio-in "" 1
            gpio-out "" 1
            iobase = 64 (0x40)
          dev: mc146818rtc, id ""
            gpio-out "" 1
            base_year = 0 (0x0)
            lost_tick_policy = "discard"
          dev: isa-i8259, id ""
            gpio-in "" 8
            gpio-out "" 1
            iobase = 160 (0xa0)
            elcr_addr = 1233 (0x4d1)
            elcr_mask = 222 (0xde)
            master = false
          dev: isa-i8259, id ""
            gpio-in "" 8
            gpio-out "" 1
            iobase = 32 (0x20)
            elcr_addr = 1232 (0x4d0)
            elcr_mask = 248 (0xf8)
            master = true
      dev: i440FX, id ""
        addr = 00.0
        romfile = ""
        rombar = 1 (0x1)
        multifunction = false
        x-pcie-lnksta-dllla = true
        x-pcie-extcap-init = true
        failover_pair_id = ""
        class Host bridge, addr 00:00.0, pci id 8086:1237 (sub 1af4:1100)
  dev: fw_cfg_io, id ""
    dma_enabled = true
    x-file-slots = 32 (0x20)
    acpi-mr-restore = true
  dev: kvmvapic, id ""


If my interpretation is correct, my brute force function shows the i440FX as a device (I thought it was supposed to be a bridge device? The header must be 0x1? Since it is the host bridge (not PCI-PCI or PCI-Cardbus bridge, I'm guessing that the header is of type 0?)
We also have the PIIX3, which is shown as a multifunction PCI device.
We have the qemu VGA device, and the ethernet controller.

* Why aren't the PIIX3-ide device, and the PIIX4_PM shown? Does it look like I have a bug in my brute force function?
* We don't have any PCI to PCI bridges on this system, and this is why all the devices reside on pci bridge 0. Am I correct?
* What is the difference between the i440FX device (8086:1237) and the i440FX-pcihost (this spawns the PCI bus 0?)



This is my pci enumeration code:
Code:
void brute_force_pci()
{
     uint16_t bus;
     uint8_t device;

     for(bus = 0; bus < BUS_PER_DOMAIN; bus++)
    {
         for(device = 0; device < DEVICE_PER_BUS; device++)
       {
          uint32_t val = pci_config_read(bus,device,0,0);
          if (val == (uint32_t)PCI_INV) continue;
          qemu_puts("\r\nBus: ");QEMU_HEX(bus);
          qemu_puts("\tSlot: ");QEMU_HEX(device);

          val = PCI_READ_WORD(bus,device,0,PCI_ENDPT_VENDOR_ID);
          qemu_puts("\tVendor: ");QEMU_HEX(val);
          val = PCI_READ_WORD(bus,device,0,PCI_ENDPT_DEVICE_ID);
          qemu_puts("\tDevice: ");QEMU_HEX(val);

          val = PCI_READ_BYTE(bus,device,0,PCI_ENDPT_CLASS);
          qemu_puts("\tClass: ");QEMU_HEX(val);
          val = PCI_READ_BYTE(bus,device,0,PCI_ENDPT_SUBCLASS);
          qemu_puts("\tSubclass: ");QEMU_HEX(val);

          val = PCI_READ_BYTE(bus,device,0,PCI_ENDPT_HEADER_TYPE);
          qemu_puts("\tHeader: ");QEMU_HEX(val);
         }
     }
}




Edit: I think those devices would be listed as functions of device 0:1.


Top
 Profile  
 
 Post subject: Re: PCI: info qtree v/s brute force enumeration
PostPosted: Mon Oct 19, 2020 3:25 am 
Offline
Member
Member

Joined: Tue Apr 03, 2018 2:44 am
Posts: 401
sunnysideup wrote:
I have written a simple PCI driver (nothing fancy... Just reads and writes to PCI config space and a function for brute force enumeration).

My brute force enumeration gives me this (I do the bus*device loops, and ignore reads which give me all 1s):
Code:
...
Bus: 0x0   Slot: 0x1   Vendor: 0x8086   Device: 0x7000   Class: 0x6   Subclass: 0x1   Header: 0x80
...


I wanted to check the validity of this, and did a `info qtree` on my qemu console.
Code:
...
  dev: i440FX-pcihost, id ""
    pci-hole64-size = 2147483648 (2 GiB)
    short_root_bus = 0 (0x0)
    x-pci-hole64-fix = true
    x-config-reg-migration-enabled = true
    bus: pci.0
      type PCI
      dev: PIIX4_PM, id ""
        smb_io_base = 1792 (0x700)
        disable_s3 = 0 (0x0)
        disable_s4 = 0 (0x0)
        s4_val = 2 (0x2)
        acpi-pci-hotplug-with-bridge-support = true
        memory-hotplug-support = true
        addr = 01.3
        romfile = ""
        rombar = 1 (0x1)
        multifunction = false
        x-pcie-lnksta-dllla = true
        x-pcie-extcap-init = true
        failover_pair_id = ""
        class Bridge, addr 00:01.3, pci id 8086:7113 (sub 1af4:1100)
        bus: i2c
          type i2c-bus
          dev: smbus-eeprom, id ""
            address = 87 (0x57)
          dev: smbus-eeprom, id ""
            address = 86 (0x56)
          dev: smbus-eeprom, id ""
            address = 85 (0x55)
          dev: smbus-eeprom, id ""
            address = 84 (0x54)
          dev: smbus-eeprom, id ""
            address = 83 (0x53)
          dev: smbus-eeprom, id ""
            address = 82 (0x52)
          dev: smbus-eeprom, id ""
            address = 81 (0x51)
          dev: smbus-eeprom, id ""
            address = 80 (0x50)
      dev: piix3-ide, id ""
        addr = 01.1
        romfile = ""
        rombar = 1 (0x1)
        multifunction = false
        x-pcie-lnksta-dllla = true
        x-pcie-extcap-init = true
        failover_pair_id = ""
        class IDE controller, addr 00:01.1, pci id 8086:7010 (sub 1af4:1100)
        bar 4: i/o at 0xc040 [0xc04f]
        bus: ide.1
          type IDE
          dev: ide-cd, id ""
            drive = "ide1-cd0"
            logical_block_size = 512 (512 B)
            physical_block_size = 512 (512 B)
            min_io_size = 0 (0 B)
            opt_io_size = 0 (0 B)
            discard_granularity = 512 (512 B)
            write-cache = "auto"
            share-rw = false
            rerror = "auto"
            werror = "auto"
            ver = "2.5+"
            wwn = 0 (0x0)
            serial = "QM00003"
            model = ""
            unit = 0 (0x0)
        bus: ide.0
          type IDE
...
      dev: PIIX3, id ""
        addr = 01.0
        romfile = ""
        rombar = 1 (0x1)
        multifunction = true
        x-pcie-lnksta-dllla = true
        x-pcie-extcap-init = true
        failover_pair_id = ""
        class ISA bridge, addr 00:01.0, pci id 8086:7000 (sub 1af4:1100)
        bus: isa.0
          type ISA
          dev: port92, id ""
            gpio-out "a20" 1
          dev: vmmouse, id ""
          dev: vmport, id ""
            x-read-set-eax = true
            x-signal-unsupported-cmd = true
            x-report-vmx-type = true
            x-cmds-v2 = true
            vmware-vmx-version = 6 (0x6)
            vmware-vmx-type = 2 (0x2)
          dev: i8042, id ""
            gpio-out "a20" 1
            isa irqs 1,12
          dev: isa-fdc, id ""
            iobase = 1008 (0x3f0)
            irq = 6 (0x6)
            dma = 2 (0x2)
            driveA = ""
            driveB = ""
            check_media_rate = true
            fdtypeA = "auto"
            fdtypeB = "auto"
            fallback = "288"
            isa irq 6
            bus: floppy-bus.0
              type floppy-bus
              dev: floppy, id ""
                unit = 0 (0x0)
                drive = "floppy0"
                logical_block_size = 512 (512 B)
                physical_block_size = 512 (512 B)
                min_io_size = 0 (0 B)
                opt_io_size = 0 (0 B)
                discard_granularity = 4294967295 (4 GiB)
                write-cache = "auto"
                share-rw = false
                drive-type = "288"
          dev: isa-parallel, id ""
            index = 0 (0x0)
            iobase = 888 (0x378)
            irq = 7 (0x7)
            chardev = "parallel0"
            isa irq 7
          dev: isa-serial, id ""
            index = 0 (0x0)
            iobase = 1016 (0x3f8)
            irq = 4 (0x4)
            chardev = "serial0"
            wakeup = 0 (0x0)
            isa irq 4
          dev: i8257, id ""
            base = 192 (0xc0)
            page-base = 136 (0x88)
            pageh-base = -1 (0xffffffffffffffff)
            dshift = 1 (0x1)
          dev: i8257, id ""
            base = 0 (0x0)
            page-base = 128 (0x80)
            pageh-base = -1 (0xffffffffffffffff)
            dshift = 0 (0x0)
          dev: isa-pcspk, id ""
            audiodev = ""
            iobase = 97 (0x61)
            migrate = true
          dev: isa-pit, id ""
            gpio-in "" 1
            gpio-out "" 1
            iobase = 64 (0x40)
          dev: mc146818rtc, id ""
            gpio-out "" 1
            base_year = 0 (0x0)
            lost_tick_policy = "discard"
          dev: isa-i8259, id ""
            gpio-in "" 8
            gpio-out "" 1
            iobase = 160 (0xa0)
            elcr_addr = 1233 (0x4d1)
            elcr_mask = 222 (0xde)
            master = false
          dev: isa-i8259, id ""
            gpio-in "" 8
            gpio-out "" 1
            iobase = 32 (0x20)
            elcr_addr = 1232 (0x4d0)
            elcr_mask = 248 (0xf8)
            master = true
      dev: i440FX, id ""
        addr = 00.0
        romfile = ""
        rombar = 1 (0x1)
        multifunction = false
        x-pcie-lnksta-dllla = true
        x-pcie-extcap-init = true
        failover_pair_id = ""
        class Host bridge, addr 00:00.0, pci id 8086:1237 (sub 1af4:1100)
...


If my interpretation is correct, my brute force function shows the i440FX as a device (I thought it was supposed to be a bridge device? The header must be 0x1? Since it is the host bridge (not PCI-PCI or PCI-Cardbus bridge, I'm guessing that the header is of type 0?)
We also have the PIIX3, which is shown as a multifunction PCI device.
We have the qemu VGA device, and the ethernet controller.

* Why aren't the PIIX3-ide device, and the PIIX4_PM shown? Does it look like I have a bug in my brute force function?


You've missed a level of probing.

Each PCI device may have multiple functions, given by bit 7 of the header being set.

So, the device at PCI 00:01 (8086:7000) is a multi-function device, which includes PIIX3-ide and PIIX4_PM as functions (addresses 00:01.1 and 00:01.3 respectively).
Quote:
* We don't have any PCI to PCI bridges on this system, and this is why all the devices reside on pci bridge 0. Am I correct?


Yes.

Quote:
* What is the difference between the i440FX device (8086:1237) and the i440FX-pcihost (this spawns the PCI bus 0?)


I think the i440FX device is the northbridge, which will contain the root PCI controller as well as the memory controller (these functions tend to be included in the CPU these days), and i440FX-pcihost is the southbridge, which is what provides the PC compatible device personality that connects to the IO devices like the IDE channels and ISA bus peripherals.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Garnek0, SanderR, SemrushBot [Bot] and 56 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group