Skip to content

Commit

Permalink
Complete tons of PCI research
Browse files Browse the repository at this point in the history
Also add PCI stub command
  • Loading branch information
stephengrice committed Feb 6, 2023
1 parent 76b0122 commit f37c9a0
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 10 deletions.
Binary file added docs/images/Pasted image 20230205212051.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 36 additions & 10 deletions docs/video_notes/OS20.canvas
Original file line number Diff line number Diff line change
@@ -1,21 +1,47 @@
{
"nodes":[
{"id":"52b3f9da494b2738","x":-871,"y":185,"width":544,"height":60,"type":"text","text":"# PCI/IDE Research"},
{"id":"acf47af792925e35","x":-452,"y":32,"width":250,"height":60,"type":"text","text":"Add basic filesystem"},
{"id":"7c4dcbf9dca210be","x":-310,"y":-78,"width":250,"height":60,"type":"text","text":"Add hard-drive driver"},
{"id":"a12911d6a4106a66","x":-871,"y":-192,"width":392,"height":60,"type":"text","text":"Fixed some VGA issues\nAdded memset, memcpy"},
{"id":"ba67b8f9d9322397","x":-452,"y":-192,"width":250,"height":60,"type":"text","text":"List PCI devices"},
{"id":"f16ba65cb37e47af","x":-871,"y":-248,"width":392,"height":56,"type":"text","text":"## Where We Left Off"},
{"id":"ecf44e240c4480cd","x":-452,"y":-248,"width":392,"height":56,"type":"text","text":"## What's Next"},
{"id":"7982f7e09c54d180","x":-871,"y":-323,"width":811,"height":60,"type":"text","text":"# PKOS 20"},
{"id":"ba67b8f9d9322397","x":-452,"y":-192,"width":250,"height":60,"type":"text","text":"List PCI devices"},
{"id":"52b3f9da494b2738","x":-871,"y":185,"width":544,"height":60,"type":"text","text":"# PCI/IDE Research"},
{"id":"b4fb3aac57491a08","x":-871,"y":316,"width":592,"height":118,"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\""},
{"id":"b1b258c861334506","x":-155,"y":331,"width":487,"height":89,"type":"text","text":"How IDE Controllers Work\nhttps://computer.howstuffworks.com/ide.htm"},
{"id":"a0e74b34b397dd0a","x":-852,"y":523,"width":555,"height":230,"type":"text","text":"https://wiki.osdev.org/PCI\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":"7c4dcbf9dca210be","x":-310,"y":-78,"width":250,"height":60,"type":"text","text":"Add hard-drive driver"},
{"id":"acf47af792925e35","x":-452,"y":32,"width":250,"height":60,"type":"text","text":"Add basic filesystem"}
{"id":"adc43319113b363f","x":-56,"y":1283,"width":450,"height":321,"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":"f96c2ede11284d4e","x":-6,"y":1731,"width":350,"height":144,"type":"text","text":"https://wiki.osdev.org/ACPI\n- Advanced Configuration and Power Interface\n- Stored in BIOS memory"},
{"id":"853cf52b96f0d935","x":1359,"y":1308,"width":601,"height":272,"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":"d21eb2c75e0b1779","x":1433,"y":1698,"width":453,"height":254,"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":"52f154a19269fb43","x":731,"y":1574,"width":298,"height":135,"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":"78b8e18e95ca819c","x":495,"y":1875,"width":771,"height":409,"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":"192fc9f44d1ca21c","x":755,"y":2356,"width":250,"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":"b4fb3aac57491a08","x":-883,"y":334,"width":592,"height":158,"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":"e2961555a6ce7d08","x":-822,"y":1309,"width":470,"height":269,"type":"text","text":"https://stackoverflow.com/questions/50545115/what-is-a-pci-address-space\n- PCI config psace, I/O, MMIO\n- On x86: CPU access PCI MMIO\n- Physical adderss 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":"b1b258c861334506","x":-56,"y":369,"width":487,"height":89,"type":"text","text":"How IDE Controllers Work\nhttps://computer.howstuffworks.com/ide.htm"},
{"id":"a0e74b34b397dd0a","x":-957,"y":585,"width":741,"height":509,"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":"28c841bd9f54358f","x":-859,"y":2659,"width":544,"height":60,"type":"text","text":"# Actionable Takeaways"},
{"id":"1c3817b1bf310e66","x":-1361,"y":806,"width":301,"height":68,"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":"6da0400b5d068ccf","x":-1610,"y":245,"width":400,"height":400,"type":"file","file":"images/Pasted image 20230205212051.png"},
{"id":"774fee607e518e9f","x":-2139,"y":709,"width":308,"height":263,"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":"df6e695a9b9ca658","x":-859,"y":2748,"width":685,"height":487,"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"}
],
"edges":[
{"id":"e7048ab42e1c68cc","fromNode":"b4fb3aac57491a08","fromSide":"right","toNode":"b1b258c861334506","toSide":"left"},
{"id":"86178168afbb911b","fromNode":"b4fb3aac57491a08","fromSide":"bottom","toNode":"a0e74b34b397dd0a","toSide":"top"},
{"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":"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"}
]
}
2 changes: 2 additions & 0 deletions src/kernel/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ void handle_keyboard_interrupt() {
vga_enter();
} else if (streq(command_buffer, "vgainfo")) {
vga_info();
} else if (streq(command_buffer, "lspci")) {
lspci();
} else if (streq(command_buffer, "help")) {
println("ls: List files");
println("clear: Clear screen");
Expand Down
4 changes: 4 additions & 0 deletions src/pci/pci.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

void lspci() {
println("hello pci");
}
6 changes: 6 additions & 0 deletions src/pci/pci.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef __PCI_H
#define __PCI_H

void lspci();

#endif

0 comments on commit f37c9a0

Please sign in to comment.