summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-10-11 21:33:40 -0400
committerIan Moffett <ian@osmora.org>2025-10-11 21:34:17 -0400
commit239dfc6d2989469826f7211d02069df0351f68b9 (patch)
tree4ba4d14e0182de3083293c6cb1b402b685b5755b /src
parentce379e9444670e88b807b5e260e1623be1304227 (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.h5
-rw-r--r--src/sys/io/usb/hcd/xhci.c42
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;
}