Contribute
Register

[BUG] Black screen 3 minutes after booting, CoffeeLake UHD 630

The issue remains with me if I use SSDT-PNLF. How did you manage with SSDT-PNLF?

The only way I got the slider was to remove the SSDT PNLF and then use the Add PNLF option in the clover. That way the slider worked but the max brightness of the laptop was very dim.
No "Problem Reporting" files attached.
Read FAQ, "Problem Reporting" again. Carefully. Attach all requested files/output.
https://www.tonymacx86.com/threads/faq-read-first-laptop-frequent-questions.164990/
Use the gen_debug.sh tool mentioned in the FAQ, that way it is less likely you'll omit something.
 
At the Clover boot screen can you press F4 to save original (OEM) ACPI tables into /EFI/CLOVER/ACPI/origin then zip the files up and attach them here.
I have same issue,This is my original ACPI table.
 

Attachments

  • origin.zip
    109.8 KB · Views: 81

Attachments

  • debug_24660.zip
    1.6 MB · Views: 69
I have same issue,This is my original ACPI table.

I'll tell you how I got the backlight slider working for my system but I still recommend you follow RehabMan's directions as he's far more experienced in this area than me.

1. Download and install RehabMan's version of MaciASL from here
2. Run MaciASL
3. Choose Preferences from the MaciASL menu bar
4. Select Sources
5. Click the [+] button
6. Give it a name (eg. "Laptop Patches")
7. Type the following URL: http://raw.github.com/RehabMan/Laptop-DSDT-Patch/master
8. Copy your DSDT.aml file to /EFI/CLOVER/ACPI/patched and then open it in MaciASL
9. Click the "Patch" icon and select "[igpu] Brightness fix (ACPI 100)" from the list
10. It should say "4 Patches, 1 Change, 0 Rejects"
11. Click Apply button
12. Click the Compile button
13. You will get several errors Eg. "Object not found or not accessible from scope (^^DD02._BCM)"
14. Double click the first error to jump to it
15. Now carefully copy/paste this code over the top of the relevant ACPI code:
Code:
                       // _BCM/_BQC: set/get for brightness level
                       Method (_BCM, 1, NotSerialized)
                       {
                           // Update backlight via existing DSDT methods
                           External(^^DD1F._BCM, MethodObj)
                           ^^DD1F._BCM(Arg0)
                       }
                       Method (_BQC, 0, NotSerialized)
                       {
                           External(^^DD1F._BQC, MethodObj)
                           Return(^^DD1F._BQC())
                       }
                       Method (_BCL, 0, NotSerialized)
                       {
                           External(^^DD1F._BCL, MethodObj)
                           Return(^^DD1F._BCL())
                       }
                       Method (_DOS, 1, NotSerialized)
                       {
                           External(^^_DOS, MethodObj)
                           ^^_DOS(Arg0)
                       }
                       // extended _BCM/_BQC for setting "in between" levels
                       Method (XBCM, 1, NotSerialized)
                       {
                           // Update backlight via existing DSDT methods
                           ^^DD1F._BCM(Arg0)
                       }
                       Method (XBQC, 0, NotSerialized)
                       {
                           Return(^^DD1F._BQC())
                       }
16. Hit Compile again and it should not show any errors
17. Save your changes and reboot
 
Last edited:
I'll tell you how I got the backlight slider working for my system but I still recommend you follow RehabMan's directions as he's far more experienced in this area than me.

1. Download and install RehabMan's version of MaciASL from here
2. Run MaciASL
3. Choose Preferences from the MaciASL menu bar
4. Select Sources
5. Click the [+] button
6. Give it a name (eg. "Laptop Patches")
7. Type the following URL: http://raw.github.com/RehabMan/Laptop-DSDT-Patch/master
8. Copy your DSDT.aml file to /EFI/CLOVER/ACPI/patched and then open it in MaciASL
9. Click the "Patch" icon and select "[igpu] Brightness fix (ACPI 100)" from the list
10. It should say "4 Patches, 1 Change, 0 Rejects"
11. Click Apply button
12. Click the Compile button
13. You will get several errors Eg. "Object not found or not accessible from scope (^^DD02._BCM)"
14. Double click the first error to jump to it
15. Now carefully copy/paste this code over the top of the relevant ACPI code:
Code:
                       // _BCM/_BQC: set/get for brightness level
                       Method (_BCM, 1, NotSerialized)
                       {
                           // Update backlight via existing DSDT methods
                           External(^^DD1F._BCM, MethodObj)
                           ^^DD1F._BCM(Arg0)
                       }
                       Method (_BQC, 0, NotSerialized)
                       {
                           External(^^DD1F._BQC, MethodObj)
                           Return(^^DD1F._BQC())
                       }
                       Method (_BCL, 0, NotSerialized)
                       {
                           External(^^DD1F._BCL, MethodObj)
                           Return(^^DD1F._BCL())
                       }
                       Method (_DOS, 1, NotSerialized)
                       {
                           External(^^_DOS, MethodObj)
                           ^^_DOS(Arg0)
                       }
                       // extended _BCM/_BQC for setting "in between" levels
                       Method (XBCM, 1, NotSerialized)
                       {
                           // Update backlight via existing DSDT methods
                           ^^DD1F._BCM(Arg0)
                       }
                       Method (XBQC, 0, NotSerialized)
                       {
                           Return(^^DD1F._BQC())
                       }
16. Hit Compile again and it should not show any errors
17. Save your changes and reboot
work now
 
Last edited:
I'll tell you how I got the backlight slider working for my system but I still recommend you follow RehabMan's directions as he's far more experienced in this area than me.

1. Download and install RehabMan's version of MaciASL from here
2. Run MaciASL
3. Choose Preferences from the MaciASL menu bar
4. Select Sources
5. Click the [+] button
6. Give it a name (eg. "Laptop Patches")
7. Type the following URL: http://raw.github.com/RehabMan/Laptop-DSDT-Patch/master
8. Copy your DSDT.aml file to /EFI/CLOVER/ACPI/patched and then open it in MaciASL
9. Click the "Patch" icon and select "[igpu] Brightness fix (ACPI 100)" from the list
10. It should say "4 Patches, 1 Change, 0 Rejects"
11. Click Apply button
12. Click the Compile button
13. You will get several errors Eg. "Object not found or not accessible from scope (^^DD02._BCM)"
14. Double click the first error to jump to it
15. Now carefully copy/paste this code over the top of the relevant ACPI code:
Code:
                       // _BCM/_BQC: set/get for brightness level
                       Method (_BCM, 1, NotSerialized)
                       {
                           // Update backlight via existing DSDT methods
                           External(^^DD1F._BCM, MethodObj)
                           ^^DD1F._BCM(Arg0)
                       }
                       Method (_BQC, 0, NotSerialized)
                       {
                           External(^^DD1F._BQC, MethodObj)
                           Return(^^DD1F._BQC())
                       }
                       Method (_BCL, 0, NotSerialized)
                       {
                           External(^^DD1F._BCL, MethodObj)
                           Return(^^DD1F._BCL())
                       }
                       Method (_DOS, 1, NotSerialized)
                       {
                           External(^^_DOS, MethodObj)
                           ^^_DOS(Arg0)
                       }
                       // extended _BCM/_BQC for setting "in between" levels
                       Method (XBCM, 1, NotSerialized)
                       {
                           // Update backlight via existing DSDT methods
                           ^^DD1F._BCM(Arg0)
                       }
                       Method (XBQC, 0, NotSerialized)
                       {
                           Return(^^DD1F._BQC())
                       }
16. Hit Compile again and it should not show any errors
17. Save your changes and reboot

All you're doing here is adding a PNLF in a very complex way (that attempts no initialization of the backlight).
Because we do not expect that AppleBacklight uses all the ACPI functions (_BCM, _BQC, _BCL, etc), the "ACPI 100" patch is overkill for what you're actually trying to accomplish (those methods are for ACPIBacklight.kext).

It is the same as using config.plist/ACPI/DSDT/Fixes/AddPNLF=true.
Or an SSDT as follows:
Code:
DefinitionBlock("", "SSDT", 2, "hack", "_PNLF", 0)
{
    Device(_SB.PCI0.IGPU.PNLF)
    {
        Name(_ADR, Zero)
        Name(_HID, EisaId ("APP0002"))
        Name(_CID, "backlight")
        Name(_UID, 10)
        Name(_STA, 0x0B)
    }
}
//EOF

You end up (without any kext for backlight profile) with ApplePanel=Default. Which works ok, but not 100%.

I think someone (maybe you) mentioned that with CoffeeLake backlight, the backlight level is stored in an additional register at 0xc8258? That would need special handling in SSDT-PNLF.aml (it would be nice to fix SSDT-PNLF.aml for CoffeeLake...).

Did you find a datasheet describing CoffeeLake IGPU backlight PWM registers?

BTW, I think the end result of the cflbkltfix code in WhateverGreen.kext is that you're fixing the issue there instead of SSDT-PNLF.aml... So, the same fix could be employed in the SSDT. The basic problem is this: Apple expects the backlight to be already setup (and as their drivers expect) by the Apple firmware (a reasonable expectation) which means that the drivers involved can assume a certain amount of initialization has already been done (which means they don't have to do the init, except on wake from sleep). So, on a PC, we need to match this firmware setup. I chose to do it in ACPI _INI, but that is not the only way (IntelBacklight.kext did the fixup in its init code). But Intel keeps changing the way the PWM registers are arranged (note difference between Ivy->Haswell, and now KabyLake->CoffeeLake), so the code in SSDT-PNLF needs changes with it.
 
Last edited:
I think someone (maybe you) mentioned that with CoffeeLake backlight, the backlight level is stored in an additional register at 0xc8258? That would need special handling in SSDT-PNLF.aml (it would be nice to fix SSDT-PNLF.aml for CoffeeLake...).

Yes there is an extra register BXT_BLC_PWM_DUTY1 (0xC8258) but also how the backlight level is written to BXT_BLC_PWM_FREQ1 (0xC8254) is also different.

The issue is inside the CFL framebuffer kext itself. The calculation for BXT_BLC_PWM_DUTY1 is performed in 32-bits which results in a truncation of the value and causes the black screen. @Fraxul's original patch changes the 32-bit op-codes to 64-bit. My patch overwrites two key functions (AppleIntelFramebufferController::hwSetBacklight and AppleIntelFramebuffer::setAttributeForConnection) in the kext and performs the calculation in 64-bits and then writes to the registers.

So my patch is this:
Code:
    uint64_t bxt_blc_pwm_freq1 = callbackIGFX->orgReadRegister32(that, BXT_BLC_PWM_FREQ1);
    uint64_t bxt_blc_pwm_duty1 = callbackIGFX->orgReadRegister32(that, BXT_BLC_PWM_DUTY1);
 
    // Calculate backlight duty in 64-bits so result is not truncated (essentially CFL backlight fix)
    bxt_blc_pwm_freq1 = callbackIGFX->backlightFrequency;
    bxt_blc_pwm_duty1 = static_cast<uint64_t>(callbackIGFX->backlightLevel) * bxt_blc_pwm_freq1 / 0xFFFFLL;
 
    callbackIGFX->orgWriteRegister32(that, BXT_BLC_PWM_FREQ1, static_cast<uint32_t>(bxt_blc_pwm_freq1));
    callbackIGFX->orgWriteRegister32(that, BXT_BLC_PWM_DUTY1, static_cast<uint32_t>(bxt_blc_pwm_duty1));

Notice that the backlight level is not written to BXT_BLC_PWM_FREQ1 (0xC8254) as it has in the past. The level is now part of the calculation of the BXT_BLC_PWM_DUTY1 (0xC8258) register. The BXT_BLC_PWM_FREQ1 value stays the same from boot so you need to store this value early on for later calculation.

So I don't think on this occasion we could get away with a SSDT-PNLF.aml only solution. It would be nice of course but I think until Apple change the CFL fb kext to calculate the duty value using 64-bit operations a low level patch of the kext itself will be necessary.

Also I sent Sherlocks a working patch for Clover which looks like this:
Code:
// Set max brightness level to 0xFFFF or set to value set by IntelMaxValue
LEVX = 0xFFFF;
LEVW = 0xC0000000;

// Read frequency value set by BIOS
PciIo->Mem.Read(PciIo, EfiPciIoWidthUint32, 0,  0xC8254, 1,  &LEVF);

// This calculation needs to be in 64-bit so result is not truncated
LEVD = (UINT32)((UINT64)LEVX * (UINT64)LEVF / 0xFFFFLL);

// Write backlight registers
PciIo->Mem.Write(PciIo, EfiPciIoWidthUint32, 0, 0xC8254, 1, &LEVF);
PciIo->Mem.Write(PciIo, EfiPciIoWidthUint32, 0, 0xC8258, 1, &LEVD);
PciIo->Mem.Write(PciIo, EfiPciIoWidthUint32, 0, 0xC8250, 1, &LEVW);

So you should be able to set IntelMaxValue upon boot and it will do the calculation correctly. But you also need the WEG patch or you will still get a black screen once the CFL fb kext loads.
 
Last edited:
Yes there is an extra register BXT_BLC_PWM_DUTY1 (0xC8258) but also how the backlight level is written to BXT_BLC_PWM_FREQ1 (0xC8254) is also different.

I'll see if I can find a datasheet/hw programming guide.

The issue is inside the CFL framebuffer kext itself. The calculation for BXT_BLC_PWM_DUTY1 is performed in 32-bits which results in a truncation of the value and causes the black screen.
...
So I don't think on this occasion we could get away with a SSDT-PNLF.aml only solution. It would be nice of course but I think until Apple change the CFL fb kext to calculate the duty value using 64-bit operations a low level patch of the kext itself will be necessary.

But it doesn't happen on real Macs, so it must not really be a bug... just a bug in pre-boot setup on PCs trying to hackintosh, no?

Also I sent Sherlocks a working patch for Clover which looks like this:
Code:
// Set max brightness level to 0xFFFF or set to value set by IntelMaxValue
LEVX = 0xFFFF;
LEVW = 0xC0000000;

// Read frequency value set by BIOS
PciIo->Mem.Read(PciIo, EfiPciIoWidthUint32, 0,  0xC8254, 1,  &LEVF);

// This calculation needs to be in 64-bit so result is not truncated
LEVD = (UINT32)((UINT64)LEVX * (UINT64)LEVF / 0xFFFFLL);

// Write backlight registers
PciIo->Mem.Write(PciIo, EfiPciIoWidthUint32, 0, 0xC8254, 1, &LEVF);
PciIo->Mem.Write(PciIo, EfiPciIoWidthUint32, 0, 0xC8258, 1, &LEVD);
PciIo->Mem.Write(PciIo, EfiPciIoWidthUint32, 0, 0xC8250, 1, &LEVW);

So you should be able to set IntelMaxValue upon boot and it will do the calculation correctly. But you also need the WEG patch or you will still get a black screen once the CFL fb kext loads.

Note that I recently changed SSDT-PNLF.dsl to use LMAX=0xFFFF for CFL.
I'll see if I can come up with some changed CFL specific code for SSDT-PNLF.aml.

BTW, it does look like they made the PWM backlight register set make a bit more sense...
 
Last edited:
But it doesn't happen on real Macs, so it must not really be a bug... just a bug in pre-boot setup on PCs trying to hackintosh, no?

On real Macs the value for BXT_BLC_PWM_FREQ1 is low enough that the multiplication part can be done in 32-bits without truncating the result. In fact we know what these values are on real Macs. Either 0x56CE or 0x4571.

So on a real Mac the 0xFFFF * 0x56CE does not overflow 32-bits while the 0xFFFF * 0x1D4C0 for Hacks does.

That being said I don't know why the screen suddenly turns on after 3 minutes without the patch.
 
Last edited:
On real Macs the value for BXT_BLC_PWM_FREQ1 is low enough that the multiplication part can be done in 32-bits without truncating the result. In fact we know what these values are on real Macs. Either 0x56CE or 0x4571.

So on a real Mac the 0xFFFF * 0x56CE does not overflow 32-bits while the 0xFFFF * 0x1D4C0 for Hacks does.

Problem seems to me that the value 0x1d4c0 is larger than the target LMAX, perhaps due to a very large PWMMax used by the PC in question. Probably not all PC laptops use such a large PWMMax, so the problem will not affect all.

And that is the entire point of the _INI code in SSDT-PNLF.. using your register names,... set BXT_BLC_PWM_DUTY1 to the value expected by macOS (0xFFFF), scaling BXT_BLC_PWM_FREQ1 as necessary (in your case, should end up <=0xFFFF) to keep the same level of brightness. Without the code in SSDT-PNLF to set BXT_BLC_PWM_FREQ1 properly, you're ending up with a value larger than BXT_BLC_PWM_DUTY1, which causes the black screen.

I think if we fix SSDT-PNLF, the WEG changes will not be needed.
 
Back
Top