Index: trunk/i386/libsaio/usb.c =================================================================== --- trunk/i386/libsaio/usb.c (revision 2527) +++ trunk/i386/libsaio/usb.c (revision 2528) @@ -31,9 +31,10 @@ struct pciList* usbList = NULL; -int legacy_off (pci_dt_t *pci_dev); -int ehci_acquire (pci_dt_t *pci_dev); -int uhci_reset (pci_dt_t *pci_dev); +static int legacy_off (pci_dt_t *pci_dev); +static int ehci_acquire (pci_dt_t *pci_dev); +static int uhci_reset (pci_dt_t *pci_dev); +static int xhci_legacy_off(pci_dt_t *pci_dev); // Add usb device to the list void notify_usb_dev(pci_dt_t *pci_dev) @@ -64,15 +65,16 @@ int usb_loop() { int retVal = 1; - bool fix_ehci, fix_uhci, fix_usb, fix_legacy; - fix_ehci = fix_uhci = fix_usb = fix_legacy = false; + bool fix_xhci, fix_ehci, fix_uhci, fix_usb, fix_legacy; + fix_xhci = fix_ehci = fix_uhci = fix_usb = fix_legacy = false; if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->chameleonConfig)) { - fix_ehci = fix_uhci = fix_legacy = fix_usb; // Disable all if none set + fix_xhci = fix_ehci = fix_uhci = fix_legacy = fix_usb; // Disable all if none set } else { + getBoolForKey(kXHCILegacyOff, &fix_xhci, &bootInfo->chameleonConfig); getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->chameleonConfig); getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->chameleonConfig); getBoolForKey(kLegacyOff, &fix_legacy, &bootInfo->chameleonConfig); @@ -84,15 +86,20 @@ { switch (pci_config_read8(current->pciDev->dev.addr, PCI_CLASS_PROG)) { + // XHCI + case PCI_IF_XHCI: + if(fix_xhci || fix_legacy) retVal &= xhci_legacy_off(current->pciDev); + break; + // EHCI - case 0x20: + case PCI_IF_EHCI: if(fix_ehci) retVal &= ehci_acquire(current->pciDev); if(fix_legacy) retVal &= legacy_off(current->pciDev); break; // UHCI - case 0x00: + case PCI_IF_UHCI: if (fix_uhci) retVal &= uhci_reset(current->pciDev); break; @@ -103,7 +110,7 @@ return retVal; } -int legacy_off (pci_dt_t *pci_dev) +static int legacy_off (pci_dt_t *pci_dev) { // Set usb legacy off modification by Signal64 // NOTE: This *must* be called after the last file is loaded from the drive in the event that we are booting form usb. @@ -197,7 +204,7 @@ return 1; } -int ehci_acquire (pci_dt_t *pci_dev) +static int ehci_acquire (pci_dt_t *pci_dev) { int j, k; uint32_t base; @@ -321,7 +328,7 @@ return 1; } -int uhci_reset (pci_dt_t *pci_dev) +static int uhci_reset (pci_dt_t *pci_dev) { uint32_t base, port_base; @@ -342,3 +349,97 @@ outw (port_base,0); return 1; } + +static int xhci_legacy_off(pci_dt_t *pci_dev) +{ + uint32_t bar0, hccparams1, extendCap, value; + int32_t timeOut; + + verbose("Setting Legacy USB Off on xHC [%04x:%04x] at %02x:%2x.%x\n", + pci_dev->vendor_id, pci_dev->device_id, + pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func); + + bar0 = pci_config_read32(pci_dev->dev.addr, 16); + /* + * Check if memory bar + */ + if (bar0 & 1) + { + DBG("%s: BAR0 not a memory range\n", __FUNCTION__); + return 0; + } + /* + * Check if outside 32-bit physical address space + */ + if (((bar0 & 6) == 4) && + pci_config_read32(pci_dev->dev.addr, 20)) + { + DBG("%s: BAR0 outside 32-bit physical address space\n", __FUNCTION__); + return 0; + } + bar0 &= ~15; + + hccparams1 = *(uint32_t const volatile*) (bar0 + 16); + if (hccparams1 == ~0) + { + DBG("%s: hccparams1 invalid 0x%x\n", __FUNCTION__, hccparams1); + return 0; + } + extendCap = (hccparams1 >> 14) & 0x3fffc; + while (extendCap) { + value = *(uint32_t const volatile*) (bar0 + extendCap); + if (value == ~0) + { + break; + } + if ((value & 0xff) == 1) { +#if DEBUG_USB + verbose("%s: Found USBLEGSUP 0x%x, USBLEGCTLSTS 0x%x\n", __FUNCTION__, + value, *(uint32_t const volatile*) (bar0 + extendCap + 4)); +#endif + value |= (1 << 24); + *(uint32_t volatile*) (bar0 + extendCap) = value; + timeOut = 40; + while (timeOut--) + { + delay(1); + value = *(uint32_t const volatile*) (bar0 + extendCap); + if (value == ~0) + { + timeOut = -1; + break; + } + if ((value & 0x01010000) == 0x01000000) + { + timeOut = -1; /* Optional - always disable the SMI */ + break; + } + } +#if DEBUG_USB + verbose("%s: USBLEGSUP 0x%x, USBLEGCTLSTS 0x%x\n", __FUNCTION__, + value, *(uint32_t const volatile*) (bar0 + extendCap + 4)); +#endif + if (timeOut >= 0) + { + break; + } + /* + * Disable the SMI in USBLEGCTLSTS if BIOS doesn't respond + */ + value = *(uint32_t const volatile*) (bar0 + extendCap + 4); + if (value == ~0) + { + break; + } + value &= 0x1f1fee; + value |= 0xe0000000; + *(uint32_t volatile*) (bar0 + extendCap + 4) = value; + break; + } + if (!(value & 0xff00)) + break; + extendCap += ((value >> 6) & 0x3fc); + } + verbose("XHCI Legacy Off Done\n"); + return 1; +} Index: trunk/i386/boot2/boot.h =================================================================== --- trunk/i386/boot2/boot.h (revision 2527) +++ trunk/i386/boot2/boot.h (revision 2528) @@ -119,6 +119,9 @@ #define kEHCIhard "EHCIhard" /* usb.c */ #define kDefaultPartition "Default Partition" /* sys.c */ +/* Zenith432: added this */ +#define kXHCILegacyOff "XHCILegacyOff" /* usb.c */ + /* Duvel300: added this */ #define kRestartFix "RestartFix" /* acpi_patcher.c */ Index: trunk/package/OptionalSettings/General.txt =================================================================== --- trunk/package/OptionalSettings/General.txt (revision 2527) +++ trunk/package/OptionalSettings/General.txt (revision 2528) @@ -34,6 +34,7 @@ Bool@ForceFullMemInfo:ForceFullMemInfo=Yes Bool@RestartFix:RestartFix=No Bool@UHCIreset:UHCIreset=Yes +Bool@XHCILegacyOff:XHCILegacyOff=Yes Bool@UseMemDetect:UseMemDetect=No Bool@UseKernelCache:UseKernelCache=Yes Bool@Wake:Wake=Yes Index: trunk/doc/BootHelp.txt =================================================================== --- trunk/doc/BootHelp.txt (revision 2527) +++ trunk/doc/BootHelp.txt (revision 2528) @@ -111,10 +111,11 @@ for ethernet interfaces. ForceHPET=Yes|No Force HPET on (disabled by default). - USBBusFix=Yes Enable the EHCI and UHCI fixes (disabled by default). + USBBusFix=Yes Enable the XHCI, EHCI and UHCI fixes (disabled by default). EHCIacquire=Yes Enable the EHCI fix (disabled by default). UHCIreset=Yes Enable the UHCI fix (disabled by default). - USBLegacyOff=Yes Force USB Legacy off (disabled by default). + USBLegacyOff=Yes Force USB Legacy off for XHCI and EHCI (disabled by default). + XHCILegacyOff=Yes Force USB Legacy off for XHCI (disabled by default). Wake=No Disable wake up after hibernation (enbaled by default). ForceWake=Yes Force using the sleepimage (disabled by default). Index: trunk/CHANGES =================================================================== --- trunk/CHANGES (revision 2527) +++ trunk/CHANGES (revision 2528) @@ -1,3 +1,4 @@ +- Zenith432 : Add turning off USB legacy for XHCI (XHCILegacyOff) - ErmaC : C6 & C7 States credits to Clover Team. - ErmaC : define recursive cpu series for BrandString - Zenith432 : saio_types.h, biosfn.c - minor typo in bios-defined data structure that isn't actually used.