]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Universal/PCD/Dxe/Service.c
771c4db54d77cca45038ba4ffd12e6b43abbd56c
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Dxe / Service.c
1 /** @file
2 Private functions used by PCD DXE driver.s
3
4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13
14 Module Name: Service.c
15
16 **/
17 #include "Service.h"
18
19
20 //
21 // Build Tool will generate DXE_PCD_DB_INIT_VALUE in Autogen.h
22 // Compression Algorithm will take care of the size optimization.
23 //
24
25 PCD_DATABASE * mPcdDatabase;
26
27 LIST_ENTRY *mCallbackFnTable;
28
29 VOID *
30 GetWorker (
31 UINTN TokenNumber,
32 UINTN GetSize
33 )
34 {
35 UINT32 *LocalTokenNumberTable;
36 UINT16 *SizeTable;
37 BOOLEAN IsPeiDb;
38 UINTN Size;
39 UINT32 Offset;
40 EFI_GUID *GuidTable;
41 UINT16 *StringTable;
42 EFI_GUID *Guid;
43 UINT16 *Name;
44 VARIABLE_HEAD *VariableHead;
45 EFI_STATUS Status;
46 UINTN DataSize;
47 VOID *Data;
48 VPD_HEAD *VpdHead;
49 UINT8 *PcdDb;
50 UINT16 StringTableIdx;
51 UINT32 LocalTokenNumber;
52
53 //
54 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
55 // We have to decrement TokenNumber by 1 to make it usable
56 // as the array index.
57 //
58 TokenNumber--;
59
60 ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);
61
62 Size = DxePcdGetSize (TokenNumber + 1);
63 ASSERT (GetSize == Size || GetSize == 0);
64
65
66 IsPeiDb = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE;
67
68 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable :
69 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
70
71 SizeTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SizeTable:
72 mPcdDatabase->DxeDb.Init.SizeTable;
73
74 TokenNumber = IsPeiDb ? TokenNumber :
75 TokenNumber - PEI_LOCAL_TOKEN_NUMBER;
76
77 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];
78
79 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
80 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size, IsPeiDb);
81 }
82
83 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);
84 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :
85 mPcdDatabase->DxeDb.Init.StringTable;
86
87 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
88
89 switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {
90 case PCD_TYPE_VPD:
91 VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset);
92 return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);
93
94 case PCD_TYPE_HII:
95 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :
96 mPcdDatabase->DxeDb.Init.GuidTable;
97
98 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
99
100 Guid = &(GuidTable[VariableHead->GuidTableIndex]);
101 Name = &(StringTable[VariableHead->StringIndex]);
102
103 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
104 if (Status == EFI_SUCCESS) {
105 return (UINT8 *) Data + VariableHead->Offset;
106 } else {
107 //
108 // Return the default value specified by Platform Integrator
109 //
110 return (VOID *) ((UINT8 *) PcdDb + VariableHead->DefaultValueOffset);
111 }
112
113 case PCD_TYPE_STRING:
114 StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset);
115 return (VOID *) &StringTable[StringTableIdx];
116
117 case PCD_TYPE_DATA:
118 return (VOID *) ((UINT8 *) PcdDb + Offset);
119 break;
120
121 default:
122 ASSERT (FALSE);
123 break;
124
125 }
126
127 ASSERT (FALSE);
128
129 return NULL;
130
131 }
132
133
134
135 EFI_STATUS
136 DxeRegisterCallBackWorker (
137 IN UINTN TokenNumber,
138 IN CONST GUID *Guid, OPTIONAL
139 IN PCD_PROTOCOL_CALLBACK CallBackFunction
140 )
141 {
142 CALLBACK_FN_ENTRY *FnTableEntry;
143 LIST_ENTRY *ListHead;
144 LIST_ENTRY *ListNode;
145
146 if (Guid != NULL) {
147 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);
148 }
149
150 //
151 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
152 // We have to decrement TokenNumber by 1 to make it usable
153 // as the array index.
154 //
155 TokenNumber--;
156
157 ListHead = &mCallbackFnTable[TokenNumber];
158 ListNode = GetFirstNode (ListHead);
159
160 while (ListNode != ListHead) {
161 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);
162
163 if (FnTableEntry->CallbackFn == CallBackFunction) {
164 //
165 // We only allow a Callback function to be register once
166 // for a TokenNumber. So just return EFI_SUCCESS
167 //
168 return EFI_SUCCESS;
169 }
170 ListNode = GetNextNode (ListHead, ListNode);
171 }
172
173 FnTableEntry = AllocatePool (sizeof(CALLBACK_FN_ENTRY));
174 ASSERT (FnTableEntry != NULL);
175
176 FnTableEntry->CallbackFn = CallBackFunction;
177 InsertTailList (ListHead, &FnTableEntry->Node);
178
179 return EFI_SUCCESS;
180 }
181
182
183
184
185 EFI_STATUS
186 DxeUnRegisterCallBackWorker (
187 IN UINTN TokenNumber,
188 IN CONST GUID *Guid, OPTIONAL
189 IN PCD_PROTOCOL_CALLBACK CallBackFunction
190 )
191 {
192 CALLBACK_FN_ENTRY *FnTableEntry;
193 LIST_ENTRY *ListHead;
194 LIST_ENTRY *ListNode;
195
196 if (Guid != NULL) {
197 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);
198 }
199
200 //
201 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
202 // We have to decrement TokenNumber by 1 to make it usable
203 // as the array index.
204 //
205 TokenNumber--;
206
207 ListHead = &mCallbackFnTable[TokenNumber];
208 ListNode = GetFirstNode (ListHead);
209
210 while (ListNode != ListHead) {
211 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);
212
213 if (FnTableEntry->CallbackFn == CallBackFunction) {
214 //
215 // We only allow a Callback function to be register once
216 // for a TokenNumber. So we can safely remove the Node from
217 // the Link List and return EFI_SUCCESS.
218 //
219 RemoveEntryList (ListNode);
220 FreePool (FnTableEntry);
221
222 return EFI_SUCCESS;
223 }
224 ListNode = GetNextNode (ListHead, ListNode);
225 }
226
227 return EFI_INVALID_PARAMETER;
228 }
229
230
231
232 UINTN
233 ExGetNextTokeNumber (
234 IN CONST EFI_GUID *Guid,
235 IN UINTN TokenNumber,
236 IN EFI_GUID *GuidTable,
237 IN UINTN SizeOfGuidTable,
238 IN DYNAMICEX_MAPPING *ExMapTable,
239 IN UINTN SizeOfExMapTable
240 )
241 {
242 EFI_GUID *MatchGuid;
243 UINTN Idx;
244 UINTN GuidTableIdx;
245 BOOLEAN Found;
246
247 MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid);
248 if (MatchGuid == NULL) {
249 return PCD_INVALID_TOKEN_NUMBER;
250 }
251
252 Found = FALSE;
253 GuidTableIdx = MatchGuid - GuidTable;
254 for (Idx = 0; Idx < SizeOfExMapTable; Idx++) {
255 if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) {
256 Found = TRUE;
257 break;
258 }
259 }
260
261 if (Found) {
262 if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
263 return ExMapTable[Idx].ExTokenNumber;
264 }
265
266 for ( ; Idx < SizeOfExMapTable; Idx++) {
267 if (ExMapTable[Idx].ExTokenNumber == TokenNumber) {
268 Idx++;
269 if (Idx == SizeOfExMapTable) {
270 //
271 // Exceed the length of ExMap Table
272 //
273 return PCD_INVALID_TOKEN_NUMBER;
274 } else if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) {
275 //
276 // Found the next match
277 //
278 return ExMapTable[Idx].ExTokenNumber;
279 } else {
280 //
281 // Guid has been changed. It is the next Token Space Guid.
282 // We should flag no more TokenNumber.
283 //
284 return PCD_INVALID_TOKEN_NUMBER;
285 }
286 }
287 }
288 }
289
290 return PCD_INVALID_TOKEN_NUMBER;
291 }
292
293
294
295
296 VOID
297 BuildPcdDxeDataBase (
298 VOID
299 )
300 {
301 PEI_PCD_DATABASE *PeiDatabase;
302 EFI_HOB_GUID_TYPE *GuidHob;
303 UINTN Idx;
304
305 mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));
306 ASSERT (mPcdDatabase != NULL);
307
308 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
309
310 if (GuidHob != NULL) {
311
312 //
313 // We will copy over the PEI phase's PCD Database.
314 //
315 // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM
316 // should not be included at all. So the GuidHob could
317 // be NULL. If it is NULL, we just copy over the DXE Default
318 // Value to PCD Database.
319 //
320
321 PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);
322 //
323 // Copy PCD Entries refereneced in PEI phase to PCD DATABASE
324 //
325 CopyMem (&mPcdDatabase->PeiDb, PeiDatabase, sizeof (PEI_PCD_DATABASE));
326 }
327
328 //
329 // Copy PCD Entries with default value to PCD DATABASE
330 //
331 CopyMem (&mPcdDatabase->DxeDb.Init, &gDXEPcdDbInit, sizeof(DXE_PCD_DATABASE_INIT));
332
333
334 //
335 // Initialized the Callback Function Table
336 //
337
338 if (PCD_TOTAL_TOKEN_NUMBER != 0) {
339 mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY));
340 }
341
342 for (Idx = 0; Idx < PCD_TOTAL_TOKEN_NUMBER; Idx++) {
343 InitializeListHead (&mCallbackFnTable[Idx]);
344 }
345
346 return;
347 }
348
349
350
351 EFI_STATUS
352 GetHiiVariable (
353 IN EFI_GUID *VariableGuid,
354 IN UINT16 *VariableName,
355 OUT VOID ** VariableData,
356 OUT UINTN *VariableSize
357 )
358 {
359 UINTN Size;
360 EFI_STATUS Status;
361 VOID *Buffer;
362
363 Size = 0;
364 Buffer = NULL;
365
366 Status = EfiGetVariable (
367 (UINT16 *)VariableName,
368 VariableGuid,
369 NULL,
370 &Size,
371 Buffer
372 );
373
374 if (Status == EFI_BUFFER_TOO_SMALL) {
375
376 Buffer = AllocatePool (Size);
377
378 ASSERT (Buffer != NULL);
379
380 Status = EfiGetVariable (
381 VariableName,
382 VariableGuid,
383 NULL,
384 &Size,
385 Buffer
386 );
387
388 ASSERT (Status == EFI_SUCCESS);
389 }
390
391 *VariableData = Buffer;
392 *VariableSize = Size;
393
394 return Status;
395
396 }
397
398
399 UINT32
400 GetSkuEnabledTokenNumber (
401 UINT32 LocalTokenNumber,
402 UINTN Size,
403 BOOLEAN IsPeiDb
404 )
405 {
406 SKU_HEAD *SkuHead;
407 SKU_ID *SkuIdTable;
408 INTN i;
409 UINT8 *Value;
410 SKU_ID *PhaseSkuIdTable;
411 UINT8 *PcdDb;
412
413 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);
414
415 PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb;
416
417 SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
418 Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset);
419
420 PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :
421 mPcdDatabase->DxeDb.Init.SkuIdTable;
422
423 SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];
424
425 for (i = 0; i < SkuIdTable[0]; i++) {
426 if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[i + 1]) {
427 break;
428 }
429 }
430 ASSERT (i < SkuIdTable[0]);
431
432 switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {
433 case PCD_TYPE_VPD:
434 Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);
435 return (UINT32) ((Value - PcdDb) | PCD_TYPE_VPD);
436
437 case PCD_TYPE_HII:
438 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);
439 return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII);
440
441 case PCD_TYPE_DATA:
442 Value += Size * i;
443 return (UINT32) (Value - PcdDb);
444
445 default:
446 ASSERT (FALSE);
447 }
448
449 ASSERT (FALSE);
450
451 return 0;
452
453 }
454
455
456
457
458
459 VOID
460 InvokeCallbackOnSet (
461 UINT32 ExTokenNumber,
462 CONST EFI_GUID *Guid, OPTIONAL
463 UINTN TokenNumber,
464 VOID *Data,
465 UINTN Size
466 )
467 {
468 CALLBACK_FN_ENTRY *FnTableEntry;
469 LIST_ENTRY *ListHead;
470 LIST_ENTRY *ListNode;
471
472 //
473 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
474 // We have to decrement TokenNumber by 1 to make it usable
475 // as the array index.
476 //
477 TokenNumber--;
478
479 ListHead = &mCallbackFnTable[TokenNumber];
480 ListNode = GetFirstNode (ListHead);
481
482 while (ListNode != ListHead) {
483 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);
484
485 FnTableEntry->CallbackFn(Guid,
486 (Guid == NULL) ? TokenNumber : ExTokenNumber,
487 Data,
488 Size);
489
490 ListNode = GetNextNode (ListHead, ListNode);
491 }
492
493 return;
494 }
495
496
497
498
499 EFI_STATUS
500 SetWorker (
501 UINTN TokenNumber,
502 VOID *Data,
503 UINTN Size,
504 BOOLEAN PtrType
505 )
506 {
507 UINT32 *LocalTokenNumberTable;
508 BOOLEAN IsPeiDb;
509 UINT32 LocalTokenNumber;
510 EFI_GUID *GuidTable;
511 UINT16 *StringTable;
512 EFI_GUID *Guid;
513 UINT16 *Name;
514 UINTN VariableOffset;
515 VOID *InternalData;
516 VARIABLE_HEAD *VariableHead;
517 UINTN Offset;
518 UINT8 *PcdDb;
519
520 //
521 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
522 // We have to decrement TokenNumber by 1 to make it usable
523 // as the array index.
524 //
525 TokenNumber--;
526
527 ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);
528
529 if (PtrType) {
530 ASSERT (Size <= DxePcdGetSize (TokenNumber + 1));
531 } else {
532 ASSERT (Size == DxePcdGetSize (TokenNumber + 1));
533 }
534
535 IsPeiDb = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE;
536
537 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable :
538 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
539
540 if ((TokenNumber < PEI_NEX_TOKEN_NUMBER) ||
541 (TokenNumber >= PEI_LOCAL_TOKEN_NUMBER || TokenNumber < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER))) {
542 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, Size);
543 }
544
545 TokenNumber = IsPeiDb ? TokenNumber
546 : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;
547
548 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];
549
550 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
551 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size, IsPeiDb);
552 }
553
554 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
555
556 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);
557
558 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :
559 mPcdDatabase->DxeDb.Init.StringTable;
560
561 InternalData = PcdDb + Offset;
562
563 switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {
564 case PCD_TYPE_VPD:
565 ASSERT (FALSE);
566 return EFI_INVALID_PARAMETER;
567
568 case PCD_TYPE_STRING:
569 CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, Size);
570 return EFI_SUCCESS;
571
572 case PCD_TYPE_HII:
573 //
574 // Bug Bug: Please implement this
575 //
576 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :
577 mPcdDatabase->DxeDb.Init.GuidTable;
578
579 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
580
581 Guid = &(GuidTable[VariableHead->GuidTableIndex]);
582 Name = &(StringTable[VariableHead->StringIndex]);
583 VariableOffset = VariableHead->Offset;
584
585 return SetHiiVariable (Guid, Name, Data, Size, VariableOffset);
586
587 case PCD_TYPE_DATA:
588 if (PtrType) {
589 CopyMem (InternalData, Data, Size);
590 return EFI_SUCCESS;
591 }
592
593 switch (Size) {
594 case sizeof(UINT8):
595 *((UINT8 *) InternalData) = *((UINT8 *) Data);
596 return EFI_SUCCESS;
597
598 case sizeof(UINT16):
599 *((UINT16 *) InternalData) = *((UINT16 *) Data);
600 return EFI_SUCCESS;
601
602 case sizeof(UINT32):
603 *((UINT32 *) InternalData) = *((UINT32 *) Data);
604 return EFI_SUCCESS;
605
606 case sizeof(UINT64):
607 *((UINT64 *) InternalData) = *((UINT64 *) Data);
608 return EFI_SUCCESS;
609
610 default:
611 ASSERT (FALSE);
612 return EFI_NOT_FOUND;
613 }
614
615 default:
616 ASSERT (FALSE);
617 break;
618 }
619
620 ASSERT (FALSE);
621 return EFI_NOT_FOUND;
622 }
623
624
625
626
627
628 VOID *
629 ExGetWorker (
630 IN CONST EFI_GUID *Guid,
631 IN UINTN ExTokenNumber,
632 IN UINTN GetSize
633 )
634 {
635 return GetWorker(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber), GetSize);
636 }
637
638
639
640
641
642 EFI_STATUS
643 ExSetWorker (
644 IN UINTN ExTokenNumber,
645 IN CONST EFI_GUID *Guid,
646 VOID *Data,
647 UINTN SetSize,
648 BOOLEAN PtrType
649 )
650 {
651 UINTN TokenNumber;
652
653 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber);
654
655 InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, SetSize);
656
657 SetWorker (TokenNumber, Data, SetSize, PtrType);
658
659 return EFI_SUCCESS;
660
661 }
662
663
664
665
666 EFI_STATUS
667 SetHiiVariable (
668 IN EFI_GUID *VariableGuid,
669 IN UINT16 *VariableName,
670 IN CONST VOID *Data,
671 IN UINTN DataSize,
672 IN UINTN Offset
673 )
674 {
675 UINTN Size;
676 VOID *Buffer;
677 EFI_STATUS Status;
678 UINT32 Attribute;
679
680 Size = 0;
681
682 Status = EfiGetVariable (
683 (UINT16 *)VariableName,
684 VariableGuid,
685 &Attribute,
686 &Size,
687 NULL
688 );
689
690 if (Status == EFI_BUFFER_TOO_SMALL) {
691
692 Buffer = AllocatePool (Size);
693
694 ASSERT (Buffer != NULL);
695
696 Status = EfiGetVariable (
697 VariableName,
698 VariableGuid,
699 &Attribute,
700 &Size,
701 Buffer
702 );
703
704 ASSERT_EFI_ERROR (Status);
705
706 CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);
707
708 } else {
709
710 Attribute = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
711 Size = DataSize + Offset;
712 Buffer = AllocateZeroPool (Size);
713 ASSERT (Buffer != NULL);
714 CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);
715
716 }
717
718 return EfiSetVariable (
719 VariableName,
720 VariableGuid,
721 Attribute,
722 Size,
723 Buffer
724 );
725
726 }
727
728
729
730
731
732 UINTN
733 GetExPcdTokenNumber (
734 IN CONST EFI_GUID *Guid,
735 IN UINT32 ExTokenNumber
736 )
737 {
738 UINT32 i;
739 DYNAMICEX_MAPPING *ExMap;
740 EFI_GUID *GuidTable;
741 EFI_GUID *MatchGuid;
742 UINTN MatchGuidIdx;
743
744 if (!PEI_DATABASE_EMPTY) {
745 ExMap = mPcdDatabase->PeiDb.Init.ExMapTable;
746 GuidTable = mPcdDatabase->PeiDb.Init.GuidTable;
747
748 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid);
749
750 if (MatchGuid != NULL) {
751
752 MatchGuidIdx = MatchGuid - GuidTable;
753
754 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {
755 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&
756 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {
757 return ExMap[i].LocalTokenNumber;
758
759 }
760 }
761 }
762 }
763
764 ExMap = mPcdDatabase->DxeDb.Init.ExMapTable;
765 GuidTable = mPcdDatabase->DxeDb.Init.GuidTable;
766
767 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);
768 //
769 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
770 // error in the BUILD system.
771 //
772 ASSERT (MatchGuid != NULL);
773
774 MatchGuidIdx = MatchGuid - GuidTable;
775
776 for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) {
777 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&
778 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {
779 return ExMap[i].LocalTokenNumber;
780 }
781 }
782
783 ASSERT (FALSE);
784
785 return 0;
786 }
787