]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/PCD/Dxe/Service.c
Make sure the PCD dxe service driver can handle the case where no PEIM is using any...
[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
4c114006 27LIST_ENTRY mCallbackFnTable[PCD_TOTAL_TOKEN_NUMBER];\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
313 for (Idx = 0; Idx < PCD_TOTAL_TOKEN_NUMBER; Idx++) {\r
314 InitializeListHead (&mCallbackFnTable[Idx]);\r
315 }\r
52e1905d 316 \r
317 return;\r
878ddf1f 318}\r
319\r
320\r
321\r
52e1905d 322EFI_STATUS\r
323GetHiiVariable (\r
324 IN EFI_GUID *VariableGuid,\r
325 IN UINT16 *VariableName,\r
326 OUT VOID ** VariableData,\r
327 OUT UINTN *VariableSize\r
878ddf1f 328 )\r
329{\r
52e1905d 330 UINTN Size;\r
331 EFI_STATUS Status;\r
332 VOID *Buffer;\r
878ddf1f 333\r
52e1905d 334 Status = EfiGetVariable (\r
335 (UINT16 *)VariableName,\r
336 VariableGuid,\r
337 NULL,\r
338 &Size,\r
339 NULL\r
340 );\r
341 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
878ddf1f 342\r
52e1905d 343 Buffer = AllocatePool (Size);\r
878ddf1f 344\r
52e1905d 345 ASSERT (Buffer != NULL);\r
878ddf1f 346\r
52e1905d 347 Status = EfiGetVariable (\r
348 VariableName,\r
349 VariableGuid,\r
350 NULL,\r
351 &Size,\r
352 Buffer\r
353 );\r
878ddf1f 354\r
52e1905d 355 return Status;\r
878ddf1f 356\r
878ddf1f 357}\r
358\r
359\r
52e1905d 360UINT32\r
361GetSkuEnabledTokenNumber (\r
362 UINT32 LocalTokenNumber,\r
363 UINTN Size,\r
364 BOOLEAN IsPeiDb\r
365 ) \r
366{\r
367 SKU_HEAD *SkuHead;\r
368 SKU_ID *SkuIdTable;\r
369 INTN i;\r
370 UINT8 *Value;\r
371 SKU_ID *PhaseSkuIdTable;\r
372 UINT8 *PcdDb;\r
878ddf1f 373\r
52e1905d 374 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
878ddf1f 375\r
4c114006 376 PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb;\r
878ddf1f 377\r
52e1905d 378 SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
379 Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset); \r
878ddf1f 380\r
4c114006 381 PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :\r
382 mPcdDatabase->DxeDb.Init.SkuIdTable;\r
52e1905d 383 \r
384 SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];\r
385 \r
386 for (i = 0; i < SkuIdTable[0]; i++) {\r
4c114006 387 if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[i + 1]) {\r
52e1905d 388 break;\r
878ddf1f 389 }\r
878ddf1f 390 }\r
52e1905d 391 ASSERT (i < SkuIdTable[0]);\r
878ddf1f 392\r
52e1905d 393 switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {\r
394 case PCD_TYPE_VPD:\r
395 Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);\r
396 return ((Value - PcdDb) | PCD_TYPE_VPD);\r
878ddf1f 397\r
52e1905d 398 case PCD_TYPE_HII:\r
399 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);\r
400 return ((Value - PcdDb) | PCD_TYPE_HII);\r
401 \r
402 case PCD_TYPE_DATA:\r
403 Value += Size * i;\r
404 return (Value - PcdDb);\r
405 \r
406 default:\r
407 ASSERT (FALSE);\r
408 }\r
409\r
410 ASSERT (FALSE);\r
411\r
412 return 0;\r
878ddf1f 413 \r
414}\r
415\r
878ddf1f 416\r
878ddf1f 417\r
878ddf1f 418\r
878ddf1f 419\r
52e1905d 420VOID\r
421InvokeCallbackOnSet (\r
422 UINT32 ExTokenNumber,\r
423 CONST EFI_GUID *Guid, OPTIONAL\r
424 UINTN TokenNumber,\r
425 VOID *Data,\r
426 UINTN Size\r
427 )\r
428{\r
4c114006 429 CALLBACK_FN_ENTRY *FnTableEntry;\r
430 LIST_ENTRY *ListHead;\r
431 LIST_ENTRY *ListNode;\r
432\r
433 ListHead = &mCallbackFnTable[TokenNumber];\r
434 ListNode = GetFirstNode (ListHead);\r
435\r
436 while (ListNode != ListHead) {\r
437 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);\r
438\r
439 FnTableEntry->CallbackFn(Guid, \r
440 (Guid == NULL) ? TokenNumber : ExTokenNumber,\r
441 Data,\r
442 Size);\r
443 \r
444 ListNode = GetNextNode (ListHead, ListNode);\r
445 }\r
446 \r
52e1905d 447 return;\r
878ddf1f 448}\r
449\r
450\r
451\r
52e1905d 452\r
878ddf1f 453EFI_STATUS\r
52e1905d 454SetWorker (\r
0653eb89 455 PCD_TOKEN_NUMBER TokenNumber,\r
456 VOID *Data,\r
457 UINTN Size,\r
458 BOOLEAN PtrType\r
878ddf1f 459 )\r
460{\r
52e1905d 461 UINT32 *LocalTokenNumberTable;\r
462 BOOLEAN IsPeiDb;\r
9d6d8b24 463 UINT32 LocalTokenNumber;\r
464 EFI_GUID *GuidTable;\r
465 UINT16 *StringTable;\r
466 EFI_GUID *Guid;\r
467 UINT16 *Name;\r
468 VOID *InternalData;\r
469 VARIABLE_HEAD *VariableHead;\r
470 UINTN Offset;\r
471 UINT8 *PcdDb;\r
878ddf1f 472\r
878ddf1f 473\r
52e1905d 474 ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);\r
878ddf1f 475\r
52e1905d 476 if (PtrType) {\r
477 ASSERT (Size <= DxePcdGetSize (TokenNumber));\r
478 } else {\r
479 ASSERT (Size == DxePcdGetSize (TokenNumber));\r
878ddf1f 480 }\r
878ddf1f 481 \r
52e1905d 482 IsPeiDb = (TokenNumber <= PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE;\r
878ddf1f 483\r
4c114006 484 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : \r
485 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
878ddf1f 486\r
9d6d8b24 487 if ((TokenNumber < PEI_NEX_TOKEN_NUMBER) ||\r
488 (TokenNumber >= PEI_LOCAL_TOKEN_NUMBER || TokenNumber < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER))) {\r
489 InvokeCallbackOnSet (0, NULL, TokenNumber, Data, Size);\r
490 }\r
0653eb89 491\r
52e1905d 492 TokenNumber = IsPeiDb ? TokenNumber\r
493 : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;\r
878ddf1f 494\r
9d6d8b24 495 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
52e1905d 496 \r
52e1905d 497 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
498 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size, IsPeiDb);\r
499 }\r
878ddf1f 500\r
52e1905d 501 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
878ddf1f 502\r
4c114006 503 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
878ddf1f 504\r
4c114006 505 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :\r
506 mPcdDatabase->DxeDb.Init.StringTable;\r
52e1905d 507 \r
508 InternalData = PcdDb + Offset;\r
878ddf1f 509\r
52e1905d 510 switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {\r
511 case PCD_TYPE_VPD:\r
512 ASSERT (FALSE);\r
513 return EFI_INVALID_PARAMETER;\r
514 \r
515 case PCD_TYPE_STRING:\r
516 CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, Size);\r
517 break;\r
878ddf1f 518\r
52e1905d 519 case PCD_TYPE_HII:\r
520 //\r
521 // Bug Bug: Please implement this\r
522 //\r
4c114006 523 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :\r
524 mPcdDatabase->DxeDb.Init.GuidTable;\r
52e1905d 525 \r
526 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
527 \r
528 Guid = &(GuidTable[VariableHead->GuidTableIndex]);\r
529 Name = &(StringTable[VariableHead->StringIndex]);\r
878ddf1f 530\r
52e1905d 531 return EFI_SUCCESS;\r
878ddf1f 532\r
52e1905d 533 case PCD_TYPE_DATA:\r
534 if (PtrType) {\r
535 CopyMem (InternalData, Data, Size);\r
536 return EFI_SUCCESS;\r
537 }\r
878ddf1f 538\r
52e1905d 539 switch (Size) {\r
540 case sizeof(UINT8):\r
541 *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
542 return EFI_SUCCESS;\r
878ddf1f 543\r
52e1905d 544 case sizeof(UINT16):\r
545 *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
546 return EFI_SUCCESS;\r
547\r
548 case sizeof(UINT32):\r
549 *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
550 return EFI_SUCCESS;\r
551\r
552 case sizeof(UINT64):\r
553 *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
554 return EFI_SUCCESS;\r
878ddf1f 555\r
52e1905d 556 default:\r
557 ASSERT (FALSE);\r
558 return EFI_NOT_FOUND;\r
559 }\r
560\r
561 default:\r
562 ASSERT (FALSE);\r
563 break;\r
564 }\r
565 \r
566 ASSERT (FALSE);\r
567 return EFI_NOT_FOUND;\r
878ddf1f 568}\r
569\r
570\r
571\r
9d6d8b24 572\r
573\r
574VOID *\r
575ExGetWorker (\r
576 IN CONST EFI_GUID *Guid,\r
577 IN UINTN ExTokenNumber,\r
578 IN UINTN GetSize\r
579 ) \r
580{\r
581 return GetWorker(GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);\r
582}\r
583\r
584\r
585\r
586\r
587\r
588EFI_STATUS\r
589ExSetWorker (\r
590 IN PCD_TOKEN_NUMBER ExTokenNumber,\r
591 IN CONST EFI_GUID *Guid,\r
592 VOID *Data,\r
593 UINTN SetSize,\r
594 BOOLEAN PtrType\r
595 )\r
596{\r
597 PCD_TOKEN_NUMBER TokenNumber;\r
598 \r
599 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
600\r
601 InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, SetSize);\r
602\r
603 SetWorker (TokenNumber, Data, SetSize, PtrType);\r
604\r
605 return EFI_SUCCESS;\r
606 \r
607}\r
608\r
609\r
610\r
611\r
878ddf1f 612EFI_STATUS\r
613SetHiiVariable (\r
614 IN EFI_GUID *VariableGuid,\r
615 IN UINT16 *VariableName,\r
616 IN CONST VOID *Data,\r
617 IN UINTN DataSize,\r
618 IN UINTN Offset\r
619 )\r
620{\r
52e1905d 621 UINTN Size;\r
622 VOID *Buffer;\r
623 EFI_STATUS Status;\r
624 UINT32 Attribute;\r
878ddf1f 625\r
626 Size = 0;\r
627\r
628 Status = EfiGetVariable (\r
629 (UINT16 *)VariableName,\r
630 VariableGuid,\r
52e1905d 631 &Attribute,\r
878ddf1f 632 &Size,\r
633 NULL\r
634 );\r
635\r
636 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
637\r
638 Buffer = AllocatePool (Size);\r
639\r
640 ASSERT (Buffer != NULL);\r
641\r
642 Status = EfiGetVariable (\r
643 VariableName,\r
644 VariableGuid,\r
52e1905d 645 &Attribute,\r
878ddf1f 646 &Size,\r
647 Buffer\r
648 );\r
649\r
650\r
651 CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);\r
652\r
653 return EfiSetVariable (\r
654 VariableName,\r
655 VariableGuid,\r
52e1905d 656 Attribute,\r
878ddf1f 657 Size,\r
658 Buffer\r
659 );\r
660\r
661}\r
662\r
52e1905d 663\r
664\r
665\r
666\r
9d6d8b24 667PCD_TOKEN_NUMBER\r
668GetExPcdTokenNumber (\r
52e1905d 669 IN CONST EFI_GUID *Guid,\r
9d6d8b24 670 IN PCD_TOKEN_NUMBER ExTokenNumber\r
52e1905d 671 )\r
672{\r
673 UINT32 i;\r
674 DYNAMICEX_MAPPING *ExMap;\r
675 EFI_GUID *GuidTable;\r
9d6d8b24 676 EFI_GUID *MatchGuid;\r
677 UINTN MatchGuidIdx;\r
52e1905d 678\r
4c114006 679 ExMap = mPcdDatabase->PeiDb.Init.ExMapTable;\r
680 GuidTable = mPcdDatabase->PeiDb.Init.GuidTable;\r
9d6d8b24 681 \r
682 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid);\r
683 ASSERT (MatchGuid != NULL);\r
684\r
685 MatchGuidIdx = MatchGuid - GuidTable;\r
52e1905d 686 \r
687 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
688 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&\r
9d6d8b24 689 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
690 return ExMap[i].LocalTokenNumber;\r
52e1905d 691\r
692 }\r
693 }\r
694 \r
4c114006 695 ExMap = mPcdDatabase->DxeDb.Init.ExMapTable;\r
696 GuidTable = mPcdDatabase->DxeDb.Init.GuidTable;\r
9d6d8b24 697\r
698 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);\r
699 ASSERT (MatchGuid != NULL);\r
700\r
701 MatchGuidIdx = MatchGuid - GuidTable;\r
52e1905d 702 \r
703 for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) {\r
704 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&\r
9d6d8b24 705 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
706 return ExMap[i].LocalTokenNumber + PEI_LOCAL_TOKEN_NUMBER;\r
52e1905d 707 }\r
708 }\r
709\r
710 ASSERT (FALSE);\r
711\r
9d6d8b24 712 return 0;\r
52e1905d 713}\r
714\r