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