aboutsummaryrefslogtreecommitdiffstats
path: root/Lessons/Lesson_21/README.md
blob: 5ed3bc16d1b5680ce2b3d937b2c9d6fad49501d1 (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
In this lesson we are going to look at the PCD override capability.

# INF override

Create new `UINT32` PCD with a name `PcdInt32Override` and a default value equal to 42 (`UefiLessonsPkg/UefiLessonsPkg.dec`):
```
[PcdsFixedAtBuild]
  gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|42|UINT32|0x3CB8ABB8
```

Now when we would populate the PCD to our application via the INF file (`UefiLessonsPkg/PCDLesson/PCDLesson.inf`), we would use the PCD override syntax to change the default value of our PCD, which looks like this:
```
[FixedPcd]
  gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|43
```

If you build our application now, and look at the `Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/PCDLesson/PCDLesson/DEBUG/AutoGen.h`, you would see that `PcdInt32Override` default value was overriden:
```
...
#define _PCD_VALUE_PcdInt32Override  43U
...
```

You can even add a print statement to the `UefiLessonsPkg/PCDLesson/PCDLesson.c` to verify the result:
```
Print(L"PcdInt32Override=%d\n", FixedPcdGet32(PcdInt32Override));
```

If you rebuild the application and execute it under OVMF you would get:
```
FS0:\> PCDLesson.efi
...
PcdInt32Override=43
```

So it means that every App/Driver can override a PCD declared in `*.dec` file differently.

# DSC override

Besides overwriting PCDs locally in every module it is possible to override PCDs globally in the package via its DSC file.

Don't delete our INF override but another one in the DSC file (`UefiLessonsPkg/UefiLessonsPkg.dsc`). In this case we would override the default value to 44:
```
[PcdsFixedAtBuild]
  gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|44
```

If you build the app and execute in under OVMF now you would get:
```
FS0:\> PCDLesson.efi
...
PcdInt32Override=44
```

So as you can see there is some order of precedence for the override statments:
```
DEC < INF < DSC
```
- Declaration file (DEC) declares PCD with its default value
- Every App/Driver Information file (INF) can override the value of this PCD differently
- However a package description file that contains all these Apps/Drivers (DSC) can override this PCD for all of them

It is important to note that the DSC file in this case means a DSC file of the package that we build. And it is not necessary the same as the DSC file of the module origin package.

For the proof let's build our module as a part of the `OvmfPkg/OvmfPkgX64.dsc` package. For this add our application to the `[Components]` section in the `OvmfPkg/OvmfPkgX64.dsc` file:
```
[Components]
  ...
  UefiLessonsPkg/PCDLesson/PCDLesson.inf
```

Now build the OVMF image:
```
build --platform=OvmfPkg/OvmfPkgX64.dsc --arch=X64 --buildtarget=RELEASE --tagname=GCC5
```

The image of our application in this case would be not at the usual `Build/UefiLessonsPkg/RELEASE_GCC5/X64/PCDLesson.efi` path, but at the path
```
Build/OvmfX64/RELEASE_GCC5/X64/PCDLesson.efi
```

So if you copy this `.efi` file to our shared disk and execute it under OVMF image, you would get:
```
FS0:\> PCDLesson.efi
...
PcdInt32Override=43
```

As you can see the override from the `UefiLessonsPkg/UefiLessonsPkg.dsc` file doesn't work in this case.

For the DSC override you need to modify the DSC of the package that we build, i.e. `OvmfPkg/OvmfPkgX64.dsc` file:
```
[PcdsFixedAtBuild]
  ...
  gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|45
```

Rebuild OVMF image, copy updated application to the shared folder, and verify that now DSC override is working correctly:
```
FS0:\> PCDLesson.efi
...
PcdInt32Override=45
```

# FDF override

When we've added our application to the `[Components]` section in the `OvmfPkg/OvmfPkgX64.dsc` we said that we want to compile our application as part of the package. If we want to include our application to the final OVMF flash image we need to add it to the `FDF` file. We won't go into details of how it is done right now, just add the `INF UefiLessonsPkg/PCDLesson/PCDLesson.inf` statement to the end of `[FV.DXEFV]` setion:
```
[FV.DXEFV]
...
INF  UefiLessonsPkg/PCDLesson/PCDLesson.inf
#################################################
```

Important part for us now is that in the same FDF file we can override our PCD via the `SET` syntax. First put it in the `[Defines]` section:
```
[Defines]
...
SET gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override = 46
...
```

Rebuild and verify the override result:
```
FS0:\> PCDLesson.efi
...
PcdInt32Override=46
```

Now add another `SET` statement to the section of our module (which is `[FV.DXEFV]` in our case):
```
[FV.DXEFV]
...
INF  UefiLessonsPkg/PCDLesson/PCDLesson.inf
SET  gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override = 47
#################################################
```

This override should take precedence over the general one in the `[Defines]` section:
```
FS0:\> PCDLesson.efi
...
PcdInt32Override=47
```

# DSC in-module overrides

The next level of PCD override is the DSC in-module overrides. The override syntax in this case looks like this:
```
[Components]
  ...
  UefiLessonsPkg/PCDLesson/PCDLesson.inf {
    <PcdsFixedAtBuild>
      gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override|48
  }
```

This override would take precedence over the ones in the FDF file:
```
FS0:\> PCDLesson.efi
...
PcdInt32Override=48
```

# Overriding via command-line argument

Finally it is possible to override PCD via a command-line argument to the `build` command, for example:
```
build --platform=OvmfPkg/OvmfPkgX64.dsc \
      --arch=X64 \
      --buildtarget=RELEASE \
      --tagname=GCC5 \
      --pcd="gUefiLessonsPkgTokenSpaceGuid.PcdInt32Override=49"
```

Verify the override via our print statement:
```
FS0:\> PCDLesson.efi
...
PcdInt32Override=49
```

# Final words

In this lesson we've investgated some of the precedence rules of the PCD override.

The complete documentation on the subject can be found at this link [https://edk2-docs.gitbook.io/edk-ii-dsc-specification/2_dsc_overview/27_pcd_section_processing#2.7.3.8-precedence](https://edk2-docs.gitbook.io/edk-ii-dsc-specification/2_dsc_overview/27_pcd_section_processing#2.7.3.8-precedence)