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