Let's explore another PCD type - feature flag PCD. This is basically a boolean value.
Add this PCD to DEC file UefiLessonsPkg/UefiLessonsPkg.dec
:
[PcdsFeatureFlag]
gUefiLessonsPkgTokenSpaceGuid.PcdFeatureFlag|TRUE|BOOLEAN|0x16DD586E
And populate it to the INF file UefiLessonsPkg/PCDLesson/PCDLesson.inf
. In the INF file PCDs of this type goes to [FeaturePcd]
section:
[FeaturePcd]
gUefiLessonsPkgTokenSpaceGuid.PcdFeatureFlag
To get the PCD value in a *.c
file either FeaturePcdGet
or PcdGetBool
can be used which are practically the same https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Library/PcdLib.h:
#define FeaturePcdGet(TokenName) _PCD_GET_MODE_BOOL_##TokenName
...
#define PcdGetBool(TokenName) _PCD_GET_MODE_BOOL_##TokenName
Let's use both methonds in our UefiLessonsPkg/PCDLesson/PCDLesson.c
to print the flag value:
Print(L"PcdFeatureFlag=%d\n", FeaturePcdGet(PcdFeatureFlag));
Print(L"PcdFeatureFlag=%d\n", PcdGetBool(PcdFeatureFlag));
Ok, we are ready to build. Build your module and check out AutoGen.h
file Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h
:
#define _PCD_TOKEN_PcdFeatureFlag 0U
#define _PCD_SIZE_PcdFeatureFlag 1
#define _PCD_GET_MODE_SIZE_PcdFeatureFlag _PCD_SIZE_PcdFeatureFlag
#define _PCD_VALUE_PcdFeatureFlag ((BOOLEAN)1U)
extern const BOOLEAN _gPcd_FixedAtBuild_PcdFeatureFlag;
#define _PCD_GET_MODE_BOOL_PcdFeatureFlag _gPcd_FixedAtBuild_PcdFeatureFlag
//#define _PCD_SET_MODE_BOOL_PcdFeatureFlag ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
So both calls for our PCD would translate to:
FeaturePcdGet/PcdGetBool(PcdFeatureFlag) --> _PCD_GET_MODE_BOOL_PcdFeatureFlag --> _gPcd_FixedAtBuild_PcdFeatureFlag
And this _gPcd_FixedAtBuild_PcdFeatureFlag
variable is a constant from the AutoGen.c
file Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.c
:
GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdFeatureFlag; // = ((BOOLEAN)1U);
If you execute the application under OVMF the print statements would get you:
FS0:\> PCDLesson.efi
...
PcdFeatureFlag=1
PcdFeatureFlag=1
As you can see a feature PCD is similar to a BOOLEAN PCD defined under PcdsFixedAtBuild
section.
Compare how they are declared in the DEC file UefiLessonsPkg/UefiLessonsPkg.dec
:
[PcdsFixedAtBuild]
...
gUefiLessonsPkgTokenSpaceGuid.PcdBool|TRUE|BOOLEAN|0x69E88A63
[PcdsFeatureFlag]
gUefiLessonsPkgTokenSpaceGuid.PcdFeatureFlag|TRUE|BOOLEAN|0x16DD586E
And in the INF file UefiLessonsPkg/PCDLesson/PCDLesson.inf
:
[FixedPcd]
...
gUefiLessonsPkgTokenSpaceGuid.PcdBool
[FeaturePcd]
gUefiLessonsPkgTokenSpaceGuid.PcdFeatureFlag
As for the UefiLessonsPkg/PCDLesson/PCDLesson.c
in case of a FeatureFlag PCD you should use FeaturePcdGet
instead of FixedPcdGetBool
. But at the same time in both cases you can use PcdGetBool
function:
Print(L"PcdFeatureFlag=%d\n", FeaturePcdGet(PcdFeatureFlag));
Print(L"PcdFeatureFlag=%d\n", PcdGetBool(PcdFeatureFlag));
Print(L"PcdBool=%d\n", FixedPcdGetBool(PcdBool));
Print(L"PcdBool=%d\n", PcdGetBool(PcdBool));
Ok, now let's compare the code for the PCDs in the AutoGen files:
AutoGen.c
:
GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdBool = _PCD_VALUE_PcdBool;
GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_PcdFeatureFlag = _PCD_VALUE_PcdFeatureFlag;
AutoGen.h
:
#define _PCD_TOKEN_PcdBool 0U
#define _PCD_SIZE_PcdBool 1
#define _PCD_GET_MODE_SIZE_PcdBool _PCD_SIZE_PcdBool
#define _PCD_VALUE_PcdBool 1U
extern const BOOLEAN _gPcd_FixedAtBuild_PcdBool;
#define _PCD_GET_MODE_BOOL_PcdBool _gPcd_FixedAtBuild_PcdBool
//#define _PCD_SET_MODE_BOOL_PcdBool ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
#define _PCD_TOKEN_PcdFeatureFlag 0U
#define _PCD_SIZE_PcdFeatureFlag 1
#define _PCD_GET_MODE_SIZE_PcdFeatureFlag _PCD_SIZE_PcdFeatureFlag
#define _PCD_VALUE_PcdFeatureFlag ((BOOLEAN)1U)
extern const BOOLEAN _gPcd_FixedAtBuild_PcdFeatureFlag;
#define _PCD_GET_MODE_BOOL_PcdFeatureFlag _gPcd_FixedAtBuild_PcdFeatureFlag
//#define _PCD_SET_MODE_BOOL_PcdFeatureFlag ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
So as you see the differences are subtle. Therefore the FeaturePcd
is simply a syntactic sugar for BOOLEAN FixedAtBuild
PCD.