/** Get PCD value's size for POINTER type PCD. The POINTER type PCD's value will be stored into a buffer in specified size. The max size of this PCD's value is described in PCD's definition in DEC file. @param LocalTokenNumberTableIdx Index of PCD token number in PCD token table @param MaxSize Maximum size of PCD's value @param Database Pcd database in PEI phase. @return PCD value's size for POINTER type PCD. **/ UINTN GetPtrTypeSize ( IN UINTN LocalTokenNumberTableIdx, OUT UINTN *MaxSize, IN PEI_PCD_DATABASE *Database ) { INTN SizeTableIdx; UINTN LocalTokenNumber; SKU_ID *SkuIdTable; SIZE_INFO *SizeTable; UINTN Index; SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database); LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx); ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset); *MaxSize = SizeTable[SizeTableIdx]; // // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type // PCD entry. // if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) { // // We have only two entry for VPD enabled PCD entry: // 1) MAX Size. // 2) Current 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, Database); for (Index = 0; Index < SkuIdTable[0]; Index++) { if (SkuIdTable[1 + Index] == Database->SystemSkuId) { return SizeTable[SizeTableIdx + 1 + Index]; } } return SizeTable[SizeTableIdx + 1]; } } }
/** Get index of PCD entry in size table. @param LocalTokenNumberTableIdx Index of this PCD in local token number table. @param Database Pointer to PCD database in PEI phase. @return index of PCD entry in size table. **/ UINTN GetSizeTableIndex ( IN UINTN LocalTokenNumberTableIdx, IN PEI_PCD_DATABASE *Database ) { UINTN Index; UINTN SizeTableIdx; UINTN LocalTokenNumber; SKU_ID *SkuIdTable; SizeTableIdx = 0; for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) { LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + Index); if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) { // // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type // PCD entry. // if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) { // // We have only two entry for VPD enabled PCD entry: // 1) MAX Size. // 2) Current Size // Current size is equal to MAX size. // SizeTableIdx += 2; } 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 // SizeTableIdx += 2; } 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 (Index, Database); SizeTableIdx += (UINTN)*SkuIdTable + 1; } } } } return SizeTableIdx; }
/** Set PCD value's size for POINTER type PCD. The POINTER type PCD's value will be stored into a buffer in specified size. The max size of this PCD's value is described in PCD's definition in DEC file. @param LocalTokenNumberTableIdx Index of PCD token number in PCD token table @param CurrentSize Maximum size of PCD's value @param Database Pcd database in PEI phase. @retval TRUE Success to set PCD's value size, which is not exceed maximum size @retval FALSE Fail to set PCD's value size, which maybe exceed maximum size **/ BOOLEAN SetPtrTypeSize ( IN UINTN LocalTokenNumberTableIdx, IN OUT UINTN *CurrentSize, IN PEI_PCD_DATABASE *Database ) { INTN SizeTableIdx; UINTN LocalTokenNumber; SKU_ID *SkuIdTable; SIZE_INFO *SizeTable; UINTN Index; UINTN MaxSize; SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database); LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx); ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset); MaxSize = SizeTable[SizeTableIdx]; // // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type // PCD entry. // if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) { // // 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, Database); for (Index = 0; Index < SkuIdTable[0]; Index++) { if (SkuIdTable[1 + Index] == Database->SystemSkuId) { SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize; return TRUE; } } SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; return TRUE; } } }