From 86e5386e27f831da4669b7dc508c7b710fcb7c50 Mon Sep 17 00:00:00 2001 From: Merry Date: Sat, 28 Oct 2023 17:25:23 +0100 Subject: [PATCH] oaknut: feature_detect: Support NetBSD --- .../feature_detection/feature_detection.hpp | 4 + .../feature_detection_freebsd.hpp | 2 +- .../feature_detection_netbsd.hpp | 81 +++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 include/oaknut/feature_detection/feature_detection_netbsd.hpp diff --git a/include/oaknut/feature_detection/feature_detection.hpp b/include/oaknut/feature_detection/feature_detection.hpp index e68aa4d..1961864 100644 --- a/include/oaknut/feature_detection/feature_detection.hpp +++ b/include/oaknut/feature_detection/feature_detection.hpp @@ -15,6 +15,10 @@ # define OAKNUT_CPU_FEATURE_DETECTION 1 # define OAKNUT_SUPPORTS_READING_ID_REGISTERS 1 # include "oaknut/feature_detection/feature_detection_linux.hpp" +#elif defined(__NetBSD__) +# define OAKNUT_CPU_FEATURE_DETECTION 1 +# define OAKNUT_SUPPORTS_READING_ID_REGISTERS 2 +# include "oaknut/feature_detection/feature_detection_netbsd.hpp" #elif defined(__OpenBSD__) # define OAKNUT_CPU_FEATURE_DETECTION 1 # define OAKNUT_SUPPORTS_READING_ID_REGISTERS 1 diff --git a/include/oaknut/feature_detection/feature_detection_freebsd.hpp b/include/oaknut/feature_detection/feature_detection_freebsd.hpp index 0a07188..714408e 100644 --- a/include/oaknut/feature_detection/feature_detection_freebsd.hpp +++ b/include/oaknut/feature_detection/feature_detection_freebsd.hpp @@ -24,7 +24,7 @@ namespace oaknut { namespace detail { -unsigned long getauxval(int aux) +inline unsigned long getauxval(int aux) { unsigned long result = 0; if (::elf_aux_info(aux, &result, static_cast(sizeof result)) == 0) { diff --git a/include/oaknut/feature_detection/feature_detection_netbsd.hpp b/include/oaknut/feature_detection/feature_detection_netbsd.hpp new file mode 100644 index 0000000..cdb1deb --- /dev/null +++ b/include/oaknut/feature_detection/feature_detection_netbsd.hpp @@ -0,0 +1,81 @@ +// SPDX-FileCopyrightText: Copyright (c) 2023 merryhime +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "oaknut/feature_detection/cpu_feature.hpp" +#include "oaknut/feature_detection/feature_detection_hwcaps.hpp" +#include "oaknut/feature_detection/feature_detection_idregs.hpp" +#include "oaknut/feature_detection/id_registers.hpp" + +namespace oaknut { + +inline std::optional read_id_registers(std::size_t core_index) +{ + const std::string path = "machdep.cpu" + std::to_string(core_index) + ".cpu_id"; + + aarch64_sysctl_cpu_id id; + std::size_t id_len = sizeof id; + + if (sysctlbyname(path.c_str(), &id, &id_len, nullptr, 0) < 0) + return std::nullopt; + + return id::IdRegisters{ + id.ac_midr, + id::Pfr0Register{id.ac_aa64pfr0}, + id::Pfr1Register{id.ac_aa64pfr1}, + id::Pfr2Register{0}, + id::Zfr0Register{id.ac_aa64zfr0}, + id::Smfr0Register{0}, + id::Isar0Register{id.ac_aa64isar0}, + id::Isar1Register{id.ac_aa64isar1}, + id::Isar2Register{0}, + id::Isar3Register{0}, + id::Mmfr0Register{id.ac_aa64mmfr0}, + id::Mmfr1Register{id.ac_aa64mmfr1}, + id::Mmfr2Register{id.ac_aa64mmfr2}, + id::Mmfr3Register{0}, + id::Mmfr4Register{0}, + }; +} + +inline std::size_t get_core_count() +{ + int result = 0; + size_t result_size = sizeof(result); + const std::array mib{CTL_HW, HW_NCPU}; + if (sysctl(mib.data(), mib.size(), &result, &result_size, nullptr, 0) < 0) + return 0; + return result; +} + +inline CpuFeatures detect_features() +{ + std::optional result; + + const std::size_t core_count = get_core_count(); + for (std::size_t core_index = 0; core_index < core_count; core_index++) { + if (const std::optional id_regs = read_id_registers(core_index)) { + const CpuFeatures current_features = detect_features_via_id_registers(*id_regs); + if (result) { + result = *result & current_features; + } else { + result = current_features; + } + } + } + + return result.value_or(CpuFeatures{}); +} + +} // namespace oaknut