github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/pci/bits.go (about) 1 // Copyright 2021 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 package pci 6 7 import ( 8 "fmt" 9 ) 10 11 // bit puller-aparters. There's a case to be made for the usual tables 12 // with widths and values and stuff but this way ends up being easier 13 // to read, surprisingly. 14 15 // Control register bits are packed, bit 0 to bit 11. Thank you, PCI people. 16 var crBits = []string{ 17 "I/O", 18 "Memory", 19 "DMA", 20 "Special", 21 "MemWINV", 22 "VGASnoop", 23 "ParErr", 24 "Stepping", 25 "SERR", 26 "FastB2B", 27 "DisInt", 28 } 29 30 // String implements Stringer. 31 func (c *Control) String() string { 32 var s string 33 for i, n := range crBits { 34 if len(s) > 0 { 35 s = s + " " 36 } 37 s += n 38 ix := (1<<i)&uint16(*c) != 0 39 if ix { 40 s += "+" 41 } else { 42 s += "-" 43 } 44 } 45 return s 46 } 47 48 var stBits = []string{ 49 "Reserved", 50 "Reserved", 51 "INTx", 52 "Cap", 53 "66MHz", 54 "UDF", 55 "FastB2b", 56 "ParErr", 57 "DEVSEL", 58 ">Tabort", 59 "<Tabort", 60 "<MABORT", 61 ">SERR", 62 "<PERR", 63 } 64 65 // String implements Stringer. 66 func (c *Status) String() string { 67 var s string 68 69 for i, n := range stBits { 70 switch i { 71 case 9: // the only multi-bit field 72 spd := (uint16(*c) & 0x600) >> 9 73 if len(s) > 0 { 74 s = s + " " 75 } 76 s += fmt.Sprintf("DEVSEL=%s", []string{"fast", "medium", "slow", "reserved"}[spd]) 77 case 0: 78 case 1: 79 case 10: 80 continue 81 default: 82 ix := (1<<i)&uint16(*c) != 0 83 if len(s) > 0 { 84 s = s + " " 85 } 86 s += n 87 if ix { 88 s += "+" 89 } else { 90 s += "-" 91 } 92 } 93 } 94 return s 95 } 96 97 // String implements Stringer. 98 func (bar *BAR) String() string { 99 // This little test lets us create empty strings, which 100 // the JSON marshaler can then omit. That way, non-bridge 101 // PCI devices won't even have this stuff show up. 102 if bar.Base == 0 { 103 return "" 104 } 105 var typ string 106 base := bar.Base 107 switch bar.Attr & 0xf { 108 case 0: 109 typ = "Memory at %08x (32-bit, non-prefetchable) [size=%#x]" 110 case 1: 111 typ = "I/O ports at %04x [size=%d]" 112 case 2: 113 typ = "Memory at %08x (32-bit, low 1Mbyte, non-prefetchable) [size=%#x]" 114 if base < 0x100000 && base >= 0xc0000 { 115 typ = "Expansion ROM at %08x (low 1Mbyte) [size=%#x]" 116 if base&1 == 0 { 117 typ = "(Disabled)" + typ 118 } else { 119 base-- 120 } 121 } 122 case 4: 123 typ = "Memory at %08x (64-bit, non-prefetchable) [size=%#x]" 124 case 8: 125 typ = "Memory at %08x (32-bit, prefetchable) [size=%#x]" 126 case 0xc: 127 typ = "Memory at %08x (64-bit, prefetchable) [size=%#x]" 128 default: 129 return fmt.Sprintf("Can't get type from %#x", bar.Attr) 130 } 131 sz := bar.Lim - base + 1 132 return fmt.Sprintf("Region %d: "+typ, bar.Index, base, sz) 133 }