Skip to content

Latest commit

 

History

History

Lesson_22

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

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

Comparision to [PcdsFixedAtBuild] BOOLEAN datum type PCD

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.