Add CPUInfo parsing for RISCV
Currently only 64-bit RISCV is supported (GOARCH=riscv64) by the Go
compiler, but the cpuinfo format would be the same for 32-bit RISCV.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Tobias Klauser authored 3 years ago
Johannes 'fish' Ziemke committed 3 years ago
33 | 33 | steps: |
34 | 34 | - checkout |
35 | 35 | - run: sudo pip install codespell |
36 | - run: codespell --skip=".git,./vendor,ttar,fixtures.ttar,./fixtures,go.mod,go.sum" -L uint,packages\',ded,alo,als,te,sie | |
36 | - run: codespell --skip=".git,./vendor,ttar,fixtures.ttar,./fixtures,go.mod,go.sum" -L uint,packages\',ded,alo,als,te,sie,hart | |
37 | 37 | |
38 | 38 | workflows: |
39 | 39 | version: 2 |
406 | 406 | return cpuinfo, nil |
407 | 407 | } |
408 | 408 | |
409 | func parseCPUInfoRISCV(info []byte) ([]CPUInfo, error) { | |
410 | scanner := bufio.NewScanner(bytes.NewReader(info)) | |
411 | ||
412 | firstLine := firstNonEmptyLine(scanner) | |
413 | if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") { | |
414 | return nil, errors.New("invalid cpuinfo file: " + firstLine) | |
415 | } | |
416 | field := strings.SplitN(firstLine, ": ", 2) | |
417 | v, err := strconv.ParseUint(field[1], 0, 32) | |
418 | if err != nil { | |
419 | return nil, err | |
420 | } | |
421 | firstcpu := CPUInfo{Processor: uint(v)} | |
422 | cpuinfo := []CPUInfo{firstcpu} | |
423 | i := 0 | |
424 | ||
425 | for scanner.Scan() { | |
426 | line := scanner.Text() | |
427 | if !strings.Contains(line, ":") { | |
428 | continue | |
429 | } | |
430 | field := strings.SplitN(line, ": ", 2) | |
431 | switch strings.TrimSpace(field[0]) { | |
432 | case "processor": | |
433 | v, err := strconv.ParseUint(field[1], 0, 32) | |
434 | if err != nil { | |
435 | return nil, err | |
436 | } | |
437 | i = int(v) | |
438 | cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor | |
439 | cpuinfo[i].Processor = uint(v) | |
440 | case "hart": | |
441 | cpuinfo[i].CoreID = field[1] | |
442 | case "isa": | |
443 | cpuinfo[i].ModelName = field[1] | |
444 | } | |
445 | } | |
446 | return cpuinfo, nil | |
447 | } | |
448 | ||
409 | 449 | func parseCPUInfoDummy(_ []byte) ([]CPUInfo, error) { // nolint:unused,deadcode |
410 | 450 | return nil, errors.New("not implemented") |
411 | 451 | } |
11 | 11 | // limitations under the License. |
12 | 12 | |
13 | 13 | // +build linux |
14 | // +build !386,!amd64,!arm,!arm64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!s390x | |
14 | // +build !386,!amd64,!arm,!arm64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!riscv64,!s390x | |
15 | 15 | |
16 | 16 | package procfs |
17 | 17 |
203 | 203 | model : IBM,8233-E8B |
204 | 204 | machine : CHRP IBM,8233-E8B |
205 | 205 | ` |
206 | ||
207 | cpuinfoRiscv64 = ` | |
208 | processor : 0 | |
209 | hart : 0 | |
210 | isa : rv64imafdcsu | |
211 | mmu : sv48 | |
212 | ||
213 | processor : 1 | |
214 | hart : 1 | |
215 | isa : rv64imafdcsu | |
216 | mmu : sv48 | |
217 | ` | |
206 | 218 | ) |
207 | 219 | |
208 | 220 | func TestCPUInfoX86(t *testing.T) { |
344 | 356 | t.Errorf("want cpu mhz %v, have %v", want, have) |
345 | 357 | } |
346 | 358 | } |
359 | ||
360 | func TestCPUInfoParseRISCV64(t *testing.T) { | |
361 | cpuinfo, err := parseCPUInfoRISCV([]byte(cpuinfoRiscv64)) | |
362 | if err != nil || cpuinfo == nil { | |
363 | t.Fatalf("unable to parse ppc cpu info: %v", err) | |
364 | } | |
365 | if want, have := 2, len(cpuinfo); want != have { | |
366 | t.Errorf("want number of processors %v, have %v", want, have) | |
367 | } | |
368 | if want, have := "1", cpuinfo[1].CoreID; want != have { | |
369 | t.Errorf("want CoreId %v, have %v", want, have) | |
370 | } | |
371 | if want, have := "rv64imafdcsu", cpuinfo[1].ModelName; want != have { | |
372 | t.Errorf("want ModelName %v, have %v", want, have) | |
373 | } | |
374 | } |