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