RehabMan
Moderator
- Joined
- May 2, 2012
- Messages
- 181,111
- Motherboard
- Intel DH67BL
- CPU
- i7-2600K
- Graphics
- HD 3000
- Mac
- Mobile Phone
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:
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):
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:
And now, looking at AppleBusPowerController.kext's Info.plist (note: image from 10.12.x):
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:
And there are our power properties again...
Looking at DSDT.aml for the iMac17,1, we find the source for USBX:
Similar for MacBookPro14,3:
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:
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):
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:
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:
And here is another, based on the USBX we find in MacBookPro14,3:
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:
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:
Problem Reporting
Read FAQ, "Problem Reporting"
https://www.tonymacx86.com/threads/faq-read-first-laptop-frequent-questions.164990/
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):
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):
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:
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:
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!
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: