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