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