/*++ | |
Copyright (c) 2006, Intel Corporation | |
All rights reserved. This program and the accompanying materials | |
are licensed and made available under the terms and conditions of the BSD License | |
which accompanies this distribution. The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
Module Name: | |
PcdEmulator.c | |
Abstract: | |
Platform Configuration Database (PCD) Service PEIM | |
--*/ | |
#include <PcdEmulator.h> | |
// | |
// BugBug: PEI early phase does not support global variable!!! | |
// This is only a temperary solution. | |
// | |
UINTN mSkuId = 0; | |
STATIC EMULATED_PCD_DATABASE_EX * | |
GetPcdDataBaseEx ( | |
VOID | |
) { | |
EFI_HOB_GUID_TYPE *GuidHob; | |
EMULATED_PCD_DATABASE_EX *EmulatedPcdDatabaseEx; | |
GuidHob = GetFirstGuidHob (&gPcdHobGuid); | |
EmulatedPcdDatabaseEx = (EMULATED_PCD_DATABASE_EX *) GET_GUID_HOB_DATA(GuidHob); | |
return EmulatedPcdDatabaseEx; | |
} | |
STATIC UINTN | |
GetPcdDataBaseExEntryCount ( | |
EMULATED_PCD_DATABASE_EX * Database | |
) { | |
return Database->Count; | |
} | |
STATIC UINTN | |
GetPcdDataBaseExSize ( | |
EMULATED_PCD_DATABASE_EX * Database | |
) { | |
UINTN Size; | |
Size = sizeof (Database->Count) | |
+ (sizeof (Database->Entry[0]) * Database->Count); | |
return Size; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSetSku ( | |
IN UINTN SkuId | |
) | |
{ | |
mSkuId = SkuId; | |
return EFI_SUCCESS; | |
} | |
UINT8 | |
EFIAPI | |
PcdEmulatorGet8 ( | |
IN UINTN TokenNumber | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
ASSERT (Pcd->DatumSize == 1); | |
return (UINT8)Pcd->Datum; | |
} | |
UINT16 | |
EFIAPI | |
PcdEmulatorGet16 ( | |
IN UINTN TokenNumber | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
ASSERT (Pcd->DatumSize == 2); | |
return (UINT16)Pcd->Datum; | |
} | |
UINT32 | |
EFIAPI | |
PcdEmulatorGet32 ( | |
IN UINTN TokenNumber | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
ASSERT (Pcd->DatumSize == 4); | |
return (UINT32)Pcd->Datum; | |
} | |
UINT64 | |
EFIAPI | |
PcdEmulatorGet64 ( | |
IN UINTN TokenNumber | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
ASSERT (Pcd->DatumSize == sizeof (UINT64)); | |
return (UINT64)Pcd->Datum; | |
} | |
VOID * | |
EFIAPI | |
PcdEmulatorGetPtr ( | |
IN UINTN TokenNumber | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
return (VOID *)(UINTN)Pcd->ExtendedData; | |
} | |
BOOLEAN | |
EFIAPI | |
PcdEmulatorGetBoolean ( | |
IN UINTN TokenNumber | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
ASSERT (Pcd->DatumSize == 1); | |
return (BOOLEAN)Pcd->Datum; | |
} | |
UINTN | |
EFIAPI | |
PcdEmulatorGetSize ( | |
IN UINTN TokenNumber | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
return Pcd->DatumSize; | |
} | |
UINT8 | |
EFIAPI | |
PcdEmulatorGet8Ex ( | |
IN CONST EFI_GUID *PcdDataBaseName, | |
IN UINTN TokenNumber | |
) | |
{ | |
ASSERT (FALSE); | |
return 0; | |
} | |
UINT16 | |
EFIAPI | |
PcdEmulatorGet16Ex ( | |
IN CONST EFI_GUID *PcdDataBaseName, | |
IN UINTN TokenNumber | |
) | |
{ | |
ASSERT (FALSE); | |
return 0; | |
} | |
UINT32 | |
EFIAPI | |
PcdEmulatorGet32Ex ( | |
IN CONST EFI_GUID *PcdDataBaseName, | |
IN UINTN TokenNumber | |
) | |
{ | |
ASSERT (FALSE); | |
return 0; | |
} | |
UINT64 | |
EFIAPI | |
PcdEmulatorGet64Ex ( | |
IN CONST EFI_GUID *PcdDataBaseName, | |
IN UINTN TokenNumber | |
) | |
{ | |
ASSERT (FALSE); | |
return 0; | |
} | |
VOID * | |
EFIAPI | |
PcdEmulatorGetPtrEx ( | |
IN CONST EFI_GUID *PcdDataBaseName, | |
IN UINTN TokenNumber | |
) | |
{ | |
ASSERT (FALSE); | |
return 0; | |
} | |
BOOLEAN | |
EFIAPI | |
PcdEmulatorGetBooleanEx ( | |
IN CONST EFI_GUID *PcdDataBaseName, | |
IN UINTN TokenNumber | |
) | |
{ | |
ASSERT (FALSE); | |
return 0; | |
} | |
UINTN | |
EFIAPI | |
PcdEmulatorGetSizeEx ( | |
IN CONST EFI_GUID *PcdDataBaseName, | |
IN UINTN TokenNumber | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
return Pcd->DatumSize; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSet8 ( | |
IN UINTN TokenNumber, | |
IN UINT8 Value | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
ASSERT (Pcd->DatumSize == sizeof (UINT8)); | |
Pcd->Datum = Value; | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSet16 ( | |
IN UINTN TokenNumber, | |
IN UINT16 Value | |
) | |
{ | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSet32 ( | |
IN UINTN TokenNumber, | |
IN UINT32 Value | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
ASSERT (Pcd->DatumSize == sizeof (UINT32)); | |
Pcd->Datum = Value; | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSet64 ( | |
IN UINTN TokenNumber, | |
IN UINT64 Value | |
) | |
{ | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSetPtr ( | |
IN UINTN TokenNumber, | |
IN CONST VOID *Value | |
) | |
{ | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSetBoolean ( | |
IN UINTN TokenNumber, | |
IN BOOLEAN Value | |
) | |
{ | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSet8Ex ( | |
IN CONST EFI_GUID *Guid, | |
IN UINTN TokenNumber, | |
IN UINT8 Value | |
) | |
{ | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSet16Ex ( | |
IN CONST EFI_GUID *Guid, | |
IN UINTN TokenNumber, | |
IN UINT16 Value | |
) | |
{ | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSet32Ex ( | |
IN CONST EFI_GUID *Guid, | |
IN UINTN TokenNumber, | |
IN UINT32 Value | |
) | |
{ | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSet64Ex ( | |
IN CONST EFI_GUID *Guid, | |
IN UINTN TokenNumber, | |
IN UINT64 Value | |
) | |
{ | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSetPtrEx ( | |
IN CONST EFI_GUID *Guid, | |
IN UINTN TokenNumber, | |
IN CONST VOID *Value | |
) | |
{ | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorSetBooleanEx ( | |
IN CONST EFI_GUID *Guid, | |
IN UINTN TokenNumber, | |
IN BOOLEAN Value | |
) | |
{ | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorCallBackOnSet ( | |
IN UINTN TokenNumber, | |
IN CONST EFI_GUID *Guid, OPTIONAL | |
IN PCD_PPI_CALLBACK CallBackFunction | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
if (Pcd->CallBackListSize == Pcd->CallBackEntries) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
Pcd->CallBackList[Pcd->CallBackEntries++] = CallBackFunction; | |
return EFI_SUCCESS; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorUnregisterCallBackOnSet ( | |
IN UINTN TokenNumber, | |
IN CONST EFI_GUID *Guid, OPTIONAL | |
IN PCD_PPI_CALLBACK CallBackfunction | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
UINT32 Index; | |
Pcd = GetPcdEntry (TokenNumber); | |
ASSERT (Pcd != NULL); | |
for (Index = 0; Index < Pcd->CallBackListSize; Index++) { | |
if (Pcd->CallBackList[Index] == CallBackfunction) { | |
Pcd->CallBackList[Index] = NULL; | |
return EFI_SUCCESS; | |
} | |
} | |
return EFI_NOT_FOUND; | |
} | |
EFI_STATUS | |
EFIAPI | |
PcdEmulatorGetNextToken ( | |
IN CONST EFI_GUID *Guid, OPTIONAL | |
IN UINTN *Token | |
) | |
{ | |
EMULATED_PCD_ENTRY_EX *Pcd; | |
EMULATED_PCD_ENTRY_EX *LastPcdEntry; | |
EMULATED_PCD_DATABASE_EX *PcdDatabase; | |
EMULATED_PCD_ENTRY_EX *PcdEntry; | |
PcdDatabase = GetPcdDataBaseEx (); | |
PcdEntry = PcdDatabase->Entry; | |
if (*Token == PCD_INVALID_TOKEN) { | |
// | |
// BugBug: Due to variable size array, ensure we convert this to a reasonable database | |
// that can accomodate array references for simplicity's sake | |
*Token = PcdEntry[0].Token; | |
return EFI_SUCCESS; | |
} | |
Pcd = GetPcdEntry (*Token); | |
if (Pcd == NULL) { | |
return EFI_NOT_FOUND; | |
} | |
LastPcdEntry = PcdEntry + GetPcdDataBaseExEntryCount (PcdDatabase); | |
if (++Pcd >= LastPcdEntry) { | |
return EFI_NOT_FOUND; | |
} | |
*Token = Pcd->Token; | |
return EFI_SUCCESS; | |
} | |
PCD_PPI mPcdPpiInstance = { | |
PcdEmulatorSetSku, | |
PcdEmulatorGet8, | |
PcdEmulatorGet16, | |
PcdEmulatorGet32, | |
PcdEmulatorGet64, | |
PcdEmulatorGetPtr, | |
PcdEmulatorGetBoolean, | |
PcdEmulatorGetSize, | |
PcdEmulatorGet8Ex, | |
PcdEmulatorGet16Ex, | |
PcdEmulatorGet32Ex, | |
PcdEmulatorGet64Ex, | |
PcdEmulatorGetPtrEx, | |
PcdEmulatorGetBooleanEx, | |
PcdEmulatorGetSizeEx, | |
PcdEmulatorSet8, | |
PcdEmulatorSet16, | |
PcdEmulatorSet32, | |
PcdEmulatorSet64, | |
PcdEmulatorSetPtr, | |
PcdEmulatorSetBoolean, | |
PcdEmulatorSet8Ex, | |
PcdEmulatorSet16Ex, | |
PcdEmulatorSet32Ex, | |
PcdEmulatorSet64Ex, | |
PcdEmulatorSetPtrEx, | |
PcdEmulatorSetBooleanEx, | |
PcdEmulatorCallBackOnSet, | |
PcdEmulatorUnregisterCallBackOnSet, | |
PcdEmulatorGetNextToken | |
}; | |
STATIC EFI_PEI_PPI_DESCRIPTOR mPpiPCD = { | |
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), | |
&gPcdPpiGuid, | |
&mPcdPpiInstance | |
}; | |
EFI_STATUS | |
EFIAPI | |
PeimPcdEmulatorEntry ( | |
IN EFI_FFS_FILE_HEADER *FfsHeader, | |
IN EFI_PEI_SERVICES **PeiServices | |
) | |
{ | |
EFI_STATUS Status; | |
UINTN Index; | |
UINTN Count; | |
UINTN Calculation; | |
UINT8 *AllocatedBuffer; | |
EMULATED_PCD_DATABASE_EX *EmulatedPcdDatabaseEx; | |
EMULATED_PCD_ENTRY_EX *EmulatedPcdEntryEx; | |
// | |
// BugBug: Normally, we would read an FFS file for this data | |
// We need to remember, that when we read the FFS file, items such as the VariableName will not be encoded as a pointer | |
// but as an array of content. In this emulation, our init is encoding this data as a pointer. | |
// In the FFS version, we will depend on the proper Entry Count in the FFS data since the structures will | |
// now be variable length. | |
// | |
// | |
// | |
// We should now read from the FFS file into the cache - for now, we fake this. | |
// | |
Count = GetPcdDataBaseSize () / sizeof (EMULATED_PCD_ENTRY); | |
// | |
// Let's now determine how big of a buffer we need for our database | |
// For the FFS version, we need to calculate/consider the VariableName/ExtendedData size!!! | |
// | |
Calculation = sizeof (UINTN) + (Count * sizeof (EMULATED_PCD_ENTRY_EX)); | |
EmulatedPcdDatabaseEx = (EMULATED_PCD_DATABASE_EX *) BuildGuidHob (&gPcdHobGuid, Calculation); | |
EmulatedPcdDatabaseEx->Count = Count; | |
EmulatedPcdEntryEx = EmulatedPcdDatabaseEx->Entry; | |
AllocatedBuffer = AllocatePool (Count * sizeof (PCD_PPI_CALLBACK) * MAX_PCD_CALLBACK); | |
ASSERT (AllocatedBuffer != NULL); | |
for (Index = 0; Index < Count; Index++) { | |
// | |
// Copy from source to our own allocated buffer - normally an FFS read | |
// | |
(*PeiServices)->CopyMem ( | |
(VOID *) (EmulatedPcdEntryEx + Index), | |
(VOID *) (gEmulatedPcdEntry + Index), | |
sizeof (EMULATED_PCD_ENTRY) | |
); | |
// | |
// All the CallBackList worker functions refer to this CallBackList as CallBackList[CallbackEntry] | |
// so we seed the same buffer address here. | |
// | |
EmulatedPcdEntryEx[Index].CallBackList = (PCD_PPI_CALLBACK *)AllocatedBuffer; | |
AllocatedBuffer+= (sizeof (PCD_PPI_CALLBACK) * MAX_PCD_CALLBACK); | |
EmulatedPcdEntryEx[Index].CallBackEntries = 0; | |
EmulatedPcdEntryEx[Index].CallBackListSize = MAX_PCD_CALLBACK; | |
} | |
// | |
// Install PCD service PPI | |
// | |
Status = PeiCoreInstallPpi (&mPpiPCD); | |
ASSERT_EFI_ERROR (Status); | |
return Status; | |
} | |
EMULATED_PCD_ENTRY_EX * | |
GetPcdEntry ( | |
IN UINTN TokenNumber | |
) | |
{ | |
UINTN Index; | |
UINTN Count; | |
EMULATED_PCD_DATABASE_EX *EmulatedPcdDatabaseEx; | |
EMULATED_PCD_ENTRY_EX *EmulatedPcdEntryEx; | |
CpuBreakpoint (); | |
EmulatedPcdDatabaseEx = GetPcdDataBaseEx (); | |
// | |
// BugBug: This Count will change when we flip over to FFS version | |
// | |
Count = EmulatedPcdDatabaseEx->Count; | |
EmulatedPcdEntryEx = EmulatedPcdDatabaseEx->Entry; | |
for (Index = 0; Index < Count; Index++) { | |
if (EmulatedPcdEntryEx[Index].Token == TokenNumber) { | |
return &EmulatedPcdEntryEx[Index]; | |
} | |
} | |
return NULL; | |
} | |