CPU (NetBSD): support temp and frequency detection

This commit is contained in:
李通洲
2024-12-21 18:53:25 +08:00
parent 1ea3264b13
commit 5a8dda27ff
+37 -26
View File
@@ -1,26 +1,42 @@
#include "cpu.h"
#include "common/sysctl.h"
#include <sys/sysctl.h>
#include "common/io/io.h"
#include <sys/envsys.h>
#include <prop/proplib.h>
#include <paths.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
static const char* detectCpuTemp(double* current)
{
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"dev.cpu.0.temperature\") failed";
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY);
if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY) failed";
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
prop_dictionary_t root = NULL;
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
static const char* detectThermalTemp(double* current)
{
int temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"hw.acpi.thermal.tz0.temperature\") failed";
prop_array_t array = prop_dictionary_get(root, "coretemp0");
if (!array) array = prop_dictionary_get(root, "amdzentemp0");
if (!array) array = prop_dictionary_get(root, "viac7temp0");
if (!array) array = prop_dictionary_get(root, "acpitz0"); // Thermal Zones
if (!array) return "No temp data found in root dictionary";
if (prop_array_count(array) != 2)
return "Unexpect `xtemp0` data";
prop_dictionary_t dict = prop_array_get(array, 0);
if (prop_object_type(dict) != PROP_TYPE_DICTIONARY)
return "Unexpect `xtemp0[0]`";
int temp = 0; // in µK
if (!prop_dictionary_get_int(dict, "cur-value", &temp))
return "Failed to get temperature";
*current = temp / 1e6 - 273.15;
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
@@ -32,26 +48,21 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
return "sysctlbyname(machdep.cpu_brand) failed";
}
ffSysctlGetString("machdep.dmi.processor-vendor", &cpu->vendor);
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
cpu->coresLogical = cpu->coresPhysical;
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.ncpuonline", cpu->coresLogical);
ffCPUDetectSpeedByCpuid(cpu);
{
struct clockinfo info;
size_t length = sizeof(info);
if (sysctl((int[]) {CTL_KERN, KERN_CLOCKRATE}, 2, &info, &length, NULL, 0) == 0)
cpu->frequencyBase = (uint32_t) info.hz / 1000;
}
uint32_t freq = (uint32_t) ffSysctlGetInt("machdep.cpu.frequency.target", 0);
if (freq > cpu->frequencyBase)
cpu->frequencyBase = freq;
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp)
{
if (detectCpuTemp(&cpu->temperature) != NULL)
detectThermalTemp(&cpu->temperature);
}
if (options->temp) detectCpuTemp(&cpu->temperature);
return NULL;
}