SMU_Neo2_PlatformPlugin.cpp [plain text]
#include <IOKit/pwr_mgt/IOPM.h>
#include "IOPlatformPluginSymbols.h"
#include "SMU_Neo2_PlatformPlugin.h"
OSDefineMetaClassAndStructors( SMU_Neo2_PlatformPlugin, IOPlatformPlugin )
SMU_Neo2_PlatformPlugin* gPlatformPlugin;
bool SMU_Neo2_PlatformPlugin::start( IOService* provider )
{
gPlatformPlugin = this;
if ( !IOPlatformPlugin::start( provider ) )
{
return( false );
}
if ( pmRootDomain != 0 )
{
pmRootDomain->publishFeature( "Reduce Processor Speed" );
pmRootDomain->publishFeature( "Dynamic Power Step" );
}
if ( gIOPPluginPlatformID )
gIOPPluginPlatformID->release();
gIOPPluginPlatformID = OSSymbol::withCString( "SMU_Neo2" );
if ( thermalProfile != NULL )
{
thermalProfile->adjustThermalProfile();
thermalNub->terminate();
thermalNub = NULL;
thermalProfile = NULL;
}
return( true );
}
UInt8 SMU_Neo2_PlatformPlugin::probeConfig( void )
{
char thermalProfilePrefix[ 128 ] = "ThermalProfile_";
OSDictionary* thermalNubDict;
OSString* modelString;
OSString* name;
UInt8 config = 0;
if ( ( thermalNubDict = OSDictionary::withCapacity( 1 ) ) == NULL )
return( 0 );
if ( ( modelString = OSDynamicCast( OSString, getProvider()->getProperty( "model" ) ) ) == NULL )
return( 0 );
strcat( thermalProfilePrefix, modelString->getCStringNoCopy() );
name = OSString::withCString( thermalProfilePrefix );
thermalNubDict->setObject( "IOName", name );
if ( ( ( thermalNub = new IOService ) == NULL ) || ( !thermalNub->init( thermalNubDict ) ) )
return( 0 );
thermalNub->attach( this );
thermalNub->start( this );
thermalNub->registerService( kIOServiceSynchronous );
if ( ( thermalProfile = OSDynamicCast( IOPlatformPluginThermalProfile, thermalNub->getClient() ) ) != NULL )
{
config = thermalProfile->getThermalConfig();
removeProperty( kIOPPluginThermalProfileKey );
setProperty( kIOPPluginThermalProfileKey, thermalProfile->copyProperty( kIOPPluginThermalProfileKey ) );
}
thermalNubDict->release();
name->release();
return( config );
}
bool SMU_Neo2_PlatformPlugin::getSDBPartitionData( UInt8 partitionID, UInt16 offset, UInt16 length, UInt8* outBuffer )
{
char partitionName[ 20 ];
bool success = false;
sprintf( partitionName, "sdb-partition-%02X", partitionID );
OSData* partitionData;
if ( ( partitionData = OSDynamicCast( OSData, getAppleSMU()->getProperty( partitionName ) ) ) != NULL )
{
const void* partitionBytes;
if ( ( partitionBytes = partitionData->getBytesNoCopy( offset, length ) ) != NULL )
{
bcopy( partitionBytes, outBuffer, length );
success = true;
}
}
return( success );
}
IOService* SMU_Neo2_PlatformPlugin::getAppleSMU( void )
{
if ( !appleSMU )
{
IOService* service;
if ( ( service = waitForService( resourceMatching( "IOPMU" ) ) ) != NULL )
{
appleSMU = OSDynamicCast( IOService, service->getProperty( "IOPMU" ) );
}
}
return( appleSMU );
}
void SMU_Neo2_PlatformPlugin::registerChassisSwitchNotifier( void )
{
IOReturn status;
if (!appleSMU && !getAppleSMU()) return;
status = appleSMU->callPlatformFunction( kSymRegisterForInts, false,
(void *) kPMUenvironmentInt ,
(void *) this ,
(void *) &SMU_Neo2_PlatformPlugin::chassisSwitchHandler ,
NULL );
if (status != kIOReturnSuccess)
{
CTRLLOOP_DLOG( "SMU_Neo2_PlatformPlugin::registerChassisSwitchNotifier failed: 0x%08lx\n", status );
}
}
OSBoolean *SMU_Neo2_PlatformPlugin::pollChassisSwitch( void )
{
IOReturn status;
UInt8 switchState;
if (!appleSMU && !getAppleSMU()) return( kOSBooleanFalse );
status = appleSMU->callPlatformFunction( kSymGetExtSwitches, false,
(void *) &switchState ,
NULL,
NULL,
NULL );
if (status == kIOReturnSuccess)
{
return ( switchState & kClamshellClosedEventMask ) ? kOSBooleanTrue : kOSBooleanFalse;
}
else
{
CTRLLOOP_DLOG( "SMU_Neo2_PlatformPlugin::pollChassisSwitch failed: 0x%08lx\n", status );
return( kOSBooleanFalse );
}
}
void SMU_Neo2_PlatformPlugin::chassisSwitchHandler( IOService * client,
UInt8 matchingMask, UInt32 length, UInt8 * buffer )
{
SMU_Neo2_PlatformPlugin *me;
IOReturn result;
IOPPluginEventData switchEvent;
CTRLLOOP_DLOG( "SMU_Neo2_PlatformPlugin::chassisSwitchHandler entered\n" );
if ((me = OSDynamicCast( SMU_Neo2_PlatformPlugin, client )) == NULL)
{
CTRLLOOP_DLOG( "SMU_Neo2_PlatformPlugin::chassisSwitchHandler client is invalid\n" );
return;
}
switchEvent.eventType = IOPPluginEventMisc;
switchEvent.param1 = (void *) me;
switchEvent.param2 = (void *) length;
switchEvent.param3 = (void *) buffer;
switchEvent.param4 = (void *) &SMU_Neo2_PlatformPlugin::chassisSwitchSyncHandler;
result = me->dispatchEvent( &switchEvent );
if (result != kIOReturnSuccess)
{
CTRLLOOP_DLOG( "SMU_Neo2_PlatformPlugin::chassisSwitchHandler got error: 0x%08lx\n", result );
}
}
IOReturn SMU_Neo2_PlatformPlugin::chassisSwitchSyncHandler( void * p1 ,
void * p2 ,
void * p3 )
{
SMU_Neo2_PlatformPlugin* me = OSDynamicCast( SMU_Neo2_PlatformPlugin, (OSMetaClassBase *) p1 );
UInt32 length = (UInt32) p2;
UInt8 * buffer = (UInt8 *) p3;
CTRLLOOP_DLOG( "SMU_Neo2_PlatformPlugin::chassisSwitchSyncHandler 0x%08lX 0x%08lX 0x%08lX\n",
(UInt32)p1, (UInt32)p2, (UInt32)p3);
if (!me)
{
CTRLLOOP_DLOG( "AppleSMU::chassisSwitchSyncHandler I've lost myself ?!!?!! \n" );
return( kIOReturnBadArgument );
}
if (length == 0)
{
CTRLLOOP_DLOG( "AppleSMU::chassisSwitchSyncHandler invalid length\n" );
return( kIOReturnBadArgument );
}
if (buffer == NULL)
{
CTRLLOOP_DLOG( "AppleSMU::chassisSwitchSyncHandler invalid buffer pointer\n" );
return( kIOReturnBadArgument );
}
me->setEnv( gIOPPluginEnvChassisSwitch, ( *buffer & kClamshellClosedEventMask ) ? kOSBooleanTrue : kOSBooleanFalse );
return( kIOReturnSuccess );
}