]>
Commit | Line | Data |
---|---|---|
80408db0 | 1 | /** @file\r |
5944a83b LG |
2 | The driver internal functions are implmented here.\r |
3 | They build Pei PCD database, and provide access service to PCD database.\r | |
80408db0 | 4 | \r |
d1102dba | 5 | Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r |
9d510e61 | 6 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
80408db0 | 7 | \r |
80408db0 | 8 | **/\r |
80408db0 | 9 | \r |
10 | #include "Service.h"\r | |
11 | \r | |
96d6d004 SZ |
12 | /**\r |
13 | Get Local Token Number by Token Number.\r | |
14 | \r | |
15 | @param[in] Database PCD database.\r | |
16 | @param[in] TokenNumber The PCD token number.\r | |
17 | \r | |
18 | @return Local Token Number.\r | |
19 | **/\r | |
20 | UINT32\r | |
21 | GetLocalTokenNumber (\r | |
1436aea4 MK |
22 | IN PEI_PCD_DATABASE *Database,\r |
23 | IN UINTN TokenNumber\r | |
96d6d004 SZ |
24 | )\r |
25 | {\r | |
1436aea4 | 26 | UINT32 LocalTokenNumber;\r |
96d6d004 SZ |
27 | \r |
28 | //\r | |
29 | // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r | |
30 | // We have to decrement TokenNumber by 1 to make it usable\r | |
31 | // as the array index.\r | |
32 | //\r | |
33 | TokenNumber--;\r | |
34 | \r | |
35 | LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + TokenNumber);\r | |
36 | \r | |
96d6d004 SZ |
37 | return LocalTokenNumber;\r |
38 | }\r | |
39 | \r | |
40 | /**\r | |
41 | Get PCD type by Local Token Number.\r | |
42 | \r | |
43 | @param[in] LocalTokenNumber The PCD local token number.\r | |
44 | \r | |
45 | @return PCD type.\r | |
46 | **/\r | |
47 | EFI_PCD_TYPE\r | |
48 | GetPcdType (\r | |
1436aea4 | 49 | IN UINT32 LocalTokenNumber\r |
96d6d004 SZ |
50 | )\r |
51 | {\r | |
52 | switch (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) {\r | |
53 | case PCD_DATUM_TYPE_POINTER:\r | |
54 | return EFI_PCD_TYPE_PTR;\r | |
55 | case PCD_DATUM_TYPE_UINT8:\r | |
b5bd21b0 | 56 | if ((LocalTokenNumber & PCD_DATUM_TYPE_UINT8_BOOLEAN) == PCD_DATUM_TYPE_UINT8_BOOLEAN) {\r |
96d6d004 SZ |
57 | return EFI_PCD_TYPE_BOOL;\r |
58 | } else {\r | |
59 | return EFI_PCD_TYPE_8;\r | |
60 | }\r | |
1436aea4 | 61 | \r |
96d6d004 SZ |
62 | case PCD_DATUM_TYPE_UINT16:\r |
63 | return EFI_PCD_TYPE_16;\r | |
64 | case PCD_DATUM_TYPE_UINT32:\r | |
65 | return EFI_PCD_TYPE_32;\r | |
66 | case PCD_DATUM_TYPE_UINT64:\r | |
67 | return EFI_PCD_TYPE_64;\r | |
68 | default:\r | |
69 | ASSERT (FALSE);\r | |
70 | return EFI_PCD_TYPE_8;\r | |
71 | }\r | |
72 | }\r | |
73 | \r | |
74 | /**\r | |
75 | Get PCD name.\r | |
76 | \r | |
77 | @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName.\r | |
78 | If FALSE, need to get the full PCD name.\r | |
79 | @param[in] Database PCD database.\r | |
80 | @param[in] TokenNumber The PCD token number.\r | |
81 | \r | |
82 | @return The TokenSpaceCName or full PCD name.\r | |
83 | **/\r | |
84 | CHAR8 *\r | |
85 | GetPcdName (\r | |
1436aea4 MK |
86 | IN BOOLEAN OnlyTokenSpaceName,\r |
87 | IN PEI_PCD_DATABASE *Database,\r | |
88 | IN UINTN TokenNumber\r | |
96d6d004 SZ |
89 | )\r |
90 | {\r | |
1436aea4 MK |
91 | UINT8 *StringTable;\r |
92 | UINTN NameSize;\r | |
93 | PCD_NAME_INDEX *PcdNameIndex;\r | |
94 | CHAR8 *TokenSpaceName;\r | |
95 | CHAR8 *PcdName;\r | |
96 | CHAR8 *Name;\r | |
96d6d004 | 97 | \r |
85d0b97d | 98 | //\r |
d1102dba | 99 | // Return NULL when PCD name table is absent.\r |
85d0b97d SZ |
100 | //\r |
101 | if (Database->PcdNameTableOffset == 0) {\r | |
102 | return NULL;\r | |
103 | }\r | |
104 | \r | |
96d6d004 SZ |
105 | //\r |
106 | // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r | |
107 | // We have to decrement TokenNumber by 1 to make it usable\r | |
108 | // as the array index.\r | |
109 | //\r | |
110 | TokenNumber--;\r | |
111 | \r | |
1436aea4 | 112 | StringTable = (UINT8 *)Database + Database->StringTableOffset;\r |
96d6d004 SZ |
113 | \r |
114 | //\r | |
115 | // Get the PCD name index.\r | |
116 | //\r | |
1436aea4 | 117 | PcdNameIndex = (PCD_NAME_INDEX *)((UINT8 *)Database + Database->PcdNameTableOffset) + TokenNumber;\r |
96d6d004 | 118 | TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex];\r |
1436aea4 | 119 | PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex];\r |
96d6d004 SZ |
120 | \r |
121 | if (OnlyTokenSpaceName) {\r | |
122 | //\r | |
123 | // Only need to get the TokenSpaceCName.\r | |
124 | //\r | |
125 | Name = AllocateCopyPool (AsciiStrSize (TokenSpaceName), TokenSpaceName);\r | |
126 | } else {\r | |
127 | //\r | |
128 | // Need to get the full PCD name.\r | |
129 | //\r | |
e85e284e | 130 | NameSize = AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName);\r |
1436aea4 | 131 | Name = AllocateZeroPool (NameSize);\r |
f47fc1cb | 132 | ASSERT (Name != NULL);\r |
96d6d004 SZ |
133 | //\r |
134 | // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.\r | |
135 | //\r | |
e85e284e | 136 | AsciiStrCatS (Name, NameSize, TokenSpaceName);\r |
96d6d004 | 137 | Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.';\r |
d1102dba | 138 | AsciiStrCatS (Name, NameSize, PcdName);\r |
96d6d004 SZ |
139 | }\r |
140 | \r | |
141 | return Name;\r | |
142 | }\r | |
143 | \r | |
144 | /**\r | |
145 | Retrieve additional information associated with a PCD token.\r | |
146 | \r | |
147 | This includes information such as the type of value the TokenNumber is associated with as well as possible\r | |
148 | human readable name that is associated with the token.\r | |
149 | \r | |
150 | @param[in] Database PCD database.\r | |
151 | @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r | |
152 | @param[in] TokenNumber The PCD token number.\r | |
153 | @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r | |
d1102dba | 154 | The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r |
96d6d004 SZ |
155 | \r |
156 | @retval EFI_SUCCESS The PCD information was returned successfully\r | |
157 | @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r | |
158 | **/\r | |
159 | EFI_STATUS\r | |
160 | ExGetPcdInfo (\r | |
1436aea4 MK |
161 | IN PEI_PCD_DATABASE *Database,\r |
162 | IN CONST EFI_GUID *Guid,\r | |
163 | IN UINTN TokenNumber,\r | |
164 | OUT EFI_PCD_INFO *PcdInfo\r | |
96d6d004 SZ |
165 | )\r |
166 | {\r | |
1436aea4 MK |
167 | UINTN GuidTableIdx;\r |
168 | EFI_GUID *MatchGuid;\r | |
169 | EFI_GUID *GuidTable;\r | |
170 | DYNAMICEX_MAPPING *ExMapTable;\r | |
171 | UINTN Index;\r | |
172 | UINT32 LocalTokenNumber;\r | |
96d6d004 SZ |
173 | \r |
174 | GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);\r | |
1436aea4 | 175 | MatchGuid = ScanGuid (GuidTable, Database->GuidTableCount * sizeof (EFI_GUID), Guid);\r |
96d6d004 SZ |
176 | \r |
177 | if (MatchGuid == NULL) {\r | |
178 | return EFI_NOT_FOUND;\r | |
179 | }\r | |
180 | \r | |
181 | GuidTableIdx = MatchGuid - GuidTable;\r | |
182 | \r | |
183 | ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)Database + Database->ExMapTableOffset);\r | |
184 | \r | |
185 | //\r | |
186 | // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.\r | |
187 | //\r | |
188 | for (Index = 0; Index < Database->ExTokenCount; Index++) {\r | |
189 | if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r | |
190 | if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r | |
191 | //\r | |
192 | // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,\r | |
193 | // PcdSize to 0 and PcdName to the null-terminated ASCII string\r | |
194 | // associated with the token's namespace Guid.\r | |
195 | //\r | |
196 | PcdInfo->PcdType = EFI_PCD_TYPE_8;\r | |
197 | PcdInfo->PcdSize = 0;\r | |
198 | //\r | |
199 | // Here use one representative in the token space to get the TokenSpaceCName.\r | |
d1102dba | 200 | //\r |
96d6d004 SZ |
201 | PcdInfo->PcdName = GetPcdName (TRUE, Database, ExMapTable[Index].TokenNumber);\r |
202 | return EFI_SUCCESS;\r | |
203 | } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {\r | |
204 | PcdInfo->PcdSize = PeiPcdGetSize (ExMapTable[Index].TokenNumber);\r | |
205 | LocalTokenNumber = GetLocalTokenNumber (Database, ExMapTable[Index].TokenNumber);\r | |
206 | PcdInfo->PcdType = GetPcdType (LocalTokenNumber);\r | |
207 | PcdInfo->PcdName = GetPcdName (FALSE, Database, ExMapTable[Index].TokenNumber);\r | |
208 | return EFI_SUCCESS;\r | |
209 | }\r | |
210 | }\r | |
211 | }\r | |
212 | \r | |
213 | return EFI_NOT_FOUND;\r | |
214 | }\r | |
215 | \r | |
216 | /**\r | |
217 | Retrieve additional information associated with a PCD token.\r | |
218 | \r | |
219 | This includes information such as the type of value the TokenNumber is associated with as well as possible\r | |
220 | human readable name that is associated with the token.\r | |
221 | \r | |
222 | @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r | |
223 | @param[in] TokenNumber The PCD token number.\r | |
224 | @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r | |
225 | The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r | |
226 | \r | |
227 | @retval EFI_SUCCESS The PCD information was returned successfully.\r | |
228 | @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r | |
229 | **/\r | |
230 | EFI_STATUS\r | |
231 | PeiGetPcdInfo (\r | |
1436aea4 MK |
232 | IN CONST EFI_GUID *Guid,\r |
233 | IN UINTN TokenNumber,\r | |
234 | OUT EFI_PCD_INFO *PcdInfo\r | |
96d6d004 SZ |
235 | )\r |
236 | {\r | |
1436aea4 MK |
237 | PEI_PCD_DATABASE *PeiPcdDb;\r |
238 | BOOLEAN PeiExMapTableEmpty;\r | |
239 | UINTN PeiNexTokenNumber;\r | |
240 | UINT32 LocalTokenNumber;\r | |
96d6d004 | 241 | \r |
96d6d004 SZ |
242 | ASSERT (PcdInfo != NULL);\r |
243 | \r | |
244 | PeiPcdDb = GetPcdDatabase ();\r | |
245 | PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r | |
246 | \r | |
247 | if (PeiPcdDb->ExTokenCount == 0) {\r | |
248 | PeiExMapTableEmpty = TRUE;\r | |
249 | } else {\r | |
250 | PeiExMapTableEmpty = FALSE;\r | |
251 | }\r | |
252 | \r | |
253 | if (Guid == NULL) {\r | |
254 | if (TokenNumber > PeiNexTokenNumber) {\r | |
255 | return EFI_NOT_FOUND;\r | |
256 | } else if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r | |
257 | //\r | |
258 | // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,\r | |
259 | // PcdSize to 0 and PcdName to NULL for default Token Space.\r | |
260 | //\r | |
261 | PcdInfo->PcdType = EFI_PCD_TYPE_8;\r | |
262 | PcdInfo->PcdSize = 0;\r | |
263 | PcdInfo->PcdName = NULL;\r | |
264 | } else {\r | |
265 | PcdInfo->PcdSize = PeiPcdGetSize (TokenNumber);\r | |
266 | LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber);\r | |
267 | PcdInfo->PcdType = GetPcdType (LocalTokenNumber);\r | |
268 | PcdInfo->PcdName = GetPcdName (FALSE, PeiPcdDb, TokenNumber);\r | |
269 | }\r | |
1436aea4 | 270 | \r |
96d6d004 SZ |
271 | return EFI_SUCCESS;\r |
272 | } else {\r | |
273 | if (PeiExMapTableEmpty) {\r | |
274 | return EFI_NOT_FOUND;\r | |
275 | }\r | |
1436aea4 | 276 | \r |
96d6d004 SZ |
277 | return ExGetPcdInfo (\r |
278 | PeiPcdDb,\r | |
279 | Guid,\r | |
280 | TokenNumber,\r | |
281 | PcdInfo\r | |
282 | );\r | |
283 | }\r | |
284 | }\r | |
285 | \r | |
80408db0 | 286 | /**\r |
287 | The function registers the CallBackOnSet fucntion\r | |
288 | according to TokenNumber and EFI_GUID space.\r | |
289 | \r | |
fc547e08 | 290 | @param ExTokenNumber The token number.\r |
80408db0 | 291 | @param Guid The GUID space.\r |
292 | @param CallBackFunction The Callback function to be registered.\r | |
293 | @param Register To register or unregister the callback function.\r | |
294 | \r | |
295 | @retval EFI_SUCCESS If the Callback function is registered.\r | |
296 | @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.\r | |
297 | @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free\r | |
298 | slot left in the CallbackFnTable.\r | |
8ec8bed4 | 299 | @retval EFI_INVALID_PARAMETER If the callback function want to be de-registered can not be found.\r |
fc547e08 | 300 | **/\r |
80408db0 | 301 | EFI_STATUS\r |
302 | PeiRegisterCallBackWorker (\r | |
1436aea4 MK |
303 | IN UINTN ExTokenNumber,\r |
304 | IN CONST EFI_GUID *Guid OPTIONAL,\r | |
305 | IN PCD_PPI_CALLBACK CallBackFunction,\r | |
306 | IN BOOLEAN Register\r | |
307 | )\r | |
80408db0 | 308 | {\r |
1436aea4 MK |
309 | EFI_HOB_GUID_TYPE *GuidHob;\r |
310 | PCD_PPI_CALLBACK *CallbackTable;\r | |
311 | PCD_PPI_CALLBACK Compare;\r | |
312 | PCD_PPI_CALLBACK Assign;\r | |
313 | UINT32 LocalTokenNumber;\r | |
314 | UINT32 LocalTokenCount;\r | |
315 | UINTN PeiNexTokenNumber;\r | |
316 | UINTN TokenNumber;\r | |
317 | UINTN Idx;\r | |
318 | PEI_PCD_DATABASE *PeiPcdDb;\r | |
319 | \r | |
320 | PeiPcdDb = GetPcdDatabase ();\r | |
419db80b BF |
321 | LocalTokenCount = PeiPcdDb->LocalTokenCount;\r |
322 | PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r | |
80408db0 | 323 | \r |
324 | if (Guid == NULL) {\r | |
325 | TokenNumber = ExTokenNumber;\r | |
80408db0 | 326 | //\r |
327 | // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r | |
328 | // We have to decrement TokenNumber by 1 to make it usable\r | |
329 | // as the array index.\r | |
330 | //\r | |
331 | TokenNumber--;\r | |
419db80b | 332 | ASSERT (TokenNumber + 1 < (PeiNexTokenNumber + 1));\r |
80408db0 | 333 | } else {\r |
334 | TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r | |
86714ccd | 335 | if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r |
336 | return EFI_NOT_FOUND;\r | |
337 | }\r | |
1436aea4 | 338 | \r |
80408db0 | 339 | //\r |
340 | // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r | |
341 | // We have to decrement TokenNumber by 1 to make it usable\r | |
342 | // as the array index.\r | |
343 | //\r | |
344 | TokenNumber--;\r | |
345 | // EBC compiler is very choosy. It may report warning about comparison\r | |
d1102dba | 346 | // between UINTN and 0 . So we add 1 in each size of the\r |
80408db0 | 347 | // comparison.\r |
419db80b | 348 | ASSERT ((TokenNumber + 1) < (LocalTokenCount + 1));\r |
80408db0 | 349 | }\r |
350 | \r | |
419db80b | 351 | LocalTokenNumber = *((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber);\r |
80408db0 | 352 | \r |
353 | //\r | |
354 | // We don't support SET for HII and VPD type PCD entry in PEI phase.\r | |
355 | // So we will assert if any register callback for such PCD entry.\r | |
356 | //\r | |
357 | ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0);\r | |
358 | ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0);\r | |
359 | \r | |
96cb78a1 | 360 | GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);\r |
80408db0 | 361 | ASSERT (GuidHob != NULL);\r |
d1102dba | 362 | \r |
80408db0 | 363 | CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r |
188e4e84 | 364 | CallbackTable = CallbackTable + (TokenNumber * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r |
80408db0 | 365 | \r |
1436aea4 MK |
366 | Compare = Register ? NULL : CallBackFunction;\r |
367 | Assign = Register ? CallBackFunction : NULL;\r | |
80408db0 | 368 | \r |
188e4e84 | 369 | for (Idx = 0; Idx < PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r |
80408db0 | 370 | if (CallbackTable[Idx] == Compare) {\r |
371 | CallbackTable[Idx] = Assign;\r | |
372 | return EFI_SUCCESS;\r | |
373 | }\r | |
374 | }\r | |
375 | \r | |
1436aea4 | 376 | return Register ? EFI_OUT_OF_RESOURCES : EFI_INVALID_PARAMETER;\r |
80408db0 | 377 | }\r |
378 | \r | |
419db80b | 379 | /**\r |
d1102dba | 380 | Find the Pcd database.\r |
419db80b BF |
381 | \r |
382 | @param FileHandle Handle of the file the external PCD database binary located.\r | |
383 | \r | |
384 | @retval The base address of external PCD database binary.\r | |
385 | @retval NULL Return NULL if not find.\r | |
386 | **/\r | |
387 | VOID *\r | |
388 | LocateExPcdBinary (\r | |
1436aea4 | 389 | IN EFI_PEI_FILE_HANDLE FileHandle\r |
419db80b BF |
390 | )\r |
391 | {\r | |
1436aea4 MK |
392 | EFI_STATUS Status;\r |
393 | VOID *PcdDb;\r | |
419db80b | 394 | \r |
1436aea4 | 395 | PcdDb = NULL;\r |
419db80b BF |
396 | \r |
397 | ASSERT (FileHandle != NULL);\r | |
398 | \r | |
399 | Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb);\r | |
400 | ASSERT_EFI_ERROR (Status);\r | |
401 | \r | |
402 | //\r | |
403 | // Check the first bytes (Header Signature Guid) and build version.\r | |
404 | //\r | |
405 | if (!CompareGuid (PcdDb, &gPcdDataBaseSignatureGuid) ||\r | |
1436aea4 MK |
406 | (((PEI_PCD_DATABASE *)PcdDb)->BuildVersion != PCD_SERVICE_PEIM_VERSION))\r |
407 | {\r | |
419db80b BF |
408 | ASSERT (FALSE);\r |
409 | }\r | |
1436aea4 | 410 | \r |
419db80b BF |
411 | return PcdDb;\r |
412 | }\r | |
413 | \r | |
80408db0 | 414 | /**\r |
415 | The function builds the PCD database.\r | |
419db80b BF |
416 | \r |
417 | @param FileHandle Handle of the file the external PCD database binary located.\r | |
418 | \r | |
96d6d004 | 419 | @return Pointer to PCD database.\r |
fc547e08 | 420 | **/\r |
96d6d004 | 421 | PEI_PCD_DATABASE *\r |
80408db0 | 422 | BuildPcdDatabase (\r |
1436aea4 | 423 | IN EFI_PEI_FILE_HANDLE FileHandle\r |
80408db0 | 424 | )\r |
425 | {\r | |
1436aea4 MK |
426 | PEI_PCD_DATABASE *Database;\r |
427 | PEI_PCD_DATABASE *PeiPcdDbBinary;\r | |
428 | VOID *CallbackFnTable;\r | |
429 | UINTN SizeOfCallbackFnTable;\r | |
419db80b BF |
430 | \r |
431 | //\r | |
432 | // Locate the external PCD database binary for one section of current FFS\r | |
433 | //\r | |
434 | PeiPcdDbBinary = LocateExPcdBinary (FileHandle);\r | |
80408db0 | 435 | \r |
1436aea4 | 436 | ASSERT (PeiPcdDbBinary != NULL);\r |
419db80b BF |
437 | \r |
438 | Database = BuildGuidHob (&gPcdDataBaseHobGuid, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize);\r | |
439 | \r | |
440 | ZeroMem (Database, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize);\r | |
80408db0 | 441 | \r |
442 | //\r | |
419db80b | 443 | // PeiPcdDbBinary is smaller than Database\r |
80408db0 | 444 | //\r |
419db80b | 445 | CopyMem (Database, PeiPcdDbBinary, PeiPcdDbBinary->Length);\r |
80408db0 | 446 | \r |
419db80b | 447 | SizeOfCallbackFnTable = Database->LocalTokenCount * sizeof (PCD_PPI_CALLBACK) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry);\r |
80408db0 | 448 | \r |
96cb78a1 | 449 | CallbackFnTable = BuildGuidHob (&gEfiCallerIdGuid, SizeOfCallbackFnTable);\r |
d1102dba | 450 | \r |
80408db0 | 451 | ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);\r |
96d6d004 SZ |
452 | \r |
453 | return Database;\r | |
80408db0 | 454 | }\r |
455 | \r | |
80408db0 | 456 | /**\r |
457 | The function is provided by PCD PEIM and PCD DXE driver to\r | |
458 | do the work of reading a HII variable from variable service.\r | |
459 | \r | |
460 | @param VariableGuid The Variable GUID.\r | |
461 | @param VariableName The Variable Name.\r | |
462 | @param VariableData The output data.\r | |
463 | @param VariableSize The size of the variable.\r | |
464 | \r | |
465 | @retval EFI_SUCCESS Operation successful.\r | |
466 | @retval EFI_NOT_FOUND Variablel not found.\r | |
fc547e08 | 467 | **/\r |
80408db0 | 468 | EFI_STATUS\r |
469 | GetHiiVariable (\r | |
1436aea4 MK |
470 | IN CONST EFI_GUID *VariableGuid,\r |
471 | IN UINT16 *VariableName,\r | |
472 | OUT VOID **VariableData,\r | |
473 | OUT UINTN *VariableSize\r | |
80408db0 | 474 | )\r |
475 | {\r | |
1436aea4 MK |
476 | UINTN Size;\r |
477 | EFI_STATUS Status;\r | |
478 | VOID *Buffer;\r | |
479 | EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;\r | |
80408db0 | 480 | \r |
1436aea4 | 481 | Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&VariablePpi);\r |
80408db0 | 482 | ASSERT_EFI_ERROR (Status);\r |
483 | \r | |
1436aea4 | 484 | Size = 0;\r |
97a079ed A |
485 | Status = VariablePpi->GetVariable (\r |
486 | VariablePpi,\r | |
80408db0 | 487 | VariableName,\r |
1436aea4 | 488 | (EFI_GUID *)VariableGuid,\r |
80408db0 | 489 | NULL,\r |
490 | &Size,\r | |
491 | NULL\r | |
97a079ed | 492 | );\r |
80408db0 | 493 | \r |
e5618791 | 494 | if (Status == EFI_BUFFER_TOO_SMALL) {\r |
80408db0 | 495 | Status = PeiServicesAllocatePool (Size, &Buffer);\r |
496 | ASSERT_EFI_ERROR (Status);\r | |
497 | \r | |
97a079ed | 498 | Status = VariablePpi->GetVariable (\r |
1436aea4 MK |
499 | VariablePpi,\r |
500 | (UINT16 *)VariableName,\r | |
501 | (EFI_GUID *)VariableGuid,\r | |
502 | NULL,\r | |
503 | &Size,\r | |
504 | Buffer\r | |
505 | );\r | |
80408db0 | 506 | ASSERT_EFI_ERROR (Status);\r |
507 | \r | |
508 | *VariableSize = Size;\r | |
509 | *VariableData = Buffer;\r | |
510 | \r | |
511 | return EFI_SUCCESS;\r | |
e5618791 | 512 | }\r |
80408db0 | 513 | \r |
fc547e08 | 514 | return EFI_NOT_FOUND;\r |
80408db0 | 515 | }\r |
516 | \r | |
fc547e08 | 517 | /**\r |
d1102dba | 518 | Invoke the callback function when dynamic PCD entry was set, if this PCD entry\r |
fc547e08 | 519 | has registered callback function.\r |
80408db0 | 520 | \r |
fc547e08 | 521 | @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx\r |
522 | type PCD.\r | |
523 | @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type\r | |
524 | PCD.\r | |
525 | @param TokenNumber PCD token number generated by build tools.\r | |
526 | @param Data Value want to be set for this PCD entry\r | |
527 | @param Size The size of value\r | |
80408db0 | 528 | \r |
fc547e08 | 529 | **/\r |
80408db0 | 530 | VOID\r |
531 | InvokeCallbackOnSet (\r | |
1436aea4 MK |
532 | UINTN ExTokenNumber,\r |
533 | CONST EFI_GUID *Guid OPTIONAL,\r | |
534 | UINTN TokenNumber,\r | |
535 | VOID *Data,\r | |
536 | UINTN Size\r | |
80408db0 | 537 | )\r |
538 | {\r | |
1436aea4 MK |
539 | EFI_HOB_GUID_TYPE *GuidHob;\r |
540 | PCD_PPI_CALLBACK *CallbackTable;\r | |
541 | UINTN Idx;\r | |
542 | PEI_PCD_DATABASE *PeiPcdDb;\r | |
543 | UINT32 LocalTokenCount;\r | |
80408db0 | 544 | \r |
545 | //\r | |
546 | // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r | |
547 | // We have to decrement TokenNumber by 1 to make it usable\r | |
548 | // as the array index.\r | |
549 | //\r | |
550 | TokenNumber--;\r | |
419db80b BF |
551 | \r |
552 | PeiPcdDb = GetPcdDatabase ();\r | |
553 | LocalTokenCount = PeiPcdDb->LocalTokenCount;\r | |
554 | \r | |
80408db0 | 555 | if (Guid == NULL) {\r |
556 | // EBC compiler is very choosy. It may report warning about comparison\r | |
d1102dba | 557 | // between UINTN and 0 . So we add 1 in each size of the\r |
80408db0 | 558 | // comparison.\r |
419db80b | 559 | ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r |
80408db0 | 560 | }\r |
561 | \r | |
96cb78a1 | 562 | GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);\r |
80408db0 | 563 | ASSERT (GuidHob != NULL);\r |
d1102dba | 564 | \r |
80408db0 | 565 | CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r |
566 | \r | |
188e4e84 | 567 | CallbackTable += (TokenNumber * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r |
80408db0 | 568 | \r |
188e4e84 | 569 | for (Idx = 0; Idx < PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r |
80408db0 | 570 | if (CallbackTable[Idx] != NULL) {\r |
1436aea4 MK |
571 | CallbackTable[Idx](Guid,\r |
572 | (Guid == NULL) ? (TokenNumber + 1) : ExTokenNumber,\r | |
573 | Data,\r | |
574 | Size\r | |
575 | );\r | |
80408db0 | 576 | }\r |
577 | }\r | |
80408db0 | 578 | }\r |
579 | \r | |
fc547e08 | 580 | /**\r |
581 | Wrapper function for setting non-pointer type value for a PCD entry.\r | |
582 | \r | |
583 | @param TokenNumber Pcd token number autogenerated by build tools.\r | |
584 | @param Data Value want to be set for PCD entry\r | |
585 | @param Size Size of value.\r | |
80408db0 | 586 | \r |
fc547e08 | 587 | @return status of SetWorker.\r |
80408db0 | 588 | \r |
fc547e08 | 589 | **/\r |
80408db0 | 590 | EFI_STATUS\r |
591 | SetValueWorker (\r | |
1436aea4 MK |
592 | IN UINTN TokenNumber,\r |
593 | IN VOID *Data,\r | |
594 | IN UINTN Size\r | |
80408db0 | 595 | )\r |
596 | {\r | |
597 | return SetWorker (TokenNumber, Data, &Size, FALSE);\r | |
598 | }\r | |
599 | \r | |
fc547e08 | 600 | /**\r |
601 | Set value for an PCD entry\r | |
602 | \r | |
603 | @param TokenNumber Pcd token number autogenerated by build tools.\r | |
604 | @param Data Value want to be set for PCD entry\r | |
605 | @param Size Size of value.\r | |
606 | @param PtrType If TRUE, the type of PCD entry's value is Pointer.\r | |
607 | If False, the type of PCD entry's value is not Pointer.\r | |
608 | \r | |
609 | @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set.\r | |
610 | @retval EFI_INVALID_PARAMETER If Size can not be set to size table.\r | |
149fb6d6 | 611 | @retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database.\r |
fc547e08 | 612 | @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in\r |
613 | range of UINT8, UINT16, UINT32, UINT64\r | |
d1102dba | 614 | @retval EFI_NOT_FOUND Can not find the PCD type according to token number.\r |
fc547e08 | 615 | **/\r |
80408db0 | 616 | EFI_STATUS\r |
617 | SetWorker (\r | |
1436aea4 MK |
618 | IN UINTN TokenNumber,\r |
619 | IN VOID *Data,\r | |
620 | IN OUT UINTN *Size,\r | |
621 | IN BOOLEAN PtrType\r | |
80408db0 | 622 | )\r |
623 | {\r | |
1436aea4 MK |
624 | UINT32 LocalTokenNumber;\r |
625 | UINTN PeiNexTokenNumber;\r | |
626 | PEI_PCD_DATABASE *PeiPcdDb;\r | |
627 | STRING_HEAD StringTableIdx;\r | |
628 | UINTN Offset;\r | |
629 | VOID *InternalData;\r | |
630 | UINTN MaxSize;\r | |
631 | UINT32 LocalTokenCount;\r | |
632 | \r | |
633 | if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {\r | |
80408db0 | 634 | return EFI_UNSUPPORTED;\r |
635 | }\r | |
d1102dba | 636 | \r |
80408db0 | 637 | //\r |
638 | // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r | |
639 | // We have to decrement TokenNumber by 1 to make it usable\r | |
640 | // as the array index.\r | |
641 | //\r | |
642 | TokenNumber--;\r | |
419db80b BF |
643 | PeiPcdDb = GetPcdDatabase ();\r |
644 | LocalTokenCount = PeiPcdDb->LocalTokenCount;\r | |
80408db0 | 645 | \r |
646 | // EBC compiler is very choosy. It may report warning about comparison\r | |
d1102dba | 647 | // between UINTN and 0 . So we add 1 in each size of the\r |
80408db0 | 648 | // comparison.\r |
419db80b | 649 | ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r |
80408db0 | 650 | \r |
8ec8bed4 | 651 | if (PtrType) {\r |
64894410 LG |
652 | //\r |
653 | // Get MaxSize first, then check new size with max buffer size.\r | |
654 | //\r | |
655 | GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r | |
656 | if (*Size > MaxSize) {\r | |
cb40609c | 657 | *Size = MaxSize;\r |
8ec8bed4 | 658 | return EFI_INVALID_PARAMETER;\r |
659 | }\r | |
660 | } else {\r | |
661 | if (*Size != PeiPcdGetSize (TokenNumber + 1)) {\r | |
662 | return EFI_INVALID_PARAMETER;\r | |
663 | }\r | |
80408db0 | 664 | }\r |
665 | \r | |
666 | //\r | |
667 | // We only invoke the callback function for Dynamic Type PCD Entry.\r | |
668 | // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX\r | |
669 | // type PCD entry in ExSetWorker.\r | |
670 | //\r | |
419db80b BF |
671 | PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r |
672 | if (TokenNumber + 1 < PeiNexTokenNumber + 1) {\r | |
80408db0 | 673 | InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r |
674 | }\r | |
675 | \r | |
96d6d004 | 676 | LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);\r |
80408db0 | 677 | \r |
1436aea4 MK |
678 | Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r |
679 | InternalData = (VOID *)((UINT8 *)PeiPcdDb + Offset);\r | |
d1102dba | 680 | \r |
80408db0 | 681 | switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r |
682 | case PCD_TYPE_VPD:\r | |
683 | case PCD_TYPE_HII:\r | |
6ac15f7c | 684 | case PCD_TYPE_HII|PCD_TYPE_STRING:\r |
80408db0 | 685 | {\r |
686 | ASSERT (FALSE);\r | |
687 | return EFI_INVALID_PARAMETER;\r | |
688 | }\r | |
689 | \r | |
690 | case PCD_TYPE_STRING:\r | |
691 | if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r | |
6cfc7292 | 692 | StringTableIdx = *((STRING_HEAD *)InternalData);\r |
419db80b | 693 | CopyMem ((UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset + StringTableIdx, Data, *Size);\r |
80408db0 | 694 | return EFI_SUCCESS;\r |
695 | } else {\r | |
696 | return EFI_INVALID_PARAMETER;\r | |
697 | }\r | |
698 | \r | |
699 | case PCD_TYPE_DATA:\r | |
700 | {\r | |
701 | if (PtrType) {\r | |
702 | if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r | |
703 | CopyMem (InternalData, Data, *Size);\r | |
704 | return EFI_SUCCESS;\r | |
705 | } else {\r | |
706 | return EFI_INVALID_PARAMETER;\r | |
707 | }\r | |
708 | }\r | |
709 | \r | |
710 | switch (*Size) {\r | |
1436aea4 MK |
711 | case sizeof (UINT8):\r |
712 | *((UINT8 *)InternalData) = *((UINT8 *)Data);\r | |
80408db0 | 713 | return EFI_SUCCESS;\r |
714 | \r | |
1436aea4 MK |
715 | case sizeof (UINT16):\r |
716 | *((UINT16 *)InternalData) = *((UINT16 *)Data);\r | |
80408db0 | 717 | return EFI_SUCCESS;\r |
718 | \r | |
1436aea4 MK |
719 | case sizeof (UINT32):\r |
720 | *((UINT32 *)InternalData) = *((UINT32 *)Data);\r | |
80408db0 | 721 | return EFI_SUCCESS;\r |
722 | \r | |
1436aea4 MK |
723 | case sizeof (UINT64):\r |
724 | *((UINT64 *)InternalData) = *((UINT64 *)Data);\r | |
80408db0 | 725 | return EFI_SUCCESS;\r |
726 | \r | |
727 | default:\r | |
728 | ASSERT (FALSE);\r | |
729 | return EFI_NOT_FOUND;\r | |
730 | }\r | |
731 | }\r | |
80408db0 | 732 | }\r |
733 | \r | |
734 | ASSERT (FALSE);\r | |
735 | return EFI_NOT_FOUND;\r | |
80408db0 | 736 | }\r |
737 | \r | |
fc547e08 | 738 | /**\r |
739 | Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD.\r | |
80408db0 | 740 | \r |
fc547e08 | 741 | @param ExTokenNumber Token number for dynamic-ex PCD.\r |
742 | @param Guid Token space guid for dynamic-ex PCD.\r | |
743 | @param Data Value want to be set.\r | |
744 | @param SetSize The size of value.\r | |
80408db0 | 745 | \r |
fc547e08 | 746 | @return status of ExSetWorker().\r |
747 | \r | |
748 | **/\r | |
80408db0 | 749 | EFI_STATUS\r |
750 | ExSetValueWorker (\r | |
1436aea4 MK |
751 | IN UINTN ExTokenNumber,\r |
752 | IN CONST EFI_GUID *Guid,\r | |
753 | IN VOID *Data,\r | |
754 | IN UINTN Size\r | |
80408db0 | 755 | )\r |
756 | {\r | |
757 | return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE);\r | |
758 | }\r | |
759 | \r | |
fc547e08 | 760 | /**\r |
419db80b | 761 | Set value for a dynamic-ex PCD entry.\r |
d1102dba LG |
762 | \r |
763 | This routine find the local token number according to dynamic-ex PCD's token\r | |
fc547e08 | 764 | space guid and token number firstly, and invoke callback function if this PCD\r |
765 | entry registered callback function. Finally, invoken general SetWorker to set\r | |
766 | PCD value.\r | |
d1102dba | 767 | \r |
fc547e08 | 768 | @param ExTokenNumber Dynamic-ex PCD token number.\r |
769 | @param Guid Token space guid for dynamic-ex PCD.\r | |
770 | @param Data PCD value want to be set\r | |
771 | @param SetSize Size of value.\r | |
772 | @param PtrType If TRUE, this PCD entry is pointer type.\r | |
773 | If FALSE, this PCD entry is not pointer type.\r | |
80408db0 | 774 | \r |
fc547e08 | 775 | @return status of SetWorker().\r |
80408db0 | 776 | \r |
fc547e08 | 777 | **/\r |
80408db0 | 778 | EFI_STATUS\r |
779 | ExSetWorker (\r | |
1436aea4 MK |
780 | IN UINTN ExTokenNumber,\r |
781 | IN CONST EFI_GUID *Guid,\r | |
782 | IN VOID *Data,\r | |
783 | IN OUT UINTN *Size,\r | |
784 | IN BOOLEAN PtrType\r | |
80408db0 | 785 | )\r |
786 | {\r | |
1436aea4 | 787 | UINTN TokenNumber;\r |
80408db0 | 788 | \r |
1436aea4 | 789 | if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {\r |
80408db0 | 790 | return EFI_UNSUPPORTED;\r |
791 | }\r | |
792 | \r | |
793 | TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r | |
86714ccd | 794 | if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r |
795 | return EFI_NOT_FOUND;\r | |
796 | }\r | |
d1102dba | 797 | \r |
80408db0 | 798 | InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size);\r |
799 | \r | |
800 | return SetWorker (TokenNumber, Data, Size, PtrType);\r | |
80408db0 | 801 | }\r |
802 | \r | |
fc547e08 | 803 | /**\r |
804 | Wrapper function for get PCD value for dynamic-ex PCD.\r | |
80408db0 | 805 | \r |
fc547e08 | 806 | @param Guid Token space guid for dynamic-ex PCD.\r |
807 | @param ExTokenNumber Token number for dyanmic-ex PCD.\r | |
808 | @param GetSize The size of dynamic-ex PCD value.\r | |
80408db0 | 809 | \r |
fc547e08 | 810 | @return PCD entry in PCD database.\r |
80408db0 | 811 | \r |
fc547e08 | 812 | **/\r |
80408db0 | 813 | VOID *\r |
814 | ExGetWorker (\r | |
815 | IN CONST EFI_GUID *Guid,\r | |
816 | IN UINTN ExTokenNumber,\r | |
817 | IN UINTN GetSize\r | |
818 | )\r | |
d1102dba | 819 | {\r |
80408db0 | 820 | return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);\r |
821 | }\r | |
822 | \r | |
fc547e08 | 823 | /**\r |
824 | Get the PCD entry pointer in PCD database.\r | |
d1102dba | 825 | \r |
fc547e08 | 826 | This routine will visit PCD database to find the PCD entry according to given\r |
d1102dba LG |
827 | token number. The given token number is autogened by build tools and it will be\r |
828 | translated to local token number. Local token number contains PCD's type and\r | |
fc547e08 | 829 | offset of PCD entry in PCD database.\r |
80408db0 | 830 | \r |
fc547e08 | 831 | @param TokenNumber Token's number, it is autogened by build tools\r |
832 | @param GetSize The size of token's value\r | |
80408db0 | 833 | \r |
fc547e08 | 834 | @return PCD entry pointer in PCD database\r |
80408db0 | 835 | \r |
fc547e08 | 836 | **/\r |
80408db0 | 837 | VOID *\r |
838 | GetWorker (\r | |
1436aea4 MK |
839 | IN UINTN TokenNumber,\r |
840 | IN UINTN GetSize\r | |
80408db0 | 841 | )\r |
842 | {\r | |
1436aea4 MK |
843 | UINT32 Offset;\r |
844 | EFI_GUID *Guid;\r | |
845 | UINT16 *Name;\r | |
846 | VARIABLE_HEAD *VariableHead;\r | |
847 | EFI_STATUS Status;\r | |
848 | UINTN DataSize;\r | |
849 | VOID *Data;\r | |
850 | UINT8 *StringTable;\r | |
851 | STRING_HEAD StringTableIdx;\r | |
852 | PEI_PCD_DATABASE *PeiPcdDb;\r | |
853 | UINT32 LocalTokenNumber;\r | |
854 | UINT32 LocalTokenCount;\r | |
855 | UINT8 *VaraiableDefaultBuffer;\r | |
856 | UINTN VpdBaseAddress;\r | |
80408db0 | 857 | \r |
858 | //\r | |
859 | // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r | |
860 | // We have to decrement TokenNumber by 1 to make it usable\r | |
861 | // as the array index.\r | |
862 | //\r | |
863 | TokenNumber--;\r | |
864 | \r | |
419db80b BF |
865 | PeiPcdDb = GetPcdDatabase ();\r |
866 | LocalTokenCount = PeiPcdDb->LocalTokenCount;\r | |
867 | \r | |
80408db0 | 868 | // EBC compiler is very choosy. It may report warning about comparison\r |
d1102dba | 869 | // between UINTN and 0 . So we add 1 in each size of the\r |
80408db0 | 870 | // comparison.\r |
419db80b | 871 | ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r |
80408db0 | 872 | \r |
1436aea4 | 873 | ASSERT ((GetSize == PeiPcdGetSize (TokenNumber + 1)) || (GetSize == 0));\r |
80408db0 | 874 | \r |
96d6d004 | 875 | LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);\r |
80408db0 | 876 | \r |
877 | Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r | |
419db80b BF |
878 | StringTable = (UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset;\r |
879 | \r | |
80408db0 | 880 | switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r |
881 | case PCD_TYPE_VPD:\r | |
882 | {\r | |
1436aea4 MK |
883 | VPD_HEAD *VpdHead;\r |
884 | VpdHead = (VPD_HEAD *)((UINT8 *)PeiPcdDb + Offset);\r | |
534efca0 LG |
885 | \r |
886 | //\r | |
887 | // PcdVpdBaseAddress64 is DynamicEx PCD only. So, PeiPcdGet64Ex() is used to get its value.\r | |
888 | //\r | |
1436aea4 | 889 | VpdBaseAddress = (UINTN)PeiPcdGet64Ex (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdVpdBaseAddress64));\r |
534efca0 LG |
890 | if (VpdBaseAddress == 0) {\r |
891 | //\r | |
892 | // PcdVpdBaseAddress64 is not set, get value from PcdVpdBaseAddress.\r | |
893 | //\r | |
1436aea4 | 894 | VpdBaseAddress = (UINTN)PcdGet32 (PcdVpdBaseAddress);\r |
534efca0 | 895 | }\r |
1436aea4 | 896 | \r |
534efca0 LG |
897 | ASSERT (VpdBaseAddress != 0);\r |
898 | return (VOID *)(VpdBaseAddress + VpdHead->Offset);\r | |
80408db0 | 899 | }\r |
d1102dba | 900 | \r |
6ac15f7c | 901 | case PCD_TYPE_HII|PCD_TYPE_STRING:\r |
80408db0 | 902 | case PCD_TYPE_HII:\r |
903 | {\r | |
1436aea4 | 904 | VariableHead = (VARIABLE_HEAD *)((UINT8 *)PeiPcdDb + Offset);\r |
d1102dba | 905 | \r |
1436aea4 MK |
906 | Guid = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + VariableHead->GuidTableIndex;\r |
907 | Name = (UINT16 *)&StringTable[VariableHead->StringIndex];\r | |
80408db0 | 908 | \r |
553e8669 | 909 | if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {\r |
80408db0 | 910 | //\r |
d1102dba | 911 | // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of\r |
553e8669 | 912 | // string array in string table.\r |
80408db0 | 913 | //\r |
1436aea4 | 914 | VaraiableDefaultBuffer = (UINT8 *)&StringTable[*(STRING_HEAD *)((UINT8 *)PeiPcdDb + VariableHead->DefaultValueOffset)];\r |
553e8669 | 915 | } else {\r |
1436aea4 | 916 | VaraiableDefaultBuffer = (UINT8 *)PeiPcdDb + VariableHead->DefaultValueOffset;\r |
553e8669 | 917 | }\r |
1436aea4 | 918 | \r |
553e8669 SZ |
919 | Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r |
920 | if ((Status == EFI_SUCCESS) && (DataSize >= (VariableHead->Offset + GetSize))) {\r | |
921 | if (GetSize == 0) {\r | |
922 | //\r | |
923 | // It is a pointer type. So get the MaxSize reserved for\r | |
924 | // this PCD entry.\r | |
925 | //\r | |
926 | GetPtrTypeSize (TokenNumber, &GetSize, PeiPcdDb);\r | |
927 | if (GetSize > (DataSize - VariableHead->Offset)) {\r | |
928 | //\r | |
929 | // Use actual valid size.\r | |
930 | //\r | |
931 | GetSize = DataSize - VariableHead->Offset;\r | |
932 | }\r | |
6ac15f7c | 933 | }\r |
1436aea4 | 934 | \r |
553e8669 SZ |
935 | //\r |
936 | // If the operation is successful, we copy the data\r | |
937 | // to the default value buffer in the PCD Database.\r | |
938 | //\r | |
1436aea4 | 939 | CopyMem (VaraiableDefaultBuffer, (UINT8 *)Data + VariableHead->Offset, GetSize);\r |
80408db0 | 940 | }\r |
1436aea4 MK |
941 | \r |
942 | return (VOID *)VaraiableDefaultBuffer;\r | |
80408db0 | 943 | }\r |
944 | \r | |
945 | case PCD_TYPE_DATA:\r | |
1436aea4 | 946 | return (VOID *)((UINT8 *)PeiPcdDb + Offset);\r |
80408db0 | 947 | \r |
948 | case PCD_TYPE_STRING:\r | |
1436aea4 MK |
949 | StringTableIdx = *(STRING_HEAD *)((UINT8 *)PeiPcdDb + Offset);\r |
950 | return (VOID *)(&StringTable[StringTableIdx]);\r | |
80408db0 | 951 | \r |
952 | default:\r | |
953 | ASSERT (FALSE);\r | |
954 | break;\r | |
80408db0 | 955 | }\r |
956 | \r | |
957 | ASSERT (FALSE);\r | |
d1102dba | 958 | \r |
80408db0 | 959 | return NULL;\r |
80408db0 | 960 | }\r |
961 | \r | |
fc547e08 | 962 | /**\r |
419db80b | 963 | Get Token Number according to dynamic-ex PCD's {token space guid:token number}\r |
fc547e08 | 964 | \r |
965 | A dynamic-ex type PCD, developer must provide pair of token space guid: token number\r | |
966 | in DEC file. PCD database maintain a mapping table that translate pair of {token\r | |
419db80b | 967 | space guid: token number} to Token Number.\r |
d1102dba | 968 | \r |
fc547e08 | 969 | @param Guid Token space guid for dynamic-ex PCD entry.\r |
419db80b | 970 | @param ExTokenNumber Dynamic-ex PCD token number.\r |
80408db0 | 971 | \r |
419db80b | 972 | @return Token Number for dynamic-ex PCD.\r |
80408db0 | 973 | \r |
fc547e08 | 974 | **/\r |
d1102dba | 975 | UINTN\r |
80408db0 | 976 | GetExPcdTokenNumber (\r |
1436aea4 MK |
977 | IN CONST EFI_GUID *Guid,\r |
978 | IN UINTN ExTokenNumber\r | |
80408db0 | 979 | )\r |
980 | {\r | |
1436aea4 MK |
981 | UINT32 Index;\r |
982 | DYNAMICEX_MAPPING *ExMap;\r | |
983 | EFI_GUID *GuidTable;\r | |
984 | EFI_GUID *MatchGuid;\r | |
985 | UINTN MatchGuidIdx;\r | |
986 | PEI_PCD_DATABASE *PeiPcdDb;\r | |
80408db0 | 987 | \r |
1436aea4 | 988 | PeiPcdDb = GetPcdDatabase ();\r |
80408db0 | 989 | \r |
1436aea4 MK |
990 | ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);\r |
991 | GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);\r | |
419db80b | 992 | \r |
1436aea4 | 993 | MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof (EFI_GUID), Guid);\r |
80408db0 | 994 | //\r |
995 | // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r | |
996 | // error in the BUILD system.\r | |
997 | //\r | |
998 | ASSERT (MatchGuid != NULL);\r | |
d1102dba | 999 | \r |
80408db0 | 1000 | MatchGuidIdx = MatchGuid - GuidTable;\r |
d1102dba | 1001 | \r |
419db80b | 1002 | for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {\r |
d1102dba | 1003 | if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&\r |
1436aea4 MK |
1004 | (MatchGuidIdx == ExMap[Index].ExGuidIndex))\r |
1005 | {\r | |
419db80b | 1006 | return ExMap[Index].TokenNumber;\r |
80408db0 | 1007 | }\r |
1008 | }\r | |
d1102dba | 1009 | \r |
86714ccd | 1010 | return PCD_INVALID_TOKEN_NUMBER;\r |
80408db0 | 1011 | }\r |
1012 | \r | |
fc547e08 | 1013 | /**\r |
1014 | Get PCD database from GUID HOB in PEI phase.\r | |
80408db0 | 1015 | \r |
fc547e08 | 1016 | @return Pointer to PCD database.\r |
80408db0 | 1017 | \r |
fc547e08 | 1018 | **/\r |
80408db0 | 1019 | PEI_PCD_DATABASE *\r |
1020 | GetPcdDatabase (\r | |
1021 | VOID\r | |
1022 | )\r | |
1023 | {\r | |
1436aea4 | 1024 | EFI_HOB_GUID_TYPE *GuidHob;\r |
80408db0 | 1025 | \r |
1026 | GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r | |
1027 | ASSERT (GuidHob != NULL);\r | |
d1102dba | 1028 | \r |
1436aea4 | 1029 | return (PEI_PCD_DATABASE *)GET_GUID_HOB_DATA (GuidHob);\r |
80408db0 | 1030 | }\r |
1031 | \r | |
fc547e08 | 1032 | /**\r |
1033 | Get index of PCD entry in size table.\r | |
1034 | \r | |
1035 | @param LocalTokenNumberTableIdx Index of this PCD in local token number table.\r | |
1036 | @param Database Pointer to PCD database in PEI phase.\r | |
80408db0 | 1037 | \r |
fc547e08 | 1038 | @return index of PCD entry in size table.\r |
80408db0 | 1039 | \r |
fc547e08 | 1040 | **/\r |
80408db0 | 1041 | UINTN\r |
1042 | GetSizeTableIndex (\r | |
1043 | IN UINTN LocalTokenNumberTableIdx,\r | |
1044 | IN PEI_PCD_DATABASE *Database\r | |
1045 | )\r | |
1046 | {\r | |
1436aea4 MK |
1047 | UINTN Index;\r |
1048 | UINTN SizeTableIdx;\r | |
1049 | UINTN LocalTokenNumber;\r | |
7c736265 | 1050 | \r |
80408db0 | 1051 | SizeTableIdx = 0;\r |
1052 | \r | |
419db80b BF |
1053 | for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) {\r |
1054 | LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + Index);\r | |
80408db0 | 1055 | \r |
1056 | if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {\r | |
1057 | //\r | |
d1102dba | 1058 | // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type\r |
80408db0 | 1059 | // PCD entry.\r |
1060 | //\r | |
fc547e08 | 1061 | if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {\r |
1436aea4 MK |
1062 | //\r |
1063 | // We have only two entry for VPD enabled PCD entry:\r | |
1064 | // 1) MAX Size.\r | |
1065 | // 2) Current Size\r | |
1066 | // Current size is equal to MAX size.\r | |
1067 | //\r | |
1068 | SizeTableIdx += 2;\r | |
80408db0 | 1069 | } else {\r |
1436aea4 MK |
1070 | //\r |
1071 | // We have only two entry for Non-Sku enabled PCD entry:\r | |
1072 | // 1) MAX SIZE\r | |
1073 | // 2) Current Size\r | |
1074 | //\r | |
1075 | SizeTableIdx += 2;\r | |
80408db0 | 1076 | }\r |
1077 | }\r | |
80408db0 | 1078 | }\r |
1079 | \r | |
1080 | return SizeTableIdx;\r | |
1081 | }\r |