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 }