1// Copyright 2017 The Fuchsia Authors 2// 3// Use of this source code is governed by a MIT-style 4// license that can be found in the LICENSE file or at 5// https://opensource.org/licenses/MIT 6 7#pragma once 8 9#include <fbl/macros.h> 10#include <fbl/ref_ptr.h> 11#include <stdint.h> 12#include <zircon/types.h> 13 14#define SMBIOS2_ANCHOR "_SM_" 15#define SMBIOS2_INTERMEDIATE_ANCHOR "_DMI_" 16#define SMBIOS3_ANCHOR "_SM3_" 17 18namespace smbios { 19 20enum class StructType : uint8_t { 21 BiosInfo = 0, 22 SystemInfo = 1, 23 Baseboard = 2, 24 SystemEnclosure = 3, 25 Processor = 4, 26 MemoryController = 5, 27 MemoryModule = 6, 28 Cache = 7, 29 PortConnector = 8, 30 SystemSlots = 9, 31 OnBoardDevices = 10, 32 OemStrings = 11, 33 SystemConfigOptions = 12, 34 BiosLanguage = 13, 35 36 EndOfTable = 127, 37}; 38 39// SMBIOS common struct header 40struct Header { 41 StructType type; 42 uint8_t length; 43 uint16_t handle; 44} __PACKED; 45static_assert(sizeof(Header) == 4, ""); 46 47// Utility for working with the table of null-terminated strings after each 48// struct. 49class StringTable { 50 public: 51 StringTable(); 52 ~StringTable(); 53 54 // Construct a StringTable from a header and a max possible length. The 55 // length includes the formatted portion (h->length). 56 zx_status_t Init(const Header* h, size_t max_struct_len); 57 58 // Return the length of the StringTable, in bytes, including terminating NUL. 59 size_t length() const { return length_; } 60 61 // This operation is slow, and indexed from 1. |*out| is always assigned a 62 // null-terminated string, even on error. 63 zx_status_t GetString(size_t idx, const char** out) const; 64 // Convenience version that does not identify the error 65 const char* GetString(size_t idx) const { 66 const char* p; 67 GetString(idx, &p); 68 return p; 69 } 70 71 void Dump() const; 72 private: 73 DISALLOW_COPY_ASSIGN_AND_MOVE(StringTable); 74 75 const char* start_ = nullptr; 76 size_t length_ = 0; 77}; 78 79// Utility for comparing specification versions. Used to select which version 80// of the spec to use for interpreting a struct. 81struct SpecVersion { 82 SpecVersion(uint8_t major, uint8_t minor) : major_ver(major), minor_ver(minor) { } 83 84 // Returns true if this support for at least the queried version. 85 bool IncludesVersion(uint8_t spec_major_ver, uint8_t spec_minor_ver) const; 86 87 uint8_t major_ver; 88 uint8_t minor_ver; 89}; 90 91enum class EntryPointVersion { 92 Unknown, 93 V2_1, 94 V3_0, 95}; 96 97// Returning ZX_ERR_STOP aborts the walk. 98using StructWalkCallback = zx_status_t (*)(SpecVersion version, const Header* h, 99 const StringTable& st, void* ctx); 100 101// System structure identifying where the SMBIOS structs are in memory. 102struct EntryPoint2_1 { 103 uint8_t anchor_string[4]; // _SM_ 104 uint8_t checksum; 105 uint8_t length; 106 107 // SMBIOS specification revision 108 uint8_t major_ver; 109 uint8_t minor_ver; 110 111 uint16_t max_struct_size; 112 113 uint8_t ep_rev; // Should be 0x00 for version SMBIOS 2.1 entry point 114 uint8_t formatted_area[5]; // Should be all 0x00 for ver 2.1 115 116 uint8_t intermediate_anchor_string[5]; // _DMI_ 117 uint8_t intermediate_checksum; 118 119 uint16_t struct_table_length; 120 uint32_t struct_table_phys; 121 uint16_t struct_count; 122 123 uint8_t bcd_rev; // Should be 0x21 124 125 bool IsValid() const; 126 127 // Walk the known SMBIOS structures, assuming they are mapped at struct_table_virt. The 128 // callback will be called once for each structure found. 129 zx_status_t WalkStructs(uintptr_t struct_table_virt, StructWalkCallback cb, void* ctx) const; 130 131 SpecVersion version() const { return SpecVersion(major_ver, minor_ver); } 132 133 void Dump() const; 134} __PACKED; 135static_assert(sizeof(EntryPoint2_1) == 0x1f, ""); 136 137struct BiosInformationStruct2_0 { 138 Header hdr; 139 140 uint8_t vendor_str_idx; 141 uint8_t bios_version_str_idx; 142 uint16_t bios_starting_address_segment; 143 uint8_t bios_release_date_str_idx; 144 uint8_t bios_rom_size; 145 uint64_t bios_characteristics; 146 uint8_t bios_characteristics_ext[0]; 147 148 void Dump(const StringTable& st) const; 149} __PACKED; 150static_assert(sizeof(BiosInformationStruct2_0) == 0x12, ""); 151 152struct BiosInformationStruct2_4 { 153 Header hdr; 154 155 uint8_t vendor_str_idx; uint8_t bios_version_str_idx; 156 uint16_t bios_starting_address_segment; 157 uint8_t bios_release_date_str_idx; 158 uint8_t bios_rom_size; 159 uint64_t bios_characteristics; 160 uint16_t bios_characteristics_ext; 161 162 uint8_t bios_major_release; 163 uint8_t bios_minor_release; 164 uint8_t ec_major_release; 165 uint8_t ec_minor_release; 166 167 void Dump(const StringTable& st) const; 168} __PACKED; 169static_assert(sizeof(BiosInformationStruct2_4) == 0x18, ""); 170 171struct SystemInformationStruct2_0 { 172 Header hdr; 173 174 uint8_t manufacturer_str_idx; 175 uint8_t product_name_str_idx; 176 uint8_t version_str_idx; 177 uint8_t serial_number_str_idx; 178 179 void Dump(const StringTable& st) const; 180} __PACKED; 181static_assert(sizeof(SystemInformationStruct2_0) == 0x8, ""); 182 183struct SystemInformationStruct2_1 { 184 Header hdr; 185 186 uint8_t manufacturer_str_idx; 187 uint8_t product_name_str_idx; 188 uint8_t version_str_idx; 189 uint8_t serial_number_str_idx; 190 191 uint8_t uuid[16]; 192 uint8_t wakeup_type; 193 194 void Dump(const StringTable& st) const; 195} __PACKED; 196static_assert(sizeof(SystemInformationStruct2_1) == 0x19, ""); 197 198struct SystemInformationStruct2_4 { 199 Header hdr; 200 201 uint8_t manufacturer_str_idx; 202 uint8_t product_name_str_idx; 203 uint8_t version_str_idx; 204 uint8_t serial_number_str_idx; 205 206 uint8_t uuid[16]; 207 uint8_t wakeup_type; 208 209 uint8_t sku_number_str_idx; 210 uint8_t family_str_idx; 211 212 void Dump(const StringTable& st) const; 213} __PACKED; 214static_assert(sizeof(SystemInformationStruct2_4) == 0x1b, ""); 215 216} // namespace smbios 217