Explain how to build for other architectures.
[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
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
2a505eac 60 IsPeiDb = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE;\r
9d6d8b24 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
4f242357 86 return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
52e1905d 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
c0e96fed 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
878ddf1f 108\r
52e1905d 109 case PCD_TYPE_STRING:\r
110 StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset);\r
111 return (VOID *) &StringTable[StringTableIdx];\r
878ddf1f 112\r
52e1905d 113 case PCD_TYPE_DATA:\r
114 return (VOID *) ((UINT8 *) PcdDb + Offset);\r
115 break;\r
878ddf1f 116\r
52e1905d 117 default:\r
118 ASSERT (FALSE);\r
119 break;\r
120 \r
121 }\r
878ddf1f 122\r
52e1905d 123 ASSERT (FALSE);\r
124 \r
125 return NULL;\r
52e1905d 126 \r
52e1905d 127}\r
878ddf1f 128\r
878ddf1f 129\r
130\r
52e1905d 131EFI_STATUS\r
132DxeRegisterCallBackWorker (\r
8a43e8dd 133 IN UINTN TokenNumber,\r
52e1905d 134 IN CONST GUID *Guid, OPTIONAL\r
4c114006 135 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
52e1905d 136)\r
137{\r
4c114006 138 CALLBACK_FN_ENTRY *FnTableEntry;\r
4c114006 139 LIST_ENTRY *ListHead;\r
140 LIST_ENTRY *ListNode;\r
141\r
142 if (Guid != NULL) {\r
4f242357 143 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
4c114006 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
52e1905d 167 \r
168 return EFI_SUCCESS;\r
878ddf1f 169}\r
170\r
171\r
4c114006 172\r
173\r
52e1905d 174EFI_STATUS\r
4c114006 175DxeUnRegisterCallBackWorker (\r
8a43e8dd 176 IN UINTN TokenNumber,\r
4c114006 177 IN CONST GUID *Guid, OPTIONAL\r
178 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
179)\r
180{\r
181 CALLBACK_FN_ENTRY *FnTableEntry;\r
4c114006 182 LIST_ENTRY *ListHead;\r
183 LIST_ENTRY *ListNode;\r
184\r
185 if (Guid != NULL) {\r
4f242357 186 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
4c114006 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
8a43e8dd 214UINTN \r
4c114006 215ExGetNextTokeNumber (\r
216 IN CONST EFI_GUID *Guid,\r
8a43e8dd 217 IN UINTN TokenNumber,\r
4c114006 218 IN EFI_GUID *GuidTable,\r
219 IN UINTN SizeOfGuidTable,\r
220 IN DYNAMICEX_MAPPING *ExMapTable,\r
221 IN UINTN SizeOfExMapTable\r
878ddf1f 222 )\r
223{\r
4c114006 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
878ddf1f 273}\r
4c114006 274 \r
878ddf1f 275\r
276\r
277\r
52e1905d 278VOID\r
279BuildPcdDxeDataBase (\r
280 VOID\r
8a43e8dd 281 )\r
878ddf1f 282{\r
52e1905d 283 PEI_PCD_DATABASE *PeiDatabase;\r
284 EFI_HOB_GUID_TYPE *GuidHob;\r
4c114006 285 UINTN Idx;\r
878ddf1f 286\r
4c114006 287 mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));\r
288 ASSERT (mPcdDatabase != NULL);\r
878ddf1f 289\r
52e1905d 290 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
878ddf1f 291\r
3496595d 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
52e1905d 309\r
310 //\r
311 // Copy PCD Entries with default value to PCD DATABASE\r
312 //\r
4c114006 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
abc25afa 319\r
320 if (PCD_TOTAL_TOKEN_NUMBER != 0) {\r
8a43e8dd 321 mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY));\r
abc25afa 322 }\r
323 \r
4c114006 324 for (Idx = 0; Idx < PCD_TOTAL_TOKEN_NUMBER; Idx++) {\r
325 InitializeListHead (&mCallbackFnTable[Idx]);\r
326 }\r
52e1905d 327 \r
328 return;\r
878ddf1f 329}\r
330\r
331\r
332\r
52e1905d 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
878ddf1f 339 )\r
340{\r
52e1905d 341 UINTN Size;\r
342 EFI_STATUS Status;\r
343 VOID *Buffer;\r
878ddf1f 344\r
52e1905d 345 Status = EfiGetVariable (\r
346 (UINT16 *)VariableName,\r
347 VariableGuid,\r
348 NULL,\r
349 &Size,\r
350 NULL\r
351 );\r
c0e96fed 352 if (Status == EFI_BUFFER_TOO_SMALL) {\r
878ddf1f 353\r
c0e96fed 354 Buffer = AllocatePool (Size);\r
878ddf1f 355\r
c0e96fed 356 ASSERT (Buffer != NULL);\r
878ddf1f 357\r
c0e96fed 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
878ddf1f 368\r
52e1905d 369 return Status;\r
878ddf1f 370\r
878ddf1f 371}\r
372\r
373\r
52e1905d 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
878ddf1f 387\r
52e1905d 388 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
878ddf1f 389\r
4c114006 390 PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb;\r
878ddf1f 391\r
52e1905d 392 SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
393 Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset); \r
878ddf1f 394\r
4c114006 395 PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :\r
396 mPcdDatabase->DxeDb.Init.SkuIdTable;\r
52e1905d 397 \r
398 SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];\r
399 \r
400 for (i = 0; i < SkuIdTable[0]; i++) {\r
4c114006 401 if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[i + 1]) {\r
52e1905d 402 break;\r
878ddf1f 403 }\r
878ddf1f 404 }\r
52e1905d 405 ASSERT (i < SkuIdTable[0]);\r
878ddf1f 406\r
52e1905d 407 switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {\r
408 case PCD_TYPE_VPD:\r
409 Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);\r
4f242357 410 return (UINT32) ((Value - PcdDb) | PCD_TYPE_VPD);\r
878ddf1f 411\r
52e1905d 412 case PCD_TYPE_HII:\r
413 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);\r
4f242357 414 return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII);\r
52e1905d 415 \r
416 case PCD_TYPE_DATA:\r
417 Value += Size * i;\r
4f242357 418 return (UINT32) (Value - PcdDb);\r
52e1905d 419 \r
420 default:\r
421 ASSERT (FALSE);\r
422 }\r
423\r
424 ASSERT (FALSE);\r
425\r
426 return 0;\r
878ddf1f 427 \r
428}\r
429\r
878ddf1f 430\r
878ddf1f 431\r
878ddf1f 432\r
878ddf1f 433\r
52e1905d 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
4c114006 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
52e1905d 461 return;\r
878ddf1f 462}\r
463\r
464\r
465\r
52e1905d 466\r
878ddf1f 467EFI_STATUS\r
52e1905d 468SetWorker (\r
8a43e8dd 469 UINTN TokenNumber,\r
0653eb89 470 VOID *Data,\r
471 UINTN Size,\r
472 BOOLEAN PtrType\r
878ddf1f 473 )\r
474{\r
52e1905d 475 UINT32 *LocalTokenNumberTable;\r
476 BOOLEAN IsPeiDb;\r
9d6d8b24 477 UINT32 LocalTokenNumber;\r
478 EFI_GUID *GuidTable;\r
479 UINT16 *StringTable;\r
480 EFI_GUID *Guid;\r
481 UINT16 *Name;\r
c0e96fed 482 UINTN VariableOffset;\r
9d6d8b24 483 VOID *InternalData;\r
484 VARIABLE_HEAD *VariableHead;\r
485 UINTN Offset;\r
486 UINT8 *PcdDb;\r
878ddf1f 487\r
878ddf1f 488\r
52e1905d 489 ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);\r
878ddf1f 490\r
52e1905d 491 if (PtrType) {\r
492 ASSERT (Size <= DxePcdGetSize (TokenNumber));\r
493 } else {\r
494 ASSERT (Size == DxePcdGetSize (TokenNumber));\r
878ddf1f 495 }\r
878ddf1f 496 \r
2a505eac 497 IsPeiDb = (TokenNumber < PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE;\r
878ddf1f 498\r
4c114006 499 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : \r
500 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
878ddf1f 501\r
9d6d8b24 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
0653eb89 506\r
52e1905d 507 TokenNumber = IsPeiDb ? TokenNumber\r
508 : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;\r
878ddf1f 509\r
9d6d8b24 510 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
52e1905d 511 \r
52e1905d 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
878ddf1f 515\r
52e1905d 516 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
878ddf1f 517\r
4c114006 518 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
878ddf1f 519\r
4c114006 520 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :\r
521 mPcdDatabase->DxeDb.Init.StringTable;\r
52e1905d 522 \r
523 InternalData = PcdDb + Offset;\r
878ddf1f 524\r
52e1905d 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
c0e96fed 532 return EFI_SUCCESS;\r
878ddf1f 533\r
52e1905d 534 case PCD_TYPE_HII:\r
535 //\r
536 // Bug Bug: Please implement this\r
537 //\r
4c114006 538 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :\r
539 mPcdDatabase->DxeDb.Init.GuidTable;\r
52e1905d 540 \r
541 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
542 \r
543 Guid = &(GuidTable[VariableHead->GuidTableIndex]);\r
544 Name = &(StringTable[VariableHead->StringIndex]);\r
c0e96fed 545 VariableOffset = VariableHead->Offset;\r
878ddf1f 546\r
c0e96fed 547 return SetHiiVariable (Guid, Name, Data, Size, VariableOffset);\r
878ddf1f 548\r
52e1905d 549 case PCD_TYPE_DATA:\r
550 if (PtrType) {\r
551 CopyMem (InternalData, Data, Size);\r
552 return EFI_SUCCESS;\r
553 }\r
878ddf1f 554\r
52e1905d 555 switch (Size) {\r
556 case sizeof(UINT8):\r
557 *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
558 return EFI_SUCCESS;\r
878ddf1f 559\r
52e1905d 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
878ddf1f 571\r
52e1905d 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
878ddf1f 584}\r
585\r
586\r
587\r
9d6d8b24 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
4f242357 597 return GetWorker(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber), GetSize);\r
9d6d8b24 598}\r
599\r
600\r
601\r
602\r
603\r
604EFI_STATUS\r
605ExSetWorker (\r
8a43e8dd 606 IN UINTN ExTokenNumber,\r
9d6d8b24 607 IN CONST EFI_GUID *Guid,\r
608 VOID *Data,\r
609 UINTN SetSize,\r
610 BOOLEAN PtrType\r
611 )\r
612{\r
8a43e8dd 613 UINTN TokenNumber;\r
9d6d8b24 614 \r
4f242357 615 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber);\r
9d6d8b24 616\r
4f242357 617 InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, SetSize);\r
9d6d8b24 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
878ddf1f 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
52e1905d 637 UINTN Size;\r
638 VOID *Buffer;\r
639 EFI_STATUS Status;\r
640 UINT32 Attribute;\r
878ddf1f 641\r
642 Size = 0;\r
643\r
644 Status = EfiGetVariable (\r
645 (UINT16 *)VariableName,\r
646 VariableGuid,\r
52e1905d 647 &Attribute,\r
878ddf1f 648 &Size,\r
649 NULL\r
650 );\r
651\r
c0e96fed 652 if (Status == EFI_BUFFER_TOO_SMALL) {\r
878ddf1f 653\r
c0e96fed 654 Buffer = AllocatePool (Size);\r
878ddf1f 655\r
c0e96fed 656 ASSERT (Buffer != NULL);\r
878ddf1f 657\r
c0e96fed 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
878ddf1f 667\r
c0e96fed 668 CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);\r
878ddf1f 669\r
c0e96fed 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
878ddf1f 679\r
680 return EfiSetVariable (\r
c0e96fed 681 VariableName,\r
682 VariableGuid,\r
683 Attribute,\r
684 Size,\r
685 Buffer\r
686 );\r
878ddf1f 687\r
688}\r
689\r
52e1905d 690\r
691\r
692\r
693\r
8a43e8dd 694UINTN \r
9d6d8b24 695GetExPcdTokenNumber (\r
52e1905d 696 IN CONST EFI_GUID *Guid,\r
4f242357 697 IN UINT32 ExTokenNumber\r
52e1905d 698 )\r
699{\r
700 UINT32 i;\r
701 DYNAMICEX_MAPPING *ExMap;\r
702 EFI_GUID *GuidTable;\r
9d6d8b24 703 EFI_GUID *MatchGuid;\r
704 UINTN MatchGuidIdx;\r
52e1905d 705\r
4c114006 706 ExMap = mPcdDatabase->PeiDb.Init.ExMapTable;\r
707 GuidTable = mPcdDatabase->PeiDb.Init.GuidTable;\r
9d6d8b24 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
52e1905d 713 \r
714 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
715 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&\r
9d6d8b24 716 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
717 return ExMap[i].LocalTokenNumber;\r
52e1905d 718\r
719 }\r
720 }\r
721 \r
4c114006 722 ExMap = mPcdDatabase->DxeDb.Init.ExMapTable;\r
723 GuidTable = mPcdDatabase->DxeDb.Init.GuidTable;\r
9d6d8b24 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
52e1905d 729 \r
730 for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) {\r
731 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&\r
9d6d8b24 732 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
733 return ExMap[i].LocalTokenNumber + PEI_LOCAL_TOKEN_NUMBER;\r
52e1905d 734 }\r
735 }\r
736\r
737 ASSERT (FALSE);\r
738\r
9d6d8b24 739 return 0;\r
52e1905d 740}\r
741\r