Commit Diff


commit - eabbd81c2041c1d54cb02608d9c375fe9c2dddfb
commit + 1dd2ad1cb1faf08ee89679b10912ddcc52542e09
blob - 64c57c6a92c04bd599dabb45c4b1a56b67f17af3
blob + cd7495ffd2707a5913be0018adef06e10661a76e
--- alpha/pci.c
+++ alpha/pci.c
@@ -159,6 +159,7 @@ pci_get_xhci()
 	u8 class;
 	u8 progif;
 	u16 vendor;
+	u16 status;
 	u8 subclass;
 	u16 command;
 	u32 bars[6];
@@ -172,6 +173,7 @@ pci_get_xhci()
 			for (u16 func = 0; func < 8; func++) {
 				if ((vendor = pciCheckVendor((u8)bus, (u8)device, func)) != 0xffff) {
 					hdr = (pciConfigReadWord(bus, device, func, 0x0E)) & 0xFF;
+					status = (pciConfigReadWord(bus, device, func, 0x06));
 					class = (pciConfigReadWord(bus, device, func, 0x0A)) >> 8;
 					progif = (pciConfigReadWord(bus, device, func, 0x08)) >> 8;
 					subclass = (pciConfigReadWord(bus, device, func, 0x0A)) & 0xFF;
@@ -213,8 +215,40 @@ pci_get_xhci()
 							if (type == 0x0) {
 								dev32_addr = (u32)(bars[0] & 0xfffffff0);
 							} else if (type == 0x2) {
+
+								// If this is unset there's no point for MSI-X
+								if (((status >> 4) & 0x1) == 0) 
+									continue;
+
+								// Gotta enable MSI-X for xHCI
+								u8 capptr = (pciConfigReadWord(bus, device, func, 0x34) & 0xff);
+								u8 msix_offset = 0;
+
+								while (capptr != 0) {
+									u16 caphdr = pciConfigReadWord(bus, device, func, capptr);
+									u8 capid = (u8)(caphdr & 0xff);
+
+									if (capid == 0x11) {
+										msix_offset = capptr;
+										break;
+									}
+
+									capptr = (u8)((caphdr >> 8) & 0xff);
+								}
+
+								if (msix_offset == 0)
+									continue;
+
+								u16 msg_ctl = pciConfigReadWord(bus, device, func, msix_offset + 2);
+
+								msg_ctl |= (1 << 15); // Enable MSI-X
+								msg_ctl &= ~(1 << 14); // Allow Interrupts
+
+								pciConfigWriteWord(bus, device, func, msix_offset + 2, msg_ctl);
+
 								dev64_addr = (u64)(bars[0] & 0xfffffff0) + 
 									((u64)(bars[1] & 0xffffffff) << 32);
+
 							} else if (type == 0x1) {
 								output("PCI 3.0 reserved\n");
 							}