aboutsummaryrefslogtreecommitdiffstats
path: root/Lessons/Lesson_22/README.md
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.