github.com/oweisse/u-root@v0.0.0-20181109060735-d005ad25fef1/cmds/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(*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  }