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