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 }