Index: trunk/doc/BootHelp.txt =================================================================== --- trunk/doc/BootHelp.txt (revision 202) +++ trunk/doc/BootHelp.txt (revision 203) @@ -71,9 +71,11 @@ EthernetBuiltIn=Yes|No Automatic "built-in"=yes device-properties generation for ethernet interfaces. - USBBusFix=Yes Enable the EHCI and UHCI fixes (disabled by default). + USBBusFix=Yes Enable all USB fixes below: EHCIacquire=Yes Enable the EHCI fix (disabled by default). UHCIreset=Yes Enable the UHCI fix (disabled by default). + USBLegacyOff=Yes Enable the USB Legacy fix (disabled by default). + ForceHPET=Yes|No Force Enable HPET. Wake=No Disable wake up after hibernation (default: enabled). Index: trunk/i386/libsaio/usb.c =================================================================== --- trunk/i386/libsaio/usb.c (revision 202) +++ trunk/i386/libsaio/usb.c (revision 203) @@ -22,6 +22,182 @@ #define DBG(x...) #endif + +struct pciList +{ + pci_dt_t* pciDev; + struct pciList* next; +}; + +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); + +// Add usb device to the list +void notify_usb_dev(pci_dt_t *pci_dev) +{ + + struct pciList* current = usbList; + if(!usbList) + { + usbList = (struct pciList*)malloc(sizeof(struct pciList)); + usbList->next = NULL; + usbList->pciDev = pci_dev; + + } + else + { + while(current != NULL && current->next != NULL) + { + current = current->next; + } + current->next = (struct pciList*)malloc(sizeof(struct pciList)); + current = current->next; + + current->pciDev = pci_dev; + current->next = NULL; + } +} + +// Loop through the list and call the apropriate patch function +int usb_loop() +{ + int retVal = 1; + bool fix_ehci, fix_uhci, fix_usb, fix_legacy; + fix_ehci = fix_uhci = fix_usb = fix_legacy = false; + + if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig)) + { + fix_ehci = fix_uhci = fix_legacy = fix_usb; // Disable all if none set + } + else + { + getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->bootConfig); + getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->bootConfig); + getBoolForKey(kLegacyOff, &fix_legacy, &bootInfo->bootConfig); + } + + struct pciList* current = usbList; + + while(current && current->next) + { + switch (pci_config_read8(current->pciDev->dev.addr, PCI_CLASS_PROG)) + { + // EHCI + case 0x20: + if(fix_ehci) retVal &= ehci_acquire(current->pciDev); + if(fix_legacy) retVal &= legacy_off(current->pciDev); + + break; + + // UHCI + case 0x00: + if (fix_uhci) retVal &= uhci_reset(current->pciDev); + + break; + } + + current = current->next; + } + return retVal; +} + +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. + // NOTE2: This should be called after any getc() call. (aka, after the Wait=y keyworkd is used) + // AKA: Make this run immediatly before the kernel is called + uint32_t capaddr, opaddr; + uint8_t eecp; + uint32_t usbcmd, usbsts, usbintr; + uint32_t usblegsup, usblegctlsts; + + int isOSowned; + int isBIOSowned; + + verbose("Setting Legacy USB Off on controller [%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); + + + // capaddr = Capability Registers = dev.addr + offset stored in dev.addr + 0x10 (USBBASE) + capaddr = pci_config_read32(pci_dev->dev.addr, 0x10); + + // opaddr = Operational Registers = capaddr + offset (8bit CAPLENGTH in Capability Registers + offset 0) + opaddr = capaddr + *((unsigned char*)(capaddr)); + + // eecp = EHCI Extended Capabilities offset = capaddr HCCPARAMS bits 15:8 + eecp=*((unsigned char*)(capaddr + 9)); + + DBG("capaddr=%x opaddr=%x eecp=%x\n", capaddr, opaddr, eecp); + + usbcmd = *((unsigned int*)(opaddr)); // Command Register + usbsts = *((unsigned int*)(opaddr + 4)); // Status Register + usbintr = *((unsigned int*)(opaddr + 8)); // Interrupt Enable Register + + DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr); + + // read PCI Config 32bit USBLEGSUP (eecp+0) + usblegsup = pci_config_read32(pci_dev->dev.addr, eecp); + + // informational only + isBIOSowned = !!((usblegsup) & (1 << (16))); + isOSowned = !!((usblegsup) & (1 << (24))); + + // read PCI Config 32bit USBLEGCTLSTS (eecp+4) + usblegctlsts = pci_config_read32(pci_dev->dev.addr, eecp + 4); + + DBG("usblegsup=%08x isOSowned=%d isBIOSowned=%d usblegctlsts=%08x\n", usblegsup, isOSowned, isBIOSowned, usblegctlsts); + + // Reset registers to Legacy OFF + DBG("Clearing USBLEGCTLSTS\n"); + pci_config_write32(pci_dev->dev.addr, eecp + 4, 0); //usblegctlsts + + // if delay value is in milliseconds it doesn't appear to work. + // setting value to anything up to 65535 does not add the expected delay here. + delay(100); + + usbcmd = *((unsigned int*)(opaddr)); + usbsts = *((unsigned int*)(opaddr + 4)); + usbintr = *((unsigned int*)(opaddr + 8)); + + DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr); + + DBG("Clearing Registers\n"); + + // clear registers to default + usbcmd = (usbcmd & 0xffffff00); + *((unsigned int*)(opaddr)) = usbcmd; + *((unsigned int*)(opaddr + 8)) = 0; //usbintr - clear interrupt registers + *((unsigned int*)(opaddr + 4)) = 0x1000; //usbsts - clear status registers + pci_config_write32(pci_dev->dev.addr, eecp, 1); //usblegsup + + // get the results + usbcmd = *((unsigned int*)(opaddr)); + usbsts = *((unsigned int*)(opaddr + 4)); + usbintr = *((unsigned int*)(opaddr + 8)); + + DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr); + + // read 32bit USBLEGSUP (eecp+0) + usblegsup = pci_config_read32(pci_dev->dev.addr, eecp); + + // informational only + isBIOSowned = !!((usblegsup) & (1 << (16))); + isOSowned = !!((usblegsup) & (1 << (24))); + + // read 32bit USBLEGCTLSTS (eecp+4) + usblegctlsts = pci_config_read32(pci_dev->dev.addr, eecp + 4); + + DBG("usblegsup=%08x isOSowned=%d isBIOSowned=%d usblegctlsts=%08x\n", usblegsup, isOSowned, isBIOSowned, usblegctlsts); + + verbose("Legacy USB Off Done\n"); + return 1; +} + int ehci_acquire (pci_dt_t *pci_dev) { int j, k; Index: trunk/i386/libsaio/pci_setup.c =================================================================== --- trunk/i386/libsaio/pci_setup.c (revision 202) +++ trunk/i386/libsaio/pci_setup.c (revision 203) @@ -6,26 +6,19 @@ #include "ati.h" extern void set_eth_builtin(pci_dt_t *eth_dev); -extern int ehci_acquire(pci_dt_t *pci_dev); -extern int uhci_reset(pci_dt_t *pci_dev); +extern void notify_usb_dev(pci_dt_t *pci_dev); extern void force_enable_hpet(pci_dt_t *lpc_dev); void setup_pci_devs(pci_dt_t *pci_dt) { char *devicepath; - bool do_eth_devprop, do_gfx_devprop, fix_ehci, fix_uhci, fix_usb, do_enable_hpet; + bool do_eth_devprop, do_gfx_devprop, do_enable_hpet; pci_dt_t *current = pci_dt; - do_eth_devprop = do_gfx_devprop = fix_ehci = fix_uhci = fix_usb = do_enable_hpet = false; + do_eth_devprop = do_gfx_devprop = do_enable_hpet = false; getBoolForKey(kEthernetBuiltIn, &do_eth_devprop, &bootInfo->bootConfig); getBoolForKey(kGraphicsEnabler, &do_gfx_devprop, &bootInfo->bootConfig); - if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig) && fix_usb) { - fix_ehci = fix_uhci = true; - } else { - getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->bootConfig); - getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->bootConfig); - } getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->bootConfig); while (current) @@ -62,20 +55,7 @@ break; case PCI_CLASS_SERIAL_USB: - switch (pci_config_read8(current->dev.addr, PCI_CLASS_PROG)) - { - /* EHCI */ - case 0x20: - if (fix_ehci) - ehci_acquire(current); - break; - - /* UHCI */ - case 0x00: - if (fix_uhci) - uhci_reset(current); - break; - } + notify_usb_dev(current); break; case PCI_CLASS_BRIDGE_ISA: Index: trunk/i386/libsaio/fake_efi.c =================================================================== --- trunk/i386/libsaio/fake_efi.c (revision 202) +++ trunk/i386/libsaio/fake_efi.c (revision 203) @@ -514,19 +514,19 @@ /* Entrypoint from boot.c */ void setupFakeEfi(void) { - // load smbios.plist file if any - setupSmbiosConfigFile(); + // load smbios.plist file if any + setupSmbiosConfigFile(); - // Generate efi device strings + // Generate efi device strings setupEfiDevices(); // Initialize the base table setupEfiTables(); - // Initialize the device tree - setupEfiDeviceTree(); - - // Add configuration table entries to both the services table and the device tree - setupEfiConfigurationTable(); + // Initialize the device tree + setupEfiDeviceTree(); + + // Add configuration table entries to both the services table and the device tree + setupEfiConfigurationTable(); } Index: trunk/i386/boot2/boot.c =================================================================== --- trunk/i386/boot2/boot.c (revision 202) +++ trunk/i386/boot2/boot.c (revision 203) @@ -175,11 +175,13 @@ } bool dummyVal; - if (getBoolForKey(kWaitForKeypressKey, &dummyVal, &bootInfo->bootConfig) && dummyVal) { - printf("Press any key to continue..."); - getc(); - } + if (getBoolForKey(kWaitForKeypressKey, &dummyVal, &bootInfo->bootConfig) && dummyVal) { + printf("Press any key to continue..."); + getc(); + } + usb_loop(); + // If we were in text mode, switch to graphics mode. // This will draw the boot graphics unless we are in // verbose mode. Index: trunk/i386/boot2/boot.h =================================================================== --- trunk/i386/boot2/boot.h (revision 202) +++ trunk/i386/boot2/boot.h (revision 203) @@ -68,6 +68,12 @@ #define kDSDT "DSDT" /* acpi_patcher.c */ #define kDropSSDT "DropSSDT" /* acpi_patcher.c */ #define kRestartFix "RestartFix" /* acpi_patcher.c */ +#define kRestartFix "RestartFix" /* acpi_patcher.c */ +#define kGeneratePStates "GeneratePStates" /* acpi_patcher.c */ +#define kGenerateCStates "GenerateCStates" /* acpi_patcher.c */ +#define kDeviceProperties "device-properties" /* device_inject.c */ +#define kHidePartition "Hide Partition" /* disk.c */ +#define kRenamePartition "Rename Partition" /* disk.c */ #define kSMBIOS "SMBIOS" /* fake_efi.c */ #define kSystemID "SystemId" /* fake_efi.c */ #define kSystemType "SystemType" /* fake_efi.c */ @@ -76,20 +82,15 @@ #define kPCIRootUID "PCIRootUID" /* pci_root.c */ #define kEthernetBuiltIn "EthernetBuiltIn" /* pci_setup.c */ #define kGraphicsEnabler "GraphicsEnabler" /* pci_setup.c */ -#define kUSBBusFix "USBBusFix" /* pci_setup.c */ -#define kEHCIacquire "EHCIacquire" /* pci_setup.c */ -#define kUHCIreset "UHCIreset" /* pci_setup.c */ #define kForceHPET "ForceHPET" /* pci_setup.c */ +#define kUseMemDetect "UseMemDetect" /* platform.c */ #define kSMBIOSdefaults "SMBIOSdefaults" /* smbios_patcher.c */ +#define kUSBBusFix "USBBusFix" /* usb.c */ +#define kEHCIacquire "EHCIacquire" /* usb.c */ +#define kUHCIreset "UHCIreset" /* usb.c */ +#define kLegacyOff "USBLegacyOff" /* usb.c */ #define kEHCIhard "EHCIhard" /* usb.c */ #define kDefaultPartition "Default Partition" /* sys.c */ -#define kDeviceProperties "device-properties" /* device_inject.c */ -#define kHidePartition "Hide Partition" /* disk.c */ -#define kRenamePartition "Rename Partition" /* disk.c */ -#define kUseMemDetect "UseMemDetect" /* platform.c */ -#define kRestartFix "RestartFix" /* acpi_patcher.c */ -#define kGeneratePStates "GeneratePStates" /* acpi_patcher.c */ -#define kGenerateCStates "GenerateCStates" /* acpi_patcher.c */ /* * Flags to the booter or kernel @@ -138,6 +139,11 @@ extern void common_boot(int biosdev); /* + * usb.c + */ +extern int usb_loop(); + +/* * graphics.c */ extern void printVBEModeInfo(); @@ -165,6 +171,7 @@ extern void drawPreview(void *src, uint8_t * saveunder); extern int getVideoMode(void); extern void loadImageScale (void *input, int iw, int ih, int ip, void *output, int ow, int oh, int op, int or); + /* * drivers.c */