From d9909ecefcc2f806a58ffb756ee2a91a58f4afd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 5 Sep 2026 12:33:52 +0200 Subject: [PATCH 1/3] std.zig.system: tiny refactor of aarch64 namespacing --- lib/std/zig/system/freebsd.zig | 36 ++++++++++++++++++---------------- lib/std/zig/system/linux.zig | 36 ++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/lib/std/zig/system/freebsd.zig b/lib/std/zig/system/freebsd.zig index be7a09f6402b65832356e9865c42b74e9f7cdc40..d36600aaa1810b5f2c0c6d52cdfc387c44bd7bab 100644 --- a/lib/std/zig/system/freebsd.zig +++ b/lib/std/zig/system/freebsd.zig @@ -3,28 +3,30 @@ const std = @import("std"); const native_arch = builtin.target.cpu.arch; -inline fn getAArch64CpuFeature(comptime feat_reg: []const u8) u64 { - return asm ("mrs %[ret], " ++ feat_reg - : [ret] "=r" (-> u64), - ); -} +const aarch64 = struct { + inline fn mrs(comptime feat_reg: []const u8) u64 { + return asm ("mrs %[ret], " ++ feat_reg + : [ret] "=r" (-> u64), + ); + } +}; pub fn detectNativeCpuAndFeatures() ?std.Target.Cpu { return switch (native_arch) { .aarch64, .aarch64_be => b: { const registers = [12]u64{ - getAArch64CpuFeature("MIDR_EL1"), - getAArch64CpuFeature("ID_AA64PFR0_EL1"), - getAArch64CpuFeature("ID_AA64PFR1_EL1"), - getAArch64CpuFeature("ID_AA64DFR0_EL1"), - getAArch64CpuFeature("ID_AA64DFR1_EL1"), - getAArch64CpuFeature("ID_AA64AFR0_EL1"), - getAArch64CpuFeature("ID_AA64AFR1_EL1"), - getAArch64CpuFeature("ID_AA64ISAR0_EL1"), - getAArch64CpuFeature("ID_AA64ISAR1_EL1"), - getAArch64CpuFeature("ID_AA64MMFR0_EL1"), - getAArch64CpuFeature("ID_AA64MMFR1_EL1"), - getAArch64CpuFeature("ID_AA64MMFR2_EL1"), + aarch64.mrs("MIDR_EL1"), + aarch64.mrs("ID_AA64PFR0_EL1"), + aarch64.mrs("ID_AA64PFR1_EL1"), + aarch64.mrs("ID_AA64DFR0_EL1"), + aarch64.mrs("ID_AA64DFR1_EL1"), + aarch64.mrs("ID_AA64AFR0_EL1"), + aarch64.mrs("ID_AA64AFR1_EL1"), + aarch64.mrs("ID_AA64ISAR0_EL1"), + aarch64.mrs("ID_AA64ISAR1_EL1"), + aarch64.mrs("ID_AA64MMFR0_EL1"), + aarch64.mrs("ID_AA64MMFR1_EL1"), + aarch64.mrs("ID_AA64MMFR2_EL1"), }; break :b @import("arm.zig").aarch64.detectNativeCpuAndFeatures(native_arch, registers); diff --git a/lib/std/zig/system/linux.zig b/lib/std/zig/system/linux.zig index fa80dc6c382be4ac3004612dec9ab6ee130f5101..d712792bf1504d02dd1a22c6f5bcd6a1c2bd5e91 100644 --- a/lib/std/zig/system/linux.zig +++ b/lib/std/zig/system/linux.zig @@ -441,11 +441,13 @@ fn CpuinfoParser(comptime impl: anytype) type { }; } -inline fn getAArch64CpuFeature(comptime feat_reg: []const u8) u64 { - return asm ("mrs %[ret], " ++ feat_reg - : [ret] "=r" (-> u64), - ); -} +const aarch64 = struct { + inline fn mrs(comptime feat_reg: []const u8) u64 { + return asm ("mrs %[ret], " ++ feat_reg + : [ret] "=r" (-> u64), + ); + } +}; const riscv = struct { const linux = std.os.linux; @@ -596,18 +598,18 @@ pub fn detectNativeCpuAndFeatures(io: Io) ?Target.Cpu { return switch (current_arch) { .aarch64, .aarch64_be => b: { const registers = [12]u64{ - getAArch64CpuFeature("MIDR_EL1"), - getAArch64CpuFeature("ID_AA64PFR0_EL1"), - getAArch64CpuFeature("ID_AA64PFR1_EL1"), - getAArch64CpuFeature("ID_AA64DFR0_EL1"), - getAArch64CpuFeature("ID_AA64DFR1_EL1"), - getAArch64CpuFeature("ID_AA64AFR0_EL1"), - getAArch64CpuFeature("ID_AA64AFR1_EL1"), - getAArch64CpuFeature("ID_AA64ISAR0_EL1"), - getAArch64CpuFeature("ID_AA64ISAR1_EL1"), - getAArch64CpuFeature("ID_AA64MMFR0_EL1"), - getAArch64CpuFeature("ID_AA64MMFR1_EL1"), - getAArch64CpuFeature("ID_AA64MMFR2_EL1"), + aarch64.mrs("MIDR_EL1"), + aarch64.mrs("ID_AA64PFR0_EL1"), + aarch64.mrs("ID_AA64PFR1_EL1"), + aarch64.mrs("ID_AA64DFR0_EL1"), + aarch64.mrs("ID_AA64DFR1_EL1"), + aarch64.mrs("ID_AA64AFR0_EL1"), + aarch64.mrs("ID_AA64AFR1_EL1"), + aarch64.mrs("ID_AA64ISAR0_EL1"), + aarch64.mrs("ID_AA64ISAR1_EL1"), + aarch64.mrs("ID_AA64MMFR0_EL1"), + aarch64.mrs("ID_AA64MMFR1_EL1"), + aarch64.mrs("ID_AA64MMFR2_EL1"), }; break :b @import("arm.zig").aarch64.detectNativeCpuAndFeatures(current_arch, registers); -- 2.54.0 From e374c985067170db17dfe1a6ee83696ccbcbb529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 5 Sep 2026 09:50:09 +0200 Subject: [PATCH 2/3] std.c: add CPU sysctl constants for aarch64-openbsd --- lib/std/c.zig | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/std/c.zig b/lib/std/c.zig index e3625edb869186614eb961174748f5fcab77f5b4..857d2296a910a3d4be22146fc91a5c2de5ab5fe8 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -1366,6 +1366,27 @@ pub const CTL = switch (native_os) { }, else => void, }; +pub const CPU = switch (native_os) { + .openbsd => switch (native_arch) { + .aarch64, .aarch64_be => struct { + pub const COMPATIBLE = 1; + pub const ID_AA64ISAR0 = 2; + pub const ID_AA64ISAR1 = 3; + pub const ID_AA64ISAR2 = 4; + pub const ID_AA64MMFR0 = 5; + pub const ID_AA64MMFR1 = 6; + pub const ID_AA64MMFR2 = 7; + pub const AA64PFR0 = 8; + pub const AA64PFR1 = 9; + pub const AA64SMFR0 = 10; + pub const AA64ZFR0 = 11; + pub const LIDACTION = 12; + pub const LED_BLINK = 13; + }, + else => void, + }, + else => void, +}; pub const KERN = switch (native_os) { .freebsd => struct { /// struct: process entries -- 2.54.0 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 3/3] 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