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