summaryrefslogtreecommitdiffstats
path: root/src/detection/cpu/cpu_nbsd.c
diff options
context:
space:
mode:
authorsumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
committersumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
commit76424950e373d3b04ac3dd13019151bfba3e8423 (patch)
tree4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/detection/cpu/cpu_nbsd.c
Add the files
Diffstat (limited to 'src/detection/cpu/cpu_nbsd.c')
-rw-r--r--src/detection/cpu/cpu_nbsd.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/detection/cpu/cpu_nbsd.c b/src/detection/cpu/cpu_nbsd.c
new file mode 100644
index 0000000..9c88c0e
--- /dev/null
+++ b/src/detection/cpu/cpu_nbsd.c
@@ -0,0 +1,109 @@
+#include "cpu.h"
+#include "common/sysctl.h"
+#include "common/io.h"
+
+#include <sys/envsys.h>
+#include <prop/proplib.h>
+#include <paths.h>
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+static void freePropDict(prop_dictionary_t* pdict) {
+ assert(pdict != NULL);
+ if (*pdict == NULL) {
+ return;
+ }
+ prop_object_release(*pdict);
+}
+
+static const char* detectCpuTemp(const FFCPUOptions* options, double* current) {
+ FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC);
+ if (fd < 0) {
+ return "open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC) failed";
+ }
+
+ FF_A_CLEANUP(freePropDict) prop_dictionary_t root = NULL;
+ if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0) {
+ return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
+ }
+
+ prop_array_t array;
+
+ if (options->tempSensor.length > 0) {
+ array = prop_dictionary_get(root, options->tempSensor.chars);
+ if (!array) {
+ return "No temp data found in specified sensor";
+ }
+ } else {
+ 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 "Unexpected `xtemp0` data";
+ }
+
+ prop_dictionary_t dict = prop_array_get(array, 0);
+ if (prop_object_type(dict) != PROP_TYPE_DICTIONARY) {
+ return "Unexpected `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;
+
+ return NULL;
+}
+
+const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) {
+ if (ffSysctlGetString("machdep.cpu_brand", &cpu->name) != NULL &&
+ ffSysctlGetString("machdep.dmi.processor-version", &cpu->name) != NULL &&
+ ffSysctlGetString("hw.cpu0.name", &cpu->name) != NULL &&
+ ffSysctlGetString("hw.model", &cpu->name) != NULL) {
+ ffStrbufSetS(&cpu->name, "Unknown CPU");
+ }
+
+ if (ffSysctlGetString("machdep.dmi.processor-vendor", &cpu->vendor) == NULL) {
+ ffStrbufTrimRightSpace(&cpu->vendor);
+ }
+
+ cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
+ cpu->coresLogical = cpu->coresPhysical;
+ cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.ncpuonline", cpu->coresLogical);
+
+ ffCPUDetectByCpuid(cpu);
+
+ uint32_t freq = (uint32_t) ffSysctlGetInt("machdep.cpu.frequency.target", 0);
+ if (freq == 0) {
+ freq = (uint32_t) (ffSysctlGetInt64("hw.cpu0.clock_frequency", 0) / 1000000);
+ }
+ if (freq == 0) {
+ freq = (uint32_t) ffSysctlGetInt("machdep.dmi.processor-frequency", 0);
+ }
+ if (freq > cpu->frequencyBase) {
+ cpu->frequencyBase = freq;
+ }
+
+ cpu->temperature = FF_CPU_TEMP_UNSET;
+
+ if (options->temp) {
+ detectCpuTemp(options, &cpu->temperature);
+ }
+
+ return NULL;
+}