1 /** @file 2 API for SMBIOS table. 3 4 Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 16 #include "../UefiShellDebug1CommandsLib.h" 17 #include <Guid/SmBios.h> 18 #include "LibSmbiosView.h" 19 #include "SmbiosView.h" 20 21 STATIC UINT8 mInit = 0; 22 STATIC UINT8 m64Init = 0; 23 STATIC SMBIOS_TABLE_ENTRY_POINT *mSmbiosTable = NULL; 24 STATIC SMBIOS_TABLE_3_0_ENTRY_POINT *mSmbios64BitTable = NULL; 25 STATIC SMBIOS_STRUCTURE_POINTER m_SmbiosStruct; 26 STATIC SMBIOS_STRUCTURE_POINTER *mSmbiosStruct = &m_SmbiosStruct; 27 STATIC SMBIOS_STRUCTURE_POINTER m_Smbios64BitStruct; 28 STATIC SMBIOS_STRUCTURE_POINTER *mSmbios64BitStruct = &m_Smbios64BitStruct; 29 30 /** 31 Init the SMBIOS VIEW API's environment. 32 33 @retval EFI_SUCCESS Successful to init the SMBIOS VIEW Lib. 34 **/ 35 EFI_STATUS 36 LibSmbiosInit ( 37 VOID 38 ) 39 { 40 EFI_STATUS Status; 41 42 // 43 // Init only once 44 // 45 if (mInit == 1) { 46 return EFI_SUCCESS; 47 } 48 // 49 // Get SMBIOS table from System Configure table 50 // 51 Status = GetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID**)&mSmbiosTable); 52 53 if (mSmbiosTable == NULL) { 54 return EFI_NOT_FOUND; 55 } 56 57 if (EFI_ERROR (Status)) { 58 ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_GET_TABLE_ERROR), gShellDebug1HiiHandle, Status); 59 return Status; 60 } 61 // 62 // Init SMBIOS structure table address 63 // 64 mSmbiosStruct->Raw = (UINT8 *) (UINTN) (mSmbiosTable->TableAddress); 65 66 mInit = 1; 67 return EFI_SUCCESS; 68 } 69 70 /** 71 Init the SMBIOS VIEW API's environment. 72 73 @retval EFI_SUCCESS Successful to init the SMBIOS VIEW Lib. 74 **/ 75 EFI_STATUS 76 LibSmbios64BitInit ( 77 VOID 78 ) 79 { 80 EFI_STATUS Status; 81 82 // 83 // Init only once 84 // 85 if (m64Init == 1) { 86 return EFI_SUCCESS; 87 } 88 // 89 // Get SMBIOS table from System Configure table 90 // 91 Status = GetSystemConfigurationTable (&gEfiSmbios3TableGuid, (VOID**)&mSmbios64BitTable); 92 93 if (mSmbios64BitTable == NULL) { 94 return EFI_NOT_FOUND; 95 } 96 97 if (EFI_ERROR (Status)) { 98 ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_GET_TABLE_ERROR), gShellDebug1HiiHandle, Status); 99 return Status; 100 } 101 // 102 // Init SMBIOS structure table address 103 // 104 mSmbios64BitStruct->Raw = (UINT8 *) (UINTN) (mSmbios64BitTable->TableAddress); 105 106 m64Init = 1; 107 return EFI_SUCCESS; 108 } 109 110 /** 111 Cleanup the Smbios information. 112 **/ 113 VOID 114 LibSmbiosCleanup ( 115 VOID 116 ) 117 { 118 // 119 // Release resources 120 // 121 if (mSmbiosTable != NULL) { 122 mSmbiosTable = NULL; 123 } 124 125 mInit = 0; 126 } 127 128 /** 129 Cleanup the Smbios information. 130 **/ 131 VOID 132 LibSmbios64BitCleanup ( 133 VOID 134 ) 135 { 136 // 137 // Release resources 138 // 139 if (mSmbios64BitTable != NULL) { 140 mSmbios64BitTable = NULL; 141 } 142 143 m64Init = 0; 144 } 145 146 /** 147 Get the entry point structure for the table. 148 149 @param[out] EntryPointStructure The pointer to populate. 150 **/ 151 VOID 152 LibSmbiosGetEPS ( 153 OUT SMBIOS_TABLE_ENTRY_POINT **EntryPointStructure 154 ) 155 { 156 // 157 // return SMBIOS Table address 158 // 159 *EntryPointStructure = mSmbiosTable; 160 } 161 162 /** 163 Get the entry point structure for the table. 164 165 @param[out] EntryPointStructure The pointer to populate. 166 **/ 167 VOID 168 LibSmbios64BitGetEPS ( 169 OUT SMBIOS_TABLE_3_0_ENTRY_POINT **EntryPointStructure 170 ) 171 { 172 // 173 // return SMBIOS Table address 174 // 175 *EntryPointStructure = mSmbios64BitTable; 176 } 177 178 /** 179 Return SMBIOS string for the given string number. 180 181 @param[in] Smbios Pointer to SMBIOS structure. 182 @param[in] StringNumber String number to return. -1 is used to skip all strings and 183 point to the next SMBIOS structure. 184 185 @return Pointer to string, or pointer to next SMBIOS strcuture if StringNumber == -1 186 **/ 187 CHAR8* 188 LibGetSmbiosString ( 189 IN SMBIOS_STRUCTURE_POINTER *Smbios, 190 IN UINT16 StringNumber 191 ) 192 { 193 UINT16 Index; 194 CHAR8 *String; 195 196 ASSERT (Smbios != NULL); 197 198 // 199 // Skip over formatted section 200 // 201 String = (CHAR8 *) (Smbios->Raw + Smbios->Hdr->Length); 202 203 // 204 // Look through unformated section 205 // 206 for (Index = 1; Index <= StringNumber; Index++) { 207 if (StringNumber == Index) { 208 return String; 209 } 210 // 211 // Skip string 212 // 213 for (; *String != 0; String++); 214 String++; 215 216 if (*String == 0) { 217 // 218 // If double NULL then we are done. 219 // Return pointer to next structure in Smbios. 220 // if you pass in a -1 you will always get here 221 // 222 Smbios->Raw = (UINT8 *)++String; 223 return NULL; 224 } 225 } 226 227 return NULL; 228 } 229 230 /** 231 Get SMBIOS structure for the given Handle, 232 Handle is changed to the next handle or 0xFFFF when the end is 233 reached or the handle is not found. 234 235 @param[in, out] Handle 0xFFFF: get the first structure 236 Others: get a structure according to this value. 237 @param[out] Buffer The pointer to the pointer to the structure. 238 @param[out] Length Length of the structure. 239 240 @retval DMI_SUCCESS Handle is updated with next structure handle or 241 0xFFFF(end-of-list). 242 243 @retval DMI_INVALID_HANDLE Handle is updated with first structure handle or 244 0xFFFF(end-of-list). 245 **/ 246 EFI_STATUS 247 LibGetSmbiosStructure ( 248 IN OUT UINT16 *Handle, 249 OUT UINT8 **Buffer, 250 OUT UINT16 *Length 251 ) 252 { 253 SMBIOS_STRUCTURE_POINTER Smbios; 254 SMBIOS_STRUCTURE_POINTER SmbiosEnd; 255 UINT8 *Raw; 256 257 if (*Handle == INVALID_HANDLE) { 258 *Handle = mSmbiosStruct->Hdr->Handle; 259 return DMI_INVALID_HANDLE; 260 } 261 262 if ((Buffer == NULL) || (Length == NULL)) { 263 ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_NO_BUFF_LEN_SPEC), gShellDebug1HiiHandle); 264 return DMI_INVALID_HANDLE; 265 } 266 267 *Length = 0; 268 Smbios.Hdr = mSmbiosStruct->Hdr; 269 SmbiosEnd.Raw = Smbios.Raw + mSmbiosTable->TableLength; 270 while (Smbios.Raw < SmbiosEnd.Raw) { 271 if (Smbios.Hdr->Handle == *Handle) { 272 Raw = Smbios.Raw; 273 // 274 // Walk to next structure 275 // 276 LibGetSmbiosString (&Smbios, (UINT16) (-1)); 277 // 278 // Length = Next structure head - this structure head 279 // 280 *Length = (UINT16) (Smbios.Raw - Raw); 281 *Buffer = Raw; 282 // 283 // update with the next structure handle. 284 // 285 if (Smbios.Raw < SmbiosEnd.Raw) { 286 *Handle = Smbios.Hdr->Handle; 287 } else { 288 *Handle = INVALID_HANDLE; 289 } 290 return DMI_SUCCESS; 291 } 292 // 293 // Walk to next structure 294 // 295 LibGetSmbiosString (&Smbios, (UINT16) (-1)); 296 } 297 298 *Handle = INVALID_HANDLE; 299 return DMI_INVALID_HANDLE; 300 } 301 302 /** 303 Get SMBIOS structure for the given Handle, 304 Handle is changed to the next handle or 0xFFFF when the end is 305 reached or the handle is not found. 306 307 @param[in, out] Handle 0xFFFF: get the first structure 308 Others: get a structure according to this value. 309 @param[out] Buffer The pointer to the pointer to the structure. 310 @param[out] Length Length of the structure. 311 312 @retval DMI_SUCCESS Handle is updated with next structure handle or 313 0xFFFF(end-of-list). 314 315 @retval DMI_INVALID_HANDLE Handle is updated with first structure handle or 316 0xFFFF(end-of-list). 317 **/ 318 EFI_STATUS 319 LibGetSmbios64BitStructure ( 320 IN OUT UINT16 *Handle, 321 OUT UINT8 **Buffer, 322 OUT UINT16 *Length 323 ) 324 { 325 SMBIOS_STRUCTURE_POINTER Smbios; 326 SMBIOS_STRUCTURE_POINTER SmbiosEnd; 327 UINT8 *Raw; 328 329 if (*Handle == INVALID_HANDLE) { 330 *Handle = mSmbios64BitStruct->Hdr->Handle; 331 return DMI_INVALID_HANDLE; 332 } 333 334 if ((Buffer == NULL) || (Length == NULL)) { 335 ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_LIBSMBIOSVIEW_NO_BUFF_LEN_SPEC), gShellDebug1HiiHandle); 336 return DMI_INVALID_HANDLE; 337 } 338 339 *Length = 0; 340 Smbios.Hdr = mSmbios64BitStruct->Hdr; 341 342 SmbiosEnd.Raw = Smbios.Raw + mSmbios64BitTableLength; 343 while (Smbios.Raw < SmbiosEnd.Raw) { 344 if (Smbios.Hdr->Handle == *Handle) { 345 Raw = Smbios.Raw; 346 // 347 // Walk to next structure 348 // 349 LibGetSmbiosString (&Smbios, (UINT16) (-1)); 350 // 351 // Length = Next structure head - this structure head 352 // 353 *Length = (UINT16) (Smbios.Raw - Raw); 354 *Buffer = Raw; 355 // 356 // update with the next structure handle. 357 // 358 if (Smbios.Raw < SmbiosEnd.Raw) { 359 *Handle = Smbios.Hdr->Handle; 360 } else { 361 *Handle = INVALID_HANDLE; 362 } 363 return DMI_SUCCESS; 364 } 365 // 366 // Walk to next structure 367 // 368 LibGetSmbiosString (&Smbios, (UINT16) (-1)); 369 } 370 371 *Handle = INVALID_HANDLE; 372 return DMI_INVALID_HANDLE; 373 } 374