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  }