diff options
author | Ian Moffett <ian@osmora.org> | 2025-10-11 21:33:40 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-10-11 21:34:17 -0400 |
commit | 239dfc6d2989469826f7211d02069df0351f68b9 (patch) | |
tree | 4ba4d14e0182de3083293c6cb1b402b685b5755b /src | |
parent | ce379e9444670e88b807b5e260e1623be1304227 (diff) |
kern: xhci: Initialize the DCBAAP register on init
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/sys/include/io/usb/xhcivar.h | 5 | ||||
-rw-r--r-- | src/sys/io/usb/hcd/xhci.c | 42 |
2 files changed, 47 insertions, 0 deletions
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 <io/pci/bar.h> #include <io/pci/pci.h> #include <os/module.h> +#include <vm/vm.h> +#include <vm/physseg.h> +#include <string.h> #define pr_trace(fmt, ...) printf("xhci: " fmt, ##__VA_ARGS__) #if defined(XHCI_DEBUG) @@ -132,6 +135,34 @@ xhci_reset_hc(struct xhci_hcd *hcd) } /* + * 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 */ static int @@ -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; } |