blob: 2d23674800581e811972301678c44ae647898819 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
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](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.
|