Files
fastfetch/src/detection/cpu/cpu_apple.c
T

130 lines
4.7 KiB
C
Raw Normal View History

2022-09-04 22:20:12 +02:00
#include "cpu.h"
2022-09-19 21:31:50 +02:00
#include "common/sysctl.h"
2022-09-25 15:23:00 +08:00
#include "detection/temps/temps_apple.h"
#include "util/stringUtils.h"
2022-09-04 14:12:04 -07:00
2022-09-25 15:23:00 +08:00
static double detectCpuTemp(const FFstrbuf* cpuName)
{
2023-08-07 10:15:08 +08:00
double result = 0;
2022-09-25 15:23:00 +08:00
2023-08-07 10:15:08 +08:00
const char* error = NULL;
2023-12-08 15:59:58 +08:00
if (ffStrbufStartsWithS(cpuName, "Apple M"))
{
switch (strtol(cpuName->chars + strlen("Apple M"), NULL, 10))
{
2023-12-27 08:46:49 +08:00
case 1: error = ffDetectSmcTemps(FF_TEMP_CPU_M1X, &result); break;
case 2: error = ffDetectSmcTemps(FF_TEMP_CPU_M2X, &result); break;
case 3: error = ffDetectSmcTemps(FF_TEMP_CPU_M3X, &result); break;
2023-12-08 15:59:58 +08:00
default: error = "Unsupported Apple Silicon CPU";
}
}
2023-08-07 10:15:08 +08:00
else // PPC?
2023-12-27 08:46:49 +08:00
error = ffDetectSmcTemps(FF_TEMP_CPU_X64, &result);
2022-09-25 15:23:00 +08:00
2023-08-07 10:15:08 +08:00
if(error)
2022-09-25 15:23:00 +08:00
return FF_CPU_TEMP_UNSET;
return result;
}
#ifdef __aarch64__
#include "util/apple/cf_helpers.h"
#include <IOKit/IOKitLib.h>
static const char* detectFrequency(FFCPUResult* cpu)
{
// https://github.com/giampaolo/psutil/pull/2222/files
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDevice = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceNameMatching("pmgr"));
if (!entryDevice)
return "IOServiceGetMatchingServices() failed";
if (!IOObjectConformsTo(entryDevice, "AppleARMIODevice"))
return "\"pmgr\" should conform to \"AppleARMIODevice\"";
FF_CFTYPE_AUTO_RELEASE CFMutableDictionaryRef properties = NULL;
if (IORegistryEntryCreateCFProperties(entryDevice, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
return "IORegistryEntryCreateCFProperties() failed";
uint32_t pMin, eMin, aMax, pCoreLength;
if (ffCfDictGetData(properties, CFSTR("voltage-states5-sram"), 0, 4, (uint8_t*) &pMin, &pCoreLength) != NULL) // pCore
return "\"voltage-states5-sram\" in \"pmgr\" is not found";
if (ffCfDictGetData(properties, CFSTR("voltage-states1-sram"), 0, 4, (uint8_t*) &eMin, NULL) != NULL) // eCore
return "\"voltage-states1-sram\" in \"pmgr\" is not found";
cpu->frequencyMin = (pMin < eMin ? pMin : eMin) / (1000.0 * 1000 * 1000);
if (pCoreLength >= 8)
{
ffCfDictGetData(properties, CFSTR("voltage-states5-sram"), pCoreLength - 8, 4, (uint8_t*) &aMax, NULL);
cpu->frequencyMax = aMax / (1000.0 * 1000 * 1000);
}
return NULL;
}
#else
static const char* detectFrequency(FFCPUResult* cpu)
{
2024-03-13 23:42:59 +08:00
cpu->frequencyBase = ffSysctlGetInt64("hw.cpufrequency", 0) / 1000.0 / 1000.0 / 1000.0;
cpu->frequencyMin = ffSysctlGetInt64("hw.cpufrequency_min", 0) / 1000.0 / 1000.0 / 1000.0;
2024-05-18 01:46:56 +08:00
cpu->frequencyMax = ffSysctlGetInt64("hw.cpufrequency_max", 0) / 1000.0 / 1000.0 / 1000.0;
if(cpu->frequencyBase != cpu->frequencyBase)
{
unsigned current = 0;
size_t size = sizeof(current);
if (sysctl((int[]){ CTL_HW, HW_CPU_FREQ }, 2, &current, &size, NULL, 0) == 0)
2024-05-18 01:46:56 +08:00
cpu->frequencyBase = (double) current / 1000.0 / 1000.0 / 1000.0;
}
return NULL;
}
#endif
2024-05-18 01:46:56 +08:00
static const char* detectCoreCount(FFCPUResult* cpu)
{
2024-05-18 18:22:32 +08:00
uint32_t nPerfLevels = (uint32_t) ffSysctlGetInt("hw.nperflevels", 0);
2024-05-18 01:46:56 +08:00
if (nPerfLevels <= 0) return "sysctl(hw.nperflevels) failed";
char sysctlKey[] = "hw.perflevelN.logicalcpu";
2024-05-18 18:22:32 +08:00
if (nPerfLevels > sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]))
nPerfLevels = sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]);
for (uint32_t i = 0; i < nPerfLevels; ++i)
2024-05-18 01:46:56 +08:00
{
sysctlKey[strlen("hw.perflevel")] = (char) ('0' + i);
2024-05-18 18:22:32 +08:00
cpu->coreTypes[i] = (FFCPUCore) {
.freq = nPerfLevels - i,
2024-05-18 18:22:32 +08:00
.count = (uint32_t) ffSysctlGetInt(sysctlKey, 0),
};
2024-05-18 01:46:56 +08:00
}
return NULL;
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
2022-09-04 22:20:12 +02:00
{
2023-06-12 09:56:03 +08:00
if (ffSysctlGetString("machdep.cpu.brand_string", &cpu->name) != NULL)
return "sysctlbyname(machdep.cpu.brand_string) failed";
2023-08-30 14:46:04 +08:00
2022-12-17 11:39:10 +08:00
ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor);
2023-08-30 14:46:04 +08:00
if (cpu->vendor.length == 0 && ffStrbufStartsWithS(&cpu->name, "Apple "))
ffStrbufAppendS(&cpu->vendor, "Apple");
2022-09-04 14:12:04 -07:00
2022-12-17 11:39:10 +08:00
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu_max", 1);
if(cpu->coresPhysical == 1)
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu", 1);
2022-09-04 14:12:04 -07:00
2022-12-17 11:39:10 +08:00
cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.logicalcpu_max", 1);
if(cpu->coresLogical == 1)
cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
2022-09-04 14:12:04 -07:00
2022-12-17 11:39:10 +08:00
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.logicalcpu", 1);
if(cpu->coresOnline == 1)
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.activecpu", 1);
2022-09-04 22:20:12 +02:00
detectFrequency(cpu);
2024-05-21 09:09:08 +08:00
if (options->showPeCoreCount) detectCoreCount(cpu);
2022-09-04 22:20:12 +02:00
2023-08-07 10:15:08 +08:00
cpu->temperature = options->temp ? detectCpuTemp(&cpu->name) : FF_CPU_TEMP_UNSET;
2023-06-12 09:56:03 +08:00
return NULL;
2022-09-04 22:20:12 +02:00
}