Artemis Milestone 2b complete: xHCI PCI discovery and BAR0 mapping
New src/starkernel/usb/ subsystem directory (added to both LOADER_SRCS_BASE and KERNEL_SRCS_BASE wildcards in Makefile.starkernel, matching the existing virtio/*.c pattern). xhci_find_and_map() locates the controller via the already-generic pci_find_first(), enables it, maps BAR0 via the already-generic pci_map_bar(), and fills in all four register-region pointers (cap/op/runtime/doorbell) plus max_slots/ max_ports/max_intrs from HCSPARAMS1 -- ready for controller bring-up (2c) to consume directly. No pci.c extension needed, per 2a's finding that PCI discovery here is ID-based lookup (already generic), not class-code scanning. Verified: clean standalone syntax check, full amd64 kernel build with zero warnings, live boot still reaches POST 1012/0/0 unaffected (nothing calls xhci_find_and_map() yet, so this is purely additive). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
94345c24b7
commit
5970c54912
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* xhci.c — xHCI USB host controller driver for StarKernel: discovery and
|
||||
* register-region mapping (Milestone 2b). Controller bring-up (2c) and
|
||||
* beyond follow in later increments.
|
||||
*
|
||||
* Memory model: BAR0 is mapped identity (virtual address == physical
|
||||
* address), matching virtio_blk.c's precedent and pci_map_bar()'s own
|
||||
* documented behavior (amd64: vmm_map_range(phys, phys, ...); other
|
||||
* arches: no-op, UEFI identity map already covers it).
|
||||
*/
|
||||
|
||||
#ifndef __STARKERNEL__
|
||||
#error "xhci.c is kernel-only"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "starkernel/pci.h"
|
||||
#include "starkernel/xhci.h"
|
||||
#include "starkernel/xhci_driver.h"
|
||||
#include "console.h"
|
||||
|
||||
/* Conservative fixed BAR0 mapping size. xHCI has no self-describing
|
||||
* capability-region length the way virtio PCI capabilities do (that's
|
||||
* virtio_blk.c's approach, not available here) — 64 KiB comfortably
|
||||
* covers Capability + Operational + Port registers + Runtime + Doorbell
|
||||
* Array + typical extended-capability space for QEMU's qemu-xhci and for
|
||||
* real hardware controllers with modest port counts. Revisit if a real
|
||||
* device's actual BAR size (via PCI BAR-sizing probe, not yet
|
||||
* implemented in pci.c) proves this insufficient. */
|
||||
#define XHCI_BAR0_MAP_SIZE 0x10000ull
|
||||
|
||||
int xhci_find_and_map(xhci_dev_t *dev)
|
||||
{
|
||||
if (!dev) return -1;
|
||||
|
||||
if (pci_find_first(XHCI_PCI_VENDOR_ID, XHCI_PCI_DEVICE_ID, &dev->pci) != 0) {
|
||||
console_println("xhci: no controller found on PCI bus 0");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pci_enable(&dev->pci);
|
||||
|
||||
dev->bar0_phys = pci_bar(&dev->pci, 0);
|
||||
if (!dev->bar0_phys) {
|
||||
console_println("xhci: BAR0 read failed (zero or I/O BAR)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pci_map_bar(dev->bar0_phys, XHCI_BAR0_MAP_SIZE) != 0) {
|
||||
console_println("xhci: BAR0 mapping failed");
|
||||
return -2;
|
||||
}
|
||||
|
||||
dev->cap = (xhci_cap_regs_t *)(uintptr_t)dev->bar0_phys;
|
||||
dev->op = (xhci_op_regs_t *)((uint8_t *)dev->cap + dev->cap->cap_length);
|
||||
dev->runtime = (xhci_runtime_regs_t *)((uint8_t *)dev->cap +
|
||||
(dev->cap->rts_off & ~0x1Fu));
|
||||
dev->doorbell = (xhci_doorbell_t *)((uint8_t *)dev->cap +
|
||||
(dev->cap->db_off & ~0x3u));
|
||||
|
||||
uint32_t hcs1 = dev->cap->hcs_params1;
|
||||
dev->max_slots = XHCI_HCSPARAMS1_MAX_SLOTS(hcs1);
|
||||
dev->max_intrs = XHCI_HCSPARAMS1_MAX_INTRS(hcs1);
|
||||
dev->max_ports = XHCI_HCSPARAMS1_MAX_PORTS(hcs1);
|
||||
|
||||
console_println("xhci: controller found, BAR0 mapped");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user