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