github.com/rminnich/u-root@v7.0.0+incompatible/pkg/smbios/type38_ipmi_device_information.go (about)

     1  // Copyright 2016-2019 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 smbios
     6  
     7  import (
     8  	"errors"
     9  	"fmt"
    10  	"strings"
    11  )
    12  
    13  // Much of this is auto-generated. If adding a new type, see README for instructions.
    14  
    15  // IPMIDeviceInfo is defined in DSP0134 7.39.
    16  type IPMIDeviceInfo struct {
    17  	Table
    18  	InterfaceType                    BMCInterfaceType // 04h
    19  	IPMISpecificationRevision        uint8            // 05h
    20  	I2CSlaveAddress                  uint8            // 06h
    21  	NVStorageDeviceAddress           uint8            // 07h
    22  	BaseAddress                      uint64           // 08h
    23  	BaseAddressModifierInterruptInfo uint8            // 10h
    24  	InterruptNumber                  uint8            // 11h
    25  }
    26  
    27  // ParseIPMIDeviceInfo parses a generic Table into IPMIDeviceInfo.
    28  func ParseIPMIDeviceInfo(t *Table) (*IPMIDeviceInfo, error) {
    29  	if t.Type != TableTypeIPMIDeviceInfo {
    30  		return nil, fmt.Errorf("invalid table type %d", t.Type)
    31  	}
    32  	if t.Len() < 0x12 {
    33  		return nil, errors.New("required fields missing")
    34  	}
    35  	di := &IPMIDeviceInfo{Table: *t}
    36  	if _, err := parseStruct(t, 0 /* off */, false /* complete */, di); err != nil {
    37  		return nil, err
    38  	}
    39  	return di, nil
    40  }
    41  
    42  func (di *IPMIDeviceInfo) String() string {
    43  	nvs := "Not Present"
    44  	if di.NVStorageDeviceAddress != 0xff {
    45  		nvs = fmt.Sprintf("%d", di.NVStorageDeviceAddress)
    46  	}
    47  
    48  	baType := "Memory-mapped"
    49  	if di.BaseAddress&1 != 0 {
    50  		baType = "I/O"
    51  	}
    52  	ba := (di.BaseAddress & 0xfffffffffffffffe) | uint64((di.BaseAddressModifierInterruptInfo>>4)&1)
    53  
    54  	lines := []string{
    55  		di.Header.String(),
    56  		fmt.Sprintf("Interface Type: %s", di.InterfaceType),
    57  		fmt.Sprintf("Specification Version: %d.%d", di.IPMISpecificationRevision>>4, di.IPMISpecificationRevision&0xf),
    58  		fmt.Sprintf("I2C Slave Address: 0x%02x", di.I2CSlaveAddress>>1),
    59  		fmt.Sprintf("NV Storage Device: %s", nvs),
    60  		fmt.Sprintf("Base Address: 0x%016X (%s)", ba, baType),
    61  	}
    62  	if di.InterfaceType != BMCInterfaceTypeSSIFSMBusSystemInterface {
    63  		rss := ""
    64  		switch (di.BaseAddressModifierInterruptInfo >> 6) & 3 {
    65  		case 0:
    66  			rss = "Successive Byte Boundaries"
    67  		case 1:
    68  			rss = "32-bit Boundaries"
    69  		case 2:
    70  			rss = "16-bit Boundaries"
    71  		case 3:
    72  			rss = outOfSpec
    73  		}
    74  		lines = append(lines, fmt.Sprintf("Register Spacing: %s", rss))
    75  		if di.BaseAddressModifierInterruptInfo&(1<<3) != 0 {
    76  			if di.BaseAddressModifierInterruptInfo&(1<<1) != 0 {
    77  				lines = append(lines, "Interrupt Polarity: Active High")
    78  			} else {
    79  				lines = append(lines, "Interrupt Polarity: Active Low")
    80  			}
    81  			if di.BaseAddressModifierInterruptInfo&(1<<0) != 0 {
    82  				lines = append(lines, "Interrupt Trigger Mode: Level")
    83  			} else {
    84  				lines = append(lines, "Interrupt Trigger Mode: Edge")
    85  			}
    86  		}
    87  	}
    88  	if di.InterruptNumber != 0 {
    89  		lines = append(lines, fmt.Sprintf("Interrupt Number: %d", di.InterruptNumber))
    90  	}
    91  	return strings.Join(lines, "\n\t")
    92  }
    93  
    94  // BMCInterfaceType is defined in DSP0134 7.39.1.
    95  type BMCInterfaceType uint8
    96  
    97  // BMCInterfaceType values are defined in DSP0134 7.39.1.
    98  const (
    99  	BMCInterfaceTypeUnknown                           BMCInterfaceType = 0x00 // Unknown
   100  	BMCInterfaceTypeKCSKeyboardControllerStyle        BMCInterfaceType = 0x01 // KCS: Keyboard Controller Style
   101  	BMCInterfaceTypeSMICServerManagementInterfaceChip BMCInterfaceType = 0x02 // SMIC: Server Management Interface Chip
   102  	BMCInterfaceTypeBTBlockTransfer                   BMCInterfaceType = 0x03 // BT: Block Transfer
   103  	BMCInterfaceTypeSSIFSMBusSystemInterface          BMCInterfaceType = 0x04 // SSIF: SMBus System Interface
   104  )
   105  
   106  func (v BMCInterfaceType) String() string {
   107  	names := map[BMCInterfaceType]string{
   108  		BMCInterfaceTypeUnknown:                           "Unknown",
   109  		BMCInterfaceTypeKCSKeyboardControllerStyle:        "KCS (Keyboard Control Style)",
   110  		BMCInterfaceTypeSMICServerManagementInterfaceChip: "SMIC (Server Management Interface Chip)",
   111  		BMCInterfaceTypeBTBlockTransfer:                   "BT (Block Transfer)",
   112  		BMCInterfaceTypeSSIFSMBusSystemInterface:          "SSIF (SMBus System Interface)",
   113  	}
   114  	if name, ok := names[v]; ok {
   115  		return name
   116  	}
   117  	return fmt.Sprintf("%#x", uint8(v))
   118  }