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