blob: 4c757097cacad9a501710d6a6e4669e236e1b2e5 [file] [log] [blame]
Lorenz Brunf9c65e92022-11-22 12:50:56 +00001package smbios
2
3import (
4 "time"
5)
6
7const (
8 structTypeBIOSInformation = 0
9 structTypeSystemInformation = 1
10 structTypeBaseboardInformation = 2
11 structTypeSystemSlot = 9
12 structTypeMemoryDevice = 17
13)
14
Tim Windelschmidta3cd52c2024-04-18 23:21:16 +020015// UEFISpecificationSupported is a bitmask for accessing the third bit,
16// which displays the support of UEFI in the smbios structure. For more
17// information check the SMBIOS documentation at Table 7.1.2.2 Bit 3.
Lorenz Brun1cd26962023-04-19 16:10:17 +020018const UEFISpecificationSupported = 1 << 3
19
Lorenz Brunf9c65e92022-11-22 12:50:56 +000020// BIOSInformationRaw contains decoded data from the BIOS Information structure
21// (SMBIOS Type 0). See Table 6 in the specification for detailed documentation
22// about the individual fields. Note that structure versions 2.1 and 2.2 are
23// "invented" here as both characteristics extensions bytes were optional
24// between 2.0 and 2.4.
25type BIOSInformationRaw struct {
26 Handle uint16
27 StructureVersion Version
28 Vendor string
29 BIOSVersion string
30 BIOSStartingAddressSegment uint16
31 BIOSReleaseDate string
32 BIOSROMSize uint8
33 BIOSCharacteristics uint64
34 BIOSCharacteristicsExtensionByte1 uint8 `smbios_min_ver:"2.1"`
35 BIOSCharacteristicsExtensionByte2 uint8 `smbios_min_ver:"2.2"`
36 SystemBIOSMajorRelease uint8 `smbios_min_ver:"2.4"`
37 SystemBIOSMinorRelease uint8
38 EmbeddedControllerFirmwareMajorRelease uint8
39 EmbeddedControllerFirmwareMinorRelease uint8
40 ExtendedBIOSROMSize uint16 `smbios_min_ver:"3.1"`
41}
42
43// ROMSizeBytes returns the ROM size in bytes
44func (rb *BIOSInformationRaw) ROMSizeBytes() uint64 {
45 if rb.StructureVersion.AtLeast(3, 1) && rb.BIOSROMSize == 0xFF {
46 // Top 2 bits are SI prefix (starting at mega, i.e. 1024^2), lower 14
47 // are value. x*1024^n => x << log2(1024)*n => x << 10*n
48 return uint64(rb.ExtendedBIOSROMSize&0x3fff) << 10 * uint64(rb.ExtendedBIOSROMSize&0xc00+2)
49 } else {
50 // (n+1) * 64KiB
51 return (uint64(rb.BIOSROMSize) + 1) * (64 * 1024)
52 }
53}
54
55// ReleaseDate returns the release date of the BIOS as a time.Time value.
56func (rb *BIOSInformationRaw) ReleaseDate() (time.Time, error) {
57 return time.Parse("01/02/2006", rb.BIOSReleaseDate)
58}
59
60// SystemInformationRaw contains decoded data from the System Information
61// structure (SMBIOS Type 1). See Table 10 in the specification for detailed
62// documentation about the individual fields.
63type SystemInformationRaw struct {
64 Handle uint16
65 StructureVersion Version
66 Manufacturer string
67 ProductName string
68 Version string
69 SerialNumber string
70 UUID [16]byte `smbios_min_ver:"2.1"`
71 WakeupType uint8
72 SKUNumber string `smbios_min_ver:"2.4"`
73 Family string
74}
75
76// BaseboardInformationRaw contains decoded data from the BIOS Information
77// structure (SMBIOS Type 3). See Table 13 in the specification for detailed
78// documentation about the individual fields.
79type BaseboardInformationRaw struct {
80 Handle uint16
81 StructureVersion Version
82 Manufacturer string
83 Product string
84 Version string
85 SerialNumber string
86 AssetTag string `smbios_min_ver:"2.1"`
87 FeatureFlags uint8
88 LocationInChassis string
89 ChassisHandle uint16
90 BoardType uint8
91 NumberOfContainedObjectHandles uint8
92 ContainedObjectHandles []uint16 `smbios_repeat:"NumberOfContainedObjectHandles"`
93}
94
95// SystemSlotRaw contains decoded data from the System Slot structure
96// (SMBIOS Type 9). See Table 44 in the specification for detailed documentation
97// about the individual fields.
98type SystemSlotRaw struct {
99 Handle uint16
100 StructureVersion Version
101 SlotDesignation string
102 SlotType uint8
103 SlotDataBusWidth uint8
104 CurrentUsage uint8
105 SlotLength uint8
106 SlotID uint16
107 SlotCharacteristics1 uint8
108 SlotCharacteristics2 uint8 `smbios_min_ver:"2.1"`
109 SegmentGroupNumber uint16 `smbios_min_ver:"2.6"`
110 BusNumber uint8
111 DeviceFunctionNumber uint8
112 DataBusWidth uint8 `smbios_min_ver:"3.2"`
113 PeerGroupingCount uint8
114 PeerGroups []SystemSlotPeerRaw `smbios_repeat:"PeerGroupingCount"`
115 SlotInformation uint8 `smbios_min_ver:"3.4"`
116 SlotPhysicalWidth uint8
117 SlotPitch uint16
118 SlotHeight uint8 `smbios_min_ver:"3.5"`
119}
120
121type SystemSlotPeerRaw struct {
122 SegmentGroupNumber uint16
123 BusNumber uint8
124 DeviceFunctionNumber uint8
125 DataBusWidth uint8
126}
127
128// MemoryDeviceRaw contains decoded data from the BIOS Information structure
129// (SMBIOS Type 17). See Table 76 in the specification for detailed
130// documentation about the individual fields.
131type MemoryDeviceRaw struct {
132 Handle uint16
133 StructureVersion Version
134 PhysicalMemoryArrayHandle uint16 `smbios_min_ver:"2.1"`
135 MemoryErrorInformationHandle uint16
136 TotalWidth uint16
137 DataWidth uint16
138 Size uint16
139 FormFactor uint8
140 DeviceSet uint8
141 DeviceLocator string
142 BankLocator string
143 MemoryType uint8
144 TypeDetail uint16
145 Speed uint16 `smbios_min_ver:"2.3"`
146 Manufacturer string
147 SerialNumber string
148 AssetTag string
149 PartNumber string
150 Attributes uint8 `smbios_min_ver:"2.6"`
151 ExtendedSize uint32 `smbios_min_ver:"2.7"`
152 ConfiguredMemorySpeed uint16
153 MinimumVoltage uint16 `smbios_min_ver:"2.8"`
154 MaximumVoltage uint16
155 ConfiguredVoltage uint16
156 MemoryTechnology uint8 `smbios_min_ver:"3.2"`
157 MemoryOperatingModeCapability uint16
158 FirmwareVersion uint8
159 ModuleManufacturerID uint16
160 ModuleProductID uint16
161 MemorySubsystemControllerManufacturerID uint16
162 MemorySubsystemControllerProductID uint16
163 NonVolatileSize uint64
164 VolatileSize uint64
165 CacheSize uint64
166 LogicalSize uint64
167 ExtendedSpeed uint32 `smbios_min_ver:"3.3"`
168 ExtendedConfiguredMemorySpeed uint32
169}
170
Lorenz Brun12450d22022-12-20 13:06:19 +0000171const (
172 kibLeftShift = 10 // 2^10 = 1KiB
173 mibLeftShift = 20 // 2^20 = 1MiB
174)
175
Lorenz Brunf9c65e92022-11-22 12:50:56 +0000176func (md *MemoryDeviceRaw) SizeBytes() (uint64, bool) {
177 if md.Size == 0 || md.Size == 0xFFFF {
178 // Device unpopulated / unknown memory, return ok false
179 return 0, false
180 }
181 if md.Size == 0x7FFF && md.StructureVersion.AtLeast(2, 7) {
182 // Bit 31 is reserved, rest is memory size in MiB
Lorenz Brun12450d22022-12-20 13:06:19 +0000183 return uint64(md.ExtendedSize&0x7FFFFFFF) << mibLeftShift, true
Lorenz Brunf9c65e92022-11-22 12:50:56 +0000184 }
Lorenz Brun12450d22022-12-20 13:06:19 +0000185 // Bit 15 flips between MiB and KiB, rest is size
186 var shift uint64 = mibLeftShift
187 if (md.Size & 0x8000) != 0 { // Bit set means KiB
188 shift = kibLeftShift
189 }
190 return uint64(md.Size&0x7FFF) << shift, true
Lorenz Brunf9c65e92022-11-22 12:50:56 +0000191}