X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkModulePkg%2FUniversal%2FPCD%2FDxe%2FService.c;h=13abab001a824920ad34cfc345169dd56f50b335;hp=84bfae7bf0841cc8044c4052f3c8dca5a13473b1;hb=a696a78c371709fc6a74295296c92c4e94b23a1d;hpb=2a505eac6181d99d6a33770b7c6517f0b1e14b19 diff --git a/EdkModulePkg/Universal/PCD/Dxe/Service.c b/EdkModulePkg/Universal/PCD/Dxe/Service.c index 84bfae7bf0..13abab001a 100644 --- a/EdkModulePkg/Universal/PCD/Dxe/Service.c +++ b/EdkModulePkg/Universal/PCD/Dxe/Service.c @@ -1,5 +1,5 @@ /** @file -Private functions used by PCD DXE driver.s +Private functions used by PCD DXE driver. Copyright (c) 2006, Intel Corporation All rights reserved. This program and the accompanying materials @@ -17,11 +17,6 @@ Module Name: Service.c #include "Service.h" -// -// Build Tool will generate DXE_PCD_DB_INIT_VALUE in Autogen.h -// Compression Algorithm will take care of the size optimization. -// - PCD_DATABASE * mPcdDatabase; LIST_ENTRY *mCallbackFnTable; @@ -34,30 +29,54 @@ GetWorker ( { UINT32 *LocalTokenNumberTable; UINT16 *SizeTable; - BOOLEAN IsPeiDb; - UINTN Size; - UINT32 Offset; EFI_GUID *GuidTable; UINT16 *StringTable; EFI_GUID *Guid; UINT16 *Name; VARIABLE_HEAD *VariableHead; - EFI_STATUS Status; - UINTN DataSize; - VOID *Data; + UINT8 *VaraiableDefaultBuffer; + UINT8 *Data; VPD_HEAD *VpdHead; UINT8 *PcdDb; - UINT16 StringTableIdx; + VOID *RetPtr; + UINTN MaxSize; + UINTN TmpTokenNumber; + UINTN DataSize; + EFI_STATUS Status; UINT32 LocalTokenNumber; + UINT32 Offset; + UINT16 StringTableIdx; + BOOLEAN IsPeiDb; + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); - ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER); - - Size = DxePcdGetSize (TokenNumber); - ASSERT (GetSize == Size || GetSize == 0); + RetPtr = NULL; + // + // 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--; + TmpTokenNumber = TokenNumber; - IsPeiDb = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE; + // + // PCD_TOTAL_TOKEN_NUMBER is a auto-generated constant. + // It could be zero. EBC compiler is very choosy. It may + // report warning. So we add 1 in each size of the + // comparison. + // + ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1); + + ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0)); + + // 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 = (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE; LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; @@ -71,7 +90,12 @@ GetWorker ( LocalTokenNumber = LocalTokenNumberTable[TokenNumber]; if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { - LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size, IsPeiDb); + if (GetSize == 0) { + GetPtrTypeSize (TmpTokenNumber, &MaxSize); + } else { + MaxSize = GetSize; + } + LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb); } PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb); @@ -80,10 +104,11 @@ GetWorker ( Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; - switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) { + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { case PCD_TYPE_VPD: VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset); - return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset); + RetPtr = (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset); + break; case PCD_TYPE_HII: GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable : @@ -93,19 +118,40 @@ GetWorker ( Guid = &(GuidTable[VariableHead->GuidTableIndex]); Name = &(StringTable[VariableHead->StringIndex]); + VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset; Status = GetHiiVariable (Guid, Name, &Data, &DataSize); - ASSERT_EFI_ERROR (Status); - ASSERT (DataSize >= (UINTN) (VariableHead->Offset + Size)); - - return (UINT8 *) Data + VariableHead->Offset; + if (Status == EFI_SUCCESS) { + if (GetSize == 0) { + // + // It is a pointer type. So get the MaxSize reserved for + // this PCD entry. + // + GetPtrTypeSize (TmpTokenNumber, &GetSize); + } + CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize); + FreePool (Data); + } + // + // If the operation is successful, we copy the data + // to the default value buffer in the PCD Database. + // So that we can free the Data allocated in GetHiiVariable. + // + // + // If the operation is not successful, + // Return 1) either the default value specified by Platform Integrator + // 2) Or the value Set by a PCD set operation. + // + RetPtr = (VOID *) VaraiableDefaultBuffer; + break; case PCD_TYPE_STRING: StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset); - return (VOID *) &StringTable[StringTableIdx]; + RetPtr = (VOID *) &StringTable[StringTableIdx]; + break; case PCD_TYPE_DATA: - return (VOID *) ((UINT8 *) PcdDb + Offset); + RetPtr = (VOID *) ((UINT8 *) PcdDb + Offset); break; default: @@ -114,9 +160,9 @@ GetWorker ( } - ASSERT (FALSE); - - return NULL; + EfiReleaseLock (&mPcdDatabaseLock); + + return RetPtr; } @@ -137,6 +183,13 @@ DxeRegisterCallBackWorker ( TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber); } + // + // 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--; + ListHead = &mCallbackFnTable[TokenNumber]; ListNode = GetFirstNode (ListHead); @@ -180,6 +233,13 @@ DxeUnRegisterCallBackWorker ( TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber); } + // + // 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--; + ListHead = &mCallbackFnTable[TokenNumber]; ListNode = GetFirstNode (ListHead); @@ -205,14 +265,14 @@ DxeUnRegisterCallBackWorker ( -UINTN +EFI_STATUS ExGetNextTokeNumber ( - IN CONST EFI_GUID *Guid, - IN UINTN TokenNumber, - IN EFI_GUID *GuidTable, - IN UINTN SizeOfGuidTable, - IN DYNAMICEX_MAPPING *ExMapTable, - IN UINTN SizeOfExMapTable + IN CONST EFI_GUID *Guid, + IN OUT UINTN *TokenNumber, + IN EFI_GUID *GuidTable, + IN UINTN SizeOfGuidTable, + IN DYNAMICEX_MAPPING *ExMapTable, + IN UINTN SizeOfExMapTable ) { EFI_GUID *MatchGuid; @@ -222,7 +282,7 @@ ExGetNextTokeNumber ( MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid); if (MatchGuid == NULL) { - return PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; } Found = FALSE; @@ -235,35 +295,39 @@ ExGetNextTokeNumber ( } if (Found) { - if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) { - return ExMapTable[Idx].ExTokenNumber; + if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) { + *TokenNumber = ExMapTable[Idx].ExTokenNumber; + return EFI_SUCCESS; } - + for ( ; Idx < SizeOfExMapTable; Idx++) { - if (ExMapTable[Idx].ExTokenNumber == TokenNumber) { + if (ExMapTable[Idx].ExTokenNumber == *TokenNumber) { Idx++; if (Idx == SizeOfExMapTable) { // // Exceed the length of ExMap Table // - return PCD_INVALID_TOKEN_NUMBER; + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_SUCCESS; } else if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) { // // Found the next match // - return ExMapTable[Idx].ExTokenNumber; + *TokenNumber = ExMapTable[Idx].ExTokenNumber; + return EFI_SUCCESS; } else { // // Guid has been changed. It is the next Token Space Guid. // We should flag no more TokenNumber. // - return PCD_INVALID_TOKEN_NUMBER; + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_SUCCESS; } } } } - return PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; } @@ -282,7 +346,6 @@ BuildPcdDxeDataBase ( ASSERT (mPcdDatabase != NULL); GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid); - if (GuidHob != NULL) { // @@ -311,11 +374,12 @@ BuildPcdDxeDataBase ( // Initialized the Callback Function Table // - if (PCD_TOTAL_TOKEN_NUMBER != 0) { - mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY)); - } + mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY)); - for (Idx = 0; Idx < PCD_TOTAL_TOKEN_NUMBER; Idx++) { + // 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. + for (Idx = 0; Idx + 1 < PCD_TOTAL_TOKEN_NUMBER + 1; Idx++) { InitializeListHead (&mCallbackFnTable[Idx]); } @@ -328,37 +392,44 @@ EFI_STATUS GetHiiVariable ( IN EFI_GUID *VariableGuid, IN UINT16 *VariableName, - OUT VOID ** VariableData, + OUT UINT8 **VariableData, OUT UINTN *VariableSize ) { UINTN Size; EFI_STATUS Status; - VOID *Buffer; + UINT8 *Buffer; - Status = EfiGetVariable ( + Size = 0; + Buffer = NULL; + + Status = gRT->GetVariable ( (UINT16 *)VariableName, VariableGuid, NULL, &Size, - NULL - ); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - Buffer = AllocatePool (Size); - - ASSERT (Buffer != NULL); - - Status = EfiGetVariable ( - VariableName, - VariableGuid, - NULL, - &Size, Buffer ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + Buffer = (UINT8 *) AllocatePool (Size); + + ASSERT (Buffer != NULL); + + Status = gRT->GetVariable ( + VariableName, + VariableGuid, + NULL, + &Size, + Buffer + ); + + ASSERT (Status == EFI_SUCCESS); + *VariableData = Buffer; + *VariableSize = Size; + } return Status; - } @@ -395,7 +466,7 @@ GetSkuEnabledTokenNumber ( } ASSERT (i < SkuIdTable[0]); - switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) { + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { case PCD_TYPE_VPD: Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]); return (UINT32) ((Value - PcdDb) | PCD_TYPE_VPD); @@ -403,11 +474,15 @@ GetSkuEnabledTokenNumber ( case PCD_TYPE_HII: Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]); return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII); + + case PCD_TYPE_STRING: + Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]); + return (UINT32) ((Value - PcdDb) | PCD_TYPE_STRING); case PCD_TYPE_DATA: Value += Size * i; return (UINT32) (Value - PcdDb); - + default: ASSERT (FALSE); } @@ -435,6 +510,13 @@ InvokeCallbackOnSet ( LIST_ENTRY *ListHead; LIST_ENTRY *ListNode; + // + // 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--; + ListHead = &mCallbackFnTable[TokenNumber]; ListNode = GetFirstNode (ListHead); @@ -453,14 +535,23 @@ InvokeCallbackOnSet ( } +EFI_STATUS +SetValueWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN UINTN Size + ) +{ + return SetWorker (TokenNumber, Data, &Size, FALSE); +} EFI_STATUS SetWorker ( - UINTN TokenNumber, - VOID *Data, - UINTN Size, - BOOLEAN PtrType + IN UINTN TokenNumber, + IN VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType ) { UINT32 *LocalTokenNumberTable; @@ -470,28 +561,53 @@ SetWorker ( UINT16 *StringTable; EFI_GUID *Guid; UINT16 *Name; + UINTN VariableOffset; VOID *InternalData; VARIABLE_HEAD *VariableHead; UINTN Offset; UINT8 *PcdDb; + EFI_STATUS Status; + UINTN MaxSize; + UINTN TmpTokenNumber; + + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); + // + // 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--; - ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER); + 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. - if (PtrType) { - ASSERT (Size <= DxePcdGetSize (TokenNumber)); - } else { - ASSERT (Size == DxePcdGetSize (TokenNumber)); + ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1); + + if (!PtrType) { + ASSERT (*Size == DxePcdGetSize (TokenNumber + 1)); } - IsPeiDb = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE; + // 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 = (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE; LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; - if ((TokenNumber < PEI_NEX_TOKEN_NUMBER) || - (TokenNumber >= PEI_LOCAL_TOKEN_NUMBER || TokenNumber < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER))) { - InvokeCallbackOnSet (0, NULL, TokenNumber, Data, Size); + // 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))) { + InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size); } TokenNumber = IsPeiDb ? TokenNumber @@ -500,7 +616,12 @@ SetWorker ( LocalTokenNumber = LocalTokenNumberTable[TokenNumber]; if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { - LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size, IsPeiDb); + if (PtrType) { + GetPtrTypeSize (TmpTokenNumber, &MaxSize); + } else { + MaxSize = *Size; + } + LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb); } Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; @@ -512,19 +633,29 @@ SetWorker ( InternalData = PcdDb + Offset; - switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) { + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { case PCD_TYPE_VPD: ASSERT (FALSE); - return EFI_INVALID_PARAMETER; + Status = EFI_INVALID_PARAMETER; + break; case PCD_TYPE_STRING: - CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, Size); + if (SetPtrTypeSize (TmpTokenNumber, Size)) { + CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, *Size); + Status = EFI_SUCCESS; + } else { + Status = EFI_INVALID_PARAMETER; + } break; case PCD_TYPE_HII: - // - // Bug Bug: Please implement this - // + if (PtrType) { + if (!SetPtrTypeSize (TmpTokenNumber, Size)) { + Status = EFI_INVALID_PARAMETER; + break; + } + } + GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable : mPcdDatabase->DxeDb.Init.GuidTable; @@ -532,44 +663,61 @@ SetWorker ( Guid = &(GuidTable[VariableHead->GuidTableIndex]); Name = &(StringTable[VariableHead->StringIndex]); + VariableOffset = VariableHead->Offset; - return EFI_SUCCESS; + Status = SetHiiVariable (Guid, Name, Data, *Size, VariableOffset); + if (EFI_NOT_FOUND == Status) { + CopyMem (PcdDb + VariableHead->DefaultValueOffset, Data, *Size); + Status = EFI_SUCCESS; + } + break; + case PCD_TYPE_DATA: if (PtrType) { - CopyMem (InternalData, Data, Size); - return EFI_SUCCESS; + if (SetPtrTypeSize (TmpTokenNumber, Size)) { + CopyMem (InternalData, Data, *Size); + Status = EFI_SUCCESS; + } else { + Status = EFI_INVALID_PARAMETER; + } + break; } - switch (Size) { + Status = EFI_SUCCESS; + switch (*Size) { case sizeof(UINT8): *((UINT8 *) InternalData) = *((UINT8 *) Data); - return EFI_SUCCESS; + break; case sizeof(UINT16): *((UINT16 *) InternalData) = *((UINT16 *) Data); - return EFI_SUCCESS; + break; case sizeof(UINT32): *((UINT32 *) InternalData) = *((UINT32 *) Data); - return EFI_SUCCESS; + break; case sizeof(UINT64): *((UINT64 *) InternalData) = *((UINT64 *) Data); - return EFI_SUCCESS; + break; default: ASSERT (FALSE); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } + break; default: ASSERT (FALSE); + Status = EFI_NOT_FOUND; break; } - - ASSERT (FALSE); - return EFI_NOT_FOUND; + + EfiReleaseLock (&mPcdDatabaseLock); + + return Status; } @@ -589,26 +737,35 @@ ExGetWorker ( +EFI_STATUS +ExSetValueWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN UINTN SetSize + ) +{ + return ExSetWorker (ExTokenNumber, Guid, Data, &SetSize, FALSE); +} + EFI_STATUS ExSetWorker ( - IN UINTN ExTokenNumber, - IN CONST EFI_GUID *Guid, - VOID *Data, - UINTN SetSize, - BOOLEAN PtrType + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN OUT UINTN *SetSize, + IN BOOLEAN PtrType ) { UINTN TokenNumber; TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber); - InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, SetSize); + InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, *SetSize); - SetWorker (TokenNumber, Data, SetSize, PtrType); + return SetWorker (TokenNumber, Data, SetSize, PtrType); - return EFI_SUCCESS; - } @@ -630,39 +787,51 @@ SetHiiVariable ( Size = 0; - Status = EfiGetVariable ( + Status = gRT->GetVariable ( (UINT16 *)VariableName, VariableGuid, - &Attribute, + NULL, &Size, NULL ); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); + if (Status == EFI_BUFFER_TOO_SMALL) { - Buffer = AllocatePool (Size); + Buffer = AllocatePool (Size); - ASSERT (Buffer != NULL); + ASSERT (Buffer != NULL); - Status = EfiGetVariable ( - VariableName, - VariableGuid, - &Attribute, - &Size, - Buffer - ); + Status = gRT->GetVariable ( + VariableName, + VariableGuid, + &Attribute, + &Size, + Buffer + ); + + ASSERT_EFI_ERROR (Status); + CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize); - CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize); + Status = gRT->SetVariable ( + VariableName, + VariableGuid, + Attribute, + Size, + Buffer + ); - return EfiSetVariable ( - VariableName, - VariableGuid, - Attribute, - Size, - Buffer - ); + FreePool (Buffer); + return Status; + } + + // + // If we drop to here, we don't have a Variable entry in + // the variable service yet. So, we will save the data + // in the PCD Database's volatile area. + // + return Status; } @@ -681,19 +850,23 @@ GetExPcdTokenNumber ( EFI_GUID *MatchGuid; UINTN MatchGuidIdx; - ExMap = mPcdDatabase->PeiDb.Init.ExMapTable; - GuidTable = mPcdDatabase->PeiDb.Init.GuidTable; - - MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid); - ASSERT (MatchGuid != NULL); + if (!PEI_DATABASE_EMPTY) { + ExMap = mPcdDatabase->PeiDb.Init.ExMapTable; + GuidTable = mPcdDatabase->PeiDb.Init.GuidTable; + + MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid); + + if (MatchGuid != NULL) { - MatchGuidIdx = MatchGuid - GuidTable; - - for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) { - if ((ExTokenNumber == ExMap[i].ExTokenNumber) && - (MatchGuidIdx == ExMap[i].ExGuidIndex)) { - return ExMap[i].LocalTokenNumber; + MatchGuidIdx = MatchGuid - GuidTable; + + for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) { + if ((ExTokenNumber == ExMap[i].ExTokenNumber) && + (MatchGuidIdx == ExMap[i].ExGuidIndex)) { + return ExMap[i].LocalTokenNumber; + } + } } } @@ -701,6 +874,10 @@ GetExPcdTokenNumber ( GuidTable = mPcdDatabase->DxeDb.Init.GuidTable; MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid); + // + // We need to ASSERT here. If GUID can't be found in GuidTable, this is a + // error in the BUILD system. + // ASSERT (MatchGuid != NULL); MatchGuidIdx = MatchGuid - GuidTable; @@ -708,7 +885,7 @@ GetExPcdTokenNumber ( for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) { if ((ExTokenNumber == ExMap[i].ExTokenNumber) && (MatchGuidIdx == ExMap[i].ExGuidIndex)) { - return ExMap[i].LocalTokenNumber + PEI_LOCAL_TOKEN_NUMBER; + return ExMap[i].LocalTokenNumber; } } @@ -717,3 +894,264 @@ GetExPcdTokenNumber ( return 0; } + + +SKU_ID * +GetSkuIdArray ( + IN UINTN LocalTokenNumberTableIdx, + IN BOOLEAN IsPeiPcd + ) +{ + SKU_HEAD *SkuHead; + UINTN LocalTokenNumber; + UINT8 *Database; + + if (IsPeiPcd) { + LocalTokenNumber = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx]; + Database = (UINT8 *) &mPcdDatabase->PeiDb; + } else { + LocalTokenNumber = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx - PEI_LOCAL_TOKEN_NUMBER]; + Database = (UINT8 *) &mPcdDatabase->DxeDb; + } + + ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0); + + SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK)); + + return (SKU_ID *) (Database + SkuHead->SkuIdTableOffset); + +} + + + +UINTN +GetSizeTableIndexA ( + IN UINTN LocalTokenNumberTableIdx, + IN UINT32 *LocalTokenNumberTable, + IN BOOLEAN IsPeiDb + ) +{ + UINTN i; + UINTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + + SizeTableIdx = 0; + + for (i=0; iPeiDb.Init.LocalTokenNumberTable; + } else { + LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; + } + return GetSizeTableIndexA (LocalTokenNumberTableIdx, + LocalTokenNumberTable, + IsPeiDb); +} + + + +UINTN +GetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + OUT UINTN *MaxSize + ) +{ + INTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + SIZE_INFO *SizeTable; + UINTN i; + BOOLEAN IsPeiDb; + UINT32 *LocalTokenNumberTable; + + // 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) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + + + if (IsPeiDb) { + LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable; + SizeTable = mPcdDatabase->PeiDb.Init.SizeTable; + } else { + LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER; + LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; + SizeTable = mPcdDatabase->DxeDb.Init.SizeTable; + } + + LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx]; + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); + + SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb); + + *MaxSize = SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if (LocalTokenNumber & PCD_TYPE_VPD) { + // + // We have only one entry for VPD enabled PCD entry: + // 1) MAX Size. + // We consider current size is equal to MAX size. + // + return *MaxSize; + } else { + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + return SizeTable[SizeTableIdx + 1]; + } else { + // + // We have these entry for SKU enabled PCD entry + // 1) MAX SIZE + // 2) Current Size for each SKU_ID (It is equal to MaxSku). + // + SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb); + for (i = 0; i < SkuIdTable[0]; i++) { + if (SkuIdTable[1 + i] == mPcdDatabase->PeiDb.Init.SystemSkuId) { + return SizeTable[SizeTableIdx + 1 + i]; + } + } + return SizeTable[SizeTableIdx + 1]; + } + } +} + + + +BOOLEAN +SetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + IN OUT UINTN *CurrentSize + ) +{ + INTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + SIZE_INFO *SizeTable; + UINTN i; + UINTN MaxSize; + BOOLEAN IsPeiDb; + UINT32 *LocalTokenNumberTable; + + // 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) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + + if (IsPeiDb) { + LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable; + SizeTable = mPcdDatabase->PeiDb.Init.SizeTable; + } else { + LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER; + LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; + SizeTable = mPcdDatabase->DxeDb.Init.SizeTable; + } + + LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx]; + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); + + SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb); + + MaxSize = SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if (LocalTokenNumber & PCD_TYPE_VPD) { + // + // We shouldn't come here as we don't support SET for VPD + // + ASSERT (FALSE); + return FALSE; + } else { + if ((*CurrentSize > MaxSize) || + (*CurrentSize == MAX_ADDRESS)) { + *CurrentSize = MaxSize; + return FALSE; + } + + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; + return TRUE; + } else { + // + // We have these entry for SKU enabled PCD entry + // 1) MAX SIZE + // 2) Current Size for each SKU_ID (It is equal to MaxSku). + // + SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb); + for (i = 0; i < SkuIdTable[0]; i++) { + if (SkuIdTable[1 + i] == mPcdDatabase->PeiDb.Init.SystemSkuId) { + SizeTable[SizeTableIdx + 1 + i] = (SIZE_INFO) *CurrentSize; + return TRUE; + } + } + SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; + return TRUE; + } + } +} +