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