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