Bug fixing for FPD ModuleSA editor.
[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
8a43e8dd 31 UINTN TokenNumber,\r
9d6d8b24 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
58f1099f 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
9d6d8b24 60 ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);\r
61\r
58f1099f 62 Size = DxePcdGetSize (TokenNumber + 1);\r
9d6d8b24 63 ASSERT (GetSize == Size || GetSize == 0);\r
52e1905d 64\r
9d6d8b24 65 \r
2a505eac 66 IsPeiDb = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE;\r
9d6d8b24 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
52e1905d 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
4c114006 83 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
84 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :\r
85 mPcdDatabase->DxeDb.Init.StringTable;\r
52e1905d 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
4f242357 92 return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
52e1905d 93 \r
94 case PCD_TYPE_HII:\r
4c114006 95 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :\r
96 mPcdDatabase->DxeDb.Init.GuidTable;\r
52e1905d 97 \r
98 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
99 \r
100 Guid = &(GuidTable[VariableHead->GuidTableIndex]);\r
101 Name = &(StringTable[VariableHead->StringIndex]);\r
878ddf1f 102\r
52e1905d 103 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
c0e96fed 104 if (Status == EFI_SUCCESS) {\r
c0e96fed 105 return (UINT8 *) Data + VariableHead->Offset;\r
106 } else {\r
107 //\r
58f1099f 108 // Return the default value specified by Platform Integrator \r
109 //\r
110 return (VOID *) ((UINT8 *) PcdDb + VariableHead->DefaultValueOffset);\r
111 }\r
878ddf1f 112\r
52e1905d 113 case PCD_TYPE_STRING:\r
114 StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset);\r
115 return (VOID *) &StringTable[StringTableIdx];\r
878ddf1f 116\r
52e1905d 117 case PCD_TYPE_DATA:\r
118 return (VOID *) ((UINT8 *) PcdDb + Offset);\r
119 break;\r
878ddf1f 120\r
52e1905d 121 default:\r
122 ASSERT (FALSE);\r
123 break;\r
124 \r
125 }\r
878ddf1f 126\r
52e1905d 127 ASSERT (FALSE);\r
128 \r
129 return NULL;\r
52e1905d 130 \r
52e1905d 131}\r
878ddf1f 132\r
878ddf1f 133\r
134\r
52e1905d 135EFI_STATUS\r
136DxeRegisterCallBackWorker (\r
8a43e8dd 137 IN UINTN TokenNumber,\r
52e1905d 138 IN CONST GUID *Guid, OPTIONAL\r
4c114006 139 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
52e1905d 140)\r
141{\r
4c114006 142 CALLBACK_FN_ENTRY *FnTableEntry;\r
4c114006 143 LIST_ENTRY *ListHead;\r
144 LIST_ENTRY *ListNode;\r
145\r
146 if (Guid != NULL) {\r
4f242357 147 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
4c114006 148 }\r
149\r
58f1099f 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
4c114006 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
52e1905d 178 \r
179 return EFI_SUCCESS;\r
878ddf1f 180}\r
181\r
182\r
4c114006 183\r
184\r
52e1905d 185EFI_STATUS\r
4c114006 186DxeUnRegisterCallBackWorker (\r
8a43e8dd 187 IN UINTN TokenNumber,\r
4c114006 188 IN CONST GUID *Guid, OPTIONAL\r
189 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
190)\r
191{\r
192 CALLBACK_FN_ENTRY *FnTableEntry;\r
4c114006 193 LIST_ENTRY *ListHead;\r
194 LIST_ENTRY *ListNode;\r
195\r
196 if (Guid != NULL) {\r
4f242357 197 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
4c114006 198 }\r
199\r
58f1099f 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
4c114006 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
8a43e8dd 232UINTN \r
4c114006 233ExGetNextTokeNumber (\r
234 IN CONST EFI_GUID *Guid,\r
8a43e8dd 235 IN UINTN TokenNumber,\r
4c114006 236 IN EFI_GUID *GuidTable,\r
237 IN UINTN SizeOfGuidTable,\r
238 IN DYNAMICEX_MAPPING *ExMapTable,\r
239 IN UINTN SizeOfExMapTable\r
878ddf1f 240 )\r
241{\r
4c114006 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
4276d5da 265\r
4c114006 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
878ddf1f 291}\r
4c114006 292 \r
878ddf1f 293\r
294\r
295\r
52e1905d 296VOID\r
297BuildPcdDxeDataBase (\r
298 VOID\r
8a43e8dd 299 )\r
878ddf1f 300{\r
52e1905d 301 PEI_PCD_DATABASE *PeiDatabase;\r
302 EFI_HOB_GUID_TYPE *GuidHob;\r
4c114006 303 UINTN Idx;\r
878ddf1f 304\r
4c114006 305 mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));\r
306 ASSERT (mPcdDatabase != NULL);\r
878ddf1f 307\r
52e1905d 308 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
878ddf1f 309\r
3496595d 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
52e1905d 327\r
328 //\r
329 // Copy PCD Entries with default value to PCD DATABASE\r
330 //\r
4c114006 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
abc25afa 337\r
338 if (PCD_TOTAL_TOKEN_NUMBER != 0) {\r
8a43e8dd 339 mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY));\r
abc25afa 340 }\r
341 \r
4c114006 342 for (Idx = 0; Idx < PCD_TOTAL_TOKEN_NUMBER; Idx++) {\r
343 InitializeListHead (&mCallbackFnTable[Idx]);\r
344 }\r
52e1905d 345 \r
346 return;\r
878ddf1f 347}\r
348\r
349\r
350\r
52e1905d 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
878ddf1f 357 )\r
358{\r
52e1905d 359 UINTN Size;\r
360 EFI_STATUS Status;\r
361 VOID *Buffer;\r
878ddf1f 362\r
58f1099f 363 Size = 0;\r
364 Buffer = NULL;\r
365 \r
52e1905d 366 Status = EfiGetVariable (\r
367 (UINT16 *)VariableName,\r
368 VariableGuid,\r
369 NULL,\r
370 &Size,\r
58f1099f 371 Buffer\r
52e1905d 372 );\r
58f1099f 373 \r
c0e96fed 374 if (Status == EFI_BUFFER_TOO_SMALL) {\r
878ddf1f 375\r
c0e96fed 376 Buffer = AllocatePool (Size);\r
878ddf1f 377\r
c0e96fed 378 ASSERT (Buffer != NULL);\r
878ddf1f 379\r
c0e96fed 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
878ddf1f 390\r
58f1099f 391 *VariableData = Buffer;\r
392 *VariableSize = Size;\r
393\r
52e1905d 394 return Status;\r
878ddf1f 395\r
878ddf1f 396}\r
397\r
398\r
52e1905d 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
878ddf1f 412\r
52e1905d 413 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
878ddf1f 414\r
4c114006 415 PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb;\r
878ddf1f 416\r
52e1905d 417 SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
418 Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset); \r
878ddf1f 419\r
4c114006 420 PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :\r
421 mPcdDatabase->DxeDb.Init.SkuIdTable;\r
52e1905d 422 \r
423 SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];\r
424 \r
425 for (i = 0; i < SkuIdTable[0]; i++) {\r
4c114006 426 if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[i + 1]) {\r
52e1905d 427 break;\r
878ddf1f 428 }\r
878ddf1f 429 }\r
52e1905d 430 ASSERT (i < SkuIdTable[0]);\r
878ddf1f 431\r
52e1905d 432 switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {\r
433 case PCD_TYPE_VPD:\r
434 Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);\r
4f242357 435 return (UINT32) ((Value - PcdDb) | PCD_TYPE_VPD);\r
878ddf1f 436\r
52e1905d 437 case PCD_TYPE_HII:\r
438 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);\r
4f242357 439 return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII);\r
52e1905d 440 \r
441 case PCD_TYPE_DATA:\r
442 Value += Size * i;\r
4f242357 443 return (UINT32) (Value - PcdDb);\r
52e1905d 444 \r
445 default:\r
446 ASSERT (FALSE);\r
447 }\r
448\r
449 ASSERT (FALSE);\r
450\r
451 return 0;\r
878ddf1f 452 \r
453}\r
454\r
878ddf1f 455\r
878ddf1f 456\r
878ddf1f 457\r
878ddf1f 458\r
52e1905d 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
4c114006 468 CALLBACK_FN_ENTRY *FnTableEntry;\r
469 LIST_ENTRY *ListHead;\r
470 LIST_ENTRY *ListNode;\r
471\r
58f1099f 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
4c114006 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
52e1905d 493 return;\r
878ddf1f 494}\r
495\r
496\r
497\r
52e1905d 498\r
878ddf1f 499EFI_STATUS\r
52e1905d 500SetWorker (\r
8a43e8dd 501 UINTN TokenNumber,\r
0653eb89 502 VOID *Data,\r
503 UINTN Size,\r
504 BOOLEAN PtrType\r
878ddf1f 505 )\r
506{\r
52e1905d 507 UINT32 *LocalTokenNumberTable;\r
508 BOOLEAN IsPeiDb;\r
9d6d8b24 509 UINT32 LocalTokenNumber;\r
510 EFI_GUID *GuidTable;\r
511 UINT16 *StringTable;\r
512 EFI_GUID *Guid;\r
513 UINT16 *Name;\r
c0e96fed 514 UINTN VariableOffset;\r
9d6d8b24 515 VOID *InternalData;\r
516 VARIABLE_HEAD *VariableHead;\r
517 UINTN Offset;\r
518 UINT8 *PcdDb;\r
878ddf1f 519\r
58f1099f 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
52e1905d 527 ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);\r
878ddf1f 528\r
52e1905d 529 if (PtrType) {\r
58f1099f 530 ASSERT (Size <= DxePcdGetSize (TokenNumber + 1));\r
52e1905d 531 } else {\r
58f1099f 532 ASSERT (Size == DxePcdGetSize (TokenNumber + 1));\r
878ddf1f 533 }\r
878ddf1f 534 \r
2a505eac 535 IsPeiDb = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE;\r
878ddf1f 536\r
4c114006 537 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : \r
538 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
878ddf1f 539\r
9d6d8b24 540 if ((TokenNumber < PEI_NEX_TOKEN_NUMBER) ||\r
541 (TokenNumber >= PEI_LOCAL_TOKEN_NUMBER || TokenNumber < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER))) {\r
58f1099f 542 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, Size);\r
9d6d8b24 543 }\r
0653eb89 544\r
52e1905d 545 TokenNumber = IsPeiDb ? TokenNumber\r
546 : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;\r
878ddf1f 547\r
9d6d8b24 548 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
52e1905d 549 \r
52e1905d 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
878ddf1f 553\r
52e1905d 554 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
878ddf1f 555\r
4c114006 556 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
878ddf1f 557\r
4c114006 558 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :\r
559 mPcdDatabase->DxeDb.Init.StringTable;\r
52e1905d 560 \r
561 InternalData = PcdDb + Offset;\r
878ddf1f 562\r
52e1905d 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
c0e96fed 570 return EFI_SUCCESS;\r
878ddf1f 571\r
52e1905d 572 case PCD_TYPE_HII:\r
573 //\r
574 // Bug Bug: Please implement this\r
575 //\r
4c114006 576 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :\r
577 mPcdDatabase->DxeDb.Init.GuidTable;\r
52e1905d 578 \r
579 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
580 \r
581 Guid = &(GuidTable[VariableHead->GuidTableIndex]);\r
582 Name = &(StringTable[VariableHead->StringIndex]);\r
c0e96fed 583 VariableOffset = VariableHead->Offset;\r
878ddf1f 584\r
c0e96fed 585 return SetHiiVariable (Guid, Name, Data, Size, VariableOffset);\r
878ddf1f 586\r
52e1905d 587 case PCD_TYPE_DATA:\r
588 if (PtrType) {\r
589 CopyMem (InternalData, Data, Size);\r
590 return EFI_SUCCESS;\r
591 }\r
878ddf1f 592\r
52e1905d 593 switch (Size) {\r
594 case sizeof(UINT8):\r
595 *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
596 return EFI_SUCCESS;\r
878ddf1f 597\r
52e1905d 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
878ddf1f 609\r
52e1905d 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
878ddf1f 622}\r
623\r
624\r
625\r
9d6d8b24 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
4f242357 635 return GetWorker(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber), GetSize);\r
9d6d8b24 636}\r
637\r
638\r
639\r
640\r
641\r
642EFI_STATUS\r
643ExSetWorker (\r
8a43e8dd 644 IN UINTN ExTokenNumber,\r
9d6d8b24 645 IN CONST EFI_GUID *Guid,\r
646 VOID *Data,\r
647 UINTN SetSize,\r
648 BOOLEAN PtrType\r
649 )\r
650{\r
8a43e8dd 651 UINTN TokenNumber;\r
9d6d8b24 652 \r
4f242357 653 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber);\r
9d6d8b24 654\r
4f242357 655 InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, SetSize);\r
9d6d8b24 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
878ddf1f 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
52e1905d 675 UINTN Size;\r
676 VOID *Buffer;\r
677 EFI_STATUS Status;\r
678 UINT32 Attribute;\r
878ddf1f 679\r
680 Size = 0;\r
681\r
682 Status = EfiGetVariable (\r
683 (UINT16 *)VariableName,\r
684 VariableGuid,\r
52e1905d 685 &Attribute,\r
878ddf1f 686 &Size,\r
687 NULL\r
688 );\r
689\r
c0e96fed 690 if (Status == EFI_BUFFER_TOO_SMALL) {\r
878ddf1f 691\r
c0e96fed 692 Buffer = AllocatePool (Size);\r
878ddf1f 693\r
c0e96fed 694 ASSERT (Buffer != NULL);\r
878ddf1f 695\r
c0e96fed 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
878ddf1f 705\r
c0e96fed 706 CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);\r
878ddf1f 707\r
c0e96fed 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
878ddf1f 717\r
718 return EfiSetVariable (\r
c0e96fed 719 VariableName,\r
720 VariableGuid,\r
721 Attribute,\r
722 Size,\r
723 Buffer\r
724 );\r
878ddf1f 725\r
726}\r
727\r
52e1905d 728\r
729\r
730\r
731\r
8a43e8dd 732UINTN \r
9d6d8b24 733GetExPcdTokenNumber (\r
52e1905d 734 IN CONST EFI_GUID *Guid,\r
4f242357 735 IN UINT32 ExTokenNumber\r
52e1905d 736 )\r
737{\r
738 UINT32 i;\r
739 DYNAMICEX_MAPPING *ExMap;\r
740 EFI_GUID *GuidTable;\r
9d6d8b24 741 EFI_GUID *MatchGuid;\r
742 UINTN MatchGuidIdx;\r
52e1905d 743\r
bb5545b6 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
9d6d8b24 751\r
bb5545b6 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
52e1905d 758\r
bb5545b6 759 }\r
760 }\r
52e1905d 761 }\r
762 }\r
763 \r
4c114006 764 ExMap = mPcdDatabase->DxeDb.Init.ExMapTable;\r
765 GuidTable = mPcdDatabase->DxeDb.Init.GuidTable;\r
9d6d8b24 766\r
767 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);\r
bb5545b6 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
9d6d8b24 772 ASSERT (MatchGuid != NULL);\r
773\r
774 MatchGuidIdx = MatchGuid - GuidTable;\r
52e1905d 775 \r
776 for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) {\r
777 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&\r
9d6d8b24 778 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
bb5545b6 779 return ExMap[i].LocalTokenNumber;\r
52e1905d 780 }\r
781 }\r
782\r
783 ASSERT (FALSE);\r
784\r
9d6d8b24 785 return 0;\r
52e1905d 786}\r
787\r