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