github.com/ratrocket/u-root@v0.0.0-20180201221235-1cf9f48ee2cf/cmds/msr/msr.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  // msr lets you read and write an msr for one or more cores.
     6  // The cores are specified via a filepath.Glob string.
     7  // The string should be for core number only, with no
     8  // surrounding paths, e.g. you use 0 for core 0, not
     9  // /dev/cpu/0/msr.
    10  // To specify all cores, use '*'
    11  // To specify all cores with two digits, use '??'
    12  // To specify all odd cores, use '*[13579]'
    13  // To specify, e.g., all the even cores, use '*[02468]'.
    14  // Usage:
    15  // msr r glob 32-bit-msr-number
    16  // msr w glob 32-bit-msr-number 64-bit-value
    17  // For each MSR operation msr will print an error if any.
    18  // If your kernel does not have MSRs for any reason,
    19  // this will fail due to file access. But it's quite possible
    20  // that non-x86 architectures might someday implement MSRs,
    21  // which on (e.g.) PPC might have a slightly different name
    22  // (DICR) but would implement the same kinds of functions.
    23  package main
    24  
    25  import (
    26  	"fmt"
    27  	"log"
    28  	"os"
    29  	"strconv"
    30  )
    31  
    32  const usage = `msr r glob register
    33  msr w glob register value`
    34  
    35  func main() {
    36  	a := os.Args[1:]
    37  	if len(a) < 3 {
    38  		log.Fatal(usage)
    39  	}
    40  
    41  	m := msrList(a[1])
    42  
    43  	reg, err := strconv.ParseUint(a[2], 0, 32)
    44  	if err != nil {
    45  		log.Fatalf("%v: %v", a[2], err)
    46  	}
    47  	switch a[0] {
    48  	case "r":
    49  		data, errs := rdmsr(m, uint32(reg))
    50  		for i, v := range m {
    51  			if errs[i] != nil {
    52  				fmt.Printf("%v: %v\n", v, errs[i])
    53  			} else {
    54  				fmt.Printf("%v: %#016x\n", v, data[i])
    55  			}
    56  		}
    57  
    58  	case "w":
    59  		// Sadly, we don't get an error on write if the values
    60  		// don't match.  Reading it back to check it is
    61  		// not always going to work. There are many write-only
    62  		// MSRs. If there are no errors there is still no
    63  		// guarantee that it worked, or if we read it we would
    64  		// see what we wrote, or that vmware did not do
    65  		// something stupid, or the x86 did not do something really
    66  		// stupid, or the particular implementation of the x86
    67  		// that we are on did not do something really stupid.
    68  		// Why is it this way? Because vendors hide proprietary
    69  		// information in hidden MSRs, or in hidden fields in MSRs.
    70  		// Checking is just not an option. There, feel better now?
    71  		if len(a) < 4 {
    72  			log.Fatal(usage)
    73  		}
    74  		v, err := strconv.ParseUint(a[3], 0, 64)
    75  		if err != nil {
    76  			log.Fatalf("%v: %v", a, err)
    77  		}
    78  		errs := wrmsr(m, uint32(reg), v)
    79  		for i, e := range errs {
    80  			if e != nil {
    81  				fmt.Printf("%v: %v\n", m[i], e)
    82  			}
    83  		}
    84  
    85  	default:
    86  		log.Fatalf(usage)
    87  	}
    88  }