Newer
Older
AMI-Aptio-BIOS-Reversed / PcdDxe / PcdDxe.md
@Ajax Dong Ajax Dong 2 days ago 11 KB Init

PcdDxe

Function Table

Address Name Description
DebugPrint
DebugAssert
ModuleEntryPoint
PcdDxeDriverEntry
PcdDxeInitDatabase
DxePcdGetSize
GetLocalTokenNumber
GetSkuIdAdjustedTokenNumber
GetPcdInfoSize
GetTokenIndex
GetTokenNumberFromGuid
NotifyPcdCallbacks
UpdatePcdSizeInfo
DxePcdSetPtr
DxePcdSetByGuid
DxePcdSetValue16
SetNvStorePcdValue
GetVariableForPcd
GetPcdNvStoreData
DxePcdCallbackNotifyAll
DxePcdOnSetVariableEvent
GetSectionFromFfs
FreePool
AcquireLock
ReleaseLock
CompareGuid
IsListValid
StrLen
AsciiStrLen
AsciiStrCpyS
ReadUnaligned64
Saved UEFI handles from ModuleEntryPoint
EFI_HANDLE gImageHandle = NULL;
Debug console protocol handle, lazily initialized by GetDebugConOut()
VOID *gDebugConProtocol = NULL;
HOB list pointer, retrieved from SystemTable configuration table
by GetHobListInternal()
VOID *mHobList = NULL;
Callback function table. Array of LIST_ENTRY (16 bytes each)
one entry per PCD token. Initialized during PcdDxeInitDatabase().
LIST_ENTRY *mCallbackFnTable = NULL;
UINT8 *mPcdDatabasePeiDb = NULL;
UINT8 *mPcdDatabaseDxeDb = NULL;
Pointer to pre-computed size info table for GetPcdInfo protocol
UINTN *mPcdInfoSizeTable = NULL;
Number of entries in mPcdInfoSizeTable
UINTN mPcdInfoCount = 0;
Total number of PCD tokens (PEI + DXE combined)
UINT32 mPcdTotalTokenCount = 0;
Number of PCD tokens from the PEI phase
UINT32 mPeiTokenCount = 0;
Number of DXE EX (extra / extension) tokens
UINT32 mDxeExTokenCount = 0;
Bit counts for token size fields (for bit-field extraction)
UINT32 mPeiTokenSizeBitCount = 0;
Size of the GUID tables in bytes (16 bytes per entry)
UINT32 mPeiGuidTableSize = 0;
Offset from end of PEI DB to start of DXE token range
UINT32 mDxeTokenOffset = 0;
Boolean flags indicating empty databases / tables
BOOLEAN mIsPeiDbEmpty = FALSE;
Lock state variable (1 = released, 2 = acquired)
UINT32 gLockState = EFI_LOCK_RELEASED;
Read CMOS diagnostic status (register 0x4B)
__outbyte **(0x70, (__inbyte (0x70) & 0x80) 0x4B);**
Check NVRAM boot flag from memory-mapped IO at 0xFDAF0490
if (CmosData == 0) {
Output the assertion message if the mask allows
if ((AssertMask & Status) != 0) {
Locate the HOB list (needed for PCD database init)
GetHobListInternal ();
Call the module-specific driver initialization
return PcdDxeDriverEntry (ImageHandle, SystemTable);
Step 1: verify gPcdProtocolGuid is NOT already installed
ExistingPcd = NULL;
Step 2: initialize the PCD database
Step 3: install PCD protocols
Step 4: install the PCD protocol on the handle
Status = gBS->InstallProtocolInterface (
Step 1: retrieve the DXE PCD DB from the firmware volume
SectionData = GetSectionFromFv (&gPcdDatabaseGuid);
Step 2: make an owned copy of the DXE PCD DB
OwnedDb = AllocateZeroPool (
Step 3: locate the PEI PCD DB from the HOB list
Step 4: set up the PEI database pointer
if (PeiDbAddr != NULL) {
Link the PEI DB into the DXE DB (patch the self-marker)
No PEI DB found allocate an empty stub
mPcdDatabasePeiDb = AllocateZeroPool (72);
Step 5: compute token counts and table sizes
The PCD database headers encode counts as UINT16 at known offsets:
DxeDbTokenCount = (UINT16 )(mPcdDatabaseDxeDb + 64);
Size bit counts = 8 * (UINT16 at +0x42)
mPeiTokenSizeBitCount = 8 (UINT16 *)(mPcdDatabasePeiDb + 66);
GUID table sizes = 16 * (UINT16 at +0x44)
mPeiGuidTableSize = 16 (UINT16 *)(mPcdDatabasePeiDb + 68);
DXE EX token count
mDxeExTokenCount = PeiDbTokenCount - (UINT16 )(mPcdDatabasePeiDb + 66);
Empty flags
mIsPeiDbEmpty = (PeiDbTokenCount == 0);
Size info table: one entry per "size table slot" across both phases
mPcdInfoCount = (UINTN)(UINT16 )(mPcdDatabasePeiDb + 66)
Step 6: allocate and initialize the callback function table
TotalTokenCount = (UINTN)(mPcdTotalTokenCount) + 1;
Initialize as a self-linked circular list head
Select the correct database (PEI vs DXE)
if (TokenNumber >= mPeiTokenCount + 1) {
Extract the 4-bit size field from the upper nibble of HIBYTE
Size = (LocalTokenNumber >> 28) & 0xF;
No pre-computed size query dynamically
GetPcdInfoSize (TokenNumber - 1, &Size);
Token has SkuId variants determine the actual size
if ((LocalTokenNumber & PCD_TYPE_MASK) == 0) {
Direct pointer into the database
Result = PcdDb + (LocalTokenNumber & PCD_TOKEN_INDEX_MASK);
VPD token: the value lives in the VPD table section
Result = DbValuePtr + (UINT32 )((LocalTokenNumber & PCD_TOKEN_INDEX_MASK) + PcdDb);
For NV / HII / String tokens, return the value pointer
into the database (the actual NV or HII access path is
handled by the SetPtr / SetNvStorePcdValue functions).
This function should only be called for tokens WITHOUT
SkuId variants at this level.
ASSERT ((LocalTokenNumber & PCD_ATTRIBUTE_SKUID_ENABLED) == 0);
Get the SkuId table pointer (offset at +4 from the token slot)
SkuIdTable = (UINTN )(PcdDb + (UINT32 *)((LocalTokenNumber & PCD_TOKEN_INDEX_MASK) + PcdDb + 4));
Walk the SkuId table looking for our SkuId matches the self-marker
if (TableCount != 0) {
Found our SkuId entry at 'Index'
goto ADJUST;
Not found: use slot 0
Index = 0;
Try to find an empty slot
SkuEntry = SkuIdTable + 1;
Recalculate the base table address and adjust offsets
TableBase = (UINTN)PcdDb + (LocalTokenNumber & PCD_TOKEN_INDEX_MASK);
Normal data: each SkuId occupies 'SkuIdValue' bytes
return **(UINT32)(TypeBits ((TableBase + SkuIdValue Index - (UINTN)PcdDb) & PCD_TOKEN_INDEX_MASK));*
VPD / NV: each SkuId entry is 4 bytes (UINT32 offset)
return **TypeBits ((UINT32)((UINTN)PcdDb + (UINT32 )(TableBase + 4) + 4 Index - (UINTN)PcdDb) & PCD_TOKEN_INDEX_MASK);*
String types: 5 entries per SkuId (20 bytes each)
return **TypeBits ((UINT32)((UINTN)PcdDb + (UINT32 )(TableBase + 4) + 20 Index - (UINTN)PcdDb) & PCD_TOKEN_INDEX_MASK);*
Must be a fixed-size token (bits 24-27 clear)
ASSERT ((LocalTokenNumber & PCD_TYPE_MASK) == 0);
Not NV-stored: check for dynamic SkuId entries
if ((LocalTokenNumber & PCD_ATTRIBUTE_SKUID_ENABLED) != 0) {
Not found: return base size
Return the SkuId-specific size
Only fixed-size tokens contribute to the size table index
if ((TokenSpace[Token] & PCD_TYPE_MASK) == 0) {
Token has SkuId variants: count = 1 + SkuId table entries
SlotCount += *GetSkuIdTableForToken (Token, IsPeiPhase) + 1;
Fixed token: always 2 slots (base + 1)
SlotCount += 2;
Must have the SkuId-enabled bit set
ASSERT ((LocalTokenNumber & PCD_ATTRIBUTE_SKUID_ENABLED) != 0);
Try the PEI database first
if (!mIsPeiDbEmpty) {
Fall through to the DXE database
PcdDb = mPcdDatabaseDxeDb;
Callback function pointer is stored at Node + 16
Must be a fixed-size-type token
If the token is NV-stored, the size field is the NV variable size
if ((LocalTokenNumber & PCD_ATTRIBUTE_NV) == 0) {
Check for SkuId variant size update
Clamp the size to the maximum allowed
GetPcdInfoSize (TokenNumber - 1, Size);
Must match the exact token size
if (*Size != DxePcdGetSize (TokenNumber)) {
Notify callbacks before modifying the value
if **(TokenNumber < mDxeExTokenCount + 1 **
Aligned direct write (1/2/4/8 bytes)
switch (*Size) {
if (UpdatePcdSizeInfo (TokenNumber - 1, Size)) {
Fall through to NV variable path
Status = SetNvStorePcdValue (
Route through the NV variable store path
VPD only direct write (should not normally happen)
CopyMem (TargetPtr, Buffer, *Size);
Step 1: query the size of the existing NV variable
Step 2: allocate + read the variable
Step 3: overwrite the value at the correct offset
CopyMem ((UINT8 *)Buffer + StringTableSize, ValueBuffer, ValueSize);
Step 4: write the variable back
Status = gRT->SetVariable (
Variable does not exist create it
Fallback path: allocate, read, modify, write back
Buffer = AllocatePool (BufferSize);
This token has valid data check if its GUID matches
if (CompareGuid (
Query the size first
Status = gRT->GetVariable (
Unexpected status must be EFI_NOT_FOUND
ASSERT (Status == EFI_NOT_FOUND);
Valid token with data check the "notify on set" flag
Token has the notify flag set
PCD_PROTOCOL_SET_CALLBACK Callback;
HOB list not found this is an ASSERT condition
ASSERT_EFI_ERROR (EFI_NOT_FOUND);
Try to open FirmwareVolume2 protocol first
Status = gBS->OpenProtocol (
Fall back to FirmwareVolumeBlock2 protocol
Call the internal REP MOVSB-based implementation
InternalCopyMem (DestinationBuffer, SourceBuffer, Length);
Call the internal REP STOSB-based implementation
InternalZeroMem (Buffer, Length);
Check for buffer overlap
if (((UINTN)Source > (UINTN)Destination &&
Overlap detected
ASSERT (FALSE);
Safe to copy no overlap
while (*Source != '\0') {

Generated by HR650X BIOS Decompilation Project