/** Get the PCD entry pointer in PCD database. This routine will visit PCD database to find the PCD entry according to given token number. The given token number is autogened by build tools and it will be translated to local token number. Local token number contains PCD's type and offset of PCD entry in PCD database. @param TokenNumber Token's number, it is autogened by build tools @param GetSize The size of token's value @return PCD entry pointer in PCD database **/ VOID * GetWorker ( IN UINTN TokenNumber, IN UINTN GetSize ) { UINT32 Offset; EFI_GUID *Guid; UINT16 *Name; VARIABLE_HEAD *VariableHead; EFI_STATUS Status; UINTN DataSize; VOID *Data; UINT8 *StringTable; UINT16 StringTableIdx; PEI_PCD_DATABASE *PeiPcdDb; UINT32 LocalTokenNumber; UINTN MaxSize; // // 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--; // 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 < PEI_LOCAL_TOKEN_NUMBER + 1); ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0)); PeiPcdDb = GetPcdDatabase (); LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber]; if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { if (GetSize == 0) { MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb); } else { MaxSize = GetSize; } LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize); } Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; StringTable = PeiPcdDb->Init.StringTable; switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { case PCD_TYPE_VPD: { VPD_HEAD *VpdHead; VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset); return (VOID *) (UINTN) (PcdGet32 (PcdVpdBaseAddress) + VpdHead->Offset); } case PCD_TYPE_HII|PCD_TYPE_STRING: case PCD_TYPE_HII: { VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset); Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]); Name = (UINT16*)&StringTable[VariableHead->StringIndex]; Status = GetHiiVariable (Guid, Name, &Data, &DataSize); if (Status == EFI_SUCCESS) { return (VOID *) ((UINT8 *) Data + VariableHead->Offset); } else { // // Return the default value specified by Platform Integrator // if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) { return (VOID*)&StringTable[*(UINT16*)((UINT8*)PeiPcdDb + VariableHead->DefaultValueOffset)]; } else { return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset); } } } case PCD_TYPE_DATA: return (VOID *) ((UINT8 *)PeiPcdDb + Offset); case PCD_TYPE_STRING: StringTableIdx = * (UINT16*) ((UINT8 *) PeiPcdDb + Offset); return (VOID *) (&StringTable[StringTableIdx]); default: ASSERT (FALSE); break; } ASSERT (FALSE); return NULL; }
/** Get the PCD entry pointer in PCD database. This routine will visit PCD database to find the PCD entry according to given token number. The given token number is autogened by build tools and it will be translated to local token number. Local token number contains PCD's type and offset of PCD entry in PCD database. @param TokenNumber Token's number, it is autogened by build tools @param GetSize The size of token's value @return PCD entry pointer in PCD database **/ VOID * GetWorker ( IN UINTN TokenNumber, IN UINTN GetSize ) { UINT32 Offset; EFI_GUID *Guid; UINT16 *Name; VARIABLE_HEAD *VariableHead; EFI_STATUS Status; UINTN DataSize; VOID *Data; UINT8 *StringTable; STRING_HEAD StringTableIdx; PEI_PCD_DATABASE *PeiPcdDb; UINT32 LocalTokenNumber; UINT32 LocalTokenCount; UINT8 *VaraiableDefaultBuffer; // // 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--; PeiPcdDb = GetPcdDatabase (); LocalTokenCount = PeiPcdDb->LocalTokenCount; // 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 < (LocalTokenCount + 1)); ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0)); LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1); Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; StringTable = (UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset; switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { case PCD_TYPE_VPD: { VPD_HEAD *VpdHead; VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset); return (VOID *) (UINTN) (PcdGet32 (PcdVpdBaseAddress) + VpdHead->Offset); } case PCD_TYPE_HII|PCD_TYPE_STRING: case PCD_TYPE_HII: { VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset); Guid = (EFI_GUID *) ((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + VariableHead->GuidTableIndex; Name = (UINT16*)&StringTable[VariableHead->StringIndex]; if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) { // // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of // string array in string table. // VaraiableDefaultBuffer = (UINT8 *) &StringTable[*(STRING_HEAD*)((UINT8*) PeiPcdDb + VariableHead->DefaultValueOffset)]; } else { VaraiableDefaultBuffer = (UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset; } Status = GetHiiVariable (Guid, Name, &Data, &DataSize); if ((Status == EFI_SUCCESS) && (DataSize >= (VariableHead->Offset + GetSize))) { if (GetSize == 0) { // // It is a pointer type. So get the MaxSize reserved for // this PCD entry. // GetPtrTypeSize (TokenNumber, &GetSize, PeiPcdDb); if (GetSize > (DataSize - VariableHead->Offset)) { // // Use actual valid size. // GetSize = DataSize - VariableHead->Offset; } } // // If the operation is successful, we copy the data // to the default value buffer in the PCD Database. // CopyMem (VaraiableDefaultBuffer, (UINT8 *) Data + VariableHead->Offset, GetSize); } return (VOID *) VaraiableDefaultBuffer; } case PCD_TYPE_DATA: return (VOID *) ((UINT8 *)PeiPcdDb + Offset); case PCD_TYPE_STRING: StringTableIdx = * (STRING_HEAD*) ((UINT8 *) PeiPcdDb + Offset); return (VOID *) (&StringTable[StringTableIdx]); default: ASSERT (FALSE); break; } ASSERT (FALSE); return NULL; }