Jump to content

No graphics / USB / Audio after wake


anor4k
 Share

586 posts in this topic

Recommended Posts

  • 3 weeks later...
  • 2 months later...

So I just put my Hackintosh (Sierra, R9 280) to sleep, forgetting that sleep/wake won't work with the Radeon installed (was using a Nvidia GPU for the last months). When I came back, the system had rebooted "because of an error" and presented a "Sleep Wake Failure" dialogue. Never saw such a thing before, maybe this happens when waking goes wrong and you wait a looong time? Don't know.

 

Most interesting part of this stackshot is here:

  Thread 0x3e7              Thread name "IOGraphicsWorkLoop"                    10 samples (1-10)         priority 93 (base 81)     cpu time 0.109
  <IO tier 0>
 *10  call_continuation + 23 (kernel + 666359) [0xffffff80002a2af7] 1-10
   *10  IOWorkLoop::threadMain() + 22 (kernel + 7063078) [0xffffff80008bc626] 1-10
     *10  IOWorkLoop::runEventSources() + 433 (kernel + 7065665) [0xffffff80008bd041] 1-10
       *10  IOInterruptEventSource::checkForWork() + 287 (kernel + 7071711) [0xffffff80008be7df] 1-10
         *10  IOFramebuffer::systemWork(OSObject*, IOInterruptEventSource*, int) + 211 (IOGraphicsFamily + 45939) [0xffffff7f81790373] 1-10
           *10  IOFramebuffer::checkPowerWork(IOFBController*, unsigned int) + 140 (IOGraphicsFamily + 62582) [0xffffff7f81794476] 1-10
             *10  IOFramebuffer::checkPowerWork(unsigned int) + 503 (IOGraphicsFamily + 66267) [0xffffff7f817952db] 1-10
               *10  AMDFramebuffer::setAttribute(unsigned int, unsigned long) + 3287 (AMDFramebuffer + 40167) [0xffffff7f8309dce7] 1-10
                 *10  AMDFramebuffer::setAttribute(unsigned int, unsigned long) + 741 (AMDFramebuffer + 37621) [0xffffff7f8309d2f5] 1-10
                   *10  AMDFramebuffer::doSetPowerState(unsigned int) + 147 (AMDFramebuffer + 65555) [0xffffff7f830a4013] 1-10
                     *10  AMDFramebuffer::setSystemPowerState(unsigned int) + 132 (AMDFramebuffer + 66468) [0xffffff7f830a43a4] 1-10
                       *10  AMDFramebuffer::doDoze() + 56 (AMDFramebuffer + 68904) [0xffffff7f830a4d28] 1-10
                         *10  AMDFramebuffer::doWake() + 995 (AMDFramebuffer + 67491) [0xffffff7f830a47a3] 1-10
                           *10  AMD7000Controller::wakePowerPlay(bool) + 144 (AMD7000Controller + 132848) [0xffffff7f830ed6f0] 1-10
                             *10  SISharedController::wakePowerPlay(bool) + 120 (AMD7000Controller + 65272) [0xffffff7f830dcef8] 1-10
                               *10  SIPowerPlayManager::wakeUp() + 98 (AMD7000Controller + 104882) [0xffffff7f830e69b2] 1-10
                                 *10  SIPowerPlayManager::initialize() + 554 (AMD7000Controller + 102666) [0xffffff7f830e610a] 1-10
                                   *10  ATIController::sendRequestToAccelerator(_eAMDAccelIOFBRequestType, void*, void*, void*) + 162 (AMDSupport + 11362) [0xffffff7f82512c62] 1-10
                                     *10  AMDRadeonX4000_AMDGraphicsAccelerator::callPlatformFunction(OSSymbol const*, bool, void*, void*, void*, void*) + 460 (AMDRadeonX4000 + 19312) [0xffffff7f8270fb70] 1-10
                                       *10  AMDRadeonX4000_AMDGraphicsAccelerator::powerUpHW() + 297 (AMDRadeonX4000 + 12457) [0xffffff7f8270e0a9] 1-10
                                         *10  AMDTahitiHardware::powerUp() + 23 (AMDRadeonX4000 + 422413) [0xffffff7f8277220d] 1-10
                                           *10  AMDSIHardware::powerUp() + 23 (AMDRadeonX4000 + 411069) [0xffffff7f8276f5bd] 1-10
                                             *10  AMDRadeonX4000_AMDHardware::powerUp() + 461 (AMDRadeonX4000 + 475259) [0xffffff7f8277f07b] 1-10
                                               *10  AMDRadeonX4000_AMDHWChannel::waitForIdle() + 99 (AMDRadeonX4000 + 304603) [0xffffff7f827555db] 1-10
                                                 *10  AMDSIPM4Engine::isIdle() + 22 (AMDRadeonX4000 + 427592) [0xffffff7f82773648] 1-10
                                                   *10  AMDRadeonX4000_AMDHWRegisters::read(unsigned int) + 40 (AMDRadeonX4000 + 353890) [0xffffff7f82761662] (running) 1-10

So it looks like AMDX4000 gets stuck / crashes within "AMDHWRegisters::read". Not sure if this is news for anyone, but it might be a starting point...

I never had to debug a kernel extension, so I might not be the best person for this job. Someone has a good idea what to do next?

 

Full Stackshot is attached. Btw, didn't manage to reproduce that behavior yet.

Sleep Wake Failure.rtf

Link to comment
Share on other sites

The kernel serializes calls to drivers setPowerState() by calling them in a separate thread and when the AMD driver hangs on the power state change, it effectively hangs the whole thread killing power management completely. This is the reason why the kernel causes the machine to reboot and it's a well known behavior, sorry!

 

Mieze

Link to comment
Share on other sites

Okay, thanks for explanation!

 

That HWREgister::Read-Function is actually quite short:

 

post-23137-0-22435100-1480023994_thumb.png

 

I don't think anyone ever got that mentioned "panic on poweroff register access" (google doesn't reveal a single hit)? Which would mean this either never happens or that debug option is always disabled. So the AMD driver might get stuck within the IOLock thingy below while trying to access a register when the GPU still sleeps?

 

Should be easy to prove that by altering the cmp-statement in line #7: Next wake attempt should produce an instant kernel panic instead of getting "just" stuck.

Maybe the GPU just doesn't wake fast enough? Did anyone ever try adding a short IOSleep in one of the wakeup functions?

 

Will have another look at this tomorrow... Have to sleep now, otherwise I'll wake up as bad as my Radeon.  :thumbsdown_anim:

 

EDIT: One last thing, did anyone ever investigate the order in which all drivers/devices are woken up? Is this deterministic? Would be interesting to know if there's a different order on working setups (e.g. iGPU=Primary or genuine Mac) and non-working setups (Hackintosh with dGPU=Primary).

 

EDIT2: Okay, changing the "jz" in line #8 to "jnz" didn't trigger the panic, so it's either not a "poweroff register access" or it gets stuck before.

Link to comment
Share on other sites

EDIT: One last thing, did anyone ever investigate the order in which all drivers/devices are woken up? Is this deterministic? Would be interesting to know if there's a different order on working setups (e.g. iGPU=Primary or genuine Mac) and non-working setups (Hackintosh with dGPU=Primary).

Three things I'd like to mention:

  1. Of course it's deterministic and, for logical reasons, the order is dictated by the device hierarchy.
  2. Searching for a solution with the AMD GPU as primary is futile because Apple designed it as a master-slave-architecture with the IGPU as master and the AMD GPU as slave, even in the 2013 MacPro where device GCON takes the role of the master.
  3. Wakeup with UEFI Video Op ROM probably doesn't work because of the UEFI driver interfering with OS X's driver as the UEFI driver gets called during wakeup. With Legacy Video OP ROM there is no such thing like wakeup support by the BIOS so that the AMD GPU is under full control of OS X's driver during sleep/wake cycles. You might ask yourself why it works with Apple's EFI drivers in real Macs? Well, I investigated the AMD GPU's EFI driver of an iMac15,1 and according to the header structure I can tell that this is not a UEFI compliant driver, it's proprietary in a certain way.

Mieze

  • Like 1
Link to comment
Share on other sites

...UEFI driver interfering with OS X's driver as the UEFI driver gets called during wakeup. With Legacy Video OP ROM there is no such thing like wakeup support by the BIOS so that the AMD GPU is under full control of OS X's driver during sleep/wake cycles. 

Mieze

 

But we have successful sleep/wake confirmations from MacPro5,1 owners with unmodified PC Radeon Cards. The OSX drivers have to interfere with the UEFI driver also in such cases or not? 

Link to comment
Share on other sites

  1. Searching for a solution with the AMD GPU as primary is futile because Apple designed it as a master-slave-architecture with the IGPU as master and the AMD GPU as slave, even in the 2013 MacPro where device GCON takes the role of the master.
  2. Wakeup with UEFI Video Op ROM probably doesn't work because of the UEFI driver interfering with OS X's driver as the UEFI driver gets called during wakeup. With Legacy Video OP ROM there is no such thing like wakeup support by the BIOS so that the AMD GPU is under full control of OS X's driver during sleep/wake cycles. You might ask yourself why it works with Apple's EFI drivers in real Macs? Well, I investigated the AMD GPU's EFI driver of an iMac15,1 and according to the header structure I can tell that this is not a UEFI compliant driver, it's proprietary in a certain way.

 

Well, classic MacPros can wake with unflashed (=> legacy OpROM) Radeon GPUs.

I also thought about the possibility that OS X might not like booting with UEFI GPU (-> so cMPs are unaffected), so I did the following experiment:

  1. Enter UEFI shell in Clover (AMD GPU primary)
  2. Disconnect and unload the UEFI AMD video driver
  3. Blindly exit UEFI shell and boot OS X
  4. Try to wake from sleep => same issue as always  :(

To prove it the other way around, one could boot OS X on a genuine Mac Pro with a stock PC GPU installed using Clover. Would be interesting to see if the MacPro still wakes properly.

I'd test it myself, but my MacPro has a broken NVRAM, so I can't configure the boot drive...

Link to comment
Share on other sites

  • 2 weeks later...

I'm starting to think the iGPU is actually completely unrelated. Did a short experiment:

 

Boot with iGPU = Primary, MultiMonitor = Disabled

  1. Display connected to dGPU on boot (didn't display anything), did wake as expected.

Note: Had to do this with CSM enabled and legacy OpROM, otherwise my Radeon will start displaying at Clover boot screen and the system won't wake. On the next boot, the Primary GPU will be reset to "auto". Not sure if this is a BIOS bug?!

 

Boot with iGPU = Primary, MultiMonitor = Enabled, CSM disabled

  1. Display connected to dGPU on boot (displays boot screen), did not wake. 
  2. Display not connected to any port, system wakes.

The iGPU was properly recognised in both cases in System Profiler -> Graphics.

 

Boot with dGPU = Primary, MultiMonitor = Enabled, CSM disabled

  1. Display connected to dGPU on boot (displays boot screen), did not wake. 
  2. Display not connected to any port, system wakes.

The iGPU was not recognised in System Profiler, but OpenCL acceleration was functional (verified with Luxmark).

 

Boot with dGPU = Primary, MultiMonitor = Disabled, CSM disabled

  1. Display connected to dGPU on boot (displays boot screen), did not wake. 
  2. Display not connected to any port, system wakes.

No iGPU at all (as expected).

 

 

So my iGPU doesn't matter at all, as long as I prevent the UEFI from init'ing my dGPU (either with proper BIOS settings or pulling the cable). As soon as the EFI video is initialised on my Radeon dGPU, sleep/wake will be broken, even if I disconnect the cable during boot phase (e.g. after selecting my OS X drive in Clover). I also tried to unload the EFI video driver from the EFI shell, but that didn't fix sleep/wake either.

 

Note: Tests were done on a Skylake system (6600K / Asus Z170M-Plus, R9 280, CSM disabled), so my Skylake iGPU will break sleep/wake, too, as soon as OS X uses it as display output. Using the Skylake iGPU just as OpenCL accelerator is fine though.

 

Thoughts?

Link to comment
Share on other sites

 

 

Thoughts?

I am sorry but I have no new thought rather then 534 posts in this thread.

To have sleep working I have to do

1. IGPU is primary.

2. IGPU memory set to 32Mb is BIOS. Nothing else.

3. CSM is ON.

There are strict 3 conditions to make my Radeon wake up and have full acceleration.

Inject->ATI=NO and so default framebuffer used.

  • Like 1
Link to comment
Share on other sites

I guess it depends on the specific UEFI implementation. On my Asus mainboard, CSM completely changes the behavior:

 

When CSM is enabled (and set to legacy OpROM), the EFI will always initialize the graphics adapter, which is specified as "Primary" (even if no display is connected). And only this one, the other alternative won't show any pre-OS video output! Accordingly the system will only wake when iGPU is primary, no matter what is connected where.

 

When CSM is disabled and MultiMonitor is enabled, the EFI will always init the GPU which has a monitor connected to it, no matter which one is primary. This means the dGPU won't get init'ed as long as no display is connected during boot time, thus sleep will work.

 

So the EFI display driver seems to do something to the GPU, which the OS X drivers don't like at all. (Btw, did anyone ever try to use a Apple GOP EFI driver on a PC? The D700's in the nMP should be GOP...).

  • Like 1
Link to comment
Share on other sites

Probably did this without success else there must be victory report but no.

Take into account also: if I erase kext AMDRadeonX3000.kext then Radeon will sleep/wake without problem no matter of BIOS. But no QE/CI/OpenGL. 

Link to comment
Share on other sites

I have been following this topic, because I have two HD6540 cards that have this problem.

Just a thought:

 

If the card wakes in a Mac.

If the software is all the same on a Mac and Hack.

 

Could there be a difference in the DSDT/SSDT between an Mac and a Hack? Some definition or method that is missing or different, but that is required for the card to wake properly?

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...
  • 2 weeks later...

Did Apple completely disable HD4000 on hardware level on Macbook Pro's that had dedicated Radeon GPU's? I mean that if they did, what's different with EliteBooks that have dedicated Radeon and HD4000 is not even wired on the motherboard.

MacBook Pro models that had HD 4000 had a 650M as the dGPU. They can switch between them (HD 4000 isn't disabled). HD 4000 also isn't part of the motherboard, it's part of the CPU.

  • Like 1
Link to comment
Share on other sites

Thanks. I guess it's the same an all Macbooks then.

All MBPro's and the 2013 MacPro have device GMUX, aka GCON on the MacPro, to switch between GPUs. For details how this works, please see the corresponding linux driver where you can find more information: https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/tree/drivers/platform/x86/apple-gmux.c?id=refs/tags/next-20161220

 

By the way, as GMUX is an I/O-port mapped device, you could make a FakeGMUX kext (just like FakeSMC emulates Apple's SMC) for notebooks with switchable graphics, provided you know how your notebook switches between both GPUs.

 

Mieze  :cat:

  • Like 3
Link to comment
Share on other sites

By the way, as GMUX is an I/O-port mapped device, you could make a FakeGMUX kext (just like FakeSMC emulates Apple's SMC) for notebooks with switchable graphics, provided you know how your notebook switches between both GPUs.

Since on most laptops the output of the dedicated graphicscard is going into the integrated graphics, which is connected to the display or hdmi and forwards the input, wouldn't this be a problem in macOS, or is it tunneled through the integrated as well on real MBs?

Sorry for OT..

Link to comment
Share on other sites

Since on most laptops the output of the dedicated graphicscard is going into the integrated graphics, which is connected to the display or hdmi and forwards the input, wouldn't this be a problem in macOS, or is it tunneled through the integrated as well on real MBs?

Sorry for OT..

Device GMUX is a microcontroller which controls an analog switch to multiplex the display outputs from the IGPU and the dedicated GPU to the panel. In order to prevent flickering, GMUX synchronizes both display signals by extending the vertical blanking gap. This procedure is patented by Apple (see link in the Linux driver) so that other manufacturers will probably use a different method to switch GPUs.

 

Provided there is a Linux driver for switching GPUs on your notebook too, you could examine it in order to find out how this task is performed on your machine.

 

Mieze

  • Like 2
Link to comment
Share on other sites

 Share

×
×
  • Create New...