forked from insomniacslk/u-root
-
Notifications
You must be signed in to change notification settings - Fork 1
/
pci.go
130 lines (121 loc) · 3.03 KB
/
pci.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright 2012-2017 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// pci: show pci bus vendor ids and other info
//
// Description:
// List the PCI bus, with names if possible.
//
// Options:
// -n: just show numbers
// -c: dump config space
// -s: specify glob for choosing devices.
package main
import (
"flag"
"fmt"
"log"
"strconv"
"strings"
"github.com/u-root/u-root/pkg/pci"
)
var (
numbers = flag.Bool("n", false, "Show numeric IDs")
dumpConfig = flag.Bool("c", false, "Dump config space")
devs = flag.String("s", "*", "Devices to match")
format = map[int]string{
32: "%08x:%08x",
16: "%08x:%04x",
8: "%08x:%02x",
}
)
// maybe we need a better syntax than the standard pcitools?
func registers(d pci.Devices, cmds ...string) {
var justCheck bool
for _, c := range cmds {
// TODO: replace this nonsense with a state machine.
// Split into register and value
rv := strings.Split(c, "=")
if len(rv) != 1 && len(rv) != 2 {
log.Printf("%v: only one = allowed. Due to this error no more commands will be issued", c)
justCheck = true
continue
}
// Split into register offset and size
rs := strings.Split(rv[0], ".")
if len(rs) != 1 && len(rs) != 2 {
log.Printf("%v: only one . allowed. Due to this error no more commands will be issued", rv[1])
justCheck = true
continue
}
s := 32
if len(rs) == 2 {
switch rs[1] {
default:
log.Printf("Bad size: %v. Due to this error no more commands will be issued", rs[1])
justCheck = true
continue
case "l":
case "w":
s = 16
case "b":
s = 8
}
}
if justCheck {
continue
}
reg, err := strconv.ParseUint(rs[0], 0, 16)
if err != nil {
log.Printf("%v:%v. Due to this error no more commands will be issued", rs[0], err)
justCheck = true
continue
}
if len(rv) == 1 {
v, err := d.ReadConfigRegister(int64(reg), int64(s))
if err != nil {
log.Printf("%v:%v. Due to this error no more commands will be issued", rv[1], err)
justCheck = true
continue
}
// Should this go in the package somewhere? Not sure.
for i := range v {
d[i].ExtraInfo = append(d[i].ExtraInfo, fmt.Sprintf(format[s], reg, v[i]))
}
}
if len(rv) == 2 {
val, err := strconv.ParseUint(rv[1], 0, s)
if err != nil {
log.Printf("%v. Due to this error no more commands will be issued", err)
justCheck = true
continue
}
if err := d.WriteConfigRegister(int64(reg), int64(s), val); err != nil {
log.Printf("%v:%v. Due to this error no more commands will be issued", rv[1], err)
justCheck = true
continue
}
}
}
}
func main() {
flag.Parse()
r, err := pci.NewBusReader(strings.Split(*devs, ",")...)
if err != nil {
log.Fatalf("%v", err)
}
d, err := r.Read()
if err != nil {
log.Fatalf("Read: %v", err)
}
if !*numbers {
d.SetVendorDeviceName()
}
if len(flag.Args()) > 0 {
registers(d, flag.Args()...)
}
if *dumpConfig {
d.ReadConfig()
}
fmt.Print(d)
}