]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/PCD/Dxe/Pcd.c
MdeModulePkg and Nt32Pkg Pcd: Add the new EFI_GET_PCD_INFO_PROTOCOL and EFI_GET_PCD_I...
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Dxe / Pcd.c
... / ...
CommitLineData
1/** @file\r
2 PCD DXE driver manage all PCD entry initialized in PEI phase and DXE phase, and\r
3 produce the implementation of native PCD protocol and EFI_PCD_PROTOCOL defined in\r
4 PI 1.2 Vol3.\r
5\r
6Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
7This program and the accompanying materials\r
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
15**/\r
16\r
17#include "Service.h"\r
18\r
19///\r
20/// PCD database lock.\r
21///\r
22EFI_LOCK mPcdDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE(TPL_NOTIFY);\r
23\r
24///\r
25/// PCD_PROTOCOL the EDKII native implementation which support dynamic \r
26/// type and dynamicEx type PCDs.\r
27///\r
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
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
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
91\r
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
111EFI_HANDLE mPcdHandle = NULL;\r
112\r
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
124EFI_STATUS\r
125EFIAPI\r
126PcdDxeInit (\r
127 IN EFI_HANDLE ImageHandle,\r
128 IN EFI_SYSTEM_TABLE *SystemTable\r
129 )\r
130{\r
131 EFI_STATUS Status;\r
132 \r
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
141 //\r
142 // Install PCD_PROTOCOL to handle dynamic type PCD\r
143 // Install EFI_PCD_PROTOCOL to handle dynamicEx type PCD\r
144 //\r
145 Status = gBS->InstallMultipleProtocolInterfaces (\r
146 &mPcdHandle,\r
147 &gPcdProtocolGuid, &mPcdInstance,\r
148 &gEfiPcdProtocolGuid, &mEfiPcdInstance,\r
149 NULL\r
150 );\r
151 ASSERT_EFI_ERROR (Status);\r
152\r
153 //\r
154 // Only install PcdInfo PROTOCOL when PCD info content is present. \r
155 //\r
156 if (mPcdDatabase.DxeDb->PcdNameTableOffset != 0) {\r
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
170 return Status;\r
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
201\r
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
234 return mPcdDatabase.PeiDb->SystemSkuId;\r
235}\r
236\r
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
257**/\r
258VOID\r
259EFIAPI\r
260DxePcdSetSku (\r
261 IN UINTN SkuId\r
262 )\r
263{\r
264 mPcdDatabase.PeiDb->SystemSkuId = (SKU_ID) SkuId;\r
265 \r
266 return;\r
267}\r
268\r
269/**\r
270 Retrieves an 8-bit value for a given PCD token.\r
271\r
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
276\r
277 @return The UINT8 value.\r
278 \r
279**/\r
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
289/**\r
290 Retrieves an 16-bit value for a given PCD token.\r
291\r
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
296\r
297 @return The UINT16 value.\r
298 \r
299**/\r
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
309/**\r
310 Retrieves an 32-bit value for a given PCD token.\r
311\r
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
316\r
317 @return The UINT32 value.\r
318 \r
319**/\r
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
329/**\r
330 Retrieves an 64-bit value for a given PCD token.\r
331\r
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
336\r
337 @return The UINT64 value.\r
338 \r
339**/\r
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
349/**\r
350 Retrieves a pointer to a value for a given PCD token.\r
351\r
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
356\r
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
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
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
378\r
379 @param[in] TokenNumber The PCD token number. \r
380\r
381 @return The Boolean value.\r
382 \r
383**/\r
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
393/**\r
394 Retrieves the size of the value for a given PCD token.\r
395\r
396 Retrieves the current size of a particular PCD token. \r
397 If the TokenNumber is invalid, the results are unpredictable.\r
398\r
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
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
430 ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);\r
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
435 IsPeiDb = (BOOLEAN) (TokenNumber + 1 < mPeiLocalTokenCount + 1);\r
436 \r
437 TokenNumber = IsPeiDb ? TokenNumber : \r
438 (TokenNumber - mPeiLocalTokenCount);\r
439\r
440 LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) \r
441 : (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);\r
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
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
463\r
464 @param[in] Guid The token space for the token number.\r
465 @param[in] ExTokenNumber The PCD token number. \r
466\r
467 @return The size 8-bit value for the PCD token.\r
468 \r
469**/\r
470UINT8\r
471EFIAPI\r
472DxePcdGet8Ex (\r
473 IN CONST EFI_GUID *Guid,\r
474 IN UINTN ExTokenNumber\r
475 )\r
476{\r
477 return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof(UINT8)));\r
478}\r
479\r
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
487\r
488 @param[in] Guid The token space for the token number.\r
489 @param[in] ExTokenNumber The PCD token number. \r
490\r
491 @return The size 16-bit value for the PCD token.\r
492 \r
493**/\r
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
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
511\r
512 @param[in] Guid The token space for the token number.\r
513 @param[in] ExTokenNumber The PCD token number. \r
514\r
515 @return The size 32-bit value for the PCD token.\r
516 \r
517**/\r
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
528/**\r
529 Retrieves an 64-bit value for a given PCD token.\r
530\r
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
535\r
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
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
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
559\r
560 @param[in] Guid The token space for the token number.\r
561 @param[in] ExTokenNumber The PCD token number. \r
562\r
563 @return The pointer to the buffer to be retrived.\r
564 \r
565**/\r
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
576/**\r
577 Retrieves an Boolean value for a given PCD token.\r
578\r
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
583\r
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
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
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
605\r
606 @param[in] Guid The token space for the token number.\r
607 @param[in] ExTokenNumber The PCD token number. \r
608\r
609 @return The size of the value for the PCD token.\r
610 \r
611**/\r
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
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
628\r
629 @param[in] TokenNumber The PCD token number. \r
630 @param[in] Value The value to set for the PCD token.\r
631\r
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
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
649/**\r
650 Sets an 16-bit value for a given PCD token.\r
651\r
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
655\r
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
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
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
682\r
683 @param[in] TokenNumber The PCD token number. \r
684 @param[in] Value The value to set for the PCD token.\r
685\r
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
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
703/**\r
704 Sets an 64-bit value for a given PCD token.\r
705\r
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
709\r
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
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
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
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
762/**\r
763 Sets an Boolean value for a given PCD token.\r
764\r
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
768\r
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
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
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
795\r
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
799\r
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
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
818/**\r
819 Sets an 16-bit value for a given PCD token.\r
820\r
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
824\r
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
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
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
853\r
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
857\r
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
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
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
882\r
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
886\r
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
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
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
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
939/**\r
940 Sets an Boolean value for a given PCD token.\r
941\r
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
945\r
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
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
968/**\r
969 Specifies a function to be called anytime the value of a designated token is changed.\r
970\r
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
974\r
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
978\r
979**/\r
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
990 if (CallBackFunction == NULL) {\r
991 return EFI_INVALID_PARAMETER;\r
992 }\r
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
1005/**\r
1006 Cancels a previously set callback function for a particular PCD token number.\r
1007\r
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
1011\r
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
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
1027 if (CallBackFunction == NULL) {\r
1028 return EFI_INVALID_PARAMETER;\r
1029 }\r
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
1043/**\r
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
1062 @param[in, out] TokenNumber \r
1063 A pointer to the PCD token number to use to find the subsequent token number. \r
1064\r
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
1067\r
1068**/\r
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
1080 Status = EFI_NOT_FOUND;\r
1081 PeiExMapTableEmpty = mPeiExMapTableEmpty;\r
1082 DxeExMapTableEmpty = mDxeExMapTableEmpty;\r
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
1091 if (((*TokenNumber + 1 > mPeiNexTokenCount + 1) && (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) ||\r
1092 ((*TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) {\r
1093 return EFI_NOT_FOUND;\r
1094 }\r
1095 \r
1096 (*TokenNumber)++;\r
1097 if ((*TokenNumber + 1 > mPeiNexTokenCount + 1) &&\r
1098 (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) {\r
1099 //\r
1100 // The first Non-Ex type Token Number for DXE PCD \r
1101 // database is mPeiLocalTokenCount + 1\r
1102 //\r
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
1110 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
1111 return EFI_NOT_FOUND;\r
1112 }\r
1113 return EFI_SUCCESS;\r
1114 }\r
1115\r
1116 if (PeiExMapTableEmpty && DxeExMapTableEmpty) {\r
1117 return EFI_NOT_FOUND;\r
1118 }\r
1119\r
1120 if (!PeiExMapTableEmpty) {\r
1121 Status = ExGetNextTokeNumber (\r
1122 Guid,\r
1123 TokenNumber,\r
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
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
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
1143 );\r
1144 }\r
1145\r
1146 return Status;\r
1147}\r
1148\r
1149/**\r
1150 Get all token space guid table which is different with given token space guid.\r
1151\r
1152 @param ExMapTableSize The size of ExMapTable in item\r
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
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
1169 UINTN TempTsIdx;\r
1170 UINTN Idx;\r
1171 BOOLEAN Match;\r
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
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
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
1206/**\r
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
1221**/\r
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
1239 ASSERT (Guid != NULL);\r
1240 \r
1241 PeiExMapTableEmpty = mPeiExMapTableEmpty;\r
1242 DxeExMapTableEmpty = mDxeExMapTableEmpty;\r
1243\r
1244 if (PeiExMapTableEmpty && DxeExMapTableEmpty) {\r
1245 return EFI_NOT_FOUND;\r
1246 }\r
1247 \r
1248 if (TmpTokenSpaceBuffer[0] == NULL) {\r
1249 PeiTokenSpaceTableSize = 0;\r
1250\r
1251 if (!PeiExMapTableEmpty) {\r
1252 PeiTokenSpaceTableSize = mPeiExMapppingTableSize / sizeof(DYNAMICEX_MAPPING);\r
1253 PeiTokenSpaceTable = GetDistinctTokenSpace (&PeiTokenSpaceTableSize,\r
1254 (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset),\r
1255 (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset)\r
1256 );\r
1257 CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID*) * PeiTokenSpaceTableSize);\r
1258 FreePool (PeiTokenSpaceTable);\r
1259 }\r
1260\r
1261 if (!DxeExMapTableEmpty) {\r
1262 DxeTokenSpaceTableSize = mDxeExMapppingTableSize / sizeof(DYNAMICEX_MAPPING);\r
1263 DxeTokenSpaceTable = GetDistinctTokenSpace (&DxeTokenSpaceTableSize,\r
1264 (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset),\r
1265 (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset)\r
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
1283\r
1284 TmpTokenSpaceBufferCount = Idx3;\r
1285 FreePool (DxeTokenSpaceTable);\r
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
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
1307 }\r
1308 }\r
1309\r
1310 return EFI_NOT_FOUND;\r
1311}\r
1312\r
1313\r