Source
pub fn detectNativeCpuAndFeatures() ?Target.Cpu {
const current_arch = builtin.cpu.arch;
const cpu: ?Target.Cpu = switch (current_arch) {
.aarch64, .aarch64_be => blk: {
var cores: [128]Target.Cpu = undefined;
const core_count = getCpuCount();
if (core_count > cores.len) break :blk null;
var i: usize = 0;
while (i < core_count) : (i += 1) {
// Backing datastore
var registers: [12]u64 = undefined;
// Registry key to system ID register mapping
// CP 4000 -> MIDR_EL1
// CP 4020 -> ID_AA64PFR0_EL1
// CP 4021 -> ID_AA64PFR1_EL1
// CP 4028 -> ID_AA64DFR0_EL1
// CP 4029 -> ID_AA64DFR1_EL1
// CP 402C -> ID_AA64AFR0_EL1
// CP 402D -> ID_AA64AFR1_EL1
// CP 4030 -> ID_AA64ISAR0_EL1
// CP 4031 -> ID_AA64ISAR1_EL1
// CP 4038 -> ID_AA64MMFR0_EL1
// CP 4039 -> ID_AA64MMFR1_EL1
// CP 403A -> ID_AA64MMFR2_EL1
getCpuInfoFromRegistry(i, .{
.{ .key = "CP 4000", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[0])) },
.{ .key = "CP 4020", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[1])) },
.{ .key = "CP 4021", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[2])) },
.{ .key = "CP 4028", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[3])) },
.{ .key = "CP 4029", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[4])) },
.{ .key = "CP 402C", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[5])) },
.{ .key = "CP 402D", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[6])) },
.{ .key = "CP 4030", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[7])) },
.{ .key = "CP 4031", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[8])) },
.{ .key = "CP 4038", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[9])) },
.{ .key = "CP 4039", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[10])) },
.{ .key = "CP 403A", .value_type = REG.QWORD, .value_buf = @as(*[8]u8, @ptrCast(®isters[11])) },
}) catch break :blk null;
cores[i] = @import("arm.zig").aarch64.detectNativeCpuAndFeatures(current_arch, registers) orelse
break :blk null;
}
// Pick the first core, usually LITTLE in big.LITTLE architecture.
break :blk cores[0];
},
else => null,
};
return cpu orelse genericCpuAndNativeFeatures(current_arch);
}