Skip to content

Commit

Permalink
Fixes a kernel panic when booting with the GPU enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
blackgate committed Nov 27, 2017
1 parent 05d6bc8 commit e9cbfe5
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0C955B6D1FADF33500EFC963"
BuildableName = "AMDGPUWakeHandler.kext"
BlueprintName = "AMDGPUWakeHandler"
ReferencedContainer = "container:AMDGPUWakeHandler.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0C955B6D1FADF33500EFC963"
BuildableName = "AMDGPUWakeHandler.kext"
BlueprintName = "AMDGPUWakeHandler"
ReferencedContainer = "container:AMDGPUWakeHandler.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0C955B6D1FADF33500EFC963"
BuildableName = "AMDGPUWakeHandler.kext"
BlueprintName = "AMDGPUWakeHandler"
ReferencedContainer = "container:AMDGPUWakeHandler.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
50 changes: 44 additions & 6 deletions AMDGPUWakeHandler/AMDGPUWakeHandler.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,51 @@
// Based on the linux implementationn of apple-gmux
// https://github.com/torvalds/linux/blob/master/drivers/platform/x86/apple-gmux.c

#include <IOKit/IOLib.h>
#include "AMDGPUWakeHandler.hpp"

#define kMyNumberOfStates 2
#define kIOPMPowerOff 0

#define GMUX_IOSTART 0x700

#define GMUX_PORT_SWITCH_DISPLAY 0x10
#define GMUX_PORT_SWITCH_DDC 0x28
#define GMUX_PORT_SWITCH_EXTERNAL 0x40
#define GMUX_PORT_DISCRETE_POWER 0x50

#define GMUX_SWITCH_DDC_IGD 0x1
#define GMUX_SWITCH_DISPLAY_IGD 0x2
#define GMUX_SWITCH_EXTERNAL_IGD 0x2

#define GMUX_DISCRETE_POWER_OFF 0x0

// This required macro defines the class's constructors, destructors,
// and several other methods I/O Kit requires.
OSDefineMetaClassAndStructors(AMDGPUWakeHandler, IOService)

static inline void outb(unsigned short port, unsigned char value)
static inline void outb(uint16_t port, uint8_t value)
{
asm volatile ("outb %0, %1" : : "a"(value), "Nd"(port));
}

static inline uint8_t inb(uint16_t port)
{
__asm__ __volatile__ ("outb %1, %0" : : "dN" (port), "a" (value));
uint8_t ret;
asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}

void gmux_write8(uint16_t port, uint8_t val) {
outb(GMUX_IOSTART + port, val);
}

uint8_t gmux_read8(unsigned short port) {
return inb(GMUX_IOSTART + port);
}

uint8_t get_discrete_state() {
return gmux_read8(GMUX_PORT_DISCRETE_POWER);
}

// Define the driver's superclass.
Expand All @@ -35,6 +69,10 @@ IOService *AMDGPUWakeHandler::probe(IOService *provider,
{
IOService *result = super::probe(provider, score);
IOLog("Probing\n");
if (get_discrete_state() != 0) {
IOLog("Failed to Load. Discrete GPU was powered on\n");
return 0;
}
return result;
}

Expand Down Expand Up @@ -64,10 +102,10 @@ void AMDGPUWakeHandler::stop(IOService *provider)
void AMDGPUWakeHandler::disableGPU()
{
IOLog("Disabling GPU\n");
outb(0x728, 0x1);
outb(0x710, 0x2);
outb(0x740, 0x2);
outb(0x750, 0x0);
gmux_write8(GMUX_PORT_SWITCH_DDC, GMUX_SWITCH_DDC_IGD);
gmux_write8(GMUX_PORT_SWITCH_DISPLAY, GMUX_SWITCH_DISPLAY_IGD);
gmux_write8(GMUX_PORT_SWITCH_EXTERNAL, GMUX_SWITCH_EXTERNAL_IGD);
gmux_write8(GMUX_PORT_DISCRETE_POWER, GMUX_DISCRETE_POWER_OFF);
}

IOReturn AMDGPUWakeHandler::setPowerState ( unsigned long whichState, IOService * whatDevice )
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This kernel extension disables the AMD GPU after waking up from sleep. It is intended to be used on a 2011 MacBook Pro with a failed AMD GPU.

**NOTE: this should only be used with the grub solution ([found here](https://gist.github.com/blackgate/17ac402e35d2f7e0f1c9708db3dc7a44)) or similar that prevents the AMD kexts from being loaded, otherwise it will kernel panic.**
**NOTE: this should only be used with the grub solution ([found here](https://gist.github.com/blackgate/17ac402e35d2f7e0f1c9708db3dc7a44)) or similar that powers down the discrete GPU before booting macOS, otherwise it will fail to load.**

## Installation

Expand Down

0 comments on commit e9cbfe5

Please sign in to comment.