From 239dfc6d2989469826f7211d02069df0351f68b9 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sat, 11 Oct 2025 21:33:40 -0400 Subject: kern: xhci: Initialize the DCBAAP register on init Signed-off-by: Ian Moffett --- src/sys/include/io/usb/xhcivar.h | 5 +++++ src/sys/io/usb/hcd/xhci.c | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/sys/include/io/usb/xhcivar.h b/src/sys/include/io/usb/xhcivar.h index bc5f59b..f98207f 100644 --- a/src/sys/include/io/usb/xhcivar.h +++ b/src/sys/include/io/usb/xhcivar.h @@ -40,14 +40,19 @@ * @max_slots: Max device slots * @max_intrs: Max interrupters * @max_ports: Max ports + * @dcbaap_pa: DCBAAP physical address */ struct xhci_hcd { struct xhci_capregs *capspace; uint8_t max_slots; uint32_t max_intrs; uint32_t max_ports; + uintptr_t dcbaap_pa; }; #define XHCI_TIMEOUT_MSEC 500 +/* Length of device context */ +#define XHCI_CTX_SIZE 32 + #endif /* !_USB_XHCIVAR_H_ */ diff --git a/src/sys/io/usb/hcd/xhci.c b/src/sys/io/usb/hcd/xhci.c index 0582aaa..296e172 100644 --- a/src/sys/io/usb/hcd/xhci.c +++ b/src/sys/io/usb/hcd/xhci.c @@ -39,6 +39,9 @@ #include #include #include +#include +#include +#include #define pr_trace(fmt, ...) printf("xhci: " fmt, ##__VA_ARGS__) #if defined(XHCI_DEBUG) @@ -131,6 +134,34 @@ xhci_reset_hc(struct xhci_hcd *hcd) return 0; } +/* + * Initialize the device context base address + * array pointer register + */ +static int +xhci_init_dcbaap(struct xhci_hcd *hcd) +{ + struct xhci_opregs *opregs; + uint32_t npages; + void *va; + + npages = BYTES_TO_PAGES(hcd->max_slots * XHCI_CTX_SIZE); + hcd->dcbaap_pa = vm_alloc_frame(npages); + if (hcd->dcbaap_pa == 0) { + pr_trace("failed to allocate dcbaap\n"); + return -ENOMEM; + } + + /* Ensure it is zeroed */ + va = PHYS_TO_VIRT(hcd->dcbaap_pa); + memset(va, 0, npages * DEFAULT_PAGESIZE); + + /* Give it to the controller, fetch! */ + opregs = XHCI_OPBASE(hcd->capspace); + mmio_write32(&opregs->dcbaa_ptr, hcd->dcbaap_pa); + return 0; +} + /* * Initialize the host controller */ @@ -139,7 +170,9 @@ xhci_init_hc(struct xhci_hcd *hcd) { struct xhci_opregs *opregs; struct xhci_capregs *capspace; + paddr_t pa; uint32_t usbcmd, hcsparams1; + uint32_t config; int error; if (hcd == NULL) { @@ -160,6 +193,15 @@ xhci_init_hc(struct xhci_hcd *hcd) hcd->max_slots = HCSPARAMS1_MAXSLOTS(hcsparams1); hcd->max_intrs = HCSPARAMS1_MAXINTRS(hcsparams1); hcd->max_ports = HCSPARAMS1_MAXPORTS(hcsparams1); + + /* Enable all the slots */ + config = mmio_read32(&opregs->config); + config |= hcd->max_slots; + mmio_write32(&opregs->config, config); + + if ((error = xhci_init_dcbaap(hcd)) < 0) { + return error; + } return 0; } -- cgit v1.2.3