# 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*