commit eabbd81c2041c1d54cb02608d9c375fe9c2dddfb from: Onana Onana Xavier Manuel date: Mon Sep 21 18:54:03 2026 UTC xhci dev : initialized DCBAAP and CRCR commit - 5baff2808906de6d7d3ed0b3b370e5e15d3b00c7 commit + eabbd81c2041c1d54cb02608d9c375fe9c2dddfb blob - 9f7cca2cfb0beb306bec088eec4730a5351ef79c blob + 2f949657ef99bc433c7f48b6254a4452c483ad88 --- servers/xhci/main.c +++ servers/xhci/main.c @@ -1,13 +1,32 @@ -// The xHCI driver possess a number of slots for each devices -// it can handle. The slot maximum can be changed at compile -// time by the end user. +// The xHCI driver is for one controller. Everytime a new +// device is added, a new instance is launched. -// There is 1 command ring per xhci controller - #include "types.h" #include "libc.h" #include "xhci.h" +#define TRB_COUNT 16 + +struct trb { + u32 Parameter_Lo; + u32 Parameter_Hi; + u32 Status; + u32 Control; // Includes TRB Type, ENT and C Flags +}; + +struct opt_reg { + u32 USBCMD; + u32 USBSTS; + u32 PAGESIZE; + u32 RsvdZ1[2]; + u32 DNCTRL; + u64 CRCR; + u32 RsvdZ2[4]; + u64 DCBAAP; + u32 CONFIG; + u32 RsvdZ3[241]; // 0x3C to 0x3FF 964 bytes +}; + struct xhci_ctl { u8 CAPLENGTH; u16 HCIVERSION; @@ -57,6 +76,11 @@ struct xhci_ctl { u8 GSC; u8 VTC; } HCCPARAMS2; + + struct opt_reg *OPTREG; + u64 *DeviceContexes; // Limit defined by HCSPARAMS1.MaxSlots + + struct trb *CommandRing; }; void setup_ctl(struct xhci_ctl *, u64); @@ -64,6 +88,7 @@ void setup_ctl(struct xhci_ctl *, u64); void xhci_main(struct contract *con) { + u8 *memptr = con->memBlock; // This is used as starting point for allocation struct shared_buffer *sbuf; struct xhci_ctl ctl; struct xhcip *xhcip; @@ -83,6 +108,25 @@ xhci_main(struct contract *con) output("xhci: bar address is "); outputh(xhcip->address); output("\n"); setup_ctl(&ctl, xhcip->address); + // Initialize controller + while ((ctl.OPTREG->USBSTS >> 11) & 0x1); + + // You can't do that while controller is running R/S = 1 or + // if the MaxSlots is 0 which is rare + ctl.OPTREG->CONFIG &= ~(0xff); + ctl.OPTREG->CONFIG |= ctl.HCSPARAMS1.MaxSlots; + + // are we allocating? + ctl.DeviceContexes = (u64 *)(memptr); + memptr += ((ctl.HCSPARAMS1.MaxSlots + 1) * 8); + ctl.OPTREG->DCBAAP = (u64)ctl.DeviceContexes; // The lower 6 bits are zero'd since alligned + + // again + memptr = (u8 *)(((u64)memptr + 63) & ~63); // 64 bytes alligned + ctl.CommandRing = (struct trb *)memptr; + memptr += (sizeof(struct trb) * TRB_COUNT); + ctl.OPTREG->CRCR = ((u64)ctl.CommandRing) | 1; + for (;;); } @@ -136,6 +180,8 @@ setup_ctl(struct xhci_ctl *ctl, u64 bar) ctl->HCCPARAMS2.GSC = (base[7] >> 8) & 0x1; ctl->HCCPARAMS2.VTC = (base[7] >> 9) & 0x1; + ctl->OPTREG = (struct opt_reg *)(bar + ctl->CAPLENGTH); + output("xhci setup: version "); outputh(ctl->HCIVERSION); output("\n");