X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkModulePkg%2FUniversal%2FPCD%2FDxe%2FService.c;h=53d9621e8cd0809b5641f5d4d6579dd7ed72e19d;hp=280a45ea3188a88dc8c1d0b2a3f2a25c5c93a2e3;hb=0653eb895dfb8d059c114120a0779b561c5578ef;hpb=878ddf1fc3540a715f63594ed22b6929e881afb4 diff --git a/EdkModulePkg/Universal/PCD/Dxe/Service.c b/EdkModulePkg/Universal/PCD/Dxe/Service.c index 280a45ea31..53d9621e8c 100644 --- a/EdkModulePkg/Universal/PCD/Dxe/Service.c +++ b/EdkModulePkg/Universal/PCD/Dxe/Service.c @@ -14,427 +14,613 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Module Name: Service.c **/ -#include "../Common/PcdCommon.h" #include "Service.h" -static PCD_DATABASE *PrivatePcdDxeDatabase; -static LIST_ENTRY mPcdDatabaseListHead = INITIALIZE_LIST_HEAD_VARIABLE(mPcdDatabaseListHead); -LIST_ENTRY * -GetPcdDatabaseListHead ( - VOID - ) -{ - return &mPcdDatabaseListHead; -} - -PCD_DATABASE * -GetPcdDxeDataBaseInstance ( - VOID -) -{ - return PrivatePcdDxeDatabase; -} +// +// Build Tool will generate DXE_PCD_DB_INIT_VALUE in Autogen.h +// Compression Algorithm will take care of the size optimization. +// -PCD_DATABASE * -SetPcdDxeDataBaseInstance ( - PCD_DATABASE *PcdDatabase -) -{ - return PrivatePcdDxeDatabase = PcdDatabase; -} +PCD_DATABASE * mPcdDatabase; +LIST_ENTRY mCallbackFnTable[PCD_TOTAL_TOKEN_NUMBER]; -VOID -DxeGetPcdEntryWorker ( - IN UINTN TokenNumber, - IN CONST GUID *Guid, OPTIONAL - IN PCD_DATA_TYPE Type, - OUT VOID *Data - ) +VOID * +GetWorkerByLocalTokenNumber ( + UINT32 LocalTokenNumber, + BOOLEAN IsPeiDb, + UINTN Size + ) { - PCD_DATABASE *Database; - Database = GetPcdDxeDataBaseInstance (); + UINT32 Offset; + EFI_GUID *GuidTable; + UINT16 *StringTable; + EFI_GUID *Guid; + UINT16 *Name; + VARIABLE_HEAD *VariableHead; + EFI_STATUS Status; + UINTN DataSize; + VOID *Data; + VPD_HEAD *VpdHead; + UINT8 *PcdDb; + UINT16 StringTableIdx; + + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { + LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size, IsPeiDb); + } + + PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb); + StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable : + mPcdDatabase->DxeDb.Init.StringTable; + + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; + + switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) { + case PCD_TYPE_VPD: + VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset); + return (VOID *) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset); + + case PCD_TYPE_HII: + GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable : + mPcdDatabase->DxeDb.Init.GuidTable; + + VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset); + + Guid = &(GuidTable[VariableHead->GuidTableIndex]); + Name = &(StringTable[VariableHead->StringIndex]); - GetPcdEntryWorker ( &Database->Info, - TokenNumber, - Guid, - Type, - Data - ); + Status = GetHiiVariable (Guid, Name, &Data, &DataSize); + ASSERT_EFI_ERROR (Status); + ASSERT (DataSize >= (UINTN) (VariableHead->Offset + Size)); + return (UINT8 *) Data + VariableHead->Offset; - return; -} + case PCD_TYPE_STRING: + StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset); + return (VOID *) &StringTable[StringTableIdx]; + case PCD_TYPE_DATA: + return (VOID *) ((UINT8 *) PcdDb + Offset); + break; + default: + ASSERT (FALSE); + break; + + } -EFI_STATUS -DxeSetPcdEntryWorker ( - IN UINTN TokenNumber, - IN CONST GUID *Guid, OPTIONAL - IN PCD_DATA_TYPE Type, - IN CONST VOID *Data + ASSERT (FALSE); + + return NULL; +} + +VOID * +GetWorker ( + UINTN TokenNumber ) { - PCD_DATABASE *Database; - PCD_INDEX *PcdIndex; - EFI_STATUS Status; + UINT32 *LocalTokenNumberTable; + UINT16 *SizeTable; + BOOLEAN IsPeiDb; - Database = GetPcdDxeDataBaseInstance (); + ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER); + + IsPeiDb = (TokenNumber <= PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE; + LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : + mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; - ASSERT (Data != NULL); + SizeTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SizeTable: + mPcdDatabase->DxeDb.Init.SizeTable; - PcdIndex = FindPcdIndex (TokenNumber, Guid, &Database->Info, NULL); + TokenNumber = IsPeiDb ? TokenNumber : + TokenNumber - PEI_LOCAL_TOKEN_NUMBER; + return GetWorkerByLocalTokenNumber (LocalTokenNumberTable[TokenNumber], IsPeiDb, SizeTable[TokenNumber]); +} - ASSERT (PcdIndex != NULL); - ASSERT (PcdIndex->StateByte.DataType == Type); - // - // Invoke the callback function. - // +EFI_STATUS +DxeRegisterCallBackWorker ( + IN UINTN TokenNumber, + IN CONST GUID *Guid, OPTIONAL + IN PCD_PROTOCOL_CALLBACK CallBackFunction +) +{ + CALLBACK_FN_ENTRY *FnTableEntry; + EX_PCD_ENTRY_ATTRIBUTE ExAttr; + LIST_ENTRY *ListHead; + LIST_ENTRY *ListNode; + + if (Guid != NULL) { + GetExPcdTokenAttributes (Guid, TokenNumber, &ExAttr); + TokenNumber = ExAttr.LocalTokenNumberAlias; + } - Status = SetPcdData (PcdIndex, &Database->Info, Data); + ListHead = &mCallbackFnTable[TokenNumber]; + ListNode = GetFirstNode (ListHead); - return Status; + while (ListNode != ListHead) { + FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node); + + if (FnTableEntry->CallbackFn == CallBackFunction) { + // + // We only allow a Callback function to be register once + // for a TokenNumber. So just return EFI_SUCCESS + // + return EFI_SUCCESS; + } + ListNode = GetNextNode (ListHead, ListNode); + } + FnTableEntry = AllocatePool (sizeof(CALLBACK_FN_ENTRY)); + ASSERT (FnTableEntry != NULL); + FnTableEntry->CallbackFn = CallBackFunction; + InsertTailList (ListHead, &FnTableEntry->Node); + + return EFI_SUCCESS; } -UINTN -DxeGetPcdEntrySizeWorker ( - IN UINTN TokenNumber, - IN CONST GUID *Guid OPTIONAL - ) + +EFI_STATUS +DxeUnRegisterCallBackWorker ( + IN UINTN TokenNumber, + IN CONST GUID *Guid, OPTIONAL + IN PCD_PROTOCOL_CALLBACK CallBackFunction +) { - PCD_DATABASE *Database; - Database = GetPcdDxeDataBaseInstance (); + CALLBACK_FN_ENTRY *FnTableEntry; + EX_PCD_ENTRY_ATTRIBUTE ExAttr; + LIST_ENTRY *ListHead; + LIST_ENTRY *ListNode; + + if (Guid != NULL) { + GetExPcdTokenAttributes (Guid, TokenNumber, &ExAttr); + TokenNumber = ExAttr.LocalTokenNumberAlias; + } + + ListHead = &mCallbackFnTable[TokenNumber]; + ListNode = GetFirstNode (ListHead); - return GetPcdEntrySizeWorker (&Database->Info, - TokenNumber, - Guid - ); + while (ListNode != ListHead) { + FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node); + + if (FnTableEntry->CallbackFn == CallBackFunction) { + // + // We only allow a Callback function to be register once + // for a TokenNumber. So we can safely remove the Node from + // the Link List and return EFI_SUCCESS. + // + RemoveEntryList (ListNode); + FreePool (FnTableEntry); + + return EFI_SUCCESS; + } + ListNode = GetNextNode (ListHead, ListNode); + } + + return EFI_INVALID_PARAMETER; } -LIST_ENTRY * -InsertToGuidSpaceListI ( - IN LIST_ENTRY *GuidSpaceListHead, - IN CONST EFI_GUID *Guid +PCD_TOKEN_NUMBER +ExGetNextTokeNumber ( + IN CONST EFI_GUID *Guid, + IN PCD_TOKEN_NUMBER TokenNumber, + IN EFI_GUID *GuidTable, + IN UINTN SizeOfGuidTable, + IN DYNAMICEX_MAPPING *ExMapTable, + IN UINTN SizeOfExMapTable ) { - PCD_GUID_SPACE *GuidSpaceEntry; + EFI_GUID *MatchGuid; + UINTN Idx; + UINTN GuidTableIdx; + BOOLEAN Found; + + MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid); + if (MatchGuid == NULL) { + return PCD_INVALID_TOKEN_NUMBER; + } - GuidSpaceEntry = AllocatePool (sizeof (PCD_GUID_SPACE)); - ASSERT (GuidSpaceEntry != NULL); + Found = FALSE; + GuidTableIdx = MatchGuid - GuidTable; + for (Idx = 0; Idx < SizeOfExMapTable; Idx++) { + if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) { + Found = TRUE; + break; + } + } - GuidSpaceEntry->GuidSpace= Guid; - InitializeListHead (&GuidSpaceEntry->TokenSpaceHead); + if (Found) { + if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) { + return ExMapTable[Idx].ExTokenNumber; + } + + for ( ; Idx < SizeOfExMapTable; Idx++) { + if (ExMapTable[Idx].ExTokenNumber == TokenNumber) { + Idx++; + if (Idx == SizeOfExMapTable) { + // + // Exceed the length of ExMap Table + // + return PCD_INVALID_TOKEN_NUMBER; + } else if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) { + // + // Found the next match + // + return ExMapTable[Idx].ExTokenNumber; + } else { + // + // Guid has been changed. It is the next Token Space Guid. + // We should flag no more TokenNumber. + // + return PCD_INVALID_TOKEN_NUMBER; + } + } + } + } - InsertTailList (GuidSpaceListHead, &GuidSpaceEntry->ListNode); - - return &GuidSpaceEntry->TokenSpaceHead; + return PCD_INVALID_TOKEN_NUMBER; } + -LIST_ENTRY * -InsertToTokenSpaceListI ( - IN LIST_ENTRY *TokenSpaceListHead, - IN UINTN TokenNumber - ) +VOID +BuildPcdDxeDataBase ( + VOID +) { - PCD_TOKEN_SPACE *TokenSpaceEntry; + PEI_PCD_DATABASE *PeiDatabase; + EFI_HOB_GUID_TYPE *GuidHob; + UINTN Idx; - TokenSpaceEntry = AllocatePool (sizeof (PCD_TOKEN_SPACE)); - ASSERT (TokenSpaceEntry != NULL); + mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE)); + ASSERT (mPcdDatabase != NULL); - TokenSpaceEntry->TokeNumber = TokenNumber; - InitializeListHead (&TokenSpaceEntry->CallbackListHead); - - InsertTailList (TokenSpaceListHead, &TokenSpaceEntry->ListNode); + GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid); + ASSERT (GuidHob != NULL); - return &TokenSpaceEntry->CallbackListHead; -} + PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob); + // + // Copy PCD Entries refereneced in PEI phase to PCD DATABASE + // + CopyMem (&mPcdDatabase->PeiDb, PeiDatabase, sizeof (PEI_PCD_DATABASE)); + // + // Copy PCD Entries with default value to PCD DATABASE + // + CopyMem (&mPcdDatabase->DxeDb.Init, &gDXEPcdDbInit, sizeof(DXE_PCD_DATABASE_INIT)); -VOID -InsertToCallbackListI ( - IN LIST_ENTRY *CallbackListHead, - IN PCD_PROTOCOL_CALLBACK CallBackFunction - ) -{ - PCD_CALLBACK_ENTRY *CallbackEntry; - - CallbackEntry = AllocatePool (sizeof (PCD_CALLBACK_ENTRY)); - ASSERT (CallbackEntry != NULL); - CallbackEntry->CallbackFunction = CallBackFunction; - InsertTailList (CallbackListHead, &CallbackEntry->ListNode); - + // + // Initialized the Callback Function Table + // + for (Idx = 0; Idx < PCD_TOTAL_TOKEN_NUMBER; Idx++) { + InitializeListHead (&mCallbackFnTable[Idx]); + } + return; } - -VOID -InsertToCallbackList ( - IN UINTN TokenNumber, - IN CONST EFI_GUID *Guid, - IN PCD_PROTOCOL_CALLBACK CallBackFunction +EFI_STATUS +GetHiiVariable ( + IN EFI_GUID *VariableGuid, + IN UINT16 *VariableName, + OUT VOID ** VariableData, + OUT UINTN *VariableSize ) { - LIST_ENTRY *GuidListNode; - LIST_ENTRY *GuidListHead; - LIST_ENTRY *TokenListNode; - LIST_ENTRY *TokenListHead; - LIST_ENTRY *CallbackListHead; - PCD_GUID_SPACE *GuidSpaceEntry; - PCD_TOKEN_SPACE *TokenSpaceEntry; + UINTN Size; + EFI_STATUS Status; + VOID *Buffer; - - GuidListHead = GetPcdDatabaseListHead (); - - GuidListNode = GetFirstNode (GuidListHead); - while (!IsNull (GuidListNode, GuidListHead)) { - GuidSpaceEntry = PCD_GUID_SPACE_FROM_LISTNODE(GuidListNode); - - if (CompareGuid (GuidSpaceEntry->GuidSpace, Guid)) { - TokenListHead = &GuidSpaceEntry->TokenSpaceHead; - TokenListNode = GetFirstNode (TokenListHead); - while (!IsNull (TokenListNode, TokenListHead)) { - TokenSpaceEntry = PCD_TOKEN_SPACE_FROM_LISTNODE(TokenListNode); - if (TokenSpaceEntry->TokeNumber == TokenNumber) { - InsertToCallbackListI (&TokenSpaceEntry->CallbackListHead , CallBackFunction); - } - } + Status = EfiGetVariable ( + (UINT16 *)VariableName, + VariableGuid, + NULL, + &Size, + NULL + ); + ASSERT (Status == EFI_BUFFER_TOO_SMALL); - // - // No TokenNumber match input found in this GuidSpace - // - CallbackListHead = InsertToTokenSpaceListI (TokenListHead, TokenNumber); - InsertToCallbackListI (CallbackListHead , CallBackFunction); - } - - GuidListNode = GetNextNode (GuidListHead, GuidListNode); - } + Buffer = AllocatePool (Size); - // - // No GuidSpace match the input Guid, so build the GuidSpace, TokenNumberSpace and Callback - // - TokenListHead = InsertToGuidSpaceListI (GuidListHead, Guid); - CallbackListHead = InsertToTokenSpaceListI (TokenListHead, TokenNumber); - InsertToCallbackListI (CallbackListHead , CallBackFunction); + ASSERT (Buffer != NULL); + + Status = EfiGetVariable ( + VariableName, + VariableGuid, + NULL, + &Size, + Buffer + ); + + return Status; - return; - } -EFI_STATUS -RemoveFromCallbackListI ( - IN LIST_ENTRY *CallbackListHead, - IN PCD_PROTOCOL_CALLBACK CallBackFunction - ) + +UINT32 +GetSkuEnabledTokenNumber ( + UINT32 LocalTokenNumber, + UINTN Size, + BOOLEAN IsPeiDb + ) { - LIST_ENTRY *ListNode; - PCD_CALLBACK_ENTRY *CallbackEntry; + SKU_HEAD *SkuHead; + SKU_ID *SkuIdTable; + INTN i; + UINT8 *Value; + SKU_ID *PhaseSkuIdTable; + UINT8 *PcdDb; - ListNode = GetFirstNode (CallbackListHead); + ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0); - while (!IsNull(CallbackListHead, ListNode)) { - CallbackEntry = PCD_CALLBACK_ENTRY_FROM_LISTNODE(ListNode); + PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb; - if (CallbackEntry->CallbackFunction == CallBackFunction) { - RemoveEntryList (ListNode); - FreePool (CallbackEntry); - return EFI_SUCCESS; + SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK)); + Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset); + + PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable : + mPcdDatabase->DxeDb.Init.SkuIdTable; + + SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset]; + + for (i = 0; i < SkuIdTable[0]; i++) { + if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[i + 1]) { + break; } - ListNode = GetNextNode (CallbackListHead, ListNode); } + ASSERT (i < SkuIdTable[0]); - return EFI_NOT_FOUND; + switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) { + case PCD_TYPE_VPD: + Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]); + return ((Value - PcdDb) | PCD_TYPE_VPD); + + case PCD_TYPE_HII: + Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]); + return ((Value - PcdDb) | PCD_TYPE_HII); + + case PCD_TYPE_DATA: + Value += Size * i; + return (Value - PcdDb); + + default: + ASSERT (FALSE); + } + + ASSERT (FALSE); + + return 0; + } -EFI_STATUS -RemoveFromCallbackList ( - IN UINTN TokenNumber, - IN CONST GUID *Guid, - IN PCD_PROTOCOL_CALLBACK CallBackFunction + + +VOID +InvokeCallbackOnSet ( + UINT32 ExTokenNumber, + CONST EFI_GUID *Guid, OPTIONAL + UINTN TokenNumber, + VOID *Data, + UINTN Size ) { - LIST_ENTRY *GuidListNode; - LIST_ENTRY *GuidListHead; - LIST_ENTRY *TokenListNode; - LIST_ENTRY *TokenListHead; - PCD_GUID_SPACE *GuidSpaceEntry; - PCD_TOKEN_SPACE *TokenSpaceEntry; + CALLBACK_FN_ENTRY *FnTableEntry; + LIST_ENTRY *ListHead; + LIST_ENTRY *ListNode; - - GuidListHead = GetPcdDatabaseListHead (); + ListHead = &mCallbackFnTable[TokenNumber]; + ListNode = GetFirstNode (ListHead); - GuidListNode = GetFirstNode (GuidListHead); - while (!IsNull (GuidListNode, GuidListHead)) { - - GuidSpaceEntry = PCD_GUID_SPACE_FROM_LISTNODE(GuidListNode); - if (CompareGuid (GuidSpaceEntry->GuidSpace, Guid)) { - - TokenListHead = &GuidSpaceEntry->TokenSpaceHead; - TokenListNode = GetFirstNode (TokenListHead); - while (!IsNull (TokenListNode, TokenListHead)) { - - TokenSpaceEntry = PCD_TOKEN_SPACE_FROM_LISTNODE(TokenListNode); - if (TokenSpaceEntry->TokeNumber == TokenNumber) { - return RemoveFromCallbackListI (&TokenSpaceEntry->CallbackListHead , CallBackFunction); - } - } + while (ListNode != ListHead) { + FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node); - // - // No TokenNumber match input found in this GuidSpace - // - return EFI_NOT_FOUND; - } + FnTableEntry->CallbackFn(Guid, + (Guid == NULL) ? TokenNumber : ExTokenNumber, + Data, + Size); - GuidListNode = GetNextNode (GuidListHead, GuidListNode); + ListNode = GetNextNode (ListHead, ListNode); } - - - return EFI_NOT_FOUND; + return; } + EFI_STATUS -DxeRegisterCallBackWorker ( - IN UINTN TokenNumber, - IN CONST GUID *Guid, OPTIONAL - IN PCD_PROTOCOL_CALLBACK CallBackFunction, - IN BOOLEAN Register -) +SetWorker ( + PCD_TOKEN_NUMBER TokenNumber, + VOID *Data, + UINTN Size, + BOOLEAN PtrType + ) { - PCD_DATABASE *Database; - PCD_INDEX *PcdIndex; - - Database = GetPcdDxeDataBaseInstance (); + UINT32 *LocalTokenNumberTable; + BOOLEAN IsPeiDb; - PcdIndex = FindPcdIndex (TokenNumber, Guid, &Database->Info, NULL); - if (PcdIndex == NULL) { - return EFI_NOT_FOUND; - } + ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER); - if (Register) { - InsertToCallbackList (TokenNumber, Guid, CallBackFunction); - return EFI_SUCCESS; + if (PtrType) { + ASSERT (Size <= DxePcdGetSize (TokenNumber)); } else { - return RemoveFromCallbackList (TokenNumber, Guid, CallBackFunction); + ASSERT (Size == DxePcdGetSize (TokenNumber)); } + + IsPeiDb = (TokenNumber <= PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE; - } - + LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : + mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; + InvokeCallbackOnSet (0, NULL, TokenNumber, Data, Size); -EFI_STATUS -DxeSetSku ( - UINTN Id -) -{ - PCD_DATABASE * Database; + TokenNumber = IsPeiDb ? TokenNumber + : TokenNumber - PEI_LOCAL_TOKEN_NUMBER; + + return SetWorkerByLocalTokenNumber (LocalTokenNumberTable[TokenNumber], Data, Size, PtrType, IsPeiDb); - Database = GetPcdDxeDataBaseInstance (); +} - return Database->Info.SkuId = Id; -} -EFI_STATUS -DxeGetNextTokenWorker ( - IN OUT UINTN *TokenNumber, - IN CONST GUID *Guid OPTIONAL - ) +VOID * +ExGetWorker ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINTN GetSize + ) { - PCD_DATABASE * Database; + EX_PCD_ENTRY_ATTRIBUTE Attr; + + GetExPcdTokenAttributes (Guid, ExTokenNumber, &Attr); - Database = GetPcdDxeDataBaseInstance (); + ASSERT ((GetSize == Attr.Size) || (GetSize == 0)); - return GetNextTokenWorker (&Database->Info, - TokenNumber, - Guid - ); + return GetWorkerByLocalTokenNumber (Attr.LocalTokenNumberAlias, + Attr.IsPeiDb, + Attr.Size + ); } -VOID -InitPcdDxeDataBase ( - VOID -) + + +EFI_STATUS +ExSetWorker ( + IN PCD_TOKEN_NUMBER ExTokenNumber, + IN CONST EFI_GUID *Guid, + VOID *Data, + UINTN SetSize, + BOOLEAN PtrType + ) { - PCD_DATABASE *PeiDatabase; - PCD_DATABASE *DxeDatabase; - EFI_HOB_GUID_TYPE *GuidHob; + EX_PCD_ENTRY_ATTRIBUTE Attr; - GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid); - ASSERT (GuidHob != NULL); + GetExPcdTokenAttributes (Guid, ExTokenNumber, &Attr); - PeiDatabase = (PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob); + ASSERT (!PtrType && (SetSize == Attr.Size)); - DxeDatabase = AllocateCopyPool (PeiDatabase->Info.DatabaseLen, PeiDatabase); + ASSERT (PtrType && (SetSize <= Attr.Size)); - ASSERT (DxeDatabase != NULL); + InvokeCallbackOnSet (ExTokenNumber, Guid, Attr.TokenNumber, Data, Attr.Size); - SetPcdDxeDataBaseInstance (DxeDatabase); + SetWorkerByLocalTokenNumber (Attr.LocalTokenNumberAlias, Data, Attr.Size, PtrType, Attr.IsPeiDb); - return; + return EFI_SUCCESS; + } + EFI_STATUS -GetHiiVariable ( - IN EFI_GUID *VariableGuid, - IN UINT16 *VariableName, - OUT VOID ** VariableData, - OUT UINTN *VariableSize +SetWorkerByLocalTokenNumber ( + UINT32 LocalTokenNumber, + VOID *Data, + UINTN Size, + BOOLEAN PtrType, + BOOLEAN IsPeiDb ) { - UINTN Size; - EFI_STATUS Status; - VOID *Buffer; + EFI_GUID *GuidTable; + UINT16 *StringTable; + EFI_GUID *Guid; + UINT16 *Name; + VOID *InternalData; + VARIABLE_HEAD *VariableHead; + UINTN Offset; + UINT8 *PcdDb; + + + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { + LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size, IsPeiDb); + } - Status = EfiGetVariable ( - (UINT16 *)VariableName, - VariableGuid, - NULL, - &Size, - NULL - ); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; - Buffer = AllocatePool (Size); + PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb); - ASSERT (Buffer != NULL); + StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable : + mPcdDatabase->DxeDb.Init.StringTable; + + InternalData = PcdDb + Offset; - Status = EfiGetVariable ( - VariableName, - VariableGuid, - NULL, - &Size, - Buffer - ); + switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) { + case PCD_TYPE_VPD: + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + + case PCD_TYPE_STRING: + CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, Size); + break; - return Status; + case PCD_TYPE_HII: + // + // Bug Bug: Please implement this + // + GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable : + mPcdDatabase->DxeDb.Init.GuidTable; + + VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset); + + Guid = &(GuidTable[VariableHead->GuidTableIndex]); + Name = &(StringTable[VariableHead->StringIndex]); + + return EFI_SUCCESS; + + case PCD_TYPE_DATA: + if (PtrType) { + CopyMem (InternalData, Data, Size); + return EFI_SUCCESS; + } + switch (Size) { + case sizeof(UINT8): + *((UINT8 *) InternalData) = *((UINT8 *) Data); + return EFI_SUCCESS; + + case sizeof(UINT16): + *((UINT16 *) InternalData) = *((UINT16 *) Data); + return EFI_SUCCESS; + + case sizeof(UINT32): + *((UINT32 *) InternalData) = *((UINT32 *) Data); + return EFI_SUCCESS; + + case sizeof(UINT64): + *((UINT64 *) InternalData) = *((UINT64 *) Data); + return EFI_SUCCESS; + + default: + ASSERT (FALSE); + return EFI_NOT_FOUND; + } + + default: + ASSERT (FALSE); + break; + } + + ASSERT (FALSE); + return EFI_NOT_FOUND; } @@ -448,16 +634,17 @@ SetHiiVariable ( IN UINTN Offset ) { - UINTN Size; - VOID *Buffer; - EFI_STATUS Status; + UINTN Size; + VOID *Buffer; + EFI_STATUS Status; + UINT32 Attribute; Size = 0; Status = EfiGetVariable ( (UINT16 *)VariableName, VariableGuid, - NULL, + &Attribute, &Size, NULL ); @@ -471,7 +658,7 @@ SetHiiVariable ( Status = EfiGetVariable ( VariableName, VariableGuid, - NULL, + &Attribute, &Size, Buffer ); @@ -482,10 +669,67 @@ SetHiiVariable ( return EfiSetVariable ( VariableName, VariableGuid, - 0, + Attribute, Size, Buffer ); } + + + + +VOID +GetExPcdTokenAttributes ( + IN CONST EFI_GUID *Guid, + IN PCD_TOKEN_NUMBER ExTokenNumber, + OUT EX_PCD_ENTRY_ATTRIBUTE *ExAttr + ) +{ + UINT32 i; + DYNAMICEX_MAPPING *ExMap; + EFI_GUID *GuidTable; + UINT16 *SizeTable; + + ExMap = mPcdDatabase->PeiDb.Init.ExMapTable; + GuidTable = mPcdDatabase->PeiDb.Init.GuidTable; + SizeTable = mPcdDatabase->PeiDb.Init.SizeTable; + + for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) { + if ((ExTokenNumber == ExMap[i].ExTokenNumber) && + CompareGuid (Guid, (CONST EFI_GUID *) &GuidTable[ExMap[i].ExGuidIndex]) + ) { + + ExAttr->IsPeiDb = TRUE; + ExAttr->Size = SizeTable[i + PEI_NEX_TOKEN_NUMBER]; + ExAttr->TokenNumber = i + PEI_NEX_TOKEN_NUMBER; + ExAttr->LocalTokenNumberAlias = ExMap[i].LocalTokenNumber; + return; + + } + } + + ExMap = mPcdDatabase->DxeDb.Init.ExMapTable; + GuidTable = mPcdDatabase->DxeDb.Init.GuidTable; + SizeTable = mPcdDatabase->DxeDb.Init.SizeTable; + + for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) { + if ((ExTokenNumber == ExMap[i].ExTokenNumber) && + CompareGuid (Guid, (CONST EFI_GUID *) &GuidTable[ExMap[i].ExGuidIndex]) + ) { + + ExAttr->IsPeiDb = FALSE; + ExAttr->Size = SizeTable[i + DXE_NEX_TOKEN_NUMBER]; + ExAttr->TokenNumber = i + PEI_LOCAL_TOKEN_NUMBER; + ExAttr->LocalTokenNumberAlias = ExMap[i].LocalTokenNumber; + return; + + } + } + + ASSERT (FALSE); + + return; +} +