| package smbios |
| |
| import ( |
| "time" |
| ) |
| |
| const ( |
| structTypeBIOSInformation = 0 |
| structTypeSystemInformation = 1 |
| structTypeBaseboardInformation = 2 |
| structTypeSystemSlot = 9 |
| structTypeMemoryDevice = 17 |
| ) |
| |
| // Table 7.1.2.2 Bit 3 |
| const UEFISpecificationSupported = 1 << 3 |
| |
| // BIOSInformationRaw contains decoded data from the BIOS Information structure |
| // (SMBIOS Type 0). See Table 6 in the specification for detailed documentation |
| // about the individual fields. Note that structure versions 2.1 and 2.2 are |
| // "invented" here as both characteristics extensions bytes were optional |
| // between 2.0 and 2.4. |
| type BIOSInformationRaw struct { |
| Handle uint16 |
| StructureVersion Version |
| Vendor string |
| BIOSVersion string |
| BIOSStartingAddressSegment uint16 |
| BIOSReleaseDate string |
| BIOSROMSize uint8 |
| BIOSCharacteristics uint64 |
| BIOSCharacteristicsExtensionByte1 uint8 `smbios_min_ver:"2.1"` |
| BIOSCharacteristicsExtensionByte2 uint8 `smbios_min_ver:"2.2"` |
| SystemBIOSMajorRelease uint8 `smbios_min_ver:"2.4"` |
| SystemBIOSMinorRelease uint8 |
| EmbeddedControllerFirmwareMajorRelease uint8 |
| EmbeddedControllerFirmwareMinorRelease uint8 |
| ExtendedBIOSROMSize uint16 `smbios_min_ver:"3.1"` |
| } |
| |
| // ROMSizeBytes returns the ROM size in bytes |
| func (rb *BIOSInformationRaw) ROMSizeBytes() uint64 { |
| if rb.StructureVersion.AtLeast(3, 1) && rb.BIOSROMSize == 0xFF { |
| // Top 2 bits are SI prefix (starting at mega, i.e. 1024^2), lower 14 |
| // are value. x*1024^n => x << log2(1024)*n => x << 10*n |
| return uint64(rb.ExtendedBIOSROMSize&0x3fff) << 10 * uint64(rb.ExtendedBIOSROMSize&0xc00+2) |
| } else { |
| // (n+1) * 64KiB |
| return (uint64(rb.BIOSROMSize) + 1) * (64 * 1024) |
| } |
| } |
| |
| // ReleaseDate returns the release date of the BIOS as a time.Time value. |
| func (rb *BIOSInformationRaw) ReleaseDate() (time.Time, error) { |
| return time.Parse("01/02/2006", rb.BIOSReleaseDate) |
| } |
| |
| // SystemInformationRaw contains decoded data from the System Information |
| // structure (SMBIOS Type 1). See Table 10 in the specification for detailed |
| // documentation about the individual fields. |
| type SystemInformationRaw struct { |
| Handle uint16 |
| StructureVersion Version |
| Manufacturer string |
| ProductName string |
| Version string |
| SerialNumber string |
| UUID [16]byte `smbios_min_ver:"2.1"` |
| WakeupType uint8 |
| SKUNumber string `smbios_min_ver:"2.4"` |
| Family string |
| } |
| |
| // BaseboardInformationRaw contains decoded data from the BIOS Information |
| // structure (SMBIOS Type 3). See Table 13 in the specification for detailed |
| // documentation about the individual fields. |
| type BaseboardInformationRaw struct { |
| Handle uint16 |
| StructureVersion Version |
| Manufacturer string |
| Product string |
| Version string |
| SerialNumber string |
| AssetTag string `smbios_min_ver:"2.1"` |
| FeatureFlags uint8 |
| LocationInChassis string |
| ChassisHandle uint16 |
| BoardType uint8 |
| NumberOfContainedObjectHandles uint8 |
| ContainedObjectHandles []uint16 `smbios_repeat:"NumberOfContainedObjectHandles"` |
| } |
| |
| // SystemSlotRaw contains decoded data from the System Slot structure |
| // (SMBIOS Type 9). See Table 44 in the specification for detailed documentation |
| // about the individual fields. |
| type SystemSlotRaw struct { |
| Handle uint16 |
| StructureVersion Version |
| SlotDesignation string |
| SlotType uint8 |
| SlotDataBusWidth uint8 |
| CurrentUsage uint8 |
| SlotLength uint8 |
| SlotID uint16 |
| SlotCharacteristics1 uint8 |
| SlotCharacteristics2 uint8 `smbios_min_ver:"2.1"` |
| SegmentGroupNumber uint16 `smbios_min_ver:"2.6"` |
| BusNumber uint8 |
| DeviceFunctionNumber uint8 |
| DataBusWidth uint8 `smbios_min_ver:"3.2"` |
| PeerGroupingCount uint8 |
| PeerGroups []SystemSlotPeerRaw `smbios_repeat:"PeerGroupingCount"` |
| SlotInformation uint8 `smbios_min_ver:"3.4"` |
| SlotPhysicalWidth uint8 |
| SlotPitch uint16 |
| SlotHeight uint8 `smbios_min_ver:"3.5"` |
| } |
| |
| type SystemSlotPeerRaw struct { |
| SegmentGroupNumber uint16 |
| BusNumber uint8 |
| DeviceFunctionNumber uint8 |
| DataBusWidth uint8 |
| } |
| |
| // MemoryDeviceRaw contains decoded data from the BIOS Information structure |
| // (SMBIOS Type 17). See Table 76 in the specification for detailed |
| // documentation about the individual fields. |
| type MemoryDeviceRaw struct { |
| Handle uint16 |
| StructureVersion Version |
| PhysicalMemoryArrayHandle uint16 `smbios_min_ver:"2.1"` |
| MemoryErrorInformationHandle uint16 |
| TotalWidth uint16 |
| DataWidth uint16 |
| Size uint16 |
| FormFactor uint8 |
| DeviceSet uint8 |
| DeviceLocator string |
| BankLocator string |
| MemoryType uint8 |
| TypeDetail uint16 |
| Speed uint16 `smbios_min_ver:"2.3"` |
| Manufacturer string |
| SerialNumber string |
| AssetTag string |
| PartNumber string |
| Attributes uint8 `smbios_min_ver:"2.6"` |
| ExtendedSize uint32 `smbios_min_ver:"2.7"` |
| ConfiguredMemorySpeed uint16 |
| MinimumVoltage uint16 `smbios_min_ver:"2.8"` |
| MaximumVoltage uint16 |
| ConfiguredVoltage uint16 |
| MemoryTechnology uint8 `smbios_min_ver:"3.2"` |
| MemoryOperatingModeCapability uint16 |
| FirmwareVersion uint8 |
| ModuleManufacturerID uint16 |
| ModuleProductID uint16 |
| MemorySubsystemControllerManufacturerID uint16 |
| MemorySubsystemControllerProductID uint16 |
| NonVolatileSize uint64 |
| VolatileSize uint64 |
| CacheSize uint64 |
| LogicalSize uint64 |
| ExtendedSpeed uint32 `smbios_min_ver:"3.3"` |
| ExtendedConfiguredMemorySpeed uint32 |
| } |
| |
| const ( |
| kibLeftShift = 10 // 2^10 = 1KiB |
| mibLeftShift = 20 // 2^20 = 1MiB |
| ) |
| |
| func (md *MemoryDeviceRaw) SizeBytes() (uint64, bool) { |
| if md.Size == 0 || md.Size == 0xFFFF { |
| // Device unpopulated / unknown memory, return ok false |
| return 0, false |
| } |
| if md.Size == 0x7FFF && md.StructureVersion.AtLeast(2, 7) { |
| // Bit 31 is reserved, rest is memory size in MiB |
| return uint64(md.ExtendedSize&0x7FFFFFFF) << mibLeftShift, true |
| } |
| // Bit 15 flips between MiB and KiB, rest is size |
| var shift uint64 = mibLeftShift |
| if (md.Size & 0x8000) != 0 { // Bit set means KiB |
| shift = kibLeftShift |
| } |
| return uint64(md.Size&0x7FFF) << shift, true |
| } |