Commit Diff


commit - 1dd2ad1cb1faf08ee89679b10912ddcc52542e09
commit + 2144824138456be824e120b8c4daf1a86461a02e
blob - 2f949657ef99bc433c7f48b6254a4452c483ad88
blob + 6539292f8d8c5720939723dbd98bfbc7b577cce4
--- servers/xhci/main.c
+++ servers/xhci/main.c
@@ -7,6 +7,12 @@
 
 #define TRB_COUNT	16
 
+struct erst_entry {
+	u64 Ring_Segment_Base_Address;
+	u32 Ring_Segment_Size;
+	u32 RsvdZ;
+};
+
 struct trb {
 	u32 Parameter_Lo;
 	u32 Parameter_Hi;
@@ -27,6 +33,29 @@ struct opt_reg {
 	u32 RsvdZ3[241]; // 0x3C to 0x3FF 964 bytes
 };
 
+struct int_reg {
+	u32 IMAN;
+	u32 IMOD;
+	u32 ERSTSZ;
+	u32 RsvdZ;
+	u64 ERSTBA;
+	u64 ERDP;
+};
+
+struct run_reg {
+	u32 MFINDEX; // Lower 14 bits are actual MFINDEX, upper are RsvdZ
+	u32 RsvdZ[7]; // 0x04 to 0x1F
+	struct int_reg IRS[];
+};
+
+struct msix_cfg {
+	u8 CAP_ID;
+	u8 NXT_PTR;
+	u16 MSIX_Message_Control;
+	u32 Table_Offset;
+	u32 PBA_Offset;
+};
+
 struct xhci_ctl {
 	u8 CAPLENGTH;
 	u16 HCIVERSION;
@@ -81,6 +110,11 @@ struct xhci_ctl {
 	u64 *DeviceContexes; // Limit defined by HCSPARAMS1.MaxSlots
 
 	struct trb *CommandRing;
+	struct trb *EventRing;
+
+	struct run_reg *RuntimeRegisters;
+	struct erst_entry *ERST;
+	struct msix_cfg *MSIXConfigurationCapability;
 };
 
 void setup_ctl(struct xhci_ctl *, u64);
@@ -108,6 +142,8 @@ xhci_main(struct contract *con)
 	output("xhci: bar address is "); outputh(xhcip->address); output("\n");
 	setup_ctl(&ctl, xhcip->address);
 
+	ctl.RuntimeRegisters = (struct run_reg *)(xhcip->address + ctl.RTSOFF);
+
 	// Initialize controller
 	while ((ctl.OPTREG->USBSTS >> 11) & 0x1);
 
@@ -127,6 +163,27 @@ xhci_main(struct contract *con)
 	memptr += (sizeof(struct trb) * TRB_COUNT);
 	ctl.OPTREG->CRCR = ((u64)ctl.CommandRing) | 1;
 
+	// Allocate EventRing
+	memptr = (u8 *)(((u64)memptr + 63) & ~63); // 64 bytes alligned
+	ctl.EventRing = (struct trb *)memptr;
+	memptr += (sizeof(struct trb) * TRB_COUNT);
+
+	// allocate ERST
+	memptr = (u8 *)(((u64)memptr + 63) & ~63); // 64 bytes alligned
+	ctl.ERST = (struct erst_entry *)memptr;
+	memptr += sizeof(struct erst_entry);
+
+	// Populate entry
+	ctl.ERST[0].Ring_Segment_Base_Address = (u64)ctl.EventRing;
+	ctl.ERST[0].Ring_Segment_Size = TRB_COUNT;
+
+	// Configure IRS 0
+	ctl.RuntimeRegisters->IRS[0].ERSTSZ = 1;
+	ctl.RuntimeRegisters->IRS[0].ERSTBA = (u64)ctl.ERST;
+	ctl.RuntimeRegisters->IRS[0].ERDP = (u64)ctl.EventRing | 1;
+
+	// Getting MSI-X Config
+
 	for (;;);
 }