Newer
Older
AMI-Aptio-BIOS-Reversed / PurleyPlatPkg / Library / PeiUbaPlatLib / UbaPcdUpdateLib.c / UpdatePcdPei / UpdatePcdPei.c
@Ajax Dong Ajax Dong 2 days ago 5 KB Restructure the repo
/** @file UpdatePcdPei - UBA PCD Update PEIM This PEIM locates the UBA PCD update table via the UBA configuration protocol and invokes the board-specific PCD update function during PEI phase.

 Source: PurleyPlatPkg/Library/PeiUbaPlatLib/UbaPcdUpdateLib.c Copyright (C) 2024, Intel Corporation. All rights reserved.
**/

#include "UpdatePcdPei.h"

/**Entry point of the UpdatePcdPei module.
 Delegates to UbaPcdUpdateEntry().

 @param[in] ImageHandle Handle for this PEIM's image.
 @param[in] SystemTable Pointer to the EFI system table.

 @retval EFI_SUCCESS The PCD update completed successfully.
 @retval others An error occurred.
**/
EFI_STATUS EFIAPI ModuleEntryPoint (
 IN EFI_HANDLE ImageHandle,
 IN EFI_SYSTEM_TABLE *SystemTable
 )
{
 return UbaPcdUpdateEntry ();
}

/**Locates the UBA PCD Update protocol and invokes the board-specific PCD update callback.

 1. Retrieves the PEI services table pointer via IDT.
 2. Locates the "gUbaPcdUpdateProtocolGuid" protocol.
 3. Reads the PCD_UPDATE_TABLE (12 bytes) from the protocol's data.
 4. Validates signature ('PPCD') and version (1).
 5. Calls the function pointer at offset 8 within the table.
 6. If the callback fails, triggers an ASSERT.

 @retval EFI_SUCCESS PCD update executed successfully.
 @retval others PCD update failed or protocol not found.
**/
INT32 UbaPcdUpdateEntry (
 VOID
 )
{
 EFI_STATUS Status;
 VOID *Interface;
 UINT32 n12;
 PCD_UPDATE_TABLE PcdTable;

 Interface = NULL;
 Status = PeiServicesLocatePpi (
 &gUbaPcdUpdatePpiGuid,
 0,
 NULL,
 &Interface
 );
 if (EFI_ERROR (Status)) {
 return Status;
 }

 n12 = sizeof (PCD_UPDATE_TABLE);
 Status = PeiPpiGetData (Interface, &gUbaPcdUpdatePpiGuid, (VOID *)&PcdTable, &n12);
 if (EFI_ERROR (Status)) {
 return Status;
 }

 ASSERT (PcdTable.Signature == PCD_UPDATE_TABLE_SIGNATURE);
 ASSERT (PcdTable.Version == PCD_UPDATE_TABLE_VERSION);

 Status = PcdTable.UpdatePcd ();
 if (EFI_ERROR (Status)) {
 DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status));
 ASSERT_EFI_ERROR (FALSE);
 }

 return Status;
}

/**Retrieves the PEI Services Table pointer via the IDT-based pointer mechanism.

 @return Pointer to the PEI Services Table, or NULL if not available.
**/
INT32 GetPeiServicesTablePointer (
 VOID
 )
{
 IA32_DESCRIPTOR Idtr;
 UINT32 *Ptr;

 X86ReadIdtr (&Idtr);
 Ptr = *(UINT32 **)(*(UINT32 *)&Idtr.IdtBase - 4);
 if (Ptr == NULL) {
 DEBUG ((EFI_D_ERROR, "PeiServices != ((void *) 0)\n"));
 }
 return (INT32)Ptr;
}

/**Locate the PCD debug protocol for reporting debug messages and asserts.

 @return Pointer to the debug protocol interface, or 0 if not found.
**/
INT32 PcdDebugProtocolLocate (
 VOID
 )
{
 INT32 DebugProtocol;

 if (PeiServicesLocatePpi (
 &gEfiPeiDebugPpiGuid,
 0,
 NULL,
 &DebugProtocol
 ) >= 0) {
 return DebugProtocol;
 }
 return 0;
}

/**Prints a debug message using the PCD debug protocol.

 @param[in] ErrorLevel Debug error level.
 @param[in] Format Format string.
 @param[in] ... Variable arguments.
**/
INT32 PcdDebugPrint (
 IN INT32 ErrorLevel,
 IN CHAR8 *Format,
 ...
 )
{
 INT32 DebugProtocol;
 INT32 ( **PrintFn)(INT32, CHAR8 *, ...);

 DebugProtocol = PcdDebugProtocolLocate ();
 if (DebugProtocol != 0) {
 PrintFn = (INT32 ( **)(INT32, CHAR8 *, ...))DebugProtocol;
 return (*PrintFn)(ErrorLevel, Format);
 }
 return DebugProtocol;
}

/**Asserts a condition and prints a debug message if the condition is FALSE.

 @param[in] ErrorLevel Assertion error level.
 @param[in] Format Format string for assert.
 @param[in] ... Variable arguments.
**/
INT32 PcdDebugAssert (
 IN INT32 ErrorLevel,
 IN CHAR8 *Format,
 ...
 )
{
 INT32 Result;
 INT32 ( **AssertFn)(INT32, CHAR8 *, ...);
 VA_LIST Marker;

 VA_START (Marker, Format);
 Result = PcdDebugProtocolLocate ();
 if (Result != 0) {
 if ((PcdGetBootMode () & ErrorLevel) != 0) {
 AssertFn = (INT32 ( **)(INT32, CHAR8 *, ...))Result;
 return (*AssertFn)(ErrorLevel, Format, (CHAR8 *)Marker);
 }
 }
 return Result;
}

/**Read the current boot mode from the CMOS.

 Reads CMOS index 0x4A (preserving bit 7 of index 0x70).
 Interprets the value at port 0x71 as boot mode.

 @return Boot mode value:
 0 = BOOT_WITH_FULL_CONFIGURATION 1 = BOOT_WITH_MINIMAL_CONFIGURATION 0xFF = invalid (default)
 -2147483644 = BOOT_WITH_DEFAULT_SETTINGS
 -2147483578 = BOOT_WITH_FULL_CONFIG_PLUS_DIAG
**/
INT32 PcdGetBootMode (
 VOID
 )
{
 UINT8 Index;
 UINT8 CmosData;

 Index = __inbyte (0x70);
 __outbyte (0x70, Index & 0x80 | 0x4A);
 CmosData = __inbyte (0x71);

 if ((UINT8)CmosData <= 3) {
 if (CmosData == 0)
 return 0;
 if (CmosData == 1)
 return -2147483644;
 return -2147483578;
 }

 if (CmosData == 0) {
 CmosData = (MEMORY[0xFDAF0490] & 2) | 1;
 if (CmosData == 0)
 return 0;
 if (CmosData == 1)
 return -2147483644;
 return -2147483578;
 }

 if (CmosData != (CHAR8)-1)
 return -2147483578;
 return 0;
}

/**Reads the IDTR register into the provided descriptor buffer.

 @param[out] Idtr Pointer to the IA32_DESCRIPTOR buffer.

 @return Pointer to Idtr.
**/
VOID *__thiscall X86ReadIdtr (
 VOID *Idtr
 )
{
 if (Idtr == NULL) {
 DEBUG ((EFI_D_ERROR, "Idtr != ((void *) 0)\n"));
 }
 __sidt (Idtr);
 return Idtr;
}