diff --git a/Library/OcAppleKernelLib/CommonPatches.c b/Library/OcAppleKernelLib/CommonPatches.c index b1a4ce7e..4831fe06 100644 --- a/Library/OcAppleKernelLib/CommonPatches.c +++ b/Library/OcAppleKernelLib/CommonPatches.c @@ -174,15 +174,107 @@ mRemoveUsbLimitV2Patch = { .Skip = 0 }; +STATIC +UINT8 +mRemoveUsbLimitIoP1Find[] = { + 0x0f, 0x0f, 0x87 +}; + +STATIC +UINT8 +mRemoveUsbLimitIoP1Replace[] = { + 0x40, 0x0f, 0x87 +}; + +STATIC +PATCHER_GENERIC_PATCH +mRemoveUsbLimitIoP1Patch = { + .Base = "__ZN16AppleUSBHostPort15setPortLocationEj", + .Find = mRemoveUsbLimitIoP1Find, + .Mask = NULL, + .Replace = mRemoveUsbLimitIoP1Replace, + .ReplaceMask = NULL, + .Size = sizeof (mRemoveUsbLimitIoP1Replace), + .Count = 1, + .Skip = 0 +}; + EFI_STATUS PatchUsbXhciPortLimit ( IN OUT PRELINKED_CONTEXT *Context ) { EFI_STATUS Status; - EFI_STATUS Status2; PATCHER_CONTEXT Patcher; + // + // On 10.14.4 and newer IOUSBHostFamily also needs limit removal. + // Thanks to ydeng discovering this. + // + Status = PatcherInitContextFromPrelinked ( + &Patcher, + Context, + "com.apple.iokit.IOUSBHostFamily" + ); + + if (!EFI_ERROR (Status)) { + Status = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitIoP1Patch); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "Failed to apply P1 patch com.apple.iokit.IOUSBHostFamily - %r\n", Status)); + } else { + DEBUG ((DEBUG_INFO, "Patch success com.apple.iokit.IOUSBHostFamily\n")); + } + } else { + DEBUG ((DEBUG_INFO, "Failed to find com.apple.iokit.IOUSBHostFamily - %r\n", Status)); + } + + // + // TODO: Implement some locationID hack in IOUSBHFamily. + // The location ID is a 32 bit number which is unique among all USB devices in the system, + // and which will not change on a system reboot unless the topology of the bus itself changes. + // See AppleUSBHostPort::setPortLocation(): + // locationId = getLocationId(); + // if (!(locationId & 0xF)) { + // int32_t shift = 20; + // while (locationId & (0xF << shift)) { + // shift -= 4; + // if (Shift < 0) { setLocationId(locationId); return; } + // } + // setLocationId(locationId | ((portNumber & 0xF) << shift)); + // } + // The value (e.g. 0x14320000) is represented as follows: 0xAABCDEFG + // AA — Ctrl number 8 bits (e.g. 0x14, aka XHCI) + // B - Port number 4 bits (e.g. 0x3, aka SS03) + // C~F - Bus number 4 bits (e.g. 0x2, aka IOUSBHostHIDDevice) + // + // C~F are filled as many times as many USB Hubs are there on the port. + // + + Status = PatcherInitContextFromPrelinked ( + &Patcher, + Context, + "com.apple.driver.usb.AppleUSBXHCIPCI" + ); + + if (!EFI_ERROR (Status)) { + Status = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitV2Patch); + if (!EFI_ERROR (Status)) { + // + // We do not need to patch com.apple.driver.usb.AppleUSBXHCI if this patch was successful. + // Only legacy systems require com.apple.driver.usb.AppleUSBXHCI to be patched. + // + DEBUG ((DEBUG_INFO, "Patch success com.apple.driver.usb.AppleUSBXHCIPCI\n")); + return EFI_SUCCESS; + } else { + DEBUG ((DEBUG_INFO, "Failed to apply patch com.apple.driver.usb.AppleUSBXHCIPCI - %r\n", Status)); + } + } else { + DEBUG ((DEBUG_INFO, "Failed to find com.apple.driver.usb.AppleUSBXHCIPCI - %r\n", Status)); + } + + // + // If we are here, we are on legacy 10.13 or below, try the oldest patch. + // Status = PatcherInitContextFromPrelinked ( &Patcher, Context, @@ -200,24 +292,7 @@ PatchUsbXhciPortLimit ( DEBUG ((DEBUG_INFO, "Failed to find com.apple.driver.usb.AppleUSBXHCI - %r\n", Status)); } - Status2 = PatcherInitContextFromPrelinked ( - &Patcher, - Context, - "com.apple.driver.usb.AppleUSBXHCIPCI" - ); - - if (!EFI_ERROR (Status2)) { - Status2 = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitV2Patch); - if (EFI_ERROR (Status2)) { - DEBUG ((DEBUG_INFO, "Failed to apply patch com.apple.driver.usb.AppleUSBXHCIPCI - %r\n", Status2)); - } else { - DEBUG ((DEBUG_INFO, "Patch success com.apple.driver.usb.AppleUSBXHCIPCI\n")); - } - } else { - DEBUG ((DEBUG_INFO, "Failed to find com.apple.driver.usb.AppleUSBXHCIPCI - %r\n", Status2)); - } - - return !EFI_ERROR (Status) ? Status : Status2; + return Status; } STATIC