diff options
-rw-r--r-- | XBMC.xcodeproj/project.pbxproj | 10 | ||||
-rw-r--r-- | xbmc/GUIInfoManager.cpp | 15 | ||||
-rw-r--r-- | xbmc/osx/smc.c | 170 | ||||
-rw-r--r-- | xbmc/osx/smc.h | 111 | ||||
-rw-r--r-- | xbmc/utils/CPUInfo.cpp | 11 |
5 files changed, 312 insertions, 5 deletions
diff --git a/XBMC.xcodeproj/project.pbxproj b/XBMC.xcodeproj/project.pbxproj index 60972e9f01..12a73fa54c 100644 --- a/XBMC.xcodeproj/project.pbxproj +++ b/XBMC.xcodeproj/project.pbxproj @@ -28,6 +28,9 @@ 0E3036EC1760F68A00D93596 /* FavouritesDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E3036EA1760F68A00D93596 /* FavouritesDirectory.cpp */; }; 0E3036ED1760F68A00D93596 /* FavouritesDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E3036EA1760F68A00D93596 /* FavouritesDirectory.cpp */; }; 0E3036EE1760F68A00D93596 /* FavouritesDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E3036EA1760F68A00D93596 /* FavouritesDirectory.cpp */; }; + 180F6C8117CE9A5700127892 /* smc.c in Sources */ = {isa = PBXBuildFile; fileRef = 180F6C8017CE9A5700127892 /* smc.c */; }; + 180F6C8217CE9A5700127892 /* smc.c in Sources */ = {isa = PBXBuildFile; fileRef = 180F6C8017CE9A5700127892 /* smc.c */; }; + 180F6C8317CE9A5700127892 /* smc.c in Sources */ = {isa = PBXBuildFile; fileRef = 180F6C8017CE9A5700127892 /* smc.c */; }; 183FDF8A11AF0B0500B81E9C /* PluginSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 183FDF8811AF0B0500B81E9C /* PluginSource.cpp */; }; 18404DA61396C31B00863BBA /* SlingboxLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18404DA51396C31B00863BBA /* SlingboxLib.a */; }; 1840B74D13993D8A007C848B /* JSONVariantParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1840B74B13993D8A007C848B /* JSONVariantParser.cpp */; }; @@ -3174,6 +3177,8 @@ 0E30286C1759FCC200D93596 /* SettingsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsManager.h; sourceTree = "<group>"; }; 0E3036EA1760F68A00D93596 /* FavouritesDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FavouritesDirectory.cpp; sourceTree = "<group>"; }; 0E3036EB1760F68A00D93596 /* FavouritesDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FavouritesDirectory.h; sourceTree = "<group>"; }; + 180F6C7F17CE9A5700127892 /* smc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smc.h; sourceTree = "<group>"; }; + 180F6C8017CE9A5700127892 /* smc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = smc.c; sourceTree = "<group>"; }; 18308CB41303370800AA309E /* stat_utf8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stat_utf8.h; sourceTree = "<group>"; }; 18308CB51303370800AA309E /* stdio_utf8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdio_utf8.h; sourceTree = "<group>"; }; 183FDF8811AF0B0500B81E9C /* PluginSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginSource.cpp; sourceTree = "<group>"; }; @@ -7125,6 +7130,8 @@ 6E2FACD20E26E92800DF79EA /* Info.plist */, F51CEEEE0F5C5D20004F4602 /* OSXGNUReplacements.c */, F51CEEF00F5C5D28004F4602 /* OSXGNUReplacements.h */, + 180F6C7F17CE9A5700127892 /* smc.h */, + 180F6C8017CE9A5700127892 /* smc.c */, E306D12C0DDF7B590052C2AD /* XBMCHelper.cpp */, E306D12D0DDF7B590052C2AD /* XBMCHelper.h */, 820023D9171A28A300667D1C /* OSXTextInputResponder.h */, @@ -10594,6 +10601,7 @@ F59EED7E17AD5174005BB7C6 /* ApplicationPlayer.cpp in Sources */, DF29668017B2B04300DF10F9 /* SettingRequirement.cpp in Sources */, DF28DF4D17B8379E0077F41A /* ProfilesOperations.cpp in Sources */, + 180F6C8117CE9A5700127892 /* smc.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -11621,6 +11629,7 @@ F59EED8017AD5174005BB7C6 /* ApplicationPlayer.cpp in Sources */, DF29668217B2B04300DF10F9 /* SettingRequirement.cpp in Sources */, DF28DF4F17B8379E0077F41A /* ProfilesOperations.cpp in Sources */, + 180F6C8317CE9A5700127892 /* smc.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -12650,6 +12659,7 @@ F59EED7F17AD5174005BB7C6 /* ApplicationPlayer.cpp in Sources */, DF29668117B2B04300DF10F9 /* SettingRequirement.cpp in Sources */, DF28DF4E17B8379E0077F41A /* ProfilesOperations.cpp in Sources */, + 180F6C8217CE9A5700127892 /* smc.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp index 56dc58d4d8..a70afca2e0 100644 --- a/xbmc/GUIInfoManager.cpp +++ b/xbmc/GUIInfoManager.cpp @@ -58,6 +58,9 @@ #include "utils/SeekHandler.h" #include "URL.h" #include "addons/Skin.h" +#if defined(TARGET_DARWIN) +#include "osx/smc.h" +#endif // stuff for current song #include "music/MusicInfoLoader.h" @@ -4021,10 +4024,15 @@ string CGUIInfoManager::GetSystemHeatInfo(int info) CTemperature CGUIInfoManager::GetGPUTemperature() { + int value = 0; + char scale = 0; + +#if defined(TARGET_DARWIN) + value = SMCGetTemperature(SMC_KEY_GPU_TEMP); + return CTemperature::CreateFromCelsius(value); +#else CStdString cmd = g_advancedSettings.m_gpuTempCmd; - int value = 0, - ret = 0; - char scale = 0; + int ret = 0; FILE *p = NULL; if (cmd.IsEmpty() || !(p = popen(cmd.c_str(), "r"))) @@ -4035,6 +4043,7 @@ CTemperature CGUIInfoManager::GetGPUTemperature() if (ret != 2) return CTemperature(); +#endif if (scale == 'C' || scale == 'c') return CTemperature::CreateFromCelsius(value); diff --git a/xbmc/osx/smc.c b/xbmc/osx/smc.c new file mode 100644 index 0000000000..9bee2d73a2 --- /dev/null +++ b/xbmc/osx/smc.c @@ -0,0 +1,170 @@ +/* + * Apple System Management Control (SMC) Tool + * Copyright (C) 2006 devnull + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <stdio.h> +#include <string.h> +#include <IOKit/IOKitLib.h> + +#include "smc.h" + +static io_connect_t conn; + +UInt32 _strtoul(char *str, int size, int base) +{ + UInt32 total = 0; + int i; + + for (i = 0; i < size; i++) + { + if (base == 16) + total += str[i] << (size - 1 - i) * 8; + else + total += (unsigned char) (str[i] << (size - 1 - i) * 8); + } + return total; +} + +void _ultostr(char *str, UInt32 val) +{ + str[0] = '\0'; + sprintf(str, "%c%c%c%c", + (unsigned int) val >> 24, + (unsigned int) val >> 16, + (unsigned int) val >> 8, + (unsigned int) val); +} + +kern_return_t SMCOpen(void) +{ + kern_return_t result; + mach_port_t masterPort; + io_iterator_t iterator; + io_object_t device; + + result = IOMasterPort(MACH_PORT_NULL, &masterPort); + + CFMutableDictionaryRef matchingDictionary = IOServiceMatching("AppleSMC"); + result = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator); + if (result != kIOReturnSuccess) + { + printf("Error: IOServiceGetMatchingServices() = %08x\n", result); + return 1; + } + + device = IOIteratorNext(iterator); + IOObjectRelease(iterator); + if (device == 0) + { + printf("Error: no SMC found\n"); + return 1; + } + + result = IOServiceOpen(device, mach_task_self(), 0, &conn); + IOObjectRelease(device); + if (result != kIOReturnSuccess) + { + printf("Error: IOServiceOpen() = %08x\n", result); + return 1; + } + + return kIOReturnSuccess; +} + +kern_return_t SMCClose() +{ + return IOServiceClose(conn); +} + + +kern_return_t SMCCall(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure) +{ + size_t structureInputSize; + size_t structureOutputSize; + + structureInputSize = sizeof(SMCKeyData_t); + structureOutputSize = sizeof(SMCKeyData_t); + +#if MAC_OS_X_VERSION_10_5 + return IOConnectCallStructMethod( conn, index, + // inputStructure + inputStructure, structureInputSize, + // ouputStructure + outputStructure, &structureOutputSize ); +#else + return IOConnectMethodStructureIStructureO( conn, index, + structureInputSize, /* structureInputSize */ + &structureOutputSize, /* structureOutputSize */ + inputStructure, /* inputStructure */ + outputStructure); /* ouputStructure */ +#endif + +} + +kern_return_t SMCReadKey(UInt32Char_t key, SMCVal_t *val) +{ + kern_return_t result; + SMCKeyData_t inputStructure; + SMCKeyData_t outputStructure; + + memset(&inputStructure, 0, sizeof(SMCKeyData_t)); + memset(&outputStructure, 0, sizeof(SMCKeyData_t)); + memset(val, 0, sizeof(SMCVal_t)); + + inputStructure.key = _strtoul(key, 4, 16); + inputStructure.data8 = SMC_CMD_READ_KEYINFO; + + result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); + if (result != kIOReturnSuccess) + return result; + + val->dataSize = outputStructure.keyInfo.dataSize; + _ultostr(val->dataType, outputStructure.keyInfo.dataType); + inputStructure.keyInfo.dataSize = val->dataSize; + inputStructure.data8 = SMC_CMD_READ_BYTES; + + result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); + if (result != kIOReturnSuccess) + return result; + + memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes)); + + return kIOReturnSuccess; +} + +double SMCGetTemperature(char *key) +{ + SMCVal_t val; + kern_return_t result; + SMCOpen(); + result = SMCReadKey(key, &val); + SMCClose(); + if (result == kIOReturnSuccess) { + // read succeeded - check returned value + if (val.dataSize > 0) { + if (strcmp(val.dataType, DATATYPE_SP78) == 0) { + // convert fp78 value to temperature + int intValue = (val.bytes[0] * 256 + val.bytes[1]) >> 2; + return intValue / 64.0; + } + } + } + // read failed + return 0.0; +} + diff --git a/xbmc/osx/smc.h b/xbmc/osx/smc.h new file mode 100644 index 0000000000..1a3f01423d --- /dev/null +++ b/xbmc/osx/smc.h @@ -0,0 +1,111 @@ +/* + * Apple System Management Control (SMC) Tool + * Copyright (C) 2006 devnull + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __SMC_H__ +#define __SMC_H__ +#endif + +#define SMC_VERSION "0.01" + +#define OP_NONE 0 +#define OP_LIST 1 +#define OP_READ 2 +#define OP_READ_FAN 3 +#define OP_WRITE 4 + +#define KERNEL_INDEX_SMC 2 + +#define SMC_CMD_READ_BYTES 5 +#define SMC_CMD_WRITE_BYTES 6 +#define SMC_CMD_READ_INDEX 8 +#define SMC_CMD_READ_KEYINFO 9 +#define SMC_CMD_READ_PLIMIT 11 +#define SMC_CMD_READ_VERS 12 + +#define DATATYPE_FPE2 "fpe2" +#define DATATYPE_UINT8 "ui8 " +#define DATATYPE_UINT16 "ui16" +#define DATATYPE_UINT32 "ui32" +#define DATATYPE_SP78 "sp78" + +// key values +#define SMC_KEY_CPU_TEMP "TC0D" +#define SMC_KEY_GPU_TEMP "TG0D" +#define SMC_KEY_FAN0_RPM_MIN "F0Mn" +#define SMC_KEY_FAN1_RPM_MIN "F1Mn" +#define SMC_KEY_FAN0_RPM_CUR "F0Ac" +#define SMC_KEY_FAN1_RPM_CUR "F1Ac" + + +typedef struct { + char major; + char minor; + char build; + char reserved[1]; + UInt16 release; +} SMCKeyData_vers_t; + +typedef struct { + UInt16 version; + UInt16 length; + UInt32 cpuPLimit; + UInt32 gpuPLimit; + UInt32 memPLimit; +} SMCKeyData_pLimitData_t; + +typedef struct { + UInt32 dataSize; + UInt32 dataType; + char dataAttributes; +} SMCKeyData_keyInfo_t; + +typedef char SMCBytes_t[32]; + +typedef struct { + UInt32 key; + SMCKeyData_vers_t vers; + SMCKeyData_pLimitData_t pLimitData; + SMCKeyData_keyInfo_t keyInfo; + char result; + char status; + char data8; + UInt32 data32; + SMCBytes_t bytes; +} SMCKeyData_t; + +typedef char UInt32Char_t[5]; + +typedef struct { + UInt32Char_t key; + UInt32 dataSize; + UInt32Char_t dataType; + SMCBytes_t bytes; +} SMCVal_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +// prototypes +double SMCGetTemperature(char *key); + +#ifdef __cplusplus +} +#endif diff --git a/xbmc/utils/CPUInfo.cpp b/xbmc/utils/CPUInfo.cpp index 2a09d073eb..efbeb53014 100644 --- a/xbmc/utils/CPUInfo.cpp +++ b/xbmc/utils/CPUInfo.cpp @@ -26,6 +26,7 @@ #if defined(TARGET_DARWIN) #include <sys/types.h> #include <sys/sysctl.h> +#include "osx/smc.h" #ifdef __ppc__ #include <mach-o/arch.h> #endif @@ -504,9 +505,14 @@ float CCPUInfo::getCPUFrequency() bool CCPUInfo::getTemperature(CTemperature& temperature) { - int value = 0, - ret = 0; + int value = 0; char scale = 0; + +#if defined(TARGET_DARWIN) + value = SMCGetTemperature(SMC_KEY_CPU_TEMP); + scale = 'c'; +#else + int ret = 0; FILE *p = NULL; CStdString cmd = g_advancedSettings.m_cpuTempCmd; @@ -546,6 +552,7 @@ bool CCPUInfo::getTemperature(CTemperature& temperature) if (ret != 2) return false; +#endif if (scale == 'C' || scale == 'c') temperature = CTemperature::CreateFromCelsius(value); |