{ "nodes":[ {"type":"text","text":"MVP: Read byte 0 of config at bus 0, device 0, func 0, offset 0\n- OUT on port 0xCF8, value:\n\t- 31: enable\n\t- 30-24: reserved\n\t- 23-16: bus\n\t- 15-11: device\n\t- 10-8: function\n\t- 7-0: offset\n- IN on port 0xCFC, value:\n\t- 31-16: Device ID\n\t- 15-0: Vendor ID\n- Examine value\n- Compare to `info qtree` to see if it matches\n\t- `class Host bridge, addr 00:00.0, pci id 8086:1237 (sub 1af4:1100)`\n- Boot Linux guest on qemu-system-i386, check PCI [via this](https://stackoverflow.com/questions/59010671/how-to-get-vendor-id-and-device-id-of-all-pci-devices)\n\t- Print vendor id for 0:0.0\n- Refactor, check more fields","id":"df6e695a9b9ca658","x":-859,"y":2748,"width":685,"height":487}, {"type":"text","text":"# Actionable Takeaways","id":"28c841bd9f54358f","x":-859,"y":2659,"width":544,"height":60}, {"type":"text","text":"Result: It's 0!\nProblem: Need ioport_in_long (32-bit version)","id":"4be572a12a1360b8","x":-859,"y":3256,"width":418,"height":60}, {"type":"text","text":"Notable:\n- `piix3-ide` has i/o at port `0xc040` (`0xc04f`)\n- VGA, ethernet also on the PCI bus","id":"192fc9f44d1ca21c","x":688,"y":2356,"width":384,"height":147}, {"type":"text","text":"```\n(qemu) info qtree\nbus: main-system-bus\n type System\n dev: hpet, id \"\"\n gpio-in \"\" 2\n gpio-out \"\" 1\n gpio-out \"sysbus-irq\" 32\n timers = 3 (0x3)\n msi = false\n hpet-intcap = 4 (0x4)\n hpet-offset-saved = true\n mmio 00000000fed00000/0000000000000400\n dev: ioapic, id \"\"\n gpio-in \"\" 24\n version = 32 (0x20)\n mmio 00000000fec00000/0000000000001000\n dev: i440FX-pcihost, id \"\"\n pci-hole64-size = 2147483648 (2 GiB)\n short_root_bus = 0 (0x0)\n x-pci-hole64-fix = true\n bus: pci.0\n type PCI\n dev: PIIX4_PM, id \"\"\n smb_io_base = 1792 (0x700)\n disable_s3 = 0 (0x0)\n disable_s4 = 0 (0x0)\n s4_val = 2 (0x2)\n acpi-pci-hotplug-with-bridge-support = true\n memory-hotplug-support = true\n addr = 01.3\n romfile = \"\"\n rombar = 1 (0x1)\n multifunction = false\n command_serr_enable = true\n x-pcie-lnksta-dllla = true\n x-pcie-extcap-init = true\n failover_pair_id = \"\"\n class Bridge, addr 00:01.3, pci id 8086:7113 (sub 1af4:1100)\n bus: i2c\n type i2c-bus\n dev: smbus-eeprom, id \"\"\n address = 87 (0x57)\n dev: smbus-eeprom, id \"\"\n address = 86 (0x56)\n dev: smbus-eeprom, id \"\"\n address = 85 (0x55)\n dev: smbus-eeprom, id \"\"\n address = 84 (0x54)\n dev: smbus-eeprom, id \"\"\n address = 83 (0x53)\n dev: smbus-eeprom, id \"\"\n address = 82 (0x52)\n dev: smbus-eeprom, id \"\"\n address = 81 (0x51)\n dev: smbus-eeprom, id \"\"\n address = 80 (0x50)\n dev: piix3-ide, id \"\"\n addr = 01.1\n romfile = \"\"\n rombar = 1 (0x1)\n multifunction = false\n command_serr_enable = true\n x-pcie-lnksta-dllla = true\n x-pcie-extcap-init = true\n failover_pair_id = \"\"\n class IDE controller, addr 00:01.1, pci id 8086:7010 (sub 1af4:1100)\n bar 4: i/o at 0xc040 [0xc04f]\n bus: ide.1\n type IDE\n dev: ide-cd, id \"\"\n drive = \"ide1-cd0\"\n logical_block_size = 512 (0x200)\n physical_block_size = 512 (0x200)\n min_io_size = 0 (0x0)\n opt_io_size = 0 (0x0)\n discard_granularity = 512 (0x200)\n write-cache = \"auto\"\n share-rw = false\n rerror = \"auto\"\n werror = \"auto\"\n ver = \"2.5+\"\n wwn = 0 (0x0)\n serial = \"QM00003\"\n model = \"\"\n unit = 0 (0x0)\n bus: ide.0\n type IDE\n dev: e1000, id \"\"\n mac = \"52:54:00:12:34:56\"\n netdev = \"hub0port0\"\n autonegotiation = true\n mitigation = true\n extra_mac_registers = true\n migrate_tso_props = true\n addr = 03.0\n romfile = \"efi-e1000.rom\"\n rombar = 1 (0x1)\n multifunction = false\n command_serr_enable = true\n x-pcie-lnksta-dllla = true\n x-pcie-extcap-init = true\n failover_pair_id = \"\"\n class Ethernet controller, addr 00:03.0, pci id 8086:100e (sub 1af4:1100)\n bar 0: mem at 0xfeb80000 [0xfeb9ffff]\n bar 1: i/o at 0xc000 [0xc03f]\n bar 6: mem at 0xffffffffffffffff [0x7fffe]\n dev: VGA, id \"\"\n vgamem_mb = 16 (0x10)\n mmio = true\n qemu-extended-regs = true\n edid = false\n xres = 0 (0x0)\n yres = 0 (0x0)\n xmax = 0 (0x0)\n ymax = 0 (0x0)\n global-vmstate = false\n addr = 02.0\n romfile = \"vgabios-stdvga.bin\"\n rombar = 1 (0x1)\n multifunction = false\n command_serr_enable = true\n x-pcie-lnksta-dllla = true\n x-pcie-extcap-init = true\n failover_pair_id = \"\"\n class VGA controller, addr 00:02.0, pci id 1234:1111 (sub 1af4:1100)\n bar 0: mem at 0xfd000000 [0xfdffffff]\n bar 2: mem at 0xfebb0000 [0xfebb0fff]\n bar 6: mem at 0xffffffffffffffff [0xfffe]\n dev: PIIX3, id \"\"\n addr = 01.0\n romfile = \"\"\n rombar = 1 (0x1)\n multifunction = true\n command_serr_enable = true\n x-pcie-lnksta-dllla = true\n x-pcie-extcap-init = true\n failover_pair_id = \"\"\n class ISA bridge, addr 00:01.0, pci id 8086:7000 (sub 1af4:1100)\n bus: isa.0\n type ISA\n dev: port92, id \"\"\n gpio-out \"a20\" 1\n dev: vmmouse, id \"\"\n dev: vmport, id \"\"\n dev: i8042, id \"\"\n gpio-out \"a20\" 1\n isa irqs 1,12\n dev: isa-fdc, id \"\"\n iobase = 1008 (0x3f0)\n irq = 6 (0x6)\n dma = 2 (0x2)\n driveA = \"\"\n driveB = \"\"\n check_media_rate = true\n fdtypeA = \"auto\"\n fdtypeB = \"auto\"\n fallback = \"288\"\n isa irq 6\n bus: floppy-bus.0\n type floppy-bus\n dev: floppy, id \"\"\n unit = 0 (0x0)\n drive = \"floppy0\"\n logical_block_size = 512 (0x200)\n physical_block_size = 512 (0x200)\n min_io_size = 0 (0x0)\n opt_io_size = 0 (0x0)\n discard_granularity = 4294967295 (0xffffffff)\n write-cache = \"auto\"\n share-rw = false\n drive-type = \"288\"\n dev: isa-parallel, id \"\"\n index = 0 (0x0)\n iobase = 888 (0x378)\n irq = 7 (0x7)\n chardev = \"parallel0\"\n isa irq 7\n dev: isa-serial, id \"\"\n index = 0 (0x0)\n iobase = 1016 (0x3f8)\n irq = 4 (0x4)\n chardev = \"serial0\"\n wakeup = 0 (0x0)\n isa irq 4\n dev: i8257, id \"\"\n base = 192 (0xc0)\n page-base = 136 (0x88)\n pageh-base = -1 (0xffffffffffffffff)\n dshift = 1 (0x1)\n dev: i8257, id \"\"\n base = 0 (0x0)\n page-base = 128 (0x80)\n pageh-base = -1 (0xffffffffffffffff)\n dshift = 0 (0x0)\n dev: isa-pcspk, id \"\"\n audiodev = \"\"\n iobase = 97 (0x61)\n migrate = true\n dev: isa-pit, id \"\"\n gpio-in \"\" 1\n gpio-out \"\" 1\n iobase = 64 (0x40)\n dev: mc146818rtc, id \"\"\n gpio-out \"\" 1\n base_year = 0 (0x0)\n lost_tick_policy = \"discard\"\n dev: isa-i8259, id \"\"\n gpio-in \"\" 8\n gpio-out \"\" 1\n iobase = 160 (0xa0)\n elcr_addr = 1233 (0x4d1)\n elcr_mask = 222 (0xde)\n master = false\n dev: isa-i8259, id \"\"\n gpio-in \"\" 8\n gpio-out \"\" 1\n iobase = 32 (0x20)\n elcr_addr = 1232 (0x4d0)\n elcr_mask = 248 (0xf8)\n master = true\n dev: i440FX, id \"\"\n addr = 00.0\n romfile = \"\"\n rombar = 1 (0x1)\n multifunction = false\n command_serr_enable = true\n x-pcie-lnksta-dllla = true\n x-pcie-extcap-init = true\n failover_pair_id = \"\"\n class Host bridge, addr 00:00.0, pci id 8086:1237 (sub 1af4:1100)\n dev: fw_cfg_io, id \"\"\n dma_enabled = true\n x-file-slots = 32 (0x20)\n dev: kvmvapic, id \"\"\n(qemu) \n```","id":"78b8e18e95ca819c","x":495,"y":1875,"width":771,"height":409}, {"type":"text","text":"https://wiki.osdev.org/ACPI\n- Advanced Configuration and Power Interface\n- Stored in BIOS memory","id":"f96c2ede11284d4e","x":-6,"y":1731,"width":350,"height":144}, {"type":"text","text":"[their OS code](https://github.com/gfoudree/cryptos/blob/b90dd6832accc438a0d71aa4e954e50fcf507f13/src/pci.c#L7)\n- Wow!\n- Bus 0 to 255\n- Bus device 0 to 31\n- Function 0 to 7\n\nBut **how can we assume address `0x80000000` is the start of PCI address space?**","id":"d21eb2c75e0b1779","x":1433,"y":1698,"width":453,"height":254}, {"type":"text","text":"[Get all devices qemu](https://serverfault.com/questions/587189/how-to-list-all-devices-emulated-in-a-qemu-virtual-machine)\n`info qtree` to list all qemu devices including PCI","id":"52f154a19269fb43","x":731,"y":1574,"width":298,"height":135}, {"type":"text","text":"[General Discussion about What is PCI](https://forum.osdev.org/viewtopic.php?f=1&t=36972)\n- PCI bus has special device to control it\n- PCI is standardized way to query peripheral config, route IRQs\n- PCI memory linked to device, each address has special meaning (NOT same as RAM)\n- How to access address space\n\t- Old PCI: IN/OUT instructions\n\t- PCIe: MMIO, like VGA\n\t\t- Extended config space reported in an ACPI table","id":"adc43319113b363f","x":-56,"y":1283,"width":450,"height":321}, {"type":"text","text":"[Advanced QEMU Debugging: PCI Read/Write](https://x86sec.com/posts/2020/10/14/advanced-qemu-debugging/)\nOkay, this is a very useful example:\n```C\n#define PCI_CONFIG_ADDR_PORT 0xCF8\n#define PCI_CONFIG_DATA_PORT 0xCFC\n```\nBut what's going on with this addr calc?\n```C\nuint32_t addr = (uint32_t)0x80000000 | (uint32_t)(bus << 16) \n | (device << 11) | (function << 8) | reg;\n```","id":"853cf52b96f0d935","x":1359,"y":1308,"width":601,"height":272}, {"type":"text","text":"https://stackoverflow.com/questions/50545115/what-is-a-pci-address-space\n- PCI config space, I/O, MMIO\n- On x86: CPU access PCI MMIO\n- Physical address programmed into BAR (BAR?)\n- In software:\n\t- Write config space register to I/O `0x0CF8`\n\t- Read/write I/O port `0x0CFC`\n\t- OR use platform-specific address","id":"e2961555a6ce7d08","x":-822,"y":1309,"width":470,"height":295}, {"type":"text","text":"[Wikipedia: PCI Bus Enumeration](https://en.wikipedia.org/wiki/PCI_configuration_space#Bus_enumeration)\n- ok\n\n[Software implementation](https://en.wikipedia.org/wiki/PCI_configuration_space#Software_implementation)\n- Legacy method: Reach the first 256 bytes of device address space via two 32-bit (!) registers\n- Addressing a device geographically = using Bus/Device/Function","id":"1c3817b1bf310e66","x":-1361,"y":806,"width":301,"height":68}, {"type":"text","text":"[linux/arch/x86/pci/early.c](https://github.com/torvalds/linux/blob/master/arch/x86/pci/early.c)\nsimple methods for reading/writing PCI config\nargs:\n- bus\n- slot\n- func\n- offset","id":"774fee607e518e9f","x":-2139,"y":709,"width":308,"height":263}, {"type":"text","text":"Side note: LOTS of good stuff in here:\n- IDE (storage)\n- e1000 (ethernet)\n- Serial\n- VGA\n- Multimedia (audio/video)\n- etc","id":"84d1059e4db9ddec","x":-123,"y":585,"width":350,"height":238}, {"type":"file","file":"images/Pasted image 20230205212051.png","id":"6da0400b5d068ccf","x":-1610,"y":245,"width":400,"height":369}, {"type":"text","text":"# PCI/IDE Research","id":"52b3f9da494b2738","x":-871,"y":185,"width":544,"height":60}, {"type":"text","text":"qemu-system-i386 docs\nhttp://www.tin.org/bin/man.cgi?section=1&topic=qemu-system-i386\n- \"2 **PCI IDE** interfaces with hard disk and CD-ROM support\"\n- (no mention of PCIe... so it's the old PCI?)","id":"b4fb3aac57491a08","x":-883,"y":334,"width":592,"height":158}, {"type":"text","text":"How IDE Controllers Work\nhttps://computer.howstuffworks.com/ide.htm","id":"b1b258c861334506","x":-56,"y":369,"width":487,"height":89}, {"type":"text","text":"Add basic filesystem","id":"acf47af792925e35","x":-452,"y":32,"width":250,"height":60}, {"type":"text","text":"Add hard-drive driver","id":"7c4dcbf9dca210be","x":-310,"y":-78,"width":250,"height":60}, {"type":"text","text":"Fixed some VGA issues\nAdded memset, memcpy","id":"a12911d6a4106a66","x":-871,"y":-192,"width":392,"height":60}, {"type":"text","text":"List PCI devices","id":"ba67b8f9d9322397","x":-452,"y":-192,"width":250,"height":60}, {"type":"text","text":"## Where We Left Off","id":"f16ba65cb37e47af","x":-871,"y":-248,"width":392,"height":56}, {"type":"text","text":"## What's Next","id":"ecf44e240c4480cd","x":-452,"y":-248,"width":392,"height":56}, {"type":"text","text":"# PKOS 20","id":"7982f7e09c54d180","x":-871,"y":-323,"width":811,"height":60}, {"type":"text","text":"https://wiki.osdev.org/PCI\n- Totally SW driven initialization\n- CPU has no PCI addr space access mechanism - use PCI Bridge (Host Bridge) for this\n- Config Space Access\n\t- `CONFIG_ADDRESS=0xCF8`: this is a 32-bit register. Bit mapping:\n\t\t- 31: enable\n\t\t- 30-24: reserved\n\t\t- 23-16: bus\n\t\t- 15-11: device\n\t\t- 10-8: function\n\t\t- 7-0: offset\n\t- `CONFIG_DATA=0xCFC`: 16-bit fields (??)\n- 3 ways to enumerate PCI\n\t- Brute force\n\t- Recursion - let firmware set it up\n\t- Recursion - DIY bus setup\n- For all three: Need a `checkDevice` method","id":"a0e74b34b397dd0a","x":-958,"y":585,"width":741,"height":509}, {"type":"text","text":"# Coding Notes","id":"ba7ac374df39d833","x":-783,"y":3380,"width":402,"height":68}, {"type":"text","text":"Data type sizes for C\nhttps://www.ibm.com/docs/en/ibm-mq/8.0?topic=platforms-standard-data-types","id":"978e39a1c31d5616","x":-783,"y":3469,"width":698,"height":87} ], "edges":[ {"id":"e7048ab42e1c68cc","fromNode":"b4fb3aac57491a08","fromSide":"right","toNode":"b1b258c861334506","toSide":"left","label":"IDE?"}, {"id":"86178168afbb911b","fromNode":"b4fb3aac57491a08","fromSide":"bottom","toNode":"a0e74b34b397dd0a","toSide":"top","label":"how do we use PCI?"}, {"id":"857f9464358330c4","fromNode":"ba67b8f9d9322397","fromSide":"bottom","toNode":"7c4dcbf9dca210be","toSide":"top"}, {"id":"942713b2f79e49d9","fromNode":"7c4dcbf9dca210be","fromSide":"bottom","toNode":"acf47af792925e35","toSide":"top"}, {"id":"2720e16c0875de3d","fromNode":"a0e74b34b397dd0a","fromSide":"bottom","toNode":"e2961555a6ce7d08","toSide":"top","label":"so where is the address space?"}, {"id":"3113543da6369fb4","fromNode":"adc43319113b363f","fromSide":"top","toNode":"a0e74b34b397dd0a","toSide":"right","label":"(links back to this article again)"}, {"id":"abd73d7c28e19cbe","fromNode":"e2961555a6ce7d08","fromSide":"right","toNode":"adc43319113b363f","toSide":"left"}, {"id":"4d6fe37ee1d13af2","fromNode":"adc43319113b363f","fromSide":"bottom","toNode":"f96c2ede11284d4e","toSide":"top","label":"an ACPI table??"}, {"id":"ab97c64978b401c5","fromNode":"adc43319113b363f","fromSide":"right","toNode":"853cf52b96f0d935","toSide":"left","label":"How do we know we're doing anything?"}, {"id":"008b391e5b753f06","fromNode":"853cf52b96f0d935","fromSide":"bottom","toNode":"d21eb2c75e0b1779","toSide":"top","label":"\"my OS Code\"? ooh"}, {"id":"54c723711322009c","fromNode":"adc43319113b363f","fromSide":"right","toNode":"52f154a19269fb43","toSide":"top"}, {"id":"3a076e13f86c8115","fromNode":"52f154a19269fb43","fromSide":"bottom","toNode":"78b8e18e95ca819c","toSide":"top","label":"run `info qtree` on PKOS"}, {"id":"274146fc6f382896","fromNode":"78b8e18e95ca819c","fromSide":"bottom","toNode":"192fc9f44d1ca21c","toSide":"top"}, {"id":"73910a597bd43865","fromNode":"a0e74b34b397dd0a","fromSide":"left","toNode":"1c3817b1bf310e66","toSide":"right"}, {"id":"774efa6679edbf88","fromNode":"1c3817b1bf310e66","fromSide":"left","toNode":"774fee607e518e9f","toSide":"right","label":"see linux kernel for example of addressing geographically"}, {"id":"45252cd69cdf1ed0","fromNode":"1c3817b1bf310e66","fromSide":"top","toNode":"6da0400b5d068ccf","toSide":"bottom","label":"config space"}, {"id":"164f9721bcce2fe0","fromNode":"774fee607e518e9f","fromSide":"top","toNode":"6da0400b5d068ccf","toSide":"left","label":"offset field must be the offset into this"} ] }