fix(usb): the xHCI controller is found by class on any bus, sized, taken from the firmware, and 64-byte contexts laid out

boards/BRINGUP.md A1, FABRIC-3 SXL.  It was matched by QEMU's own IDs on
bus 0 alone, so no real board's was found.  Now pci_find_class() reads
every bus/slot/function; pci_bar_size() sizes BAR0; the USB Legacy Support
capability hands the controller over from the BIOS, SMIs off; CSZ=1
contexts are placed 64 bytes apart instead of refused.  XHCI_QEMU_ARGS
lets QEMU place the controller as real hardware does.

Test first: an NEC controller behind a PCIe root port -- no attach before,
Zuse minted after, on all three ISAs.  Standard acceptance unchanged; five
hot-plugged identities attach.  Not rehearsable: firmware handoff, CSZ=1.
Still open: only the first controller found is used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-14 13:30:50 -04:00
co-authored by Claude Opus 5.5
parent 0e2c60dac3
commit 080b7012ba
24 changed files with 72536 additions and 67 deletions
+15
View File
@@ -72,6 +72,15 @@ int pci_init(void *rsdp);
*/
int pci_find_first(uint16_t vendor_id, uint16_t device_id, PciDevice *out);
/*
* pci_find_class — the index-th function (0 = the first) on any bus,
* slot and function whose class code, subclass and programming interface
* match: e.g. 0x0C 0x03 0x30 is an xHCI controller of any vendor.
* Returns 0 and fills *out, or -1 if there are not that many.
*/
int pci_find_class(uint8_t class_code, uint8_t subclass, uint8_t prog_if,
unsigned index, PciDevice *out);
/* Config space accessors */
uint32_t pci_read32 (const PciDevice *d, uint16_t offset);
uint16_t pci_read16 (const PciDevice *d, uint16_t offset);
@@ -93,6 +102,12 @@ void pci_enable(const PciDevice *d);
*/
uint64_t pci_bar(const PciDevice *d, int bar_idx);
/*
* pci_bar_size — the size of memory BAR bar_idx, by the standard sizing
* probe (decoding off meanwhile). 0 for an I/O BAR or none.
*/
uint64_t pci_bar_size(const PciDevice *d, int bar_idx);
/*
* pci_map_bar — make the BAR MMIO region accessible.
* amd64: calls vmm_map_range(phys, phys, size, WR|CD).