alder_lake_bios/Intel/AlderLake/AlderLakeBoardPkg/BiosInfo/BiosInfo.c

499 lines
18 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2014 - 2018, Insyde Software Corporation. 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.
;*
;******************************************************************************
*/
/** @file
PEIM to provide BiosInfo structure listing up all firmware volume's base addresses, sizes,
attributes, and information associated to the firmware volume.
Primarily the structure is used on FIT table creation and Bpm.
@copyright
INTEL CONFIDENTIAL
Copyright 2011 - 2021 Intel Corporation.
The source code contained or described herein and all documents related to the
source code ("Material") are owned by Intel Corporation or its suppliers or
licensors. Title to the Material remains with Intel Corporation or its suppliers
and licensors. The Material may contain trade secrets and proprietary and
confidential information of Intel Corporation and its suppliers and licensors,
and is protected by worldwide copyright and trade secret laws and treaty
provisions. No part of the Material may be used, copied, reproduced, modified,
published, uploaded, posted, transmitted, distributed, or disclosed in any way
without Intel's prior express written permission.
No license under any patent, copyright, trade secret or other intellectual
property right is granted to or conferred upon you by disclosure or delivery
of the Materials, either expressly, by implication, inducement, estoppel or
otherwise. Any license under such intellectual property rights must be
express and approved by Intel in writing.
Unless otherwise agreed by Intel in writing, you may not remove or alter
this notice or any other notice embedded in Materials by Intel or
Intel's suppliers or licensors in any way.
This file contains a 'Sample Driver' and is licensed as such under the terms
of your license agreement with Intel or your vendor. This file may be modified
by the user, subject to the additional terms of the license agreement.
@par Specification Reference:
**/
#include <PiPei.h>
#include <Guid/BiosInfo.h>
#include <Library/PeiServicesLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <IndustryStandard/FirmwareInterfaceTable.h>
#include <Guid/SysFwUpdateProgress.h>
#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/SpiAccessLib.h>
//[-start-180815-IB15410176-add]//
#include <BootGuardTableDefinition.h>
//[-end-180815-IB15410176-add]//
//[-start-201130-IB16560229-remove]//
//#define BASE_FV_SIZE 10
//
//#define FSP_WRAPPER_FV_SIZE 3
//
//#if FixedPcdGet8(PcdEmbeddedEnable) == 0x1
// #define TSN_MAC_ADDRESS_FV_SIZE 1
//#else
// #define TSN_MAC_ADDRESS_FV_SIZE 0
//#endif
//
#if FixedPcdGetBool(PcdExtendedBiosRegionSupport) == 1
// #define EXTENDED_REGION_FV_SIZE 2
#define EXTENDED_REGION_FV_SIZE 0
#else
#define EXTENDED_REGION_FV_SIZE 0
#endif
//#define BIOS_INFO_STRUCT_SIZE (BASE_FV_SIZE + FSP_WRAPPER_FV_SIZE + TSN_MAC_ADDRESS_FV_SIZE + EXTENDED_REGION_FV_SIZE)
//[-end-201130-IB16560229-remove]//
//[-start-180815-IB15410176-remove]//
// //
// // Internal
/*
BIOS_INFO structure is the base of the firmware volume layout for Intel platform BIOS implementation
so security checker module can run based on the structure and throw warnings, error or deadloop
when any unexpected firmware volumes are detected.
BIOS_INFO is recommended to support full entries of firmware volumes present in a flash
with right type, attribute, version, flash map base address and size,
all associated information which is defined by BIOS_INFO_STRUCT structure.
- IBB firmware volumes, which are expected to be measured or/and verified
by hardware base security solution to meet SecureBoot chain of trust
(Intel BootGuard for example), have attribute 0x0.
- Post IBB firmware volumes, which are expected to be measured or/and verified
by BIOS (TCG code for measurement, RSA2048SHA256Sign algorithm for verification for example),
have attribute BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB.
- Else, follows Firmware Interface Table specification.
*/
//#pragma pack (1)
//typedef struct {
// BIOS_INFO_HEADER Header;
// BIOS_INFO_STRUCT Entry[BIOS_INFO_STRUCT_SIZE];
//} BIOS_INFO;
//#pragma pack ()
//
//GLOBAL_REMOVE_IF_UNREFERENCED BIOS_INFO mBiosInfo = {
// {
// BIOS_INFO_SIGNATURE,
// BIOS_INFO_STRUCT_SIZE,
// 0,
// },
// {
// /*
// Extended Bios region may not be mapped yet when BiosInfoChecker
// reads FvHeader from flash. Extended FVs are excluded from
// BiosInfo so BiosInfoChecker skips checking on the Security requirements.
// @todo the region wants to be dynamically checked on FV installation.
// Use EXTENDED_REGION_FV_SIZE macro to increase BiosInfo struct entries,
// once the dynamic check solution is implemented.
//#if FixedPcdGetBool(PcdExtendedBiosRegionSupport) == 1
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvExtendedPostMemorySize),
// FixedPcdGet32 (PcdFlashFvExtendedPostMemoryBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvExtendedAdvancedSize),
// FixedPcdGet32 (PcdFlashFvExtendedAdvancedBase)
// },
//#endif
// */
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_GENERAL_EXCLUDE_FROM_FIT,
// 0x0100,
// FixedPcdGet32 (PcdFlashNvStorageVariableSize) + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize),
// FixedPcdGet32 (PcdFlashNvStorageVariableBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvAdvancedSize),
// FixedPcdGet32 (PcdFlashFvAdvancedBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvOptionalSize),
// FixedPcdGet32 (PcdFlashFvOptionalBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvSecuritySize),
// FixedPcdGet32 (PcdFlashFvSecurityBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvOsBootSize),
// FixedPcdGet32 (PcdFlashFvOsBootBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvUefiBootSize),
// FixedPcdGet32 (PcdFlashFvUefiBootBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvPostMemorySize),
// FixedPcdGet32 (PcdFlashFvPostMemoryBase)
// },
// {
// /*
// Note :
// Startup ACM is one of the binaries in FvFirmwareBinaries,
// so put type 07 but not type 02.
// FIT table will contain a type 02 entry with actual address
// of ACM binary (it is passed as an input to FitGen tool).
// */
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_GENERAL_EXCLUDE_FROM_FIT,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvFirmwareBinariesSize),
// FixedPcdGet32 (PcdFlashFvFirmwareBinariesBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvFspSSize),
// FixedPcdGet32 (PcdFlashFvFspSBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// 0x00, // IBB FV
// 0x0100,
// FixedPcdGet32 (PcdFlashFvFspMSize),
// FixedPcdGet32 (PcdFlashFvFspMBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// 0x00, // IBB FV
// 0x0100,
// FixedPcdGet32 (PcdFlashFvFspTSize),
// FixedPcdGet32 (PcdFlashFvFspTBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// 0x00, // IBB FV
// 0x0100,
// FixedPcdGet32 (PcdFlashFvPreMemorySize),
// FixedPcdGet32 (PcdFlashFvPreMemoryBase)
// },
// {
// FIT_TYPE_01_MICROCODE,
// BIOS_INFO_STRUCT_ATTRIBUTE_MICROCODE_WHOLE_REGION,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvMicrocodeSize),
// FixedPcdGet32 (PcdFlashFvMicrocodeBase)
// },
//
//#if FixedPcdGet8(PcdEmbeddedEnable) == 0x1
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_GENERAL_EXCLUDE_FROM_FIT,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvTsnMacAddressSize),
// FixedPcdGet32 (PcdFlashFvTsnMacAddressBase)
// },
//#endif
// }
//};
//[-end-180815-IB15410176-remove]//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mBiosInfoPpiList = {
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gBiosInfoGuid,
&mBiosInfo
};
EFI_STATUS
InstallMeasurementExcludedFvListCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
static EFI_PEI_NOTIFY_DESCRIPTOR mExcludeFvNotifyList = {
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gPeiFvMeasurementExcludedPlatformPpiGuid,
InstallMeasurementExcludedFvListCallback
};
//[-start-201030-IB16810136-remove]//
//#if FixedPcdGetBool(PcdCapsuleEnable) == 1
//#define BIOS_RECOVERY_INFO_SIGNATURE SIGNATURE_64 ('$', 'B', 'I', 'O', 'S', 'R', 'I', '$')
// #define BIOS_RECOVERY_INFO_STRUCT_SIZE 2
//#pragma pack (1)
//typedef struct {
// BIOS_INFO_HEADER Header;
// BIOS_INFO_STRUCT Entry[BIOS_RECOVERY_INFO_STRUCT_SIZE];
//} BIOS_RECOVERY_INFO;
//#pragma pack ()
//GLOBAL_REMOVE_IF_UNREFERENCED BIOS_RECOVERY_INFO mBiosInfoRecovery = {
// {
// BIOS_RECOVERY_INFO_SIGNATURE,
// BIOS_RECOVERY_INFO_STRUCT_SIZE,
// 0,
// },
// {
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvPostMemorySize),
// FixedPcdGet32 (PcdFlashFvPostMemoryBase)
// },
// {
// FIT_TYPE_07_BIOS_STARTUP_MODULE,
// BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB,
// 0x0100,
// FixedPcdGet32 (PcdFlashFvFspSSize),
// FixedPcdGet32 (PcdFlashFvFspSBase)
// },
// }
//};
//GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mBiosInfoRecoveryPpiList = {
// EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
// &gBiosInfoGuid, // Consumed by BiosInfoChecker
// &mBiosInfoRecovery
//};
/**
Determine if Bios Check on Obb FVs should be deferred.
This happens when Obb on SPI is not trusted:
E.g., BIOS update is interrupted, update is not happened but TopSwap is enabled.
@retval TRUE Install mBiosInfoRecoveryPpiList to defer BIOS check on Obb SPI region.
@retval FALSE Install mBiosInfoPpiList normally.
**/
//BOOLEAN
//IsDeferredBiosCheckOnObbFvs (
// VOID
// )
//{
// EFI_HOB_GUID_TYPE *GuidHob;
// SYSTEM_FIRMWARE_UPDATE_PROGRESS *UpdateProgress;
//
// GuidHob = NULL;
// GuidHob = GetFirstGuidHob (&gSysFwUpdateProgressGuid);
// if (GuidHob != NULL) {
// UpdateProgress = (SYSTEM_FIRMWARE_UPDATE_PROGRESS *) GET_GUID_HOB_DATA (GuidHob);
//
// if (UpdateProgress->Component == UpdatingBios) {
// DEBUG ((DEBUG_INFO, "BIOS update is in progress, defer Obb FV checks to PlatformRecoveryModule\n"));
// return TRUE;
// }
//
// if ((UpdateProgress->Component == UpdatingResiliency) && (SpiIsTopSwapEnabled ())) {
// DEBUG ((DEBUG_INFO, "Post-BIOS update while the new BIOS is a bad one\n"));
// return TRUE;
// }
// } else if (SpiIsTopSwapEnabled ()) {
// DEBUG ((DEBUG_INFO, "BIOS update is not happened while TopSwap is enabled somehow\n"));
// return TRUE;
// }
//
// return FALSE;
//}
//#endif
//[-end-201030-IB16810136-remove]//
/**
Installs BiosInfo Ppi.
@param FileHandle Handle of the file being invoked.
@param PeiServices Describes the list of possible PEI Services.
@retval EFI_SUCCESS Install the BiosInfo Ppi successfully.
**/
EFI_STATUS
EFIAPI
BiosInfoEntryPoint (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
VOID *HobData;
//[-start-201030-IB16810136-remove]//
//#if FixedPcdGetBool(PcdCapsuleEnable) == 1
// if (IsDeferredBiosCheckOnObbFvs ()) {
// //
// // Install PPI, so that BiosInfoChecker PEI module can check Signed Section of the table.
// //
// Status = PeiServicesInstallPpi (&mBiosInfoRecoveryPpiList);
// ASSERT_EFI_ERROR (Status);
// //
// // Build BiosInfoRecovery hob to indicate PostMem FV checks on Obb are deferred.
// //
// HobData = BuildGuidHob (&gBiosInfoRecoveryGuid, sizeof (mBiosInfoRecovery));
// ASSERT (HobData != NULL);
// if (HobData == NULL) {
// return EFI_OUT_OF_RESOURCES;
// }
// CopyMem (HobData, &mBiosInfoRecovery, sizeof (mBiosInfoRecovery));
// } else {
//#endif
//[-end-201030-IB16810136-remove]//
//
// Install PPI, so that other PEI module can add dependency.
//
Status = PeiServicesInstallPpi (&mBiosInfoPpiList);
ASSERT_EFI_ERROR (Status);
//
// Notify PPI so other PEI module can run the callbacks as needed.
//
Status = PeiServicesNotifyPpi (&mExcludeFvNotifyList);
ASSERT_EFI_ERROR (Status);
//
// Build hob, so that DXE module can also get the data.
//
HobData = BuildGuidHob (&gBiosInfoGuid, sizeof (mBiosInfo));
ASSERT (HobData != NULL);
if (HobData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
CopyMem (HobData, &mBiosInfo, sizeof (mBiosInfo));
//[-start-201030-IB16810136-remove]//
//#if FixedPcdGetBool(PcdCapsuleEnable) == 1
// }
//#endif
//[-end-201030-IB16810136-remove]//
return EFI_SUCCESS;
}
/**
This function call dynamically creates the IBB FV list based on BiosInfo structure,
and install the measurement excluded PPI. The primary consumer of the PPI is TCG code.
**/
EFI_STATUS
InstallMeasurementExcludedFvListCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
EFI_STATUS Status;
BIOS_INFO_HEADER *BiosInfoHeader;
BIOS_INFO_STRUCT *BiosInfoStruct;
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
UINT32 IbbFvCount;
UINTN Index;
EFI_PEI_PPI_DESCRIPTOR *PeiFirmwareVolumeInfoMeasurementExcludedPpi;
EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV FvListTmp [BIOS_INFO_STRUCT_SIZE];
EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *IbbFvPpi;
DEBUG ((DEBUG_INFO, "InstallMeasurementExcludedFvListCallback : Creating Exclude FV List from Measurement\n"));
Status = PeiServicesLocatePpi (&gBiosInfoGuid, 0, NULL, (VOID **) &BiosInfoHeader);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "InstallMeasurementExcludedFvListCallback : BiosInfo PPI not found\n"));
ASSERT_EFI_ERROR (Status);
return EFI_NOT_FOUND;
}
BiosInfoStruct = (BIOS_INFO_STRUCT *) ((UINT8 *) BiosInfoHeader + sizeof (BIOS_INFO_HEADER));
/*
First go through all BiosInfoStructure and store IBB FV to FvListTmp.
- FvBase is filled with the value read from BiosInfoStruct.
- FvLength is filled with the value read FV Header, which has the exact installed size information.
Note: BiosInfo structure's size values may not be the exact size of actually installed FV (example FSP FVs).
*/
IbbFvCount = 0;
for (Index = 0; Index < BiosInfoHeader->EntryCount; Index++) {
if (BiosInfoStruct [Index].Type != FIT_TYPE_07_BIOS_STARTUP_MODULE) {
continue;
}
if (BiosInfoStruct [Index].Attributes == 0x0) { // IBB FV attribute
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BiosInfoStruct [Index].Address;
FvListTmp [IbbFvCount].FvBase = (EFI_PHYSICAL_ADDRESS) BiosInfoStruct [Index].Address;
FvListTmp [IbbFvCount].FvLength = FvHeader->FvLength;
IbbFvCount++;
}
}
IbbFvPpi = (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *) AllocateZeroPool (sizeof (UINT32) + IbbFvCount * sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV));
if (IbbFvPpi == NULL) {
DEBUG ((DEBUG_ERROR, "InstallMeasurementExcludedFvListCallback : buffer allocation failure\n"));
Status = RETURN_OUT_OF_RESOURCES;
ASSERT_EFI_ERROR (Status);
return Status;
}
IbbFvPpi->Count = IbbFvCount;
CopyMem (IbbFvPpi->Fv, FvListTmp, (UINTN) (IbbFvCount * sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV)));
DEBUG ((DEBUG_INFO, "InstallMeasurementExcludedFvListCallback :\n"));
for (Index = 0; Index < IbbFvPpi->Count; Index++) {
DEBUG ((DEBUG_INFO, " %x FV FvBase = 0x%x\n", Index, IbbFvPpi->Fv [Index].FvBase));
DEBUG ((DEBUG_INFO, " FvLength = 0x%x\n", IbbFvPpi->Fv [Index].FvLength));
}
PeiFirmwareVolumeInfoMeasurementExcludedPpi = AllocatePool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
if (PeiFirmwareVolumeInfoMeasurementExcludedPpi == NULL) {
DEBUG((DEBUG_ERROR, "InstallMeasurementExcludedFvListCallback : buffer allocation failure\n"));
Status = RETURN_OUT_OF_RESOURCES;
ASSERT_EFI_ERROR(Status);
return Status;
}
PeiFirmwareVolumeInfoMeasurementExcludedPpi->Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
PeiFirmwareVolumeInfoMeasurementExcludedPpi->Guid = &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid;
PeiFirmwareVolumeInfoMeasurementExcludedPpi->Ppi = IbbFvPpi;
Status = PeiServicesInstallPpi (PeiFirmwareVolumeInfoMeasurementExcludedPpi);
ASSERT_EFI_ERROR (Status);
return Status;
}