github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/exp/smn/main.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 // smn: read or write registers in the System Management Network on AMD cpus 6 // 7 // Synopsis: 8 // snm [0 or more addresses] 9 // N.B. having no addresses is an easy way to see if you can 10 // access PCI at all. 11 // 12 // Description: 13 // read and write System Management Network registers 14 // 15 // Options: 16 // -s: device glob in the form tttt:bb:dd.fn with * as needed 17 // -n: number of 32-bit words to dump. 18 // -v: 32-bit value to write 19 // -w: write the value to the register(s) 20 package main 21 22 import ( 23 "flag" 24 "fmt" 25 "log" 26 "strconv" 27 "strings" 28 29 "github.com/u-root/u-root/pkg/pci" 30 ) 31 32 // Index/Data register pairs, as, e.g., cf8/cfc for PCI, 33 // are known to be a terrible idea, from almost any point of view. 34 // It took years to kill them on regular PCI. 35 // AMD brought them back for the SMN. Bummer. 36 const ( 37 regIndex = 0xa0 38 regData = 0xa4 39 ) 40 41 var ( 42 devs = flag.String("s", "0000:00:00.0", "Glob for northbridge") 43 n = flag.Uint("n", 1, "Number 32-bit words to dump/set") 44 val = flag.Uint64("v", 0, "Val to set on write") 45 write = flag.Bool("w", false, "Write a value") 46 ) 47 48 func usage() { 49 log.Fatal("Usage: smn [-w] [-d glob] address [# 32-words to read | 32-bit value to write]") 50 } 51 52 func main() { 53 flag.Parse() 54 r, err := pci.NewBusReader(strings.Split(*devs, ",")...) 55 if err != nil { 56 log.Fatalf("%v", err) 57 } 58 59 d, err := r.Read() 60 if err != nil { 61 log.Fatalf("Read: %v", err) 62 } 63 64 a := flag.Args() 65 if uint32(*val>>32) != 0 { 66 log.Fatalf("Value:%#x is not a 32-bit number", *val) 67 } 68 for i := range a { 69 addr, err := strconv.ParseUint(a[i], 16, 32) 70 if err != nil { 71 log.Fatal(err) 72 } 73 switch *write { 74 case true: 75 if err := d.WriteConfigRegister(regIndex, 32, addr); err != nil { 76 log.Fatal(err) 77 } 78 if err := d.WriteConfigRegister(regData, 32, *val); err != nil { 79 log.Fatal(err) 80 } 81 case false: 82 for i := addr; i < addr+uint64(*n); i += 4 { 83 if err := d.WriteConfigRegister(regIndex, 32, i); err != nil { 84 log.Fatal(err) 85 } 86 // SMN data is 32 bits! 87 dat, err := d.ReadConfigRegister(regData, 32) 88 if err != nil { 89 log.Fatal(err) 90 } 91 fmt.Printf("%#x:", i) 92 for i := range dat { 93 fmt.Printf("%s:%#x,", d[i].Addr, dat[i]) 94 } 95 fmt.Println() 96 } 97 } 98 } 99 }