• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
PcdPeimInit(IN EFI_PEI_FILE_HANDLE FileHandle,IN CONST EFI_PEI_SERVICES ** PeiServices)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
PeiGetPcdInfoGetInfo(IN UINTN TokenNumber,OUT EFI_PCD_INFO * PcdInfo)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
PeiGetPcdInfoGetInfoEx(IN CONST EFI_GUID * Guid,IN UINTN TokenNumber,OUT EFI_PCD_INFO * PcdInfo)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
PeiGetPcdInfoGetSku(VOID)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
PeiPcdSetSku(IN UINTN SkuId)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
PeiPcdGet8(IN UINTN TokenNumber)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
PeiPcdGet16(IN UINTN TokenNumber)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
PeiPcdGet32(IN UINTN TokenNumber)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
PeiPcdGet64(IN UINTN TokenNumber)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
PeiPcdGetPtr(IN UINTN TokenNumber)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
PeiPcdGetBool(IN UINTN TokenNumber)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
PeiPcdGetSize(IN UINTN TokenNumber)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
PeiPcdGet8Ex(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber)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
PeiPcdGet16Ex(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber)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
PeiPcdGet32Ex(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber)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
PeiPcdGet64Ex(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber)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
PeiPcdGetPtrEx(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber)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
PeiPcdGetBoolEx(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber)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
PeiPcdGetSizeEx(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber)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
PeiPcdSet8(IN UINTN TokenNumber,IN UINT8 Value)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
PeiPcdSet16(IN UINTN TokenNumber,IN UINT16 Value)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
PeiPcdSet32(IN UINTN TokenNumber,IN UINT32 Value)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
PeiPcdSet64(IN UINTN TokenNumber,IN UINT64 Value)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
PeiPcdSetPtr(IN UINTN TokenNumber,IN OUT UINTN * SizeOfBuffer,IN VOID * Buffer)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
PeiPcdSetBool(IN UINTN TokenNumber,IN BOOLEAN Value)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
PeiPcdSet8Ex(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber,IN UINT8 Value)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
PeiPcdSet16Ex(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber,IN UINT16 Value)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
PeiPcdSet32Ex(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber,IN UINT32 Value)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
PeiPcdSet64Ex(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber,IN UINT64 Value)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
PeiPcdSetPtrEx(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber,IN OUT UINTN * SizeOfBuffer,IN VOID * Value)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
PeiPcdSetBoolEx(IN CONST EFI_GUID * Guid,IN UINTN ExTokenNumber,IN BOOLEAN Value)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
PeiRegisterCallBackOnSet(IN CONST EFI_GUID * Guid,OPTIONAL IN UINTN ExTokenNumber,IN PCD_PPI_CALLBACK CallBackFunction)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
PcdUnRegisterCallBackOnSet(IN CONST EFI_GUID * Guid,OPTIONAL IN UINTN ExTokenNumber,IN PCD_PPI_CALLBACK CallBackFunction)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
PeiPcdGetNextToken(IN CONST EFI_GUID * Guid,OPTIONAL IN OUT UINTN * TokenNumber)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
PeiPcdGetNextTokenSpace(IN OUT CONST EFI_GUID ** Guid)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
GetPtrTypeSize(IN UINTN LocalTokenNumberTableIdx,OUT UINTN * MaxSize,IN PEI_PCD_DATABASE * Database)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
SetPtrTypeSize(IN UINTN LocalTokenNumberTableIdx,IN OUT UINTN * CurrentSize,IN PEI_PCD_DATABASE * Database)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 }
1414