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