Skip to content

Commit

Permalink
Added support for CPUInfo for ARM on Linux kernels 3.8+
Browse files Browse the repository at this point in the history
Fixes issue #294

Signed-off-by: kadern0 <[email protected]>
  • Loading branch information
kadern0 authored and discordianfish committed May 21, 2020
1 parent b8aca74 commit b101fad
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 8 deletions.
27 changes: 23 additions & 4 deletions cpuinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -216,20 +227,28 @@ 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
}
cpuinfo[i].BogoMips = v
case "Features":
featuresLine = line
case "model name":
cpuinfo[i].ModelName = field[1]
}
}
fields := strings.SplitN(featuresLine, ": ", 2)
for i := range cpuinfo {
cpuinfo[i].Flags = strings.Fields(fields[1])
}
return cpuinfo, nil

}

func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) {
Expand Down
99 changes: 95 additions & 4 deletions cpuinfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package procfs
import "testing"

const (
cpuinfoArm7 = `
cpuinfoArm7Legacy = `
Processor : ARMv7 Processor rev 5 (v7l)
processor : 0
BogoMIPS : 2400.00
Expand All @@ -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
Expand Down Expand Up @@ -153,22 +212,54 @@ 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 {
t.Errorf("want flag %v, have %v", want, have)
}
}

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 {
Expand Down

0 comments on commit b101fad

Please sign in to comment.