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