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