diff --git a/cpuinfo.go b/cpuinfo.go index bb3be99ff..d19ce853c 100644 --- a/cpuinfo.go +++ b/cpuinfo.go @@ -190,15 +190,26 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) { scanner := bufio.NewScanner(bytes.NewReader(info)) firstLine := firstNonEmptyLine(scanner) - if !strings.HasPrefix(firstLine, "Processor") || !strings.Contains(firstLine, ":") { + match, _ := regexp.MatchString("^[Pp]rocessor", firstLine) + if !match || !strings.Contains(firstLine, ":") { return nil, errors.New("invalid cpuinfo file: " + firstLine) } field := strings.SplitN(firstLine, ": ", 2) - commonCPUInfo := CPUInfo{VendorID: field[1]} - cpuinfo := []CPUInfo{} - i := -1 featuresLine := "" + commonCPUInfo := CPUInfo{} + i := 0 + if strings.TrimSpace(field[0]) == "Processor" { + commonCPUInfo = CPUInfo{ModelName: field[1]} + i = -1 + } else { + v, err := strconv.ParseUint(field[1], 0, 32) + if err != nil { + return nil, err + } + firstcpu := CPUInfo{Processor: uint(v)} + cpuinfo = []CPUInfo{firstcpu} + } for scanner.Scan() { line := scanner.Text() @@ -216,6 +227,11 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) { } cpuinfo[i].Processor = uint(v) case "BogoMIPS": + if i == -1 { + cpuinfo = append(cpuinfo, commonCPUInfo) // There is only one processor + i++ + cpuinfo[i].Processor = 0 + } v, err := strconv.ParseFloat(field[1], 64) if err != nil { return nil, err @@ -223,6 +239,8 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) { cpuinfo[i].BogoMips = v case "Features": featuresLine = line + case "model name": + cpuinfo[i].ModelName = field[1] } } fields := strings.SplitN(featuresLine, ": ", 2) @@ -230,6 +248,7 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) { cpuinfo[i].Flags = strings.Fields(fields[1]) } return cpuinfo, nil + } func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) { diff --git a/cpuinfo_test.go b/cpuinfo_test.go index b6869acee..17eefbe45 100644 --- a/cpuinfo_test.go +++ b/cpuinfo_test.go @@ -18,7 +18,7 @@ package procfs import "testing" const ( - cpuinfoArm7 = ` + cpuinfoArm7Legacy = ` Processor : ARMv7 Processor rev 5 (v7l) processor : 0 BogoMIPS : 2400.00 @@ -37,6 +37,65 @@ Hardware : sun8i Revision : 0000 Serial : 5400503583203c3c040e` + cpuinfoArm7LegacyV1 = ` +Processor : ARMv6-compatible processor rev 5 (v6l) +BogoMIPS : 791.34 +Features : swp half thumb fastmult vfp edsp java +CPU implementer : 0x41 +CPU architecture: 6TEJ +CPU variant : 0x1 +CPU part : 0xb36 +CPU revision : 5 + +Hardware : IMAPX200 +Revision : 0000 +Serial : 0000000000000000` + + cpuinfoArm7 = ` +processor : 0 +model name : ARMv7 Processor rev 3 (v7l) +BogoMIPS : 108.00 +Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xd08 +CPU revision : 3 + +processor : 1 +model name : ARMv7 Processor rev 3 (v7l) +BogoMIPS : 108.00 +Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xd08 +CPU revision : 3 + +processor : 2 +model name : ARMv7 Processor rev 3 (v7l) +BogoMIPS : 108.00 +Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xd08 +CPU revision : 3 + +processor : 3 +model name : ARMv7 Processor rev 3 (v7l) +BogoMIPS : 108.00 +Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xd08 +CPU revision : 3 + +Hardware : BCM2835 +Revision : c03111 +` + cpuinfoS390x = ` vendor_id : IBM/S390 # processors : 4 @@ -153,15 +212,15 @@ func TestCPUInfoX86(t *testing.T) { } } -func TestCPUInfoParseARM(t *testing.T) { - cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7)) +func TestCPUInfoParseARMLegacy(t *testing.T) { + cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7Legacy)) if err != nil || cpuinfo == nil { t.Fatalf("unable to parse arm cpu info: %v", err) } if want, have := 2, len(cpuinfo); want != have { t.Errorf("want number of processors %v, have %v", want, have) } - if want, have := "ARMv7 Processor rev 5 (v7l)", cpuinfo[0].VendorID; want != have { + if want, have := "ARMv7 Processor rev 5 (v7l)", cpuinfo[0].ModelName; want != have { t.Errorf("want vendor %v, have %v", want, have) } if want, have := "thumb", cpuinfo[1].Flags[2]; want != have { @@ -169,6 +228,38 @@ func TestCPUInfoParseARM(t *testing.T) { } } +func TestCPUInfoParseARMLegacyV1(t *testing.T) { + cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7LegacyV1)) + if err != nil || cpuinfo == nil { + t.Fatalf("unable to parse arm cpu info: %v", err) + } + if want, have := 1, len(cpuinfo); want != have { + t.Errorf("want number of processors %v, have %v", want, have) + } + if want, have := "ARMv6-compatible processor rev 5 (v6l)", cpuinfo[0].ModelName; want != have { + t.Errorf("want vendor %v, have %v", want, have) + } + if want, have := "thumb", cpuinfo[0].Flags[2]; want != have { + t.Errorf("want flag %v, have %v", want, have) + } +} + +func TestCPUInfoParseARM(t *testing.T) { + cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7)) + if err != nil || cpuinfo == nil { + t.Fatalf("unable to parse arm cpu info: %v", err) + } + if want, have := 4, len(cpuinfo); want != have { + t.Errorf("want number of processors %v, have %v", want, have) + } + if want, have := "ARMv7 Processor rev 3 (v7l)", cpuinfo[0].ModelName; want != have { + t.Errorf("want vendor %v, have %v", want, have) + } + if want, have := "thumb", cpuinfo[1].Flags[1]; want != have { + t.Errorf("want flag %v, have %v", want, have) + } +} + func TestCPUInfoParseS390X(t *testing.T) { cpuinfo, err := parseCPUInfoS390X([]byte(cpuinfoS390x)) if err != nil || cpuinfo == nil {