diff --git a/cpuinfo.go b/cpuinfo.go index 7a31a455..b3757bbf 100644 --- a/cpuinfo.go +++ b/cpuinfo.go @@ -243,6 +243,14 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) { featuresLine = line case "model name": cpuinfo[i].ModelName = field[1] + case "CPU implementer": + cpuinfo[i].VendorID = field[1] + case "CPU variant": + cpuinfo[i].CPUFamily = field[1] + case "CPU part": + cpuinfo[i].Model = field[1] + case "CPU revision": + cpuinfo[i].Stepping = field[1] } } fields := strings.SplitN(featuresLine, ": ", 2) diff --git a/cpuinfo_test.go b/cpuinfo_test.go index 9f49eeb3..6f6316e9 100644 --- a/cpuinfo_test.go +++ b/cpuinfo_test.go @@ -478,3 +478,47 @@ func TestCPUInfoParseLoong64(t *testing.T) { t.Errorf("want CPUFamily '%v', have '%v'", want, have) } } + +const cpuinfoArm64Identity = `processor : 0 +BogoMIPS : 100.00 +Features : fp asimd aes sha1 sha2 crc32 +CPU implementer : 0x41 +CPU variant : 0x1 +CPU part : 0xd40 +CPU revision : 0 + +processor : 1 +BogoMIPS : 100.00 +Features : fp asimd aes sha1 sha2 crc32 +CPU implementer : 0x41 +CPU variant : 0x1 +CPU part : 0xd40 +CPU revision : 0 +` + +func TestParseCPUInfoARM64IdentityFields(t *testing.T) { + parsed, err := parseCPUInfoARM([]byte(cpuinfoArm64Identity)) + if err != nil { + t.Fatalf("parseCPUInfoARM returned an error: %v", err) + } + if len(parsed) != 2 { + t.Fatalf("expected 2 CPUs, got %d", len(parsed)) + } + for i, cpu := range parsed { + // arm64 kernels have no "model name" line; the implementer/variant/ + // part/revision fields are the only CPU identity available and must + // not be dropped by the parser. + if cpu.VendorID != "0x41" { + t.Errorf("cpu %d: VendorID = %q, want %q", i, cpu.VendorID, "0x41") + } + if cpu.CPUFamily != "0x1" { + t.Errorf("cpu %d: CPUFamily = %q, want %q", i, cpu.CPUFamily, "0x1") + } + if cpu.Model != "0xd40" { + t.Errorf("cpu %d: Model = %q, want %q", i, cpu.Model, "0xd40") + } + if cpu.Stepping != "0" { + t.Errorf("cpu %d: Stepping = %q, want %q", i, cpu.Stepping, "0") + } + } +}