| author | |
| committer | |
| log | a0de077600a35e41ce861398eaf3c8e832fee42e |
| tree | 65573517c636b1a42e5e018b6de6740eec21b8a6 |
| parent | 1fb23813166e768a59bc7468d09bcb2e8e0f8f03 |
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 { | ... | @@ -374,6 +374,12 @@ fn CpuinfoParser(comptime impl: anytype) type { |
| 374 | }; | 374 | }; |
| 375 | } | 375 | } |
| 376 | 376 | ||
| 377 | inline fn getAArch64CpuFeature(comptime feat_reg: []const u8) u64 { | ||
| 378 | return asm ("mrs %[ret], " ++ feat_reg | ||
| 379 | : [ret] "=r" (-> u64), | ||
| 380 | ); | ||
| 381 | } | ||
| 382 | |||
| 377 | pub fn detectNativeCpuAndFeatures() ?Target.Cpu { | 383 | pub fn detectNativeCpuAndFeatures() ?Target.Cpu { |
| 378 | var f = fs.openFileAbsolute("/proc/cpuinfo", .{}) catch |err| switch (err) { | 384 | var f = fs.openFileAbsolute("/proc/cpuinfo", .{}) catch |err| switch (err) { |
| 379 | else => return null, | 385 | else => return null, |
| ... | @@ -382,9 +388,28 @@ pub fn detectNativeCpuAndFeatures() ?Target.Cpu { | ... | @@ -382,9 +388,28 @@ pub fn detectNativeCpuAndFeatures() ?Target.Cpu { |
| 382 | 388 | ||
| 383 | const current_arch = builtin.cpu.arch; | 389 | const current_arch = builtin.cpu.arch; |
| 384 | switch (current_arch) { | 390 | switch (current_arch) { |
| 385 | .arm, .armeb, .thumb, .thumbeb, .aarch64, .aarch64_be, .aarch64_32 => { | 391 | .arm, .armeb, .thumb, .thumbeb => { |
| 386 | return ArmCpuinfoParser.parse(current_arch, f.reader()) catch null; | 392 | return ArmCpuinfoParser.parse(current_arch, f.reader()) catch null; |
| 387 | }, | 393 | }, |
| 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 | }, | ||
| 388 | .sparc64 => { | 413 | .sparc64 => { |
| 389 | return SparcCpuinfoParser.parse(current_arch, f.reader()) catch null; | 414 | return SparcCpuinfoParser.parse(current_arch, f.reader()) catch null; |
| 390 | }, | 415 | }, |