authorgravatar for liviu@dudau.co.ukLiviu Dudau <liviu@dudau.co.uk> 2024-04-09 18:47:20+00:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-04-17 15:06:48-07:00
loga0de077600a35e41ce861398eaf3c8e832fee42e
tree65573517c636b1a42e5e018b6de6740eec21b8a6
parent1fb23813166e768a59bc7468d09bcb2e8e0f8f03

std.zig.system.linux: Use arm.zig detection for AArch64 CPU features

When building zig natively from source on an RK3588 SoC board, the generated stage3 compiler will use unsupported 'sha256h.4s' instructions due to mis-identified CPU features. This happens when trying to compile a new project generated with "zig init" $ ~/devel/zig/build/stage3/bin/zig build thread 919 panic: Illegal instruction at address 0x1fdc0c4 /home/dliviu/devel/zig/lib/std/crypto/sha2.zig:223:29: 0x1fdc0c4 in round (zig) asm volatile ( ^ /home/dliviu/devel/zig/lib/std/crypto/sha2.zig:168:20: 0x1fdca87 in final (zig) d.round(&d.buf); ^ /home/dliviu/devel/zig/lib/std/crypto/sha2.zig:180:20: 0x1c8bb33 in finalResult (zig) d.final(&result); ^ /mnt/home/dliviu/devel/zig/src/Package/Fetch.zig:754:49: 0x1a3a8eb in relativePathDigest (zig) return Manifest.hexDigest(hasher.finalResult()); ^ /mnt/home/dliviu/devel/zig/src/main.zig:5128:53: 0x1a37413 in cmdBuild (zig) Package.Fetch.relativePathDigest(build_mod.root, global_cache_directory), ^ ???:?:?: 0xff09ffffffffffff in ??? (???) Unwind information for `???:0xff09ffffffffffff` was not available, trace may be incomplete ???:?:?: 0x3f7f137 in ??? (???) Aborted (core dumped) system/linux.zig parses "/proc/cpuinfo" to determine the CPU features, but it seems to generate the wrong set of features from: $ cat /proc/cpuinfo processor : 0 BogoMIPS : 48.00 Features : fp asimd evtstrm crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x2 CPU part : 0xd05 CPU revision : 0 ..... processor : 4 BogoMIPS : 48.00 Features : fp asimd evtstrm crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x4 CPU part : 0xd0b CPU revision : 0 ..... To fix this, use the Linux kernel way of reading the feature registers as documented here: https://www.kernel.org/doc/html/latest/arch/arm64/cpu-feature-registers.html arm.zig already has the code to parse the feature register values, we just need to collect them in an array and pass them for identification. Signed-off-by: Liviu Dudau <liviu@dudau.co.uk>

1 files changed, 26 insertions(+), 1 deletions(-)

lib/std/zig/system/linux.zig+26-1
......@@ -374,6 +374,12 @@ fn CpuinfoParser(comptime impl: anytype) type {
374374 };
375375}
376376
377inline fn getAArch64CpuFeature(comptime feat_reg: []const u8) u64 {
378 return asm ("mrs %[ret], " ++ feat_reg
379 : [ret] "=r" (-> u64),
380 );
381}
382
377383pub fn detectNativeCpuAndFeatures() ?Target.Cpu {
378384 var f = fs.openFileAbsolute("/proc/cpuinfo", .{}) catch |err| switch (err) {
379385 else => return null,
......@@ -382,9 +388,28 @@ pub fn detectNativeCpuAndFeatures() ?Target.Cpu {
382388
383389 const current_arch = builtin.cpu.arch;
384390 switch (current_arch) {
385 .arm, .armeb, .thumb, .thumbeb, .aarch64, .aarch64_be, .aarch64_32 => {
391 .arm, .armeb, .thumb, .thumbeb => {
386392 return ArmCpuinfoParser.parse(current_arch, f.reader()) catch null;
387393 },
394 .aarch64, .aarch64_be, .aarch64_32 => {
395 const registers = [12]u64{
396 getAArch64CpuFeature("MIDR_EL1"),
397 getAArch64CpuFeature("ID_AA64PFR0_EL1"),
398 getAArch64CpuFeature("ID_AA64PFR1_EL1"),
399 getAArch64CpuFeature("ID_AA64DFR0_EL1"),
400 getAArch64CpuFeature("ID_AA64DFR1_EL1"),
401 getAArch64CpuFeature("ID_AA64AFR0_EL1"),
402 getAArch64CpuFeature("ID_AA64AFR1_EL1"),
403 getAArch64CpuFeature("ID_AA64ISAR0_EL1"),
404 getAArch64CpuFeature("ID_AA64ISAR1_EL1"),
405 getAArch64CpuFeature("ID_AA64MMFR0_EL1"),
406 getAArch64CpuFeature("ID_AA64MMFR1_EL1"),
407 getAArch64CpuFeature("ID_AA64MMFR2_EL1"),
408 };
409
410 const core = @import("arm.zig").aarch64.detectNativeCpuAndFeatures(current_arch, registers);
411 return core;
412 },
388413 .sparc64 => {
389414 return SparcCpuinfoParser.parse(current_arch, f.reader()) catch null;
390415 },