alder_lake_bios/Insyde/InsydeModulePkg/Universal/Smbios/PnpRuntimeDxe/PnpRuntimeDxe.c

408 lines
12 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2012 - 2020, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include <Library/FlashRegionLib.h>
#include "PnpRuntimeDxe.h"
#define FixedPcdGetPtrSize(TokenName) (UINTN)_PCD_PATCHABLE_##TokenName##_SIZE
//
// global varibles
//
PNP_RUNTIME_PRIVATE_DATA *mPrivateData;
EFI_EVENT mSmbiosGetTableEvent;
EFI_EVENT mVirtualAddressChangeEvent;
BOOLEAN mIsOemGPNVMap = FALSE;
//
// PnpRuntime services
//
PNP_REDIRECTED_ENTRY_POINT mPnpDmiFunctions[] = {
Pnp0x50,
Pnp0x51,
Pnp0x52
//
// new services to be added
//
};
/**
ExitBootService callback function
@param [in] Event Registered callback event
@param [in] Context
@retval None.
**/
VOID
EFIAPI
SmbiosGetTableEntryPointCallback (
IN EFI_EVENT Event,
IN VOID *Context
)
{
VOID *TempAddress;
VOID *TempAddress64Bit;
UINTN EntryLength;
UINTN EntryLength64Bit;
UINTN VarSize;
BOOLEAN IsSmbios32BitTable;
BOOLEAN IsSmbios64BitTable;
IsSmbios32BitTable = FALSE;
IsSmbios64BitTable = FALSE;
if (mPrivateData == NULL) {
return;
}
gBS->CloseEvent (Event);
//
// Check 32Bit, 64 Bit Smbios Table support
//
if (((PcdGet16 (PcdSmbiosVersion) >> 8) < 0x3) ||
(((PcdGet16 (PcdSmbiosVersion) >> 8) >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT0) == BIT0))) {
IsSmbios32BitTable = TRUE;
}
if (((PcdGet16 (PcdSmbiosVersion) >> 8) >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT1) == BIT1)) {
IsSmbios64BitTable = TRUE;
}
//
// For 32 Bit Smbios Table
//
if (IsSmbios32BitTable && mPrivateData->SMBIOSTableEntryAddress == 0){
//
// find physical address of Smbios Table
//
EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **)&TempAddress);
mPrivateData->SMBIOSTableEntryAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)TempAddress;
mPrivateData->SmbiosTableEntryPoint = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)mPrivateData->SMBIOSTableEntryAddress;
if (mPrivateData->SmbiosTableEntryPoint == NULL) {
return;
}
mPrivateData->SmbiosTable = (SMBIOS_STRUCTURE *)(UINTN)(mPrivateData->SmbiosTableEntryPoint->TableAddress);
EntryLength = mPrivateData->SmbiosTableEntryPoint->EntryPointLength;
//
// temp buffer for Pnp0x52ChangeString()
//
VarSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES ((UINTN) mPrivateData->SmbiosTableEntryPoint->TableLength));
mPrivateData->TempStoreArea = AllocateRuntimePool(VarSize);
if (mPrivateData->TempStoreArea == NULL) {
return;
}
gBS->SetMem (mPrivateData->TempStoreArea, VarSize, 0x00);
//
// for Runtime Access Smbios Table
//
VarSize += EntryLength;
mPrivateData->SmbiosStoreArea = AllocateRuntimePool (VarSize);
if (mPrivateData->SmbiosStoreArea == NULL) {
return;
}
gBS->SetMem (mPrivateData->SmbiosStoreArea, VarSize, 0x00);
//
// copy to runtime memory
//
CopyMem (
mPrivateData->SmbiosStoreArea,
mPrivateData->SmbiosTableEntryPoint,
EntryLength
);
CopyMem (
(UINT8 *)((UINTN)mPrivateData->SmbiosStoreArea + EntryLength),
mPrivateData->SmbiosTable,
mPrivateData->SmbiosTableEntryPoint->TableLength
);
//
// change pointer
//
mPrivateData->SmbiosTableEntryPoint = (SMBIOS_TABLE_ENTRY_POINT *)mPrivateData->SmbiosStoreArea;
mPrivateData->SmbiosTable = (SMBIOS_STRUCTURE *)((UINTN)mPrivateData->SmbiosStoreArea + EntryLength);
}
//
// For 64 Bit Smbios Table
//
if ( IsSmbios64BitTable || mPrivateData->SMBIOSTableEntryAddress64Bit == 0){
EfiGetSystemConfigurationTable (&gEfiSmbios3TableGuid, (VOID **)&TempAddress64Bit);
mPrivateData->SMBIOSTableEntryAddress64Bit = (EFI_PHYSICAL_ADDRESS)(UINTN)TempAddress64Bit;
mPrivateData->SmbiosTableEntryPoint64Bit = (SMBIOS_TABLE_3_0_ENTRY_POINT *)(UINTN)mPrivateData->SMBIOSTableEntryAddress64Bit;
if (mPrivateData->SmbiosTableEntryPoint64Bit == NULL) {
return;
}
mPrivateData->SmbiosTable64Bit = (SMBIOS_STRUCTURE *)(UINTN)(mPrivateData->SmbiosTableEntryPoint64Bit->TableAddress);
EntryLength64Bit = sizeof (SMBIOS_TABLE_3_0_ENTRY_POINT);
//
// for Runtime Access 64 Bit Smbios Table
//
VarSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES ((UINTN) mPrivateData->SmbiosTableEntryPoint64Bit->TableMaximumSize));
VarSize += EntryLength64Bit;
mPrivateData->SmbiosStoreArea64Bit = AllocateRuntimePool (VarSize);
if (mPrivateData->SmbiosStoreArea64Bit == NULL) {
return;
}
gBS->SetMem (mPrivateData->SmbiosStoreArea64Bit, VarSize, 0x00);
//
// copy to runtime memory
//
CopyMem (
mPrivateData->SmbiosStoreArea64Bit,
mPrivateData->SmbiosTableEntryPoint64Bit,
EntryLength64Bit
);
CopyMem (
(UINT8 *)((UINTN)mPrivateData->SmbiosStoreArea64Bit + EntryLength64Bit),
mPrivateData->SmbiosTable64Bit,
mPrivateData->SmbiosTableEntryPoint64Bit->TableMaximumSize
);
//
// change pointer
//
mPrivateData->SmbiosTableEntryPoint64Bit = (SMBIOS_TABLE_3_0_ENTRY_POINT *)mPrivateData->SmbiosStoreArea64Bit;
mPrivateData->SmbiosTable64Bit = (SMBIOS_STRUCTURE *)((UINTN)mPrivateData->SmbiosStoreArea64Bit + EntryLength64Bit);
}
}
/**
VirtualAddressChange callback function
@param [in] Event Registered callback event
@param [in] Context
@retval None.
**/
VOID
EFIAPI
VirtualAddressChangeCallBack (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
if (mPrivateData == NULL) {
return;
}
if (mPrivateData->SmbiosTableEntryPoint != NULL) {
Status = EfiConvertPointer (0, (VOID **)&mPrivateData->SmbiosTableEntryPoint);
ASSERT_EFI_ERROR (Status);
}
if (mPrivateData->SmbiosTableEntryPoint64Bit != NULL) {
Status = EfiConvertPointer (0, (VOID **)&mPrivateData->SmbiosTableEntryPoint64Bit);
ASSERT_EFI_ERROR (Status);
}
if (mPrivateData->SmbiosTable != NULL) {
Status = EfiConvertPointer (0, (VOID **)&mPrivateData->SmbiosTable);
ASSERT_EFI_ERROR (Status);
}
if (mPrivateData->SmbiosTable64Bit != NULL) {
Status = EfiConvertPointer (0, (VOID **)&mPrivateData->SmbiosTable64Bit);
ASSERT_EFI_ERROR (Status);
}
if (mPrivateData->GPNVHeader != NULL) {
EfiConvertPointer (0, (VOID **)&mPrivateData->GPNVHeader);
}
if (mPrivateData->UpdatableStrings != NULL) {
EfiConvertPointer (0, (VOID **)&mPrivateData->UpdatableStrings);
}
if (mPrivateData->DmiVariableBuf != NULL) {
EfiConvertPointer (0, (VOID **)&mPrivateData->DmiVariableBuf);
}
if (mPrivateData->SmbiosStoreArea != NULL) {
Status = EfiConvertPointer (0, (VOID **)&mPrivateData->SmbiosStoreArea);
ASSERT_EFI_ERROR (Status);
}
if (mPrivateData->SmbiosStoreArea64Bit != NULL) {
Status = EfiConvertPointer (0, (VOID **)&mPrivateData->SmbiosStoreArea64Bit);
ASSERT_EFI_ERROR (Status);
}
if (mPrivateData->TempStoreArea != NULL) {
EfiConvertPointer (0, (VOID **)&mPrivateData->TempStoreArea);
}
Status = EfiConvertPointer (0, (VOID **)&mPrivateData);
ASSERT_EFI_ERROR (Status);
}
/**
Driver entry point
@param [in] ImageHandle The image handle
@param [in] SystemTable
@retval EFI_SUCCESS Command completed successfully
@return Other value Runtime memory allocation failed
or IrsiRegisterFunction failed
**/
EFI_STATUS
EFIAPI
PnpRuntimeDxeInit (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
DMI_UPDATABLE_STRING *TempStringTable;
UINTN VarSize;
UINT32 Index;
UINT32 Command;
BOOLEAN NeedFreePnpTable;
OEM_GPNV_MAP *OemGPNVMap = NULL;
//
// initialize global variable
//
mPrivateData = AllocateRuntimePool(sizeof (PNP_RUNTIME_PRIVATE_DATA));
if (mPrivateData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
TempStringTable = NULL;
mPrivateData->UpdatableStringCount = 0;
mPrivateData->UpdatableStrings = NULL;
mPrivateData->OemGPNVHandleCount = 0;
mPrivateData->SMBIOSTableEntryAddress = 0;
mPrivateData->SMBIOSTableEntryAddress64Bit = 0;
mPrivateData->SmbiosTableEntryPoint = NULL;
mPrivateData->SmbiosTableEntryPoint64Bit = NULL;
mPrivateData->SmbiosTable = NULL;
mPrivateData->SmbiosTable64Bit = NULL;
VarSize = (UINTN) FdmGetNAtSize(&gH2OFlashMapRegionSmbiosUpdateGuid, 1);
mPrivateData->DmiVariableBuf = AllocateRuntimePool(VarSize);
if (mPrivateData->DmiVariableBuf == NULL) {
return EFI_OUT_OF_RESOURCES;
}
gBS->SetMem (mPrivateData->DmiVariableBuf, VarSize, 0xFF);
//
// OemServices (Dxe)
NeedFreePnpTable = TRUE;
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcDxeInstallPnpStringTable \n"));
Status = OemSvcDxeInstallPnpStringTable (
&mPrivateData->UpdatableStringCount,
&TempStringTable
);
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcDxeInstallPnpStringTable Status: %r\n", Status));
if (Status == EFI_UNSUPPORTED) {
NeedFreePnpTable = FALSE;
TempStringTable = PcdGetPtr(PcdSmbiosUpdatableStringTable);
mPrivateData->UpdatableStringCount = FixedPcdGetPtrSize(PcdSmbiosUpdatableStringTable) / sizeof(DMI_UPDATABLE_STRING);
}
if ((TempStringTable != NULL) && (mPrivateData->UpdatableStringCount != 0)) {
mPrivateData->UpdatableStrings = AllocateRuntimePool (((mPrivateData->UpdatableStringCount) * sizeof (DMI_UPDATABLE_STRING)));
if (mPrivateData->UpdatableStrings != NULL) {
gBS->CopyMem (
mPrivateData->UpdatableStrings,
TempStringTable,
((mPrivateData->UpdatableStringCount) * sizeof (DMI_UPDATABLE_STRING))
);
}
if (NeedFreePnpTable) {
FreePool(TempStringTable);
}
}
//
// OemServices (Dxe)
//
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcDxeInstallPnpGpnvTable \n"));
Status = OemSvcDxeInstallPnpGpnvTable (&mPrivateData->OemGPNVHandleCount, &OemGPNVMap);
DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcDxeInstallPnpGpnvTable Status: %r\n", Status));
if (Status == EFI_MEDIA_CHANGED && OemGPNVMap != NULL) {
mIsOemGPNVMap = TRUE;
} else {
mIsOemGPNVMap = FALSE;
}
//
// This event will be triggered after SMBIOS table entry point is ready.
// So, we can get the address of entry point and save it.
//
Status = EfiCreateEventReadyToBootEx (
TPL_CALLBACK - 1,
SmbiosGetTableEntryPointCallback,
NULL,
&mSmbiosGetTableEvent
);
ASSERT_EFI_ERROR (Status);
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
VirtualAddressChangeCallBack,
NULL,
&gEfiEventVirtualAddressChangeGuid,
&mVirtualAddressChangeEvent
);
ASSERT_EFI_ERROR (Status);
//
// Register PnpRuntime services using IrsiLib
//
Command = PNP_0X50_SERVICES;
for (Index = 0; Index < (sizeof (mPnpDmiFunctions) / sizeof (PNP_REDIRECTED_ENTRY_POINT)); Index++) {
Status = IrsiRegisterFunction (
&gIsbServicesGuid,
Command,
(IRSI_FUNCTION)mPnpDmiFunctions[Index]
);
if (EFI_ERROR (Status)) {
break;
}
Command++;
}
return Status;
}