github.com/mem/u-root@v2.0.1-0.20181004165302-9b18b4636a33+incompatible/cmds/io/io.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  // io lets you do IO operations.
     6  //
     7  // Synopsis:
     8  //     io [inb|inw|inl] address
     9  //     io [outb|outw|outl] address value
    10  //
    11  // Description:
    12  //     io will let you do IO instructions on various architectures that support it.
    13  //
    14  package main
    15  
    16  import (
    17  	"fmt"
    18  	"log"
    19  	"os"
    20  	"strconv"
    21  )
    22  
    23  const usage = `io [inb|inw|inl|rb|rw|rl|rq] address
    24  io [outb|outw|outl|wb|ww|wl|wq] address value`
    25  
    26  type iod struct {
    27  	nargs    int
    28  	addrbits int // not all addresses are multiples of 8 in size.
    29  	val      interface{}
    30  	valbits  int // not all value bits are multiples of 8 in size.
    31  	format   string
    32  	dev      string
    33  	mode     int
    34  }
    35  
    36  var (
    37  	ios = map[string]iod{
    38  		"inb":  {2, 16, &b, 8, "%#02x", "/dev/port", os.O_RDONLY},
    39  		"inw":  {2, 16, &w, 16, "%#04x", "/dev/port", os.O_RDONLY},
    40  		"inl":  {2, 16, &l, 32, "%#08x", "/dev/port", os.O_RDONLY},
    41  		"outb": {3, 16, b, 8, "", "/dev/port", os.O_WRONLY},
    42  		"outw": {3, 16, w, 16, "", "/dev/port", os.O_WRONLY},
    43  		"outl": {3, 16, l, 32, "", "/dev/port", os.O_WRONLY},
    44  		"rb":   {2, 64, &b, 8, "%#02x", "/dev/mem", os.O_RDONLY},
    45  		"rw":   {2, 64, &w, 16, "%#04x", "/dev/mem", os.O_RDONLY},
    46  		"rl":   {2, 64, &l, 32, "%#08x", "/dev/mem", os.O_RDONLY},
    47  		"rq":   {2, 64, &q, 64, "%#16x", "/dev/mem", os.O_RDONLY},
    48  		"wb":   {3, 64, b, 8, "", "/dev/mem", os.O_WRONLY},
    49  		"ww":   {3, 64, w, 16, "", "/dev/mem", os.O_WRONLY},
    50  		"wl":   {3, 64, l, 32, "", "/dev/mem", os.O_WRONLY},
    51  		"wq":   {3, 64, q, 64, "", "/dev/mem", os.O_WRONLY},
    52  	}
    53  	b    byte
    54  	w    uint16
    55  	l    uint32
    56  	q    uint64
    57  	addr uint64
    58  )
    59  
    60  func main() {
    61  	var err error
    62  	a := os.Args[1:]
    63  
    64  	if len(a) == 0 {
    65  		log.Fatal(usage)
    66  	}
    67  
    68  	i, ok := ios[a[0]]
    69  	if !ok || len(a) != i.nargs {
    70  		log.Fatal(usage)
    71  	}
    72  
    73  	f, err := os.OpenFile(i.dev, i.mode, 0)
    74  	if err != nil {
    75  		log.Fatalf("%v", err)
    76  	}
    77  
    78  	addr, err := strconv.ParseUint(a[1], 0, i.addrbits)
    79  	if err != nil {
    80  		log.Fatalf("Parsing address for %d bits: %v %v", i.addrbits, a[1], err)
    81  	}
    82  
    83  	switch a[0][0] {
    84  	case 'i', 'r':
    85  		err = in(f, addr, i.val)
    86  	case 'o', 'w':
    87  		var v uint64
    88  		v, err = strconv.ParseUint(a[2], 0, i.valbits)
    89  		if err != nil {
    90  			log.Fatalf("%v: %v", a, err)
    91  		}
    92  		switch i.valbits {
    93  		case 8:
    94  			err = out(f, addr, uint8(v))
    95  		case 16:
    96  			err = out(f, addr, uint16(v))
    97  		case 32:
    98  			err = out(f, addr, uint32(v))
    99  		case 64:
   100  			err = out(f, addr, uint64(v))
   101  		}
   102  	default:
   103  		log.Fatalf(usage)
   104  	}
   105  
   106  	if err != nil {
   107  		log.Fatalf("%v: %v", a, err)
   108  	}
   109  
   110  	if i.format != "" {
   111  		switch i.val.(type) {
   112  		case *uint8:
   113  			fmt.Printf(i.format, *i.val.(*uint8))
   114  		case *uint16:
   115  			fmt.Printf(i.format, *i.val.(*uint16))
   116  		case *uint32:
   117  			fmt.Printf(i.format, *i.val.(*uint32))
   118  		case *uint64:
   119  			fmt.Printf(i.format, *i.val.(*uint64))
   120  		}
   121  
   122  	}
   123  }