]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/PCD/Dxe/Pcd.c
MdeModulePkg Pcd DXE: Handle the case gPcdDataBaseHobGuid HOB is not present.
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Dxe / Pcd.c
CommitLineData
80408db0 1/** @file\r
2ab6330e 2 PCD DXE driver manage all PCD entry initialized in PEI phase and DXE phase, and\r
8a541f0a 3 produce the implementation of native PCD protocol and EFI_PCD_PROTOCOL defined in\r
4 PI 1.2 Vol3.\r
80408db0 5\r
419db80b 6Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 7This program and the accompanying materials\r
80408db0 8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
80408db0 15**/\r
16\r
80408db0 17#include "Service.h"\r
18\r
2ab6330e 19///\r
20/// PCD database lock.\r
21///\r
6a429dfa 22EFI_LOCK mPcdDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE(TPL_NOTIFY);\r
80408db0 23\r
17e7fa8f 24///\r
25/// PCD_PROTOCOL the EDKII native implementation which support dynamic \r
26/// type and dynamicEx type PCDs.\r
27///\r
80408db0 28PCD_PROTOCOL mPcdInstance = {\r
29 DxePcdSetSku,\r
30\r
31 DxePcdGet8,\r
32 DxePcdGet16,\r
33 DxePcdGet32,\r
34 DxePcdGet64,\r
35 DxePcdGetPtr,\r
36 DxePcdGetBool,\r
37 DxePcdGetSize,\r
38\r
39 DxePcdGet8Ex,\r
40 DxePcdGet16Ex,\r
41 DxePcdGet32Ex,\r
42 DxePcdGet64Ex,\r
43 DxePcdGetPtrEx,\r
44 DxePcdGetBoolEx,\r
45 DxePcdGetSizeEx,\r
46\r
47 DxePcdSet8,\r
48 DxePcdSet16,\r
49 DxePcdSet32,\r
50 DxePcdSet64,\r
51 DxePcdSetPtr,\r
52 DxePcdSetBool,\r
53\r
54 DxePcdSet8Ex,\r
55 DxePcdSet16Ex,\r
56 DxePcdSet32Ex,\r
57 DxePcdSet64Ex,\r
58 DxePcdSetPtrEx,\r
59 DxePcdSetBoolEx,\r
60\r
61 DxeRegisterCallBackOnSet,\r
62 DxeUnRegisterCallBackOnSet,\r
63 DxePcdGetNextToken,\r
64 DxePcdGetNextTokenSpace\r
65};\r
66\r
17e7fa8f 67///\r
68/// EFI_PCD_PROTOCOL is defined in PI 1.2 Vol 3 which only support dynamicEx type\r
69/// PCD.\r
70///\r
c896d682 71EFI_PCD_PROTOCOL mEfiPcdInstance = {\r
72 DxePcdSetSku,\r
73 DxePcdGet8Ex,\r
74 DxePcdGet16Ex,\r
75 DxePcdGet32Ex,\r
76 DxePcdGet64Ex,\r
77 DxePcdGetPtrEx,\r
78 DxePcdGetBoolEx,\r
79 DxePcdGetSizeEx,\r
80 DxePcdSet8Ex,\r
81 DxePcdSet16Ex,\r
82 DxePcdSet32Ex,\r
83 DxePcdSet64Ex,\r
84 DxePcdSetPtrEx,\r
85 DxePcdSetBoolEx,\r
86 (EFI_PCD_PROTOCOL_CALLBACK_ON_SET) DxeRegisterCallBackOnSet,\r
87 (EFI_PCD_PROTOCOL_CANCEL_CALLBACK) DxeUnRegisterCallBackOnSet,\r
88 DxePcdGetNextToken,\r
89 DxePcdGetNextTokenSpace\r
90};\r
80408db0 91\r
96d6d004
SZ
92///\r
93/// Instance of GET_PCD_INFO_PROTOCOL protocol is EDKII native implementation.\r
94/// This protocol instance support dynamic and dynamicEx type PCDs.\r
95///\r
96GET_PCD_INFO_PROTOCOL mGetPcdInfoInstance = {\r
97 DxeGetPcdInfoGetInfo,\r
98 DxeGetPcdInfoGetInfoEx,\r
99 DxeGetPcdInfoGetSku\r
100};\r
101\r
102///\r
103/// Instance of EFI_GET_PCD_INFO_PROTOCOL which is defined in PI 1.2.1 Vol 3.\r
104/// This PPI instance only support dyanmicEx type PCD.\r
105///\r
106EFI_GET_PCD_INFO_PROTOCOL mEfiGetPcdInfoInstance = {\r
107 DxeGetPcdInfoGetInfoEx,\r
108 DxeGetPcdInfoGetSku\r
109};\r
110\r
17e7fa8f 111EFI_HANDLE mPcdHandle = NULL;\r
80408db0 112\r
2ab6330e 113/**\r
114 Main entry for PCD DXE driver.\r
115 \r
116 This routine initialize the PCD database and install PCD_PROTOCOL.\r
117 \r
118 @param ImageHandle Image handle for PCD DXE driver.\r
119 @param SystemTable Pointer to SystemTable.\r
120\r
121 @return Status of gBS->InstallProtocolInterface()\r
122\r
123**/\r
80408db0 124EFI_STATUS\r
125EFIAPI\r
126PcdDxeInit (\r
127 IN EFI_HANDLE ImageHandle,\r
128 IN EFI_SYSTEM_TABLE *SystemTable\r
129 )\r
130{\r
8a541f0a 131 EFI_STATUS Status;\r
8a541f0a 132 \r
80408db0 133 //\r
134 // Make sure the Pcd Protocol is not already installed in the system\r
135 //\r
136\r
137 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gPcdProtocolGuid);\r
138\r
139 BuildPcdDxeDataBase ();\r
140\r
c896d682 141 //\r
8a541f0a 142 // Install PCD_PROTOCOL to handle dynamic type PCD\r
143 // Install EFI_PCD_PROTOCOL to handle dynamicEx type PCD\r
c896d682 144 //\r
8a541f0a 145 Status = gBS->InstallMultipleProtocolInterfaces (\r
17e7fa8f 146 &mPcdHandle,\r
147 &gPcdProtocolGuid, &mPcdInstance,\r
148 &gEfiPcdProtocolGuid, &mEfiPcdInstance,\r
149 NULL\r
c896d682 150 );\r
80408db0 151 ASSERT_EFI_ERROR (Status);\r
152\r
61d8989f
SZ
153 //\r
154 // Only install PcdInfo PROTOCOL when PCD info content is present. \r
155 //\r
156 if (mPcdDatabase.DxeDb->PcdNameTableOffset != 0) {\r
96d6d004
SZ
157 //\r
158 // Install GET_PCD_INFO_PROTOCOL to handle dynamic type PCD\r
159 // Install EFI_GET_PCD_INFO_PROTOCOL to handle dynamicEx type PCD\r
160 //\r
161 Status = gBS->InstallMultipleProtocolInterfaces (\r
162 &mPcdHandle,\r
163 &gGetPcdInfoProtocolGuid, &mGetPcdInfoInstance,\r
164 &gEfiGetPcdInfoProtocolGuid, &mEfiGetPcdInfoInstance,\r
165 NULL\r
166 );\r
167 ASSERT_EFI_ERROR (Status);\r
168 }\r
169\r
17e7fa8f 170 return Status;\r
96d6d004
SZ
171}\r
172\r
173/**\r
174 Retrieve additional information associated with a PCD token in the default token space.\r
175\r
176 This includes information such as the type of value the TokenNumber is associated with as well as possible\r
177 human readable name that is associated with the token.\r
178\r
179 @param[in] TokenNumber The PCD token number.\r
180 @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r
181 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r
182\r
183 @retval EFI_SUCCESS The PCD information was returned successfully.\r
184 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
185**/\r
186EFI_STATUS\r
187EFIAPI\r
188DxeGetPcdInfoGetInfo (\r
189 IN UINTN TokenNumber,\r
190 OUT EFI_PCD_INFO *PcdInfo\r
191 )\r
192{\r
193 return DxeGetPcdInfo (NULL, TokenNumber, PcdInfo);\r
194}\r
195\r
196/**\r
197 Retrieve additional information associated with a PCD token.\r
198\r
199 This includes information such as the type of value the TokenNumber is associated with as well as possible\r
200 human readable name that is associated with the token.\r
80408db0 201\r
96d6d004
SZ
202 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
203 @param[in] TokenNumber The PCD token number.\r
204 @param[out] PcdInfo The returned information associated with the requested TokenNumber.\r
205 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r
206\r
207 @retval EFI_SUCCESS The PCD information was returned successfully.\r
208 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
209**/\r
210EFI_STATUS\r
211EFIAPI\r
212DxeGetPcdInfoGetInfoEx (\r
213 IN CONST EFI_GUID *Guid,\r
214 IN UINTN TokenNumber,\r
215 OUT EFI_PCD_INFO *PcdInfo\r
216 )\r
217{\r
218 return DxeGetPcdInfo (Guid, TokenNumber, PcdInfo);\r
219}\r
220\r
221/**\r
222 Retrieve the currently set SKU Id.\r
223\r
224 @return The currently set SKU Id. If the platform has not set at a SKU Id, then the\r
225 default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU\r
226 Id is returned.\r
227**/\r
228UINTN\r
229EFIAPI\r
230DxeGetPcdInfoGetSku (\r
231 VOID\r
232 )\r
233{\r
efd6b412 234 return mPcdDatabase.DxeDb->SystemSkuId;\r
80408db0 235}\r
236\r
2ab6330e 237/**\r
238 Sets the SKU value for subsequent calls to set or get PCD token values.\r
239\r
240 SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values. \r
241 SetSku() is normally called only once by the system.\r
242\r
243 For each item (token), the database can hold a single value that applies to all SKUs, \r
244 or multiple values, where each value is associated with a specific SKU Id. Items with multiple, \r
245 SKU-specific values are called SKU enabled. \r
246 \r
247 The SKU Id of zero is reserved as a default. The valid SkuId range is 1 to 255. \r
248 For tokens that are not SKU enabled, the system ignores any set SKU Id and works with the \r
249 single value for that token. For SKU-enabled tokens, the system will use the SKU Id set by the \r
250 last call to SetSku(). If no SKU Id is set or the currently set SKU Id isn't valid for the specified token, \r
251 the system uses the default SKU Id. If the system attempts to use the default SKU Id and no value has been \r
252 set for that Id, the results are unpredictable.\r
253\r
254 @param[in] SkuId The SKU value that will be used when the PCD service will retrieve and \r
255 set values associated with a PCD token.\r
256\r
2ab6330e 257**/\r
80408db0 258VOID\r
259EFIAPI\r
260DxePcdSetSku (\r
261 IN UINTN SkuId\r
262 )\r
263{\r
efd6b412 264 mPcdDatabase.DxeDb->SystemSkuId = (SKU_ID) SkuId;\r
80408db0 265 \r
266 return;\r
267}\r
268\r
2ab6330e 269/**\r
270 Retrieves an 8-bit value for a given PCD token.\r
80408db0 271\r
2ab6330e 272 Retrieves the current byte-sized value for a PCD token number. \r
273 If the TokenNumber is invalid, the results are unpredictable.\r
274 \r
275 @param[in] TokenNumber The PCD token number. \r
80408db0 276\r
2ab6330e 277 @return The UINT8 value.\r
278 \r
279**/\r
80408db0 280UINT8\r
281EFIAPI\r
282DxePcdGet8 (\r
283 IN UINTN TokenNumber\r
284 )\r
285{\r
286 return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8)));\r
287}\r
288\r
2ab6330e 289/**\r
290 Retrieves an 16-bit value for a given PCD token.\r
80408db0 291\r
2ab6330e 292 Retrieves the current 16-bits value for a PCD token number. \r
293 If the TokenNumber is invalid, the results are unpredictable.\r
294 \r
295 @param[in] TokenNumber The PCD token number. \r
80408db0 296\r
2ab6330e 297 @return The UINT16 value.\r
298 \r
299**/\r
80408db0 300UINT16\r
301EFIAPI\r
302DxePcdGet16 (\r
303 IN UINTN TokenNumber\r
304 )\r
305{\r
306 return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16)));\r
307}\r
308\r
2ab6330e 309/**\r
310 Retrieves an 32-bit value for a given PCD token.\r
80408db0 311\r
2ab6330e 312 Retrieves the current 32-bits value for a PCD token number. \r
313 If the TokenNumber is invalid, the results are unpredictable.\r
314 \r
315 @param[in] TokenNumber The PCD token number. \r
80408db0 316\r
2ab6330e 317 @return The UINT32 value.\r
318 \r
319**/\r
80408db0 320UINT32\r
321EFIAPI\r
322DxePcdGet32 (\r
323 IN UINTN TokenNumber\r
324 )\r
325{\r
326 return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32)));\r
327}\r
328\r
2ab6330e 329/**\r
330 Retrieves an 64-bit value for a given PCD token.\r
80408db0 331\r
2ab6330e 332 Retrieves the current 64-bits value for a PCD token number. \r
333 If the TokenNumber is invalid, the results are unpredictable.\r
334 \r
335 @param[in] TokenNumber The PCD token number. \r
80408db0 336\r
2ab6330e 337 @return The UINT64 value.\r
338 \r
339**/\r
80408db0 340UINT64\r
341EFIAPI\r
342DxePcdGet64 (\r
343 IN UINTN TokenNumber\r
344 )\r
345{\r
346 return ReadUnaligned64(GetWorker (TokenNumber, sizeof (UINT64)));\r
347}\r
348\r
2ab6330e 349/**\r
350 Retrieves a pointer to a value for a given PCD token.\r
80408db0 351\r
2ab6330e 352 Retrieves the current pointer to the buffer for a PCD token number. \r
353 Do not make any assumptions about the alignment of the pointer that \r
354 is returned by this function call. If the TokenNumber is invalid, \r
355 the results are unpredictable.\r
80408db0 356\r
2ab6330e 357 @param[in] TokenNumber The PCD token number. \r
358\r
359 @return The pointer to the buffer to be retrived.\r
360 \r
361**/\r
80408db0 362VOID *\r
363EFIAPI\r
364DxePcdGetPtr (\r
365 IN UINTN TokenNumber\r
366 )\r
367{\r
368 return GetWorker (TokenNumber, 0);\r
369}\r
370\r
2ab6330e 371/**\r
372 Retrieves a Boolean value for a given PCD token.\r
373\r
374 Retrieves the current boolean value for a PCD token number. \r
375 Do not make any assumptions about the alignment of the pointer that \r
376 is returned by this function call. If the TokenNumber is invalid, \r
377 the results are unpredictable.\r
80408db0 378\r
2ab6330e 379 @param[in] TokenNumber The PCD token number. \r
80408db0 380\r
2ab6330e 381 @return The Boolean value.\r
382 \r
383**/\r
80408db0 384BOOLEAN\r
385EFIAPI\r
386DxePcdGetBool (\r
387 IN UINTN TokenNumber\r
388 )\r
389{\r
390 return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN)));\r
391}\r
392\r
2ab6330e 393/**\r
394 Retrieves the size of the value for a given PCD token.\r
80408db0 395\r
2ab6330e 396 Retrieves the current size of a particular PCD token. \r
397 If the TokenNumber is invalid, the results are unpredictable.\r
80408db0 398\r
2ab6330e 399 @param[in] TokenNumber The PCD token number. \r
400\r
401 @return The size of the value for the PCD token.\r
402 \r
403**/\r
80408db0 404UINTN\r
405EFIAPI\r
406DxePcdGetSize (\r
407 IN UINTN TokenNumber\r
408 )\r
409{\r
410 UINTN Size;\r
411 UINT32 *LocalTokenNumberTable;\r
412 BOOLEAN IsPeiDb;\r
413 UINTN MaxSize;\r
414 UINTN TmpTokenNumber;\r
415 //\r
416 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
417 // We have to decrement TokenNumber by 1 to make it usable\r
418 // as the array index.\r
419 //\r
420 TokenNumber--;\r
421\r
422 //\r
423 // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber\r
424 // \r
425 TmpTokenNumber = TokenNumber;\r
426\r
427 // EBC compiler is very choosy. It may report warning about comparison\r
428 // between UINTN and 0 . So we add 1 in each size of the \r
429 // comparison.\r
419db80b 430 ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);\r
80408db0 431\r
432 // EBC compiler is very choosy. It may report warning about comparison\r
433 // between UINTN and 0 . So we add 1 in each size of the \r
434 // comparison.\r
419db80b 435 IsPeiDb = (BOOLEAN) (TokenNumber + 1 < mPeiLocalTokenCount + 1);\r
80408db0 436 \r
437 TokenNumber = IsPeiDb ? TokenNumber : \r
419db80b 438 (TokenNumber - mPeiLocalTokenCount);\r
80408db0 439\r
419db80b
BF
440 LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) \r
441 : (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);\r
80408db0 442\r
443 Size = (LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;\r
444\r
445 if (Size == 0) {\r
446 //\r
447 // For pointer type, we need to scan the SIZE_TABLE to get the current size.\r
448 //\r
449 return GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
450 } else {\r
451 return Size;\r
452 }\r
453\r
454}\r
455\r
2ab6330e 456/**\r
457 Retrieves an 8-bit value for a given PCD token.\r
458\r
459 Retrieves the 8-bit value of a particular PCD token. \r
460 If the TokenNumber is invalid or the token space\r
461 specified by Guid does not exist, the results are \r
462 unpredictable.\r
80408db0 463\r
2ab6330e 464 @param[in] Guid The token space for the token number.\r
465 @param[in] ExTokenNumber The PCD token number. \r
80408db0 466\r
2ab6330e 467 @return The size 8-bit value for the PCD token.\r
468 \r
469**/\r
80408db0 470UINT8\r
471EFIAPI\r
472DxePcdGet8Ex (\r
473 IN CONST EFI_GUID *Guid,\r
2ab6330e 474 IN UINTN ExTokenNumber\r
80408db0 475 )\r
476{\r
477 return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof(UINT8)));\r
478}\r
479\r
2ab6330e 480/**\r
481 Retrieves an 16-bit value for a given PCD token.\r
482\r
483 Retrieves the 16-bit value of a particular PCD token. \r
484 If the TokenNumber is invalid or the token space\r
485 specified by Guid does not exist, the results are \r
486 unpredictable.\r
80408db0 487\r
2ab6330e 488 @param[in] Guid The token space for the token number.\r
489 @param[in] ExTokenNumber The PCD token number. \r
80408db0 490\r
2ab6330e 491 @return The size 16-bit value for the PCD token.\r
492 \r
493**/\r
80408db0 494UINT16\r
495EFIAPI\r
496DxePcdGet16Ex (\r
497 IN CONST EFI_GUID *Guid,\r
498 IN UINTN ExTokenNumber\r
499 )\r
500{\r
501 return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT16)));\r
502}\r
503\r
2ab6330e 504/**\r
505 Retrieves an 32-bit value for a given PCD token.\r
506\r
507 Retrieves the 32-bit value of a particular PCD token. \r
508 If the TokenNumber is invalid or the token space\r
509 specified by Guid does not exist, the results are \r
510 unpredictable.\r
80408db0 511\r
2ab6330e 512 @param[in] Guid The token space for the token number.\r
513 @param[in] ExTokenNumber The PCD token number. \r
80408db0 514\r
2ab6330e 515 @return The size 32-bit value for the PCD token.\r
516 \r
517**/\r
80408db0 518UINT32\r
519EFIAPI\r
520DxePcdGet32Ex (\r
521 IN CONST EFI_GUID *Guid,\r
522 IN UINTN ExTokenNumber\r
523 )\r
524{\r
525 return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT32)));\r
526}\r
527\r
2ab6330e 528/**\r
529 Retrieves an 64-bit value for a given PCD token.\r
80408db0 530\r
2ab6330e 531 Retrieves the 64-bit value of a particular PCD token. \r
532 If the TokenNumber is invalid or the token space\r
533 specified by Guid does not exist, the results are \r
534 unpredictable.\r
80408db0 535\r
2ab6330e 536 @param[in] Guid The token space for the token number.\r
537 @param[in] ExTokenNumber The PCD token number. \r
538\r
539 @return The size 64-bit value for the PCD token.\r
540 \r
541**/\r
80408db0 542UINT64\r
543EFIAPI\r
544DxePcdGet64Ex (\r
545 IN CONST EFI_GUID *Guid,\r
546 IN UINTN ExTokenNumber\r
547 )\r
548{\r
549 return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT64)));\r
550}\r
551\r
2ab6330e 552/**\r
553 Retrieves a pointer to a value for a given PCD token.\r
554\r
555 Retrieves the current pointer to the buffer for a PCD token number. \r
556 Do not make any assumptions about the alignment of the pointer that \r
557 is returned by this function call. If the TokenNumber is invalid, \r
558 the results are unpredictable.\r
80408db0 559\r
2ab6330e 560 @param[in] Guid The token space for the token number.\r
561 @param[in] ExTokenNumber The PCD token number. \r
80408db0 562\r
2ab6330e 563 @return The pointer to the buffer to be retrived.\r
564 \r
565**/\r
80408db0 566VOID *\r
567EFIAPI\r
568DxePcdGetPtrEx (\r
569 IN CONST EFI_GUID *Guid,\r
570 IN UINTN ExTokenNumber\r
571 )\r
572{\r
573 return ExGetWorker (Guid, ExTokenNumber, 0);\r
574}\r
575\r
2ab6330e 576/**\r
577 Retrieves an Boolean value for a given PCD token.\r
80408db0 578\r
2ab6330e 579 Retrieves the Boolean value of a particular PCD token. \r
580 If the TokenNumber is invalid or the token space\r
581 specified by Guid does not exist, the results are \r
582 unpredictable.\r
80408db0 583\r
2ab6330e 584 @param[in] Guid The token space for the token number.\r
585 @param[in] ExTokenNumber The PCD token number. \r
586\r
587 @return The size Boolean value for the PCD token.\r
588 \r
589**/\r
80408db0 590BOOLEAN\r
591EFIAPI\r
592DxePcdGetBoolEx (\r
593 IN CONST EFI_GUID *Guid,\r
594 IN UINTN ExTokenNumber\r
595 )\r
596{\r
597 return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof(BOOLEAN)));\r
598}\r
599\r
2ab6330e 600/**\r
601 Retrieves the size of the value for a given PCD token.\r
602\r
603 Retrieves the current size of a particular PCD token. \r
604 If the TokenNumber is invalid, the results are unpredictable.\r
80408db0 605\r
2ab6330e 606 @param[in] Guid The token space for the token number.\r
607 @param[in] ExTokenNumber The PCD token number. \r
80408db0 608\r
2ab6330e 609 @return The size of the value for the PCD token.\r
610 \r
611**/\r
80408db0 612UINTN\r
613EFIAPI\r
614DxePcdGetSizeEx (\r
615 IN CONST EFI_GUID *Guid,\r
616 IN UINTN ExTokenNumber\r
617 )\r
618{\r
619 return DxePcdGetSize(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber));\r
620}\r
621\r
2ab6330e 622/**\r
623 Sets an 8-bit value for a given PCD token.\r
624\r
625 When the PCD service sets a value, it will check to ensure that the \r
626 size of the value being set is compatible with the Token's existing definition. \r
627 If it is not, an error will be returned.\r
80408db0 628\r
2ab6330e 629 @param[in] TokenNumber The PCD token number. \r
630 @param[in] Value The value to set for the PCD token.\r
80408db0 631\r
2ab6330e 632 @retval EFI_SUCCESS Procedure returned successfully.\r
633 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
634 being set was incompatible with a call to this function. \r
635 Use GetSize() to retrieve the size of the target data.\r
636 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
637 \r
638**/\r
80408db0 639EFI_STATUS\r
640EFIAPI\r
641DxePcdSet8 (\r
642 IN UINTN TokenNumber,\r
643 IN UINT8 Value\r
644 )\r
645{\r
646 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
647}\r
648\r
2ab6330e 649/**\r
650 Sets an 16-bit value for a given PCD token.\r
80408db0 651\r
2ab6330e 652 When the PCD service sets a value, it will check to ensure that the \r
653 size of the value being set is compatible with the Token's existing definition. \r
654 If it is not, an error will be returned.\r
80408db0 655\r
2ab6330e 656 @param[in] TokenNumber The PCD token number. \r
657 @param[in] Value The value to set for the PCD token.\r
658\r
659 @retval EFI_SUCCESS Procedure returned successfully.\r
660 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
661 being set was incompatible with a call to this function. \r
662 Use GetSize() to retrieve the size of the target data.\r
663 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
664 \r
665**/\r
80408db0 666EFI_STATUS\r
667EFIAPI\r
668DxePcdSet16 (\r
669 IN UINTN TokenNumber,\r
670 IN UINT16 Value\r
671 )\r
672{\r
673 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
674}\r
675\r
2ab6330e 676/**\r
677 Sets an 32-bit value for a given PCD token.\r
678\r
679 When the PCD service sets a value, it will check to ensure that the \r
680 size of the value being set is compatible with the Token's existing definition. \r
681 If it is not, an error will be returned.\r
80408db0 682\r
2ab6330e 683 @param[in] TokenNumber The PCD token number. \r
684 @param[in] Value The value to set for the PCD token.\r
80408db0 685\r
2ab6330e 686 @retval EFI_SUCCESS Procedure returned successfully.\r
687 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
688 being set was incompatible with a call to this function. \r
689 Use GetSize() to retrieve the size of the target data.\r
690 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
691 \r
692**/\r
80408db0 693EFI_STATUS\r
694EFIAPI\r
695DxePcdSet32 (\r
696 IN UINTN TokenNumber,\r
697 IN UINT32 Value\r
698 )\r
699{\r
700 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
701}\r
702\r
2ab6330e 703/**\r
704 Sets an 64-bit value for a given PCD token.\r
80408db0 705\r
2ab6330e 706 When the PCD service sets a value, it will check to ensure that the \r
707 size of the value being set is compatible with the Token's existing definition. \r
708 If it is not, an error will be returned.\r
80408db0 709\r
2ab6330e 710 @param[in] TokenNumber The PCD token number. \r
711 @param[in] Value The value to set for the PCD token.\r
712\r
713 @retval EFI_SUCCESS Procedure returned successfully.\r
714 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
715 being set was incompatible with a call to this function. \r
716 Use GetSize() to retrieve the size of the target data.\r
717 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
718 \r
719**/\r
80408db0 720EFI_STATUS\r
721EFIAPI\r
722DxePcdSet64 (\r
723 IN UINTN TokenNumber,\r
724 IN UINT64 Value\r
725 )\r
726{\r
727 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
728}\r
729\r
2ab6330e 730/**\r
731 Sets a value of a specified size for a given PCD token.\r
732\r
733 When the PCD service sets a value, it will check to ensure that the \r
734 size of the value being set is compatible with the Token's existing definition. \r
735 If it is not, an error will be returned.\r
736\r
737 @param[in] TokenNumber The PCD token number. \r
738 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token. \r
739 On input, if the SizeOfValue is greater than the maximum size supported \r
740 for this TokenNumber then the output value of SizeOfValue will reflect \r
741 the maximum size supported for this TokenNumber.\r
742 @param[in] Buffer The buffer to set for the PCD token.\r
743\r
744 @retval EFI_SUCCESS Procedure returned successfully.\r
745 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
746 being set was incompatible with a call to this function. \r
747 Use GetSize() to retrieve the size of the target data.\r
748 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
749 \r
750**/\r
80408db0 751EFI_STATUS\r
752EFIAPI\r
753DxePcdSetPtr (\r
754 IN UINTN TokenNumber,\r
755 IN OUT UINTN *SizeOfBuffer,\r
756 IN VOID *Buffer\r
757 )\r
758{\r
759 return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);\r
760}\r
761\r
2ab6330e 762/**\r
763 Sets an Boolean value for a given PCD token.\r
80408db0 764\r
2ab6330e 765 When the PCD service sets a value, it will check to ensure that the \r
766 size of the value being set is compatible with the Token's existing definition. \r
767 If it is not, an error will be returned.\r
80408db0 768\r
2ab6330e 769 @param[in] TokenNumber The PCD token number. \r
770 @param[in] Value The value to set for the PCD token.\r
771\r
772 @retval EFI_SUCCESS Procedure returned successfully.\r
773 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
774 being set was incompatible with a call to this function. \r
775 Use GetSize() to retrieve the size of the target data.\r
776 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
777 \r
778**/\r
80408db0 779EFI_STATUS\r
780EFIAPI\r
781DxePcdSetBool (\r
782 IN UINTN TokenNumber,\r
783 IN BOOLEAN Value\r
784 )\r
785{\r
786 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
787}\r
788\r
2ab6330e 789/**\r
790 Sets an 8-bit value for a given PCD token.\r
791\r
792 When the PCD service sets a value, it will check to ensure that the \r
793 size of the value being set is compatible with the Token's existing definition. \r
794 If it is not, an error will be returned.\r
80408db0 795\r
2ab6330e 796 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
797 @param[in] ExTokenNumber The PCD token number. \r
798 @param[in] Value The value to set for the PCD token.\r
80408db0 799\r
2ab6330e 800 @retval EFI_SUCCESS Procedure returned successfully.\r
801 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
802 being set was incompatible with a call to this function. \r
803 Use GetSize() to retrieve the size of the target data.\r
804 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
805 \r
806**/\r
80408db0 807EFI_STATUS\r
808EFIAPI\r
809DxePcdSet8Ex (\r
810 IN CONST EFI_GUID *Guid,\r
811 IN UINTN ExTokenNumber,\r
812 IN UINT8 Value\r
813 )\r
814{\r
815 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
816}\r
817\r
2ab6330e 818/**\r
819 Sets an 16-bit value for a given PCD token.\r
80408db0 820\r
2ab6330e 821 When the PCD service sets a value, it will check to ensure that the \r
822 size of the value being set is compatible with the Token's existing definition. \r
823 If it is not, an error will be returned.\r
80408db0 824\r
2ab6330e 825 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
826 @param[in] ExTokenNumber The PCD token number. \r
827 @param[in] Value The value to set for the PCD token.\r
828\r
829 @retval EFI_SUCCESS Procedure returned successfully.\r
830 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
831 being set was incompatible with a call to this function. \r
832 Use GetSize() to retrieve the size of the target data.\r
833 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
834 \r
835**/\r
80408db0 836EFI_STATUS\r
837EFIAPI\r
838DxePcdSet16Ex (\r
839 IN CONST EFI_GUID *Guid,\r
840 IN UINTN ExTokenNumber,\r
841 IN UINT16 Value\r
842 )\r
843{\r
844 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
845}\r
846\r
2ab6330e 847/**\r
848 Sets an 32-bit value for a given PCD token.\r
849\r
850 When the PCD service sets a value, it will check to ensure that the \r
851 size of the value being set is compatible with the Token's existing definition. \r
852 If it is not, an error will be returned.\r
80408db0 853\r
2ab6330e 854 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
855 @param[in] ExTokenNumber The PCD token number. \r
856 @param[in] Value The value to set for the PCD token.\r
80408db0 857\r
2ab6330e 858 @retval EFI_SUCCESS Procedure returned successfully.\r
859 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
860 being set was incompatible with a call to this function. \r
861 Use GetSize() to retrieve the size of the target data.\r
862 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
863 \r
864**/\r
80408db0 865EFI_STATUS\r
866EFIAPI\r
867DxePcdSet32Ex (\r
868 IN CONST EFI_GUID *Guid,\r
869 IN UINTN ExTokenNumber,\r
870 IN UINT32 Value\r
871 )\r
872{\r
873 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
874}\r
875\r
2ab6330e 876/**\r
877 Sets an 64-bit value for a given PCD token.\r
878\r
879 When the PCD service sets a value, it will check to ensure that the \r
880 size of the value being set is compatible with the Token's existing definition. \r
881 If it is not, an error will be returned.\r
80408db0 882\r
2ab6330e 883 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
884 @param[in] ExTokenNumber The PCD token number. \r
885 @param[in] Value The value to set for the PCD token.\r
80408db0 886\r
2ab6330e 887 @retval EFI_SUCCESS Procedure returned successfully.\r
888 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
889 being set was incompatible with a call to this function. \r
890 Use GetSize() to retrieve the size of the target data.\r
891 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
892 \r
893**/\r
80408db0 894EFI_STATUS\r
895EFIAPI\r
896DxePcdSet64Ex (\r
897 IN CONST EFI_GUID *Guid,\r
898 IN UINTN ExTokenNumber,\r
899 IN UINT64 Value\r
900 )\r
901{\r
902 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
903}\r
904\r
2ab6330e 905/**\r
906 Sets a value of a specified size for a given PCD token.\r
907\r
908 When the PCD service sets a value, it will check to ensure that the \r
909 size of the value being set is compatible with the Token's existing definition. \r
910 If it is not, an error will be returned.\r
911\r
912 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
913 @param[in] ExTokenNumber The PCD token number. \r
914 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token. \r
915 On input, if the SizeOfValue is greater than the maximum size supported \r
916 for this TokenNumber then the output value of SizeOfValue will reflect \r
917 the maximum size supported for this TokenNumber.\r
918 @param[in] Buffer The buffer to set for the PCD token.\r
919\r
920 @retval EFI_SUCCESS Procedure returned successfully.\r
921 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
922 being set was incompatible with a call to this function. \r
923 Use GetSize() to retrieve the size of the target data.\r
924 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
925 \r
926**/\r
80408db0 927EFI_STATUS\r
928EFIAPI\r
929DxePcdSetPtrEx (\r
930 IN CONST EFI_GUID *Guid,\r
931 IN UINTN ExTokenNumber,\r
932 IN OUT UINTN *SizeOfBuffer,\r
933 IN VOID *Buffer\r
934 )\r
935{\r
936 return ExSetWorker(ExTokenNumber, Guid, Buffer, SizeOfBuffer, TRUE);\r
937}\r
938\r
2ab6330e 939/**\r
940 Sets an Boolean value for a given PCD token.\r
80408db0 941\r
2ab6330e 942 When the PCD service sets a value, it will check to ensure that the \r
943 size of the value being set is compatible with the Token's existing definition. \r
944 If it is not, an error will be returned.\r
80408db0 945\r
2ab6330e 946 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
947 @param[in] ExTokenNumber The PCD token number. \r
948 @param[in] Value The value to set for the PCD token.\r
949\r
950 @retval EFI_SUCCESS Procedure returned successfully.\r
951 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data \r
952 being set was incompatible with a call to this function. \r
953 Use GetSize() to retrieve the size of the target data.\r
954 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.\r
955 \r
956**/\r
80408db0 957EFI_STATUS\r
958EFIAPI\r
959DxePcdSetBoolEx (\r
960 IN CONST EFI_GUID *Guid,\r
961 IN UINTN ExTokenNumber,\r
962 IN BOOLEAN Value\r
963 )\r
964{\r
965 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
966}\r
967\r
2ab6330e 968/**\r
969 Specifies a function to be called anytime the value of a designated token is changed.\r
80408db0 970\r
2ab6330e 971 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
972 @param[in] TokenNumber The PCD token number. \r
973 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. \r
80408db0 974\r
2ab6330e 975 @retval EFI_SUCCESS The PCD service has successfully established a call event \r
976 for the CallBackToken requested.\r
977 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.\r
80408db0 978\r
2ab6330e 979**/\r
80408db0 980EFI_STATUS\r
981EFIAPI\r
982DxeRegisterCallBackOnSet (\r
983 IN CONST EFI_GUID *Guid, OPTIONAL\r
984 IN UINTN TokenNumber,\r
985 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
986 )\r
987{\r
988 EFI_STATUS Status;\r
989 \r
e4a3922f 990 if (CallBackFunction == NULL) {\r
991 return EFI_INVALID_PARAMETER;\r
992 }\r
80408db0 993 //\r
994 // Aquire lock to prevent reentrance from TPL_CALLBACK level\r
995 //\r
996 EfiAcquireLock (&mPcdDatabaseLock);\r
997\r
998 Status = DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);\r
999\r
1000 EfiReleaseLock (&mPcdDatabaseLock);\r
1001 \r
1002 return Status;\r
1003}\r
1004\r
2ab6330e 1005/**\r
1006 Cancels a previously set callback function for a particular PCD token number.\r
80408db0 1007\r
2ab6330e 1008 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
1009 @param[in] TokenNumber The PCD token number. \r
1010 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. \r
80408db0 1011\r
2ab6330e 1012 @retval EFI_SUCCESS The PCD service has successfully established a call event \r
1013 for the CallBackToken requested.\r
1014 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.\r
1015\r
1016**/\r
80408db0 1017EFI_STATUS\r
1018EFIAPI\r
1019DxeUnRegisterCallBackOnSet (\r
1020 IN CONST EFI_GUID *Guid, OPTIONAL\r
1021 IN UINTN TokenNumber,\r
1022 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
1023 )\r
1024{\r
1025 EFI_STATUS Status;\r
1026 \r
e4a3922f 1027 if (CallBackFunction == NULL) {\r
1028 return EFI_INVALID_PARAMETER;\r
1029 }\r
80408db0 1030\r
1031 //\r
1032 // Aquire lock to prevent reentrance from TPL_CALLBACK level\r
1033 //\r
1034 EfiAcquireLock (&mPcdDatabaseLock);\r
1035 \r
1036 Status = DxeUnRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);\r
1037\r
1038 EfiReleaseLock (&mPcdDatabaseLock);\r
1039 \r
1040 return Status;\r
1041}\r
1042\r
2ab6330e 1043/**\r
90e06556 1044 Retrieves the next valid token number in a given namespace. \r
1045 \r
1046 This is useful since the PCD infrastructure contains a sparse list of token numbers, \r
1047 and one cannot a priori know what token numbers are valid in the database. \r
1048 \r
1049 If TokenNumber is 0 and Guid is not NULL, then the first token from the token space specified by Guid is returned. \r
1050 If TokenNumber is not 0 and Guid is not NULL, then the next token in the token space specified by Guid is returned. \r
1051 If TokenNumber is 0 and Guid is NULL, then the first token in the default token space is returned. \r
1052 If TokenNumber is not 0 and Guid is NULL, then the next token in the default token space is returned. \r
1053 The token numbers in the default token space may not be related to token numbers in token spaces that are named by Guid. \r
1054 If the next token number can be retrieved, then it is returned in TokenNumber, and EFI_SUCCESS is returned. \r
1055 If TokenNumber represents the last token number in the token space specified by Guid, then EFI_NOT_FOUND is returned. \r
1056 If TokenNumber is not present in the token space specified by Guid, then EFI_NOT_FOUND is returned.\r
1057\r
1058\r
1059 @param[in] Guid The 128-bit unique value that designates the namespace from which to retrieve the next token. \r
1060 This is an optional parameter that may be NULL. If this parameter is NULL, then a request is \r
1061 being made to retrieve tokens from the default token space.\r
4140a663 1062 @param[in, out] TokenNumber \r
90e06556 1063 A pointer to the PCD token number to use to find the subsequent token number. \r
1064\r
419db80b
BF
1065 @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.\r
1066 @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.\r
2ab6330e 1067\r
1068**/\r
80408db0 1069EFI_STATUS\r
1070EFIAPI\r
1071DxePcdGetNextToken (\r
1072 IN CONST EFI_GUID *Guid, OPTIONAL\r
1073 IN OUT UINTN *TokenNumber\r
1074 )\r
1075{\r
1076 EFI_STATUS Status;\r
1077 BOOLEAN PeiExMapTableEmpty;\r
1078 BOOLEAN DxeExMapTableEmpty;\r
1079\r
80408db0 1080 Status = EFI_NOT_FOUND;\r
419db80b
BF
1081 PeiExMapTableEmpty = mPeiExMapTableEmpty;\r
1082 DxeExMapTableEmpty = mDxeExMapTableEmpty;\r
80408db0 1083\r
1084 //\r
1085 // Scan the local token space\r
1086 //\r
1087 if (Guid == NULL) {\r
1088 // EBC compiler is very choosy. It may report warning about comparison\r
1089 // between UINTN and 0 . So we add 1 in each size of the \r
1090 // comparison.\r
419db80b
BF
1091 if (((*TokenNumber + 1 > mPeiNexTokenCount + 1) && (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) ||\r
1092 ((*TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) {\r
1093 return EFI_NOT_FOUND;\r
80408db0 1094 }\r
1095 \r
1096 (*TokenNumber)++;\r
419db80b
BF
1097 if ((*TokenNumber + 1 > mPeiNexTokenCount + 1) &&\r
1098 (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) {\r
80408db0 1099 //\r
1100 // The first Non-Ex type Token Number for DXE PCD \r
419db80b 1101 // database is mPeiLocalTokenCount + 1\r
80408db0 1102 //\r
419db80b
BF
1103 if (mDxeNexTokenCount > 0) {\r
1104 *TokenNumber = mPeiLocalTokenCount + 1;\r
1105 } else {\r
1106 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
1107 return EFI_NOT_FOUND;\r
1108 }\r
1109 } else if (*TokenNumber + 1 > mDxeNexTokenCount + mPeiLocalTokenCount + 1) {\r
80408db0 1110 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
419db80b 1111 return EFI_NOT_FOUND;\r
80408db0 1112 }\r
1113 return EFI_SUCCESS;\r
1114 }\r
1115\r
1116 if (PeiExMapTableEmpty && DxeExMapTableEmpty) {\r
80408db0 1117 return EFI_NOT_FOUND;\r
1118 }\r
1119\r
1120 if (!PeiExMapTableEmpty) {\r
1121 Status = ExGetNextTokeNumber (\r
1122 Guid,\r
1123 TokenNumber,\r
419db80b
BF
1124 (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset),\r
1125 mPeiGuidTableSize,\r
1126 (DYNAMICEX_MAPPING *)((UINT8 *) mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset),\r
1127 mPeiExMapppingTableSize\r
80408db0 1128 );\r
1129 }\r
1130\r
1131 if (Status == EFI_SUCCESS) {\r
1132 return Status;\r
1133 }\r
1134\r
1135 if (!DxeExMapTableEmpty) {\r
1136 Status = ExGetNextTokeNumber (\r
1137 Guid,\r
1138 TokenNumber,\r
419db80b
BF
1139 (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset),\r
1140 mDxeGuidTableSize,\r
1141 (DYNAMICEX_MAPPING *)((UINT8 *) mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset),\r
1142 mDxeExMapppingTableSize\r
80408db0 1143 );\r
1144 }\r
1145\r
1146 return Status;\r
1147}\r
1148\r
2ab6330e 1149/**\r
1150 Get all token space guid table which is different with given token space guid.\r
1151\r
419db80b 1152 @param ExMapTableSize The size of ExMapTable in item\r
2ab6330e 1153 @param ExMapTable Token space guid table that want to be scaned.\r
1154 @param GuidTable Guid table\r
1155\r
1156 @return all token space guid table which is different with given token space guid.\r
1157\r
1158**/\r
80408db0 1159EFI_GUID **\r
1160GetDistinctTokenSpace (\r
1161 IN OUT UINTN *ExMapTableSize,\r
1162 IN DYNAMICEX_MAPPING *ExMapTable,\r
1163 IN EFI_GUID *GuidTable\r
1164 )\r
1165{\r
1166 EFI_GUID **DistinctTokenSpace;\r
1167 UINTN OldGuidIndex;\r
1168 UINTN TsIdx;\r
419db80b 1169 UINTN TempTsIdx;\r
80408db0 1170 UINTN Idx;\r
419db80b 1171 BOOLEAN Match;\r
80408db0 1172\r
1173 DistinctTokenSpace = AllocateZeroPool (*ExMapTableSize * sizeof (EFI_GUID *));\r
1174 ASSERT (DistinctTokenSpace != NULL);\r
1175\r
1176 TsIdx = 0;\r
1177 OldGuidIndex = ExMapTable[0].ExGuidIndex;\r
1178 DistinctTokenSpace[TsIdx] = &GuidTable[OldGuidIndex];\r
1179 for (Idx = 1; Idx < *ExMapTableSize; Idx++) {\r
419db80b
BF
1180 Match = FALSE;\r
1181 OldGuidIndex = ExMapTable[Idx].ExGuidIndex;\r
1182 for (TempTsIdx = 0; TempTsIdx <= TsIdx; TempTsIdx++) {\r
1183 if (&GuidTable[OldGuidIndex] == DistinctTokenSpace[TempTsIdx]) {\r
1184 //\r
1185 // Have recorded this GUID.\r
1186 //\r
1187 Match = TRUE;\r
1188 break;\r
1189 }\r
1190 }\r
1191 if (!Match) {\r
80408db0 1192 DistinctTokenSpace[++TsIdx] = &GuidTable[OldGuidIndex];\r
1193 }\r
1194 }\r
1195\r
1196 //\r
1197 // The total number of Distinct Token Space\r
1198 // is TsIdx + 1 because we use TsIdx as a index\r
1199 // to the DistinctTokenSpace[]\r
1200 //\r
1201 *ExMapTableSize = TsIdx + 1;\r
1202 return DistinctTokenSpace;\r
1203 \r
1204}\r
1205 \r
2ab6330e 1206/**\r
419db80b
BF
1207 Retrieves the next valid PCD token namespace for a given namespace.\r
1208\r
1209 Gets the next valid token namespace for a given namespace. This is useful to traverse the valid\r
1210 token namespaces on a platform.\r
1211\r
1212 @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token\r
1213 namespace from which the search will start. On output, it designates the next valid\r
1214 token namespace on the platform. If *Guid is NULL, then the GUID of the first token\r
1215 space of the current platform is returned. If the search cannot locate the next valid\r
1216 token namespace, an error is returned and the value of *Guid is undefined.\r
1217 \r
1218 @retval EFI_SUCCESS The PCD service retrieved the value requested.\r
1219 @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace.\r
1220\r
2ab6330e 1221**/\r
80408db0 1222EFI_STATUS\r
1223EFIAPI\r
1224DxePcdGetNextTokenSpace (\r
1225 IN OUT CONST EFI_GUID **Guid\r
1226 )\r
1227{\r
1228 UINTN Idx;\r
1229 UINTN Idx2;\r
1230 UINTN Idx3;\r
1231 UINTN PeiTokenSpaceTableSize;\r
1232 UINTN DxeTokenSpaceTableSize;\r
1233 EFI_GUID **PeiTokenSpaceTable;\r
1234 EFI_GUID **DxeTokenSpaceTable;\r
1235 BOOLEAN Match;\r
1236 BOOLEAN PeiExMapTableEmpty;\r
1237 BOOLEAN DxeExMapTableEmpty;\r
1238\r
80408db0 1239 ASSERT (Guid != NULL);\r
1240 \r
419db80b
BF
1241 PeiExMapTableEmpty = mPeiExMapTableEmpty;\r
1242 DxeExMapTableEmpty = mDxeExMapTableEmpty;\r
80408db0 1243\r
1244 if (PeiExMapTableEmpty && DxeExMapTableEmpty) {\r
419db80b 1245 return EFI_NOT_FOUND;\r
80408db0 1246 }\r
1247 \r
80408db0 1248 if (TmpTokenSpaceBuffer[0] == NULL) {\r
1249 PeiTokenSpaceTableSize = 0;\r
1250\r
1251 if (!PeiExMapTableEmpty) {\r
419db80b 1252 PeiTokenSpaceTableSize = mPeiExMapppingTableSize / sizeof(DYNAMICEX_MAPPING);\r
80408db0 1253 PeiTokenSpaceTable = GetDistinctTokenSpace (&PeiTokenSpaceTableSize,\r
419db80b
BF
1254 (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset),\r
1255 (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset)\r
80408db0 1256 );\r
1257 CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID*) * PeiTokenSpaceTableSize);\r
419db80b 1258 FreePool (PeiTokenSpaceTable);\r
80408db0 1259 }\r
1260\r
1261 if (!DxeExMapTableEmpty) {\r
419db80b 1262 DxeTokenSpaceTableSize = mDxeExMapppingTableSize / sizeof(DYNAMICEX_MAPPING);\r
80408db0 1263 DxeTokenSpaceTable = GetDistinctTokenSpace (&DxeTokenSpaceTableSize,\r
419db80b
BF
1264 (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset),\r
1265 (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset)\r
80408db0 1266 );\r
1267\r
1268 //\r
1269 // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable\r
1270 //\r
1271 for (Idx2 = 0, Idx3 = PeiTokenSpaceTableSize; Idx2 < DxeTokenSpaceTableSize; Idx2++) {\r
1272 Match = FALSE;\r
1273 for (Idx = 0; Idx < PeiTokenSpaceTableSize; Idx++) {\r
1274 if (CompareGuid (TmpTokenSpaceBuffer[Idx], DxeTokenSpaceTable[Idx2])) {\r
1275 Match = TRUE;\r
1276 break;\r
1277 }\r
1278 }\r
1279 if (!Match) {\r
1280 TmpTokenSpaceBuffer[Idx3++] = DxeTokenSpaceTable[Idx2];\r
1281 }\r
1282 }\r
419db80b
BF
1283\r
1284 TmpTokenSpaceBufferCount = Idx3;\r
1285 FreePool (DxeTokenSpaceTable);\r
80408db0 1286 }\r
1287 }\r
1288\r
1289 if (*Guid == NULL) {\r
1290 *Guid = TmpTokenSpaceBuffer[0];\r
1291 return EFI_SUCCESS;\r
1292 }\r
1293 \r
419db80b
BF
1294 for (Idx = 0; Idx < TmpTokenSpaceBufferCount; Idx++) {\r
1295 if (CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) {\r
1296 if (Idx == TmpTokenSpaceBufferCount - 1) {\r
1297 //\r
1298 // It has been the last token namespace.\r
1299 //\r
1300 *Guid = NULL;\r
1301 return EFI_NOT_FOUND;\r
1302 } else {\r
1303 Idx++;\r
1304 *Guid = TmpTokenSpaceBuffer[Idx];\r
1305 return EFI_SUCCESS;\r
1306 }\r
80408db0 1307 }\r
1308 }\r
1309\r
1310 return EFI_NOT_FOUND;\r
80408db0 1311}\r
1312\r
1313\r