commit - 5baff2808906de6d7d3ed0b3b370e5e15d3b00c7
commit + eabbd81c2041c1d54cb02608d9c375fe9c2dddfb
blob - 9f7cca2cfb0beb306bec088eec4730a5351ef79c
blob + 2f949657ef99bc433c7f48b6254a4452c483ad88
--- servers/xhci/main.c
+++ servers/xhci/main.c
-// 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;
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);
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;
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 (;;);
}
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");