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