Contribute
Register

[Guide] USB power property injection for Sierra (and later)

RehabMan

Moderator
Joined
May 2, 2012
Messages
181,111
Motherboard
Intel DH67BL
CPU
i7-2600K
Graphics
HD 3000
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
Summary

It appears that Sierra has changed how USB power properties are set. In prior versions, we have injected AAPL,current-available, AAPL,current-extra, AAPL,current-extra-in-sleep, and AAPL,max-port-current-in-sleep directly on the XHC/EHCI ACPI objects. In Sierra, these appear to be replaced by new properties that are injected on the AppleBusPowerController object in ioreg.

Note: 10.12.x uses AppleBusPowerControllerUSB, not AppleBusPowerController. But the configuration data for USBInjectAll is placed in "AppleBusPowerController" no matter the version (as you will see later in the guide).

Let's take a look at the changes required...


Tracing the evidence

Some of these changes were noticed during development of USBInjectAll.kext... And I had remembered about some "kUSB*" properties that looked interesting in one of the USB kext Info.plist files. A simple grep search can reveal where we might look:

Code:
SPEEDY-NUC:nuc.git rehabman$ grep -l kUSB.* -R /System/Library/Extensions/IOUSBHostFamily.kext
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/Info.plist
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/MacOS/IOUSBHostFamily
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBEHCI.kext/Contents/MacOS/AppleUSBEHCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBEHCIPCI.kext/Contents/Info.plist
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBEHCIPCI.kext/Contents/MacOS/AppleUSBEHCIPCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHostCompositeDevice.kext/Contents/MacOS/AppleUSBHostCompositeDevice
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHostMergeProperties.kext/Contents/Info.plist
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHub.kext/Contents/Info.plist
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHub.kext/Contents/MacOS/AppleUSBHub
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBOHCIPCI.kext/Contents/MacOS/AppleUSBOHCIPCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBUHCI.kext/Contents/MacOS/AppleUSBUHCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBUHCIPCI.kext/Contents/MacOS/AppleUSBUHCIPCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBXHCI.kext/Contents/MacOS/AppleUSBXHCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBXHCIPCI.kext/Contents/Info.plist
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBXHCIPCI.kext/Contents/MacOS/AppleUSBXHCIPCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/IOUSBHostHIDDevice.kext/Contents/MacOS/IOUSBHostHIDDevice

So... it looks like /System/Library/Extensions/IOUSBHostFamily.kext/Contents/Info.plist is a good place to start.

And look what we find (note: image from 10.12.x):
Screen Shot 2017-05-17 at 8.15.56 AM.png


As you can see there are various properties (kUSBSleepPortCurrentLimit, kUSBSleepPowerSupply, kUSBWakePortCurrentLimit, kUSBWakePowerSupply), which are being injected to provider AppleBusPowerController via an AppleUSBHostMergeProperties injector.

But I checked my own ioreg and AppleBusPowerController was not loaded anywhere. So now the question is what causes it to load... Another simple grep search will tell us:

Code:
SPEEDY-NUC:nuc.git rehabman$ grep -l AppleBusPowerController -R /System/Library/Extensions
/System/Library/Extensions/AppleBusPowerController.kext/Contents/Info.plist
/System/Library/Extensions/AppleBusPowerController.kext/Contents/MacOS/AppleBusPowerController
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/Info.plist

And now, looking at AppleBusPowerController.kext's Info.plist (note: image from 10.12.x):
Screen Shot 2017-05-17 at 8.19.52 AM.png


We can see that it matches on an ACPI device named 'EC'. Some PCs use EC for the Embedded Controller, but most use EC0 or H_EC.
With that knowledge, we can simply rename H_EC->EC, or EC0->EC, and then AppleBusPowerController will load, as will the related injections for each supported SMBIOS in IOUSBHostFamily.kext/Contents/Info.plist.

Now, if you look carefully at the IOUSBHostFamily Info.plist, you find that newer SMBIOS are missing. Such as MacBookPro9,1, iMac17,1, and MacBookPro13,x. These models must use a different method for USB power property injection.

Disassembly of AppleBusPowerController reveals that it is looking in IOACPIPlane for an object named 'USBX'. It then appears to extract the necessary data from device-properties. If we look at the ioreg for an iMac17,1, we find this:
Screen Shot 2017-05-17 at 8.34.14 AM.png


And there are our power properties again...

Looking at DSDT.aml for the iMac17,1, we find the source for USBX:
Code:
    Scope (_SB)
    {
...
        Device (USBX)
        {
            Name (_ADR, Zero)  // _ADR: Address
            Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
            {
                Store (Package (0x08)
                    {
                        "kUSBSleepPowerSupply",
                        0x13EC,
                        "kUSBSleepPortCurrentLimit",
                        0x0834,
                        "kUSBWakePowerSupply",
                        0x13EC,
                        "kUSBWakePortCurrentLimit",
                        0x0834
                    }, Local0)
                DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
                Return (Local0)
            }
        }

Similar for MacBookPro14,3:
Code:
    Scope (_SB)
    {
...
        Device (USBX)
        {
            Name (_ADR, Zero)  // _ADR: Address
            Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
            {
                Store (Package (0x04)
                    {
                        "kUSBSleepPortCurrentLimit",
                        0x0BB8,
                        "kUSBWakePortCurrentLimit",
                        0x0BB8
                    }, Local0)
                DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
                Return (Local0)
            }
        }

So, no surprise there... standard _DSM injection of the four USB power properties.

Summary:
- if the PC has an EC, name it 'EC' and AppleBusPowerController will load.
- if the SMBIOS matches one of the "legacy SMBIOS" in IOUSBHostFamily.kext/Contents/Info.plist, power properties for that Mac model will be injected (they may or may not be appropriate for your hardware)
- if the SMBIOS is not present in IOUSBHostFamily.kext/Contents/Info.plist, power properties are determined by the USBX device in ACPI via normal _DSM property injection


Insuring AppleBusPowerController loads

If you have an Embedded Controller (most laptops, some desktops), you can simply make sure the ACPI device is named EC. This is easily accomplished with a ACPI hotpatch in config.plist. I have added both the common renames into all the laptop guide plists.

Here is what they look like:
Screen Shot 2017-05-17 at 8.41.21 AM.png


Note: If you are using static patched SSDTs (that is, patched OEM SSDTs in ACPI/patched), you must make sure the EC rename is accomplished in each of those files manually. Clover config.plist/ACPI/DSDT/Patches applies only to DSDT.aml in ACPI/patched, and OEM DSDT and SSDTs loaded from BIOS... not to SSDTs in ACPI/patched.

Note: If your computer has an ECDT in ACPI, you should not rename anything along the EC path, including the EC itself. Use a "Fake EC" instead as described below. You can check if you have ECDT by extracting ACPI with Clover (F4) and checking for ECDT.aml in EFI/Clover/ACPI/origin.

If you don't have an embedded controller, you can add a "fake" one with the following SSDT-EC.dsl (compile to AML):
Code:
// Inject Fake EC device
DefinitionBlock("", "SSDT", 2, "hack", "EC", 0)
{
    Device(_SB.EC)
    {
        Name(_HID, "EC000000")
    }
}
//EOF

Note: You may find you have an EC in your DSDT: Device with "Name (_HID, EisaId ("PNP0C09"))", even if it is not active.

For example, this is on my NUC6i7KYK:
Code:
    Scope (_SB.PCI0.LPCB)
    {
        Device (H_EC)
        {
            Name (_HID, EisaId ("PNP0C09"))  // _HID: Hardware ID
            Name (_UID, One)  // _UID: Unique ID
            Method (_STA, 0, NotSerialized)  // _STA: Status
            {
                Store (0x03, ^^^IGPU.CLID)
                Return (Zero)
            }
...

As you can see, it is returning zero from _STA. Which according to the ACPI spec is "not present". It means this H_EC device is effectively ignored. You will notice that it doesn't show in ioreg, IOService plane.

DO NOT be tempted to activate the EC device by changing the return value of _STA. The reason it is returning zero here is because the computer DOES NOT HAVE an EC. In this case, you should add a "fake" EC as mentioned above.


An SSDT to inject the USBX device

For SMBIOS that are not already covered in IOUSBHostFamily.kext/Contents/Info.plist, you will need to inject the USBX device in order to provide the power properties for AppleBusPowerController.

Here is an example SSDT-USBX.dsl:
Code:
// USB power properties via USBX device
DefinitionBlock("", "SSDT", 2, "hack", "USBX", 0)
{
    Device(_SB.USBX)
    {
        Name(_ADR, 0)
        Method (_DSM, 4)
        {
            If (!Arg2) { Return (Buffer() { 0x03 } ) }
            Return (Package()
            {
                // these values from iMac17,1
                "kUSBSleepPortCurrentLimit", 2100,
                "kUSBSleepPowerSupply", 5100,
                "kUSBWakePortCurrentLimit", 2100,
                "kUSBWakePowerSupply", 5100,
            })
        }
    }
}
//EOF

And here is another, based on the USBX we find in MacBookPro14,3:
Code:
// USB power properties via USBX device
DefinitionBlock("", "SSDT", 2, "hack", "USBX", 0)
{
    Device(_SB.USBX)
    {
        Name(_ADR, 0)
        Method (_DSM, 4)
        {
            If (!Arg2) { Return (Buffer() { 0x03 } ) }
            Return (Package()
            {
                // these values from MacBookPro14,3
                "kUSBSleepPortCurrentLimit", 3000,
                "kUSBWakePortCurrentLimit", 3000,
            })
        }
    }
}
//EOF

You might think that you could also override the values provided by IOUSBHostFamily.kext/Contents/Info.plist in the case a supported SMBIOS is being used. But unfortunately, that is not the case... the values in IOUSBHostFamily.kext/Contents/Info.plist override those that are provided by USBX.

Also, if you already have an SSDT-UIAC.aml (as you should), it probably makes sense to simply add the _SB.USBX device to that SSDT instead of creating a new one.


Overriding the IOUSBHostFamily.kext/Contents/Info.plist

Although you could patch this kext Info.plist to provide different properties for any supported SMBIOS, it is desirable to do so without patching since patching would need to be redone after any update that provided a new copy of the file.

I have added support in USBInjectAll.kext to inject these properties. And, at least in my testing, the properties injected by USBInjectAll.kext are succesful in overriding those from IOUSBHostFamily.kext.

To specify power property overrides via USBInjectAll.kext, you must provide an "AppleBusPowerController" in your UIAC.RMCF.

For example:
Code:
DefinitionBlock ("", "SSDT", 2, "hack", "usb", 0)
{
//
// Override for USBInjectAll.kext
//
    Device(UIAC)
    {
        Name(_HID, "UIA00000")
        Name(RMCF, Package()
        {
            // USB Power Properties for Sierra (using USBInjectAll injection)
            "AppleBusPowerController", Package()
            {
                // these values happen to be iMac14,2 values...
                "kUSBSleepPortCurrentLimit", 2100,
                "kUSBSleepPowerSupply", 4700,
                "kUSBWakePortCurrentLimit", 2100,
                "kUSBWakePowerSupply", 4700,
            },
            // XHC overrides (8086:9cb1, NUC5)
            "8086_9cb1", Package()
            {
// other UIAC.RMCF content follows (for custom port injection)
...
}
//EOF

This feature is newly added in v0.6.0 of USBInjectAll.kext, so don't expect it to work in older versions.


Are you new to hackintosh? Are you confused?

Perhaps a read of @balazs631 post here might help:
Thank you for the findings and for writing this guide RehabMan, I could make it work on my build! :clap:

I wrote a shorter guide for beginners not familiar with Hackintosh topics and the common inspector tools we use:
  • 1.) You can read "ioreg" several places but I cannot find a link or description at post #1 what ioreg actually is... So if you're wondering how you can view ioreg, there is an application called IORegistryExplorer (version 2.1 !), which you can download from here: https://www.tonymacx86.com/threads/guide-how-to-make-a-copy-of-ioreg.58368/ If you open it up it will show you a list in alphabetical order.. Look for the name "EC" (Embedded Controller), it will be before the FAN labels... If you can find the element called "EC" in there, continue with step 5.)

  • 2.) If the "EC" element is not there in the IORegistryExplorer, you need to check if you have EC0 or the H_EC name (or neither) under the hood in so called ACPI. There is another application to check that: MaciASL. It's also not mentioned in post #1, you can download it from here: RehabMan / OS-X-MaciASL-patchmatic / Downloads — Bitbucket. Open it up, press Command + F, and search for these terms: "Device (H_EC)" and "Device (EC0)". You will hopefully find the H_EC or the EC0 code block (not both). Don't bother with the meaning of the code you see, you don't have to understand it. There will be a code block in a few lines down, starting with "Method (_STA, ....". If you see a "Return (Zero)" in this {} block, then it means it's ignored as per post #1.
    So what we done in this step: You have to check if you have EC0 or H_EC device or neither in MaciASL. If you find EC0 or H_EC you need to check if it's ignored: "Return (Zero)" or not. Remember your findings...

  • 3.) Now you know what you have under the hood...
    • If you didn't have EC0 or H_EC device or it's returning Zero in method _STA, then you need to copy the file SSDT-EC.aml (attached to this post) to your main macOS drive's EFI partition, under EFI/CLOVER/ACPI/patched.
    • If you have found the EC0 or H_EC device in IORegistryExplorer and it's not returning Zero in method _STA, then you need to add a Clover config patch in EFI/CLOVER/config.plist to rename "EC0 to EC" or "H_EC to EC". Choose which one you have. The patch can be seen in post #1, under the title: "Insuring AppleBusPowerControllerUSB loads". In the picture, the config.plist file was opened in an application called Xcode, available free from the Mac App Store.

  • 4.) Restart you PC. Once macOS is loaded, open IORegistryExplorer again and check weather you see EC in the list. If "EC" shows up, everything is fine, continue with step 5.) If the name "EC" is still not there in IORegistryExplorer, start it over from 1.), more carefully.

  • 5.) Check your system definition in a built in macOS app called "System Information". Under the "Hardware Overview" section, you can find your system definition at "Model identifier", for example: iMac 18,3
    • If you have newer system definition than Macbook8,1 or MacBookAir7,2 or MacBookPro12,1 or MacPro6,1 or MacMini7,1 or iMac15,2 THEN copy the file SSDT-USBX.aml (attached to this post) to your main macOS drive's EFI partition, under EFI/CLOVER/ACPI/patched.
    • If you use one of the system def listed above or older, then you have nothing to do, continue with step 6.)

  • 6.) Restart your PC. Once macOS is loaded, plug in an iPhone or iPad to your Hackintosh with a USB cable. Open System Information app and choose the "USB" section from the left sidebar. Click on the iPhone or iPad in the list. If you can see all 4 lines you're won! ;)
    • Current Available (mA):
    • Current Required (mA):
    • Extra Operating Current (mA):
    • Sleep current (mA):
If all 4 lines are there, it's the obvious indicator of working USB power under macOS.
Hope this post will help others to understand the process described in post #1.


Problem Reporting

Read FAQ, "Problem Reporting"
https://www.tonymacx86.com/threads/faq-read-first-laptop-frequent-questions.164990/
 
Last edited:
Great and detailed guide as always RehabMan!

Could you explain why those changes are needed? as the custom SSDT-UIAC.aml + USBInjectAll.kext were doing a great job (I think).


So for my Skylake Machine, I chose the MacBookPro13,2 SMBIOS which isn't supported by IOUSBHostFamily.ket/Contents/Info.plist.

Following the guide, I should've:
1. Used an EC0->EC DSDT 'hotpatch'
2. Add an SSDT-USBX.aml to ACPI/patched
3. Optional - Add to SortedOrder in my case. Didn't move to the 'hotpatch' method yet

(I am still with macOS 10.12.3, I have a big 8086 Assembly project and I don't want to get into trouble until I finish it. Have a look at GitHub :p )

Problem Reporting files are attached, hope I did it well and maybe this feedback can also help you :)

Terminal outputs:
Code:
Bens-MacBook-Pro:RehabMan benraz$ kextstat|grep -y acpiplat
   13    2 0xffffff7f82910000 0x66000    0x66000    com.apple.driver.AppleACPIPlatform (5.0) 867C81BE-EA01-3A65-89F4-06D78E6514CA <12 11 7 6 5 4 3 1>
Bens-MacBook-Pro:RehabMan benraz$ kextstat|grep -y appleintelcpu
Bens-MacBook-Pro:RehabMan benraz$ kextstat|grep -y applelpc
   90    0 0xffffff7f820e6000 0x3000     0x3000     com.apple.driver.AppleLPC (3.1) F51595F0-F9B1-3B85-A1C3-F984DAD4107E <88 12 5 4 3>
Bens-MacBook-Pro:RehabMan benraz$ kextstat|grep -y applehda
  103    1 0xffffff7f825d1000 0x1d000    0x1d000    com.apple.driver.AppleHDAController (278.56) CFB0D0AE-F09A-3660-8F95-7A02FD5FBF07 <102 101 75 12 7 6 5 4 3 1>
  123    0 0xffffff7f82753000 0xb4000    0xb4000    com.apple.driver.AppleHDA (278.56) A4EB06C9-A40A-39EF-9C4A-D7F23DB9A2F9 <122 103 102 101 80 75 6 5 4 3 1>



Bens-MacBook-Pro:~ benraz$ sudo touch /System/Library/Extensions && sudo kextcache -u /

Password:

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext VoodooPS2Trackpad.kext

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext VoodooPS2Mouse.kext

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext VoodooPS2Keyboard.kext

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext VoodooPS2Controller.kext

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext VoodooI2C.kext

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext USBInjectAll.kext

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext SATA-100-series-unsupported.kext

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext RealtekRTL8111.kext

kext-dev-mode allowing invalid signature -67054 0xFFFFFFFFFFFEFA12 for kext X86PlatformPlugin.kext

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext IntelBacklight.kext

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext FakeSMC.kext

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext CodecCommander.kext

kext-dev-mode allowing invalid signature -67013 0xFFFFFFFFFFFEFA3B for kext AppleMobileDevice.kext

AppleHPM.kext - dependency 'com.apple.driver.AppleIntelLpssI2CController' not found.

AppleHPM.kext is missing dependencies (including anyway; dependencies may be available from elsewhere)

kext-dev-mode allowing invalid signature -67030 0xFFFFFFFFFFFEFA2A for kext AppleHDAHardwareConfigDriver.kext

kext-dev-mode allowing invalid signature -67061 0xFFFFFFFFFFFEFA0B for kext AppleHDA.kext

kext-dev-mode allowing invalid signature -67062 0xFFFFFFFFFFFEFA0A for kext ACPIBatteryManager.kext

AppleHPM.kext - dependency 'com.apple.driver.AppleIntelLpssI2CController' not found.

AppleHPM.kext - dependency 'com.apple.driver.AppleIntelLpssI2CController' not found.

Prelink failed for com.apple.driver.AppleHPM; omitting from prelinked kernel.

KernelCache ID: B7795F058969EF7C9912C7AA158BD32F

symlink("/System/Library/PrelinkedKernels/prelinkedkernel", "/System/Library/Caches/com.apple.kext.caches/Startup/kernelcache") failed 17 (File exists) <createPrelinkedKernel 2795>

Bens-MacBook-Pro:~ benraz$

BTW, you may want to add 'SSDT-USBX.aml' to your commented-out SortedOrder in your config.plist files :)
 

Attachments

  • RehabMan.zip
    58.9 KB · Views: 1,034
  • Ben’s MacBook Pro.zip
    558 KB · Views: 748
  • CLOVER.zip
    1.7 MB · Views: 1,136
Great and detailed guide as always RehabMan!

Could you explain why those changes are needed? as the custom SSDT-UIAC.aml + USBInjectAll.kext were doing a great job (I think).

They each address different issues.
This one addresses power property injection.

So for my Skylake Machine, I chose the MacBookPro13,2 SMBIOS which isn't supported by IOUSBHostFamily.ket/Contents/Info.plist.

Following the guide, I should've:
1. Used an EC0->EC DSDT 'hotpatch'
2. Add an SSDT-USBX.aml to ACPI/patched
3. Optional - Add to SortedOrder in my case. Didn't move to the 'hotpatch' method yet

Problem Reporting files are attached, hope I did it well and maybe this feedback can also help you :)

Yes... looks as expected. You have successfully injected 2100/5100 as you can see in ioreg...

BTW, you may want to add 'SSDT-USBX.aml' to your commented-out SortedOrder in your config.plist files :)

For most people, I would probably suggest adding it to your SSDT-UAIC.aml instead of a separate SSDT...
And I'm really trying to phase out SortedOrder (eg. hotpatch for renames, DropOem=false, no SortedOrder)
 
Summary

It appears that Sierra has changed how USB power properties are set. In prior versions, we have injected, AAPL,current-available, AAPL,current-extra, AAPL,current-extra-in-sleep, and AAPL,max-port-current-in-sleep directly on the XHC/EHCI ACPI objects. In Sierra, these appear to be replaced by new properties that are injected on the AppleBusPowerControllerUSB object in ioreg.

Let's take a look at the changes required...


Tracing the evidence

Some of these changes were noticed during development of USBInjectAll.kext... And I had remembered about some "kUSB*" properties that looked interesting in one of the USB kext Info.plist files. A simple grep search can reveal where we might look:

Code:
SPEEDY-NUC:nuc.git rehabman$ grep -l kUSB.* -R /System/Library/Extensions/IOUSBHostFamily.kext
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/Info.plist
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/MacOS/IOUSBHostFamily
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBEHCI.kext/Contents/MacOS/AppleUSBEHCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBEHCIPCI.kext/Contents/Info.plist
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBEHCIPCI.kext/Contents/MacOS/AppleUSBEHCIPCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHostCompositeDevice.kext/Contents/MacOS/AppleUSBHostCompositeDevice
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHostMergeProperties.kext/Contents/Info.plist
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHub.kext/Contents/Info.plist
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHub.kext/Contents/MacOS/AppleUSBHub
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBOHCIPCI.kext/Contents/MacOS/AppleUSBOHCIPCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBUHCI.kext/Contents/MacOS/AppleUSBUHCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBUHCIPCI.kext/Contents/MacOS/AppleUSBUHCIPCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBXHCI.kext/Contents/MacOS/AppleUSBXHCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBXHCIPCI.kext/Contents/Info.plist
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBXHCIPCI.kext/Contents/MacOS/AppleUSBXHCIPCI
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/IOUSBHostHIDDevice.kext/Contents/MacOS/IOUSBHostHIDDevice

So... it looks like /System/Library/Extensions/IOUSBHostFamily.kext/Contents/Info.plist is a good place to start.

And look what we find:
View attachment 255374

As you can see there are various properties (kUSBSleepPortCurrentLimit, kUSBSleepPowerSupply, kUSBWakePortCurrentLimit, kUSBWakePowerSupply), which are being injected to provider AppleBusPOwerControllerUSB via an AppleUSBHostMergeProperties injector.

But I checked my own ioreg and AppleBusPowerControllerUSB was not loaded anywhere. So now the question is what causes it to load... Another simple grep search will tell us:

Code:
SPEEDY-NUC:nuc.git rehabman$ grep -l AppleBusPowerControllerUSB -R /System/Library/Extensions
/System/Library/Extensions/AppleBusPowerController.kext/Contents/Info.plist
/System/Library/Extensions/AppleBusPowerController.kext/Contents/MacOS/AppleBusPowerController
/System/Library/Extensions/IOUSBHostFamily.kext/Contents/Info.plist

And now, looking at AppleBusPowerController.kext's Info.plist:
View attachment 255375

We can see that it matches on an ACPI device named 'EC'. Some PCs use EC for the Embedded Controller, but most use EC0 or H_EC.
With that knowledge, we can simply rename H_EC->EC, or EC0->EC, and then AppleBusPowerControllerUSB will load, as will the related injections for each supported SMBIOS in IOUSBHostFamily.kext/Contents/Info.plist.

Now, if you look carefully at the IOUSBHostFamily Info.plist, you find that newer SMBIOS are missing. Such as MacBookPro9,1, iMac17,1, and MacBookPro13,x. These models must use a different method for USB power property injection.

Disassembly of AppleBusPowerController reveals that it is looking in IOACPIPlane for an object named 'USBX'. It then appears to extract the necessary data from device-properties. If we look at the ioreg for an iMac17,1, we find this:
View attachment 255376

And there are our power properties again...

Looking at DSDT.aml for the iMac17,1, we find the source for USBX:
Code:
    Scope (_SB)
    {
...
        Device (USBX)
        {
            Name (_ADR, Zero)  // _ADR: Address
            Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
            {
                Store (Package (0x08)
                    {
                        "kUSBSleepPowerSupply",
                        0x13EC,
                        "kUSBSleepPortCurrentLimit",
                        0x0834,
                        "kUSBWakePowerSupply",
                        0x13EC,
                        "kUSBWakePortCurrentLimit",
                        0x0834
                    }, Local0)
                DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
                Return (Local0)
            }
        }

So, no surprise there... standard _DSM injection of the four USB power properties.

Summary:
- if the PC has an EC, name it 'EC' and AppleBusPowerControllerUSB will load.
- if the SMBIOS matches one of the "legacy SMBIOS" in IOUSBHostFamily.kext/Contents/Info.plist, power properties for that Mac model will be injected (they may or may not be appropriate for your hardware)
- if the SMBIOS is not present in IOUSBHostFamily.kext/Contents/Info.plist, power properties are determined by the USBX device in ACPI via normal _DSM property injection


Insuring AppleBusPowerControllerUSB loads

If you have an Embedded Controller (most laptops, some desktops), you can simply make sure the ACPI device is named EC. This is easily accomplished with a ACPI hotpatch in config.plist. I have added both the common renames into all the laptop guide plists.

Here is what they look like:
View attachment 255377

If you don't have an embedded controller, you can add a "fake" one with the following SSDT-EC.dsl (compile to AML):
Code:
// Inject Fake EC device
DefinitionBlock("", "SSDT", 2, "hack", "EC", 0)
{
    Device(_SB.EC)
    {
        Name(_HID, "EC000000")
    }
}
//EOF


An SSDT to inject the USBX device

For SMBIOS that are not already covered in IOUSBHostFamily.kext/Contents/Info.plist, you will need to inject the USBX device in order to provide the power properties for AppleBusPowerControllerUSB.

Here is an example SSDT-USBX.dsl:
Code:
// USB power properties via USBX device
DefinitionBlock("", "SSDT", 2, "hack", "USBX", 0)
{
    Device(_SB.USBX)
    {
        Name(_ADR, 0)
        Method (_DSM, 4)
        {
            If (!Arg2) { Return (Buffer() { 0x03 } ) }
            Return (Package()
            {
                // these values from iMac17,1
                "kUSBSleepPortCurrentLimit", 2100,
                "kUSBSleepPowerSupply", 5100,
                "kUSBWakePortCurrentLimit", 2100,
                "kUSBWakePowerSupply", 5100,
            })
        }
    }
}
//EOF

You might think that you could also override the values provided by IOUSBHostFamily.kext/Contents/Info.plist in the case a supported SMBIOS is being used. But unfortunately, that is not the case... the values in IOUSBHostFamily.kext/Contents/Info.plist override those that are provided by USBX.


Overriding the IOUSBHostFamily.kext/Contents/Info.plist

Although you could patch this kext Info.plist to provide different properties for any supported SMBIOS, it is desirable to do so without patching since patching would need to be redone after any update that provided a new copy of the file.

I have added support in USBInjectAll.kext to inject these properties. And, at least in my testing, the properties injected by USBInjectAll.kext are succesful in overriding those from IOUSBHostFamily.kext.

To specify power property overrides via USBInjectAll.kext, you must provide an "AppleBusPowerControllerUSB" in your UIAC.RMCF.

For example:
Code:
DefinitionBlock ("", "SSDT", 2, "hack", "usb", 0)
{
//
// Override for USBInjectAll.kext
//
    Device(UIAC)
    {
        Name(_HID, "UIA00000")
        Name(RMCF, Package()
        {
            // USB Power Properties for Sierra (using USBInjectAll injection)
            "AppleBusPowerControllerUSB", Package()
            {
                // these values happen to be iMac14,2 values...
                "kUSBSleepPortCurrentLimit", 2100,
                "kUSBSleepPowerSupply", 4700,
                "kUSBWakePortCurrentLimit", 2100,
                "kUSBWakePowerSupply", 4700,
            },
            // XHC overrides (8086:9cb1, NUC5)
            "8086_9cb1", Package()
            {
// other UIAC.RMCF content follows (for custom port injection)
...
}
//EOF

This feature is newly added in v0.6.0 of USBInjectAll.kext, so don't expect it to work in older versions.


Problem Reporting

Read FAQ, "Problem Reporting"
https://www.tonymacx86.com/threads/faq-read-first-laptop-frequent-questions.164990/

Hey. Great Guide mate :thumbup:. Now heres a question. What about SSDT-XHC? Can we leave that in place and add? Ive also noticed in my Native Extracted DSDT and in Patchmatic i don't have a entry for H_EC or EC0.

Code:
DefinitionBlock ("", "SSDT", 2, "hack", "usb", 0)
{
//
// Override for USBInjectAll.kext
//
    Device(UIAC)
    {
        Name(_HID, "UIA00000")
        Name(RMCF, Package()
        {
            // USB Power Properties for Sierra (using USBInjectAll injection)
            "AppleBusPowerControllerUSB", Package()
            {
                // these values happen to be iMac14,2 values...
                "kUSBSleepPortCurrentLimit", 2100,
                "kUSBSleepPowerSupply", 4700,
                "kUSBWakePortCurrentLimit", 2100,
                "kUSBWakePowerSupply", 4700,
            },
            // XHC overrides (8086:9cb1, NUC5)
            "8086_9cb1", Package()
            {
// other UIAC.RMCF content follows (for custom port injection)
...
}
//EOF
 
Hey. Great Guide mate :thumbup:. Now heres a question. What about SSDT-XHC? Can we leave that in place and add?

You can leave the other AAPL, property injects still there for the case you're booting 10.11 or older...

Ive also noticed in my Native Extracted DSDT and in Patchmatic i don't have a entry for H_EC or EC0.

If it is a desktop, you may not have an EC (even some laptops don't have an EC).
That scenario is covered in post #1.
 
You can leave the other AAPL, property injects still there for the case you're booting 10.11 or older...



If it is a desktop, you may not have an EC (even some laptops don't have an EC).
That scenario is covered in post #1.

Cheers mate. Im going to take a look into this with iMac 13,2 see what the outcome is. Seems to be easy enough for EC as you mentioned create a Fake SSDT for EC.
 
Last edited:
Yes... looks as expected. You have successfully injected 2100/5100 as you can see in ioreg...
That's great, thank you! :)

For most people, I would probably suggest adding it to your SSDT-UAIC.aml instead of a separate SSDT...
Will be moved to SSDT-UIAC.

And I'm really trying to phase out SortedOrder (eg. hotpatch for renames, DropOem=false, no SortedOrder)
Understood, the advantages it has over static patching are a big difference.
I wish I had time to do so now (together with an update to 10.12.5), but I have that big project and I need a fully functional laptop, and I don't have that much time - this change was very quick but an upgrade/move to hotpatch would take much more time (link for my 8086 project in post #2, have a look :p )
 
Just a thumbs up here are the Values for iMac 13,2 from IOUSBHostFamily.kext.

Code:
DefinitionBlock("", "SSDT", 2, "hack", "USBX", 0)
{
    Device(_SB.USBX)
    {
        Name(_ADR, 0)
        Method (_DSM, 4)
        {
            If (!Arg2) { Return (Buffer() { 0x03 } ) }
            Return (Package()
            {
                // these values from iMac13,2
                "kUSBSleepPortCurrentLimit", 2100,
                "kUSBSleepPowerSupply", 4700,
                "kUSBWakePortCurrentLimit", 2100,
                "kUSBWakePowerSupply", 4700,
            })
        }
    }
}
//EOF
 
Cheers mate. Im going to take a look into this with iMac 13,2 see what the outcome is. Seems to be easy enough for EC as you mentioned create a Fake SSDT for EC.

Im trying to create a New SSDT-UIAC. Could you take a look at my ioreg because I'm not sure if I need to leave PR01, PR12 on EH01 and EH02. What do you think?
 

Attachments

  • Jack’s iMac.ioreg
    4.4 MB · Views: 764
Back
Top