X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkModulePkg%2FUniversal%2FPCD%2FDxe%2FPcd.c;h=c8db1b02b743d6a79f83c302151a7e113d439ea0;hp=45a6c5932affbaf3cb25ecb819f29eb30f3168a1;hb=3b06f97c13b36be92dd85fcd62059fda42271fc5;hpb=2a505eac6181d99d6a33770b7c6517f0b1e14b19 diff --git a/EdkModulePkg/Universal/PCD/Dxe/Pcd.c b/EdkModulePkg/Universal/PCD/Dxe/Pcd.c index 45a6c5932a..c8db1b02b7 100644 --- a/EdkModulePkg/Universal/PCD/Dxe/Pcd.c +++ b/EdkModulePkg/Universal/PCD/Dxe/Pcd.c @@ -53,14 +53,15 @@ PCD_PROTOCOL mPcdInstance = { DxeRegisterCallBackOnSet, DxeUnRegisterCallBackOnSet, - DxePcdGetNextToken + DxePcdGetNextToken, + DxePcdGetNextTokenSpace }; // // Static global to reduce the code size // -static EFI_HANDLE NewHandle = NULL; +static EFI_HANDLE mNewHandle = NULL; EFI_STATUS EFIAPI @@ -79,12 +80,8 @@ PcdDxeInit ( BuildPcdDxeDataBase (); - // - // BugBug Check if PcdDatabase is already installed. - // - Status = gBS->InstallProtocolInterface ( - &NewHandle, + &mNewHandle, &gPcdProtocolGuid, EFI_NATIVE_INTERFACE, &mPcdInstance @@ -182,15 +179,50 @@ DxePcdGetSize ( IN UINTN TokenNumber ) { - UINT16 * SizeTable; + UINTN Size; + UINT32 *LocalTokenNumberTable; + BOOLEAN IsPeiDb; + UINTN MaxSize; + UINTN TmpTokenNumber; + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; - SizeTable = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? mPcdDatabase->PeiDb.Init.SizeTable : - mPcdDatabase->DxeDb.Init.SizeTable; + // + // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber + // + TmpTokenNumber = TokenNumber; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1); + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + IsPeiDb = (BOOLEAN) (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + + TokenNumber = IsPeiDb ? TokenNumber : + (TokenNumber - PEI_LOCAL_TOKEN_NUMBER); + LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable + : mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; - TokenNumber = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? TokenNumber : (TokenNumber - PEI_LOCAL_TOKEN_NUMBER); + Size = (LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT; + + if (Size == 0) { + // + // For pointer type, we need to scan the SIZE_TABLE to get the current size. + // + return GetPtrTypeSize (TmpTokenNumber, &MaxSize); + } else { + return Size; + } - return SizeTable[TokenNumber]; } @@ -250,7 +282,7 @@ DxePcdGetPtrEx ( IN UINTN ExTokenNumber ) { - return ExGetWorker (Guid, ExTokenNumber, 0); + return ExGetWorker (Guid, ExTokenNumber, 0); } @@ -286,7 +318,7 @@ DxePcdSet8 ( IN UINT8 Value ) { - return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE); + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); } @@ -298,7 +330,7 @@ DxePcdSet16 ( IN UINT16 Value ) { - return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE); + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); } @@ -310,7 +342,7 @@ DxePcdSet32 ( IN UINT32 Value ) { - return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE); + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); } @@ -322,7 +354,7 @@ DxePcdSet64 ( IN UINT64 Value ) { - return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE); + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); } @@ -330,9 +362,9 @@ DxePcdSet64 ( EFI_STATUS EFIAPI DxePcdSetPtr ( - IN UINTN TokenNumber, - IN UINTN SizeOfBuffer, - IN VOID *Buffer + IN UINTN TokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer ) { return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE); @@ -347,7 +379,7 @@ DxePcdSetBool ( IN BOOLEAN Value ) { - return SetWorker (TokenNumber, &Value, sizeof (Value), FALSE); + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); } @@ -360,13 +392,7 @@ DxePcdSet8Ex ( IN UINT8 Value ) { - return ExSetWorker( - ExTokenNumber, - Guid, - &Value, - sizeof (Value), - FALSE - ); + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); } @@ -379,13 +405,7 @@ DxePcdSet16Ex ( IN UINT16 Value ) { - return ExSetWorker( - ExTokenNumber, - Guid, - &Value, - sizeof (Value), - FALSE - ); + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); } @@ -398,13 +418,7 @@ DxePcdSet32Ex ( IN UINT32 Value ) { - return ExSetWorker( - ExTokenNumber, - Guid, - &Value, - sizeof (Value), - FALSE - ); + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); } @@ -417,13 +431,7 @@ DxePcdSet64Ex ( IN UINT64 Value ) { - return ExSetWorker( - ExTokenNumber, - Guid, - &Value, - sizeof (Value), - FALSE - ); + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); } @@ -431,19 +439,13 @@ DxePcdSet64Ex ( EFI_STATUS EFIAPI DxePcdSetPtrEx ( - IN CONST EFI_GUID *Guid, - IN UINTN ExTokenNumber, - IN UINTN SizeOfBuffer, - IN VOID *Buffer + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer ) { - return ExSetWorker( - ExTokenNumber, - Guid, - Buffer, - SizeOfBuffer, - TRUE - ); + return ExSetWorker(ExTokenNumber, Guid, Buffer, SizeOfBuffer, TRUE); } @@ -456,13 +458,7 @@ DxePcdSetBoolEx ( IN BOOLEAN Value ) { - return ExSetWorker( - ExTokenNumber, - Guid, - &Value, - sizeof (Value), - TRUE - ); + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); } @@ -471,8 +467,8 @@ DxePcdSetBoolEx ( EFI_STATUS EFIAPI DxeRegisterCallBackOnSet ( - IN UINTN TokenNumber, IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN TokenNumber, IN PCD_PROTOCOL_CALLBACK CallBackFunction ) { @@ -486,14 +482,14 @@ DxeRegisterCallBackOnSet ( EFI_STATUS EFIAPI DxeUnRegisterCallBackOnSet ( - IN UINTN TokenNumber, IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN TokenNumber, IN PCD_PROTOCOL_CALLBACK CallBackFunction ) { ASSERT (CallBackFunction != NULL); - return DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction); + return DxeUnRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction); } @@ -505,41 +501,48 @@ DxePcdGetNextToken ( IN OUT UINTN *TokenNumber ) { - UINTN ExTokenNumber; - + EFI_STATUS Status; + + if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled)) { + return EFI_UNSUPPORTED; + } + + Status = EFI_NOT_FOUND; // // Scan the local token space // if (Guid == NULL) { + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + if (((*TokenNumber + 1 > PEI_NEX_TOKEN_NUMBER + 1) && (*TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1)) || + ((*TokenNumber + 1 > (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1)))) { + return EFI_NOT_FOUND; + } + (*TokenNumber)++; - if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) { - return EFI_SUCCESS; - } else { - if (*TokenNumber >= PEI_NEX_TOKEN_NUMBER && - *TokenNumber < PEI_LOCAL_TOKEN_NUMBER) { - // - // The first Non-Ex type Token Number for DXE PCD - // database is PEI_LOCAL_TOKEN_NUMBER - // - *TokenNumber = PEI_LOCAL_TOKEN_NUMBER; - return EFI_SUCCESS; - } else if (*TokenNumber >= DXE_NEX_TOKEN_NUMBER + PEI_LOCAL_TOKEN_NUMBER) { - *TokenNumber = PCD_INVALID_TOKEN_NUMBER; - return EFI_SUCCESS; - } + if ((*TokenNumber + 1 > PEI_NEX_TOKEN_NUMBER + 1) && + (*TokenNumber <= PEI_LOCAL_TOKEN_NUMBER)) { + // + // The first Non-Ex type Token Number for DXE PCD + // database is PEI_LOCAL_TOKEN_NUMBER + // + *TokenNumber = PEI_LOCAL_TOKEN_NUMBER; + } else if (*TokenNumber + 1 > DXE_NEX_TOKEN_NUMBER + PEI_LOCAL_TOKEN_NUMBER + 1) { + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; } + return EFI_SUCCESS; } - if (PEI_EXMAP_TABLE_EMPTY && PEI_EXMAP_TABLE_EMPTY) { - *TokenNumber = (UINTN) PCD_INVALID_TOKEN_NUMBER; + if (PEI_EXMAP_TABLE_EMPTY && DXE_EXMAP_TABLE_EMPTY) { + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; return EFI_NOT_FOUND; } - ExTokenNumber = *TokenNumber; if (!PEI_EXMAP_TABLE_EMPTY) { - ExTokenNumber = ExGetNextTokeNumber ( + Status = ExGetNextTokeNumber ( Guid, - ExTokenNumber, + TokenNumber, mPcdDatabase->PeiDb.Init.GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), mPcdDatabase->PeiDb.Init.ExMapTable, @@ -547,19 +550,150 @@ DxePcdGetNextToken ( ); } + if (Status == EFI_SUCCESS) { + return Status; + } + if (!DXE_EXMAP_TABLE_EMPTY) { - ExTokenNumber = ExGetNextTokeNumber ( + Status = ExGetNextTokeNumber ( Guid, - ExTokenNumber, - mPcdDatabase->PeiDb.Init.GuidTable, - sizeof(mPcdDatabase->PeiDb.Init.GuidTable), - mPcdDatabase->PeiDb.Init.ExMapTable, - sizeof(mPcdDatabase->PeiDb.Init.ExMapTable) + TokenNumber, + mPcdDatabase->DxeDb.Init.GuidTable, + sizeof(mPcdDatabase->DxeDb.Init.GuidTable), + mPcdDatabase->DxeDb.Init.ExMapTable, + sizeof(mPcdDatabase->DxeDb.Init.ExMapTable) ); } - *TokenNumber = ExTokenNumber; + return Status; +} - return EFI_SUCCESS; + +EFI_GUID ** +GetDistinctTokenSpace ( + IN OUT UINTN *ExMapTableSize, + IN DYNAMICEX_MAPPING *ExMapTable, + IN EFI_GUID *GuidTable + ) +{ + EFI_GUID **DistinctTokenSpace; + UINTN OldGuidIndex; + UINTN TsIdx; + UINTN Idx; + + + DistinctTokenSpace = AllocateZeroPool (*ExMapTableSize * sizeof (EFI_GUID *)); + ASSERT (DistinctTokenSpace != NULL); + + TsIdx = 0; + OldGuidIndex = ExMapTable[0].ExGuidIndex; + DistinctTokenSpace[TsIdx] = &GuidTable[OldGuidIndex]; + for (Idx = 1; Idx < *ExMapTableSize; Idx++) { + if (ExMapTable[Idx].ExGuidIndex != OldGuidIndex) { + OldGuidIndex = ExMapTable[Idx].ExGuidIndex; + DistinctTokenSpace[++TsIdx] = &GuidTable[OldGuidIndex]; + } + } + + // + // The total number of Distinct Token Space + // is TsIdx + 1 because we use TsIdx as a index + // to the DistinctTokenSpace[] + // + *ExMapTableSize = TsIdx + 1; + return DistinctTokenSpace; + } + +// +// Just pre-allocate a memory buffer that is big enough to +// host all distinct TokenSpace guid in both +// PEI ExMap and DXE ExMap. +// +STATIC EFI_GUID *TmpTokenSpaceBuffer[PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE] = { 0 }; + +EFI_STATUS +EFIAPI +DxePcdGetNextTokenSpace ( + IN OUT CONST EFI_GUID **Guid + ) +{ + UINTN Idx; + UINTN Idx2; + UINTN Idx3; + UINTN PeiTokenSpaceTableSize; + UINTN DxeTokenSpaceTableSize; + EFI_GUID **PeiTokenSpaceTable; + EFI_GUID **DxeTokenSpaceTable; + BOOLEAN Match; + + if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled)) { + return EFI_UNSUPPORTED; + } + + ASSERT (Guid != NULL); + + if (PEI_EXMAP_TABLE_EMPTY && DXE_EXMAP_TABLE_EMPTY) { + if (*Guid != NULL) { + return EFI_NOT_FOUND; + } else { + return EFI_SUCCESS; + } + } + + + if (TmpTokenSpaceBuffer[0] == NULL) { + PeiTokenSpaceTableSize = 0; + + if (!PEI_EXMAP_TABLE_EMPTY) { + PeiTokenSpaceTableSize = PEI_EXMAPPING_TABLE_SIZE; + PeiTokenSpaceTable = GetDistinctTokenSpace (&PeiTokenSpaceTableSize, + mPcdDatabase->PeiDb.Init.ExMapTable, + mPcdDatabase->PeiDb.Init.GuidTable + ); + CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID*) * PeiTokenSpaceTableSize); + } + + if (!DXE_EXMAP_TABLE_EMPTY) { + DxeTokenSpaceTableSize = DXE_EXMAPPING_TABLE_SIZE; + DxeTokenSpaceTable = GetDistinctTokenSpace (&DxeTokenSpaceTableSize, + mPcdDatabase->DxeDb.Init.ExMapTable, + mPcdDatabase->DxeDb.Init.GuidTable + ); + + // + // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable + // + for (Idx2 = 0, Idx3 = PeiTokenSpaceTableSize; Idx2 < DxeTokenSpaceTableSize; Idx2++) { + Match = FALSE; + for (Idx = 0; Idx < PeiTokenSpaceTableSize; Idx++) { + if (CompareGuid (TmpTokenSpaceBuffer[Idx], DxeTokenSpaceTable[Idx2])) { + Match = TRUE; + break; + } + } + if (!Match) { + TmpTokenSpaceBuffer[Idx3++] = DxeTokenSpaceTable[Idx2]; + } + } + } + } + + if (*Guid == NULL) { + *Guid = TmpTokenSpaceBuffer[0]; + return EFI_SUCCESS; + } + + for (Idx = 0; Idx < (PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE); Idx++) { + if(CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) { + Idx++; + *Guid = TmpTokenSpaceBuffer[Idx]; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; + +} +