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