From 88ee09fd917b93397926aa077772c89aec92e864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 5 Sep 2026 09:50:22 +0200 Subject: [PATCH] std.zig.system: add aarch64 CPU feature/model detection for NetBSD and OpenBSD ref https://codeberg.org/ziglang/zig/issues/36724 --- lib/std/zig/system.zig | 9 ++-- lib/std/zig/system/netbsd.zig | 75 ++++++++++++++++++++++++++++++++++ lib/std/zig/system/openbsd.zig | 49 ++++++++++++++++++++++ 3 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 lib/std/zig/system/netbsd.zig create mode 100644 lib/std/zig/system/openbsd.zig diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index b8bb161a5da98ede37391dbe1dac4b850ff9bd40..567d03b59f3f55c72451278ad0cc44563d5337f5 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -12,10 +12,12 @@ const Io = std.Io; pub const NativePaths = @import("system/NativePaths.zig"); -pub const windows = @import("system/windows.zig"); pub const darwin = @import("system/darwin.zig"); -pub const linux = @import("system/linux.zig"); pub const freebsd = @import("system/freebsd.zig"); +pub const linux = @import("system/linux.zig"); +pub const netbsd = @import("system/netbsd.zig"); +pub const openbsd = @import("system/openbsd.zig"); +pub const windows = @import("system/windows.zig"); pub const Executor = union(enum) { native, @@ -547,12 +549,13 @@ fn detectNativeCpuAndFeatures(io: Io, cpu_arch: Target.Cpu.Arch, os: Target.Os, .freebsd => return freebsd.detectNativeCpuAndFeatures(), .linux => return linux.detectNativeCpuAndFeatures(io), .macos => return darwin.macos.detectNativeCpuAndFeatures(), + .netbsd => return netbsd.detectNativeCpuAndFeatures(), + .openbsd => return openbsd.detectNativeCpuAndFeatures(), .windows => return windows.detectNativeCpuAndFeatures(), else => {}, } // This architecture does not have CPU model & feature detection yet. - // See https://github.com/ziglang/zig/issues/4591 return null; } diff --git a/lib/std/zig/system/netbsd.zig b/lib/std/zig/system/netbsd.zig new file mode 100644 index 0000000000000000000000000000000000000000..2319807018a64709f664f04fd2e4121037057ad0 --- /dev/null +++ b/lib/std/zig/system/netbsd.zig @@ -0,0 +1,75 @@ +const builtin = @import("builtin"); +const std = @import("std"); + +const native_arch = builtin.target.cpu.arch; + +const aarch64 = struct { + const sysctl_cpu_id = extern struct { + midr: u64, + revidr: u64, + mpidr: u64, + + aa64dfr0: u64, + aa64dfr1: u64, + + aa64isar0: u64, + aa64isar1: u64, + + aa64mmfr0: u64, + aa64mmfr1: u64, + aa64mmfr2: u64, + + aa64pfr0: u64, + aa64pfr1: u64, + + aa64zfr0: u64, + + mvfr0: u32, + mvfr1: u32, + mvfr2: u32, + _pad: u32 = 0, + + clidr: u64, + ctr: u64, + }; +}; + +pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu { + return switch (native_arch) { + .aarch64, .aarch64_be => b: { + var value: aarch64.sysctl_cpu_id = undefined; + var len: usize = @sizeOf(@TypeOf(value)); + switch (std.posix.errno(std.c.sysctlbyname("machdep.cpu0.cpu_id", &value, &len, null, 0))) { + .SUCCESS => {}, + .FAULT => unreachable, + .INVAL => unreachable, + .ISDIR => unreachable, + .NOENT => unreachable, // 👻 + .NOMEM => {}, // `aarch64.sysctl_cpu_id` has grown upstream, harmless + .NOTDIR => unreachable, + .NOTEMPTY => unreachable, + .OPNOTSUPP => unreachable, + .PERM => unreachable, + else => return null, + } + + const registers = [12]u64{ + value.midr, + value.aa64pfr0, + value.aa64pfr1, + value.aa64dfr0, + value.aa64dfr1, + 0, // ID_AA64AFR0_EL1 + 0, // ID_AA64AFR1_EL1 + value.aa64isar0, + value.aa64isar1, + value.aa64mmfr0, + value.aa64mmfr1, + value.aa64mmfr2, + }; + + break :b @import("arm.zig").aarch64.detectNativeCpuAndFeatures(native_arch, registers); + }, + else => null, + }; +} diff --git a/lib/std/zig/system/openbsd.zig b/lib/std/zig/system/openbsd.zig new file mode 100644 index 0000000000000000000000000000000000000000..211222d33ed376e90f70e9461c856cea61fe918f --- /dev/null +++ b/lib/std/zig/system/openbsd.zig @@ -0,0 +1,49 @@ +const builtin = @import("builtin"); +const std = @import("std"); + +const native_arch = builtin.target.cpu.arch; + +const aarch64 = struct { + fn sysctlReg(key: c_int) u64 { + const mib: [2]c_int = [_]c_int{ + std.c.CTL.MACHDEP, + key, + }; + var value: u64 = undefined; + var len: usize = @sizeOf(@TypeOf(value)); + + std.posix.sysctl(&mib, &value, &len, null, 0) catch |err| switch (err) { + error.NameTooLong => unreachable, + error.PermissionDenied => unreachable, + error.SystemResources => unreachable, + error.UnknownName => unreachable, + error.Unexpected => return 0, + }; + + return value; + } +}; + +pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu { + return switch (native_arch) { + .aarch64, .aarch64_be => b: { + const registers = [12]u64{ + 0, // MIDR_EL1 + aarch64.sysctlReg(std.c.CPU.AA64PFR0), + aarch64.sysctlReg(std.c.CPU.AA64PFR1), + 0, // ID_AA64DFR0_EL1 + 0, // ID_AA64DFR1_EL1 + 0, // ID_AA64AFR0_EL1 + 0, // ID_AA64AFR1_EL1 + aarch64.sysctlReg(std.c.CPU.ID_AA64ISAR0), + aarch64.sysctlReg(std.c.CPU.ID_AA64ISAR1), + aarch64.sysctlReg(std.c.CPU.ID_AA64MMFR0), + aarch64.sysctlReg(std.c.CPU.ID_AA64MMFR1), + aarch64.sysctlReg(std.c.CPU.ID_AA64MMFR2), + }; + + break :b @import("arm.zig").aarch64.detectNativeCpuAndFeatures(native_arch, registers); + }, + else => null, + }; +} -- 2.54.0