/** @file | |
This driver parses the mSmbiosMiscDataTable structure and reports | |
any generated data using SMBIOS protocol. | |
Based on files under Nt32Pkg/MiscSubClassPlatformDxe/ | |
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR> | |
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> | |
Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR> | |
Copyright (c) 2015, Linaro Limited. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include <Library/BaseLib.h> | |
#include <Library/BaseMemoryLib.h> | |
#include <Library/DebugLib.h> | |
#include <Library/HiiLib.h> | |
#include <Library/MemoryAllocationLib.h> | |
#include <Library/UefiBootServicesTableLib.h> | |
#include "SmbiosMisc.h" | |
STATIC EFI_HANDLE mSmbiosMiscImageHandle; | |
STATIC EFI_SMBIOS_PROTOCOL *mSmbiosMiscSmbios = NULL; | |
EFI_HII_HANDLE mSmbiosMiscHiiHandle; | |
/** | |
Standard EFI driver point. This driver parses the mSmbiosMiscDataTable | |
structure and reports any generated data using SMBIOS protocol. | |
@param ImageHandle Handle for the image of this driver | |
@param SystemTable Pointer to the EFI System Table | |
@retval EFI_SUCCESS The data was successfully stored. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
SmbiosMiscEntryPoint ( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) | |
{ | |
UINTN Index; | |
EFI_STATUS EfiStatus; | |
mSmbiosMiscImageHandle = ImageHandle; | |
EfiStatus = gBS->LocateProtocol ( | |
&gEfiSmbiosProtocolGuid, | |
NULL, | |
(VOID **)&mSmbiosMiscSmbios | |
); | |
if (EFI_ERROR (EfiStatus)) { | |
DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol. %r\n", EfiStatus)); | |
return EfiStatus; | |
} | |
mSmbiosMiscHiiHandle = HiiAddPackages ( | |
&gEfiCallerIdGuid, | |
mSmbiosMiscImageHandle, | |
SmbiosMiscDxeStrings, | |
NULL | |
); | |
if (mSmbiosMiscHiiHandle == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
for (Index = 0; Index < mSmbiosMiscDataTableEntries; ++Index) { | |
// | |
// If the entry have a function pointer, just log the data. | |
// | |
if (mSmbiosMiscDataTable[Index].Function != NULL) { | |
EfiStatus = (*mSmbiosMiscDataTable[Index].Function)( | |
mSmbiosMiscDataTable[Index].RecordData, | |
mSmbiosMiscSmbios | |
); | |
if (EFI_ERROR (EfiStatus)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"Misc smbios store error. Index=%d," | |
"ReturnStatus=%r\n", | |
Index, | |
EfiStatus | |
)); | |
return EfiStatus; | |
} | |
} | |
} | |
return EfiStatus; | |
} | |
/** | |
Adds an SMBIOS record. | |
@param Buffer The data for the SMBIOS record. | |
The format of the record is determined by | |
EFI_SMBIOS_TABLE_HEADER.Type. The size of the | |
formatted area is defined by EFI_SMBIOS_TABLE_HEADER.Length | |
and either followed by a double-null (0x0000) or a set | |
of null terminated strings and a null. | |
@param SmbiosHandle A unique handle will be assigned to the SMBIOS record | |
if not NULL. | |
@retval EFI_SUCCESS Record was added. | |
@retval EFI_OUT_OF_RESOURCES Record was not added due to lack of system resources. | |
@retval EFI_ALREADY_STARTED The SmbiosHandle passed in was already in use. | |
**/ | |
EFI_STATUS | |
SmbiosMiscAddRecord ( | |
IN UINT8 *Buffer, | |
IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle OPTIONAL | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_SMBIOS_HANDLE Handle; | |
Handle = SMBIOS_HANDLE_PI_RESERVED; | |
if (SmbiosHandle != NULL) { | |
Handle = *SmbiosHandle; | |
} | |
Status = mSmbiosMiscSmbios->Add ( | |
mSmbiosMiscSmbios, | |
NULL, | |
&Handle, | |
(EFI_SMBIOS_TABLE_HEADER *)Buffer | |
); | |
if (SmbiosHandle != NULL) { | |
*SmbiosHandle = Handle; | |
} | |
return Status; | |
} | |
/** Fetches the number of handles of the specified SMBIOS type. | |
* | |
* @param SmbiosType The type of SMBIOS record to look for. | |
* | |
* @return The number of handles | |
* | |
**/ | |
STATIC | |
UINTN | |
GetHandleCount ( | |
IN UINT8 SmbiosType | |
) | |
{ | |
UINTN HandleCount; | |
EFI_STATUS Status; | |
EFI_SMBIOS_HANDLE SmbiosHandle; | |
EFI_SMBIOS_TABLE_HEADER *Record; | |
HandleCount = 0; | |
// Iterate through entries to get the number | |
do { | |
Status = mSmbiosMiscSmbios->GetNext ( | |
mSmbiosMiscSmbios, | |
&SmbiosHandle, | |
&SmbiosType, | |
&Record, | |
NULL | |
); | |
if (Status == EFI_SUCCESS) { | |
HandleCount++; | |
} | |
} while (!EFI_ERROR (Status)); | |
return HandleCount; | |
} | |
/** | |
Fetches a list of the specified SMBIOS table types. | |
@param[in] SmbiosType The type of table to fetch | |
@param[out] **HandleArray The array of handles | |
@param[out] *HandleCount Number of handles in the array | |
**/ | |
VOID | |
SmbiosMiscGetLinkTypeHandle ( | |
IN UINT8 SmbiosType, | |
OUT SMBIOS_HANDLE **HandleArray, | |
OUT UINTN *HandleCount | |
) | |
{ | |
UINTN Index; | |
EFI_STATUS Status; | |
EFI_SMBIOS_HANDLE SmbiosHandle; | |
EFI_SMBIOS_TABLE_HEADER *Record; | |
if (mSmbiosMiscSmbios == NULL) { | |
return; | |
} | |
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; | |
*HandleCount = GetHandleCount (SmbiosType); | |
*HandleArray = AllocateZeroPool (sizeof (SMBIOS_HANDLE) * (*HandleCount)); | |
if (*HandleArray == NULL) { | |
DEBUG ((DEBUG_ERROR, "HandleArray allocate memory resource failed.\n")); | |
*HandleCount = 0; | |
return; | |
} | |
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; | |
for (Index = 0; Index < (*HandleCount); Index++) { | |
Status = mSmbiosMiscSmbios->GetNext ( | |
mSmbiosMiscSmbios, | |
&SmbiosHandle, | |
&SmbiosType, | |
&Record, | |
NULL | |
); | |
if (!EFI_ERROR (Status)) { | |
(*HandleArray)[Index] = Record->Handle; | |
} else { | |
break; | |
} | |
} | |
} |