Skip to content

Commit 12d4418

Browse files
committed
Added support for CPUInfo for ARM on Linux kernels 3.8+
Fixes issue #294 Signed-off-by: kadern0 <kaderno@gmail.com>
1 parent c6ff04b commit 12d4418

File tree

2 files changed

+118
-8
lines changed

2 files changed

+118
-8
lines changed

cpuinfo.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,15 +190,26 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) {
190190
scanner := bufio.NewScanner(bytes.NewReader(info))
191191

192192
firstLine := firstNonEmptyLine(scanner)
193-
if !strings.HasPrefix(firstLine, "Processor") || !strings.Contains(firstLine, ":") {
193+
match, _ := regexp.MatchString("^[Pp]rocessor", firstLine)
194+
if !match || !strings.Contains(firstLine, ":") {
194195
return nil, errors.New("invalid cpuinfo file: " + firstLine)
195196
}
196197
field := strings.SplitN(firstLine, ": ", 2)
197-
commonCPUInfo := CPUInfo{VendorID: field[1]}
198-
199198
cpuinfo := []CPUInfo{}
200-
i := -1
201199
featuresLine := ""
200+
commonCPUInfo := CPUInfo{}
201+
i := 0
202+
if strings.TrimSpace(field[0]) == "Processor" {
203+
commonCPUInfo = CPUInfo{ModelName: field[1]}
204+
i = -1
205+
} else {
206+
v, err := strconv.ParseUint(field[1], 0, 32)
207+
if err != nil {
208+
return nil, err
209+
}
210+
firstcpu := CPUInfo{Processor: uint(v)}
211+
cpuinfo = []CPUInfo{firstcpu}
212+
}
202213

203214
for scanner.Scan() {
204215
line := scanner.Text()
@@ -216,20 +227,28 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) {
216227
}
217228
cpuinfo[i].Processor = uint(v)
218229
case "BogoMIPS":
230+
if i == -1 {
231+
cpuinfo = append(cpuinfo, commonCPUInfo) // There is only one processor
232+
i++
233+
cpuinfo[i].Processor = 0
234+
}
219235
v, err := strconv.ParseFloat(field[1], 64)
220236
if err != nil {
221237
return nil, err
222238
}
223239
cpuinfo[i].BogoMips = v
224240
case "Features":
225241
featuresLine = line
242+
case "model name":
243+
cpuinfo[i].ModelName = field[1]
226244
}
227245
}
228246
fields := strings.SplitN(featuresLine, ": ", 2)
229247
for i := range cpuinfo {
230248
cpuinfo[i].Flags = strings.Fields(fields[1])
231249
}
232250
return cpuinfo, nil
251+
233252
}
234253

235254
func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) {

cpuinfo_test.go

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package procfs
1818
import "testing"
1919

2020
const (
21-
cpuinfoArm7 = `
21+
cpuinfoArm7Legacy = `
2222
Processor : ARMv7 Processor rev 5 (v7l)
2323
processor : 0
2424
BogoMIPS : 2400.00
@@ -37,6 +37,65 @@ Hardware : sun8i
3737
Revision : 0000
3838
Serial : 5400503583203c3c040e`
3939

40+
cpuinfoArm7LegacyV1 = `
41+
Processor : ARMv6-compatible processor rev 5 (v6l)
42+
BogoMIPS : 791.34
43+
Features : swp half thumb fastmult vfp edsp java
44+
CPU implementer : 0x41
45+
CPU architecture: 6TEJ
46+
CPU variant : 0x1
47+
CPU part : 0xb36
48+
CPU revision : 5
49+
50+
Hardware : IMAPX200
51+
Revision : 0000
52+
Serial : 0000000000000000`
53+
54+
cpuinfoArm7 = `
55+
processor : 0
56+
model name : ARMv7 Processor rev 3 (v7l)
57+
BogoMIPS : 108.00
58+
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
59+
CPU implementer : 0x41
60+
CPU architecture: 7
61+
CPU variant : 0x0
62+
CPU part : 0xd08
63+
CPU revision : 3
64+
65+
processor : 1
66+
model name : ARMv7 Processor rev 3 (v7l)
67+
BogoMIPS : 108.00
68+
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
69+
CPU implementer : 0x41
70+
CPU architecture: 7
71+
CPU variant : 0x0
72+
CPU part : 0xd08
73+
CPU revision : 3
74+
75+
processor : 2
76+
model name : ARMv7 Processor rev 3 (v7l)
77+
BogoMIPS : 108.00
78+
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
79+
CPU implementer : 0x41
80+
CPU architecture: 7
81+
CPU variant : 0x0
82+
CPU part : 0xd08
83+
CPU revision : 3
84+
85+
processor : 3
86+
model name : ARMv7 Processor rev 3 (v7l)
87+
BogoMIPS : 108.00
88+
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
89+
CPU implementer : 0x41
90+
CPU architecture: 7
91+
CPU variant : 0x0
92+
CPU part : 0xd08
93+
CPU revision : 3
94+
95+
Hardware : BCM2835
96+
Revision : c03111
97+
`
98+
4099
cpuinfoS390x = `
41100
vendor_id : IBM/S390
42101
# processors : 4
@@ -153,22 +212,54 @@ func TestCPUInfoX86(t *testing.T) {
153212
}
154213
}
155214

156-
func TestCPUInfoParseARM(t *testing.T) {
157-
cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7))
215+
func TestCPUInfoParseARMLegacy(t *testing.T) {
216+
cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7Legacy))
158217
if err != nil || cpuinfo == nil {
159218
t.Fatalf("unable to parse arm cpu info: %v", err)
160219
}
161220
if want, have := 2, len(cpuinfo); want != have {
162221
t.Errorf("want number of processors %v, have %v", want, have)
163222
}
164-
if want, have := "ARMv7 Processor rev 5 (v7l)", cpuinfo[0].VendorID; want != have {
223+
if want, have := "ARMv7 Processor rev 5 (v7l)", cpuinfo[0].ModelName; want != have {
165224
t.Errorf("want vendor %v, have %v", want, have)
166225
}
167226
if want, have := "thumb", cpuinfo[1].Flags[2]; want != have {
168227
t.Errorf("want flag %v, have %v", want, have)
169228
}
170229
}
171230

231+
func TestCPUInfoParseARMLegacyV1(t *testing.T) {
232+
cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7LegacyV1))
233+
if err != nil || cpuinfo == nil {
234+
t.Fatalf("unable to parse arm cpu info: %v", err)
235+
}
236+
if want, have := 1, len(cpuinfo); want != have {
237+
t.Errorf("want number of processors %v, have %v", want, have)
238+
}
239+
if want, have := "ARMv6-compatible processor rev 5 (v6l)", cpuinfo[0].ModelName; want != have {
240+
t.Errorf("want vendor %v, have %v", want, have)
241+
}
242+
if want, have := "thumb", cpuinfo[0].Flags[2]; want != have {
243+
t.Errorf("want flag %v, have %v", want, have)
244+
}
245+
}
246+
247+
func TestCPUInfoParseARM(t *testing.T) {
248+
cpuinfo, err := parseCPUInfoARM([]byte(cpuinfoArm7))
249+
if err != nil || cpuinfo == nil {
250+
t.Fatalf("unable to parse arm cpu info: %v", err)
251+
}
252+
if want, have := 4, len(cpuinfo); want != have {
253+
t.Errorf("want number of processors %v, have %v", want, have)
254+
}
255+
if want, have := "ARMv7 Processor rev 3 (v7l)", cpuinfo[0].ModelName; want != have {
256+
t.Errorf("want vendor %v, have %v", want, have)
257+
}
258+
if want, have := "thumb", cpuinfo[1].Flags[1]; want != have {
259+
t.Errorf("want flag %v, have %v", want, have)
260+
}
261+
}
262+
172263
func TestCPUInfoParseS390X(t *testing.T) {
173264
cpuinfo, err := parseCPUInfoS390X([]byte(cpuinfoS390x))
174265
if err != nil || cpuinfo == nil {

0 commit comments

Comments
 (0)