blob: 3a5626b50c0db5ec2573788abb71106da6c2ce5f [file] [log] [blame]
/** @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;
}
}
}