]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/PCD/Pei/Service.c
Make EDK Module Package pass Intel IPF compiler with /Ox switch.
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Pei / Service.c
CommitLineData
878ddf1f 1/** @file\r
2Private functions used by PCD PEIM.\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 The function registers the CallBackOnSet fucntion\r
21 according to TokenNumber and EFI_GUID space.\r
878ddf1f 22\r
a7c5092f 23 @param TokenNumber The token number.\r
24 @param Guid The GUID space.\r
25 @param CallBackFunction The Callback function to be registered.\r
26 @param Register To register or unregister the callback function.\r
878ddf1f 27\r
52e1905d 28 @retval EFI_SUCCESS If the Callback function is registered.\r
29 @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.\r
a7c5092f 30 @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free\r
31 slot left in the CallbackFnTable.\r
878ddf1f 32--*/\r
52e1905d 33EFI_STATUS\r
34PeiRegisterCallBackWorker (\r
8a43e8dd 35 IN UINTN ExTokenNumber,\r
52e1905d 36 IN CONST EFI_GUID *Guid, OPTIONAL\r
37 IN PCD_PPI_CALLBACK CallBackFunction,\r
38 IN BOOLEAN Register\r
878ddf1f 39)\r
40{\r
52e1905d 41 EFI_HOB_GUID_TYPE *GuidHob;\r
42 PCD_PPI_CALLBACK *CallbackTable;\r
43 PCD_PPI_CALLBACK Compare;\r
44 PCD_PPI_CALLBACK Assign;\r
45 UINT32 LocalTokenNumber;\r
8a43e8dd 46 UINTN TokenNumber;\r
52e1905d 47 UINTN Idx;\r
878ddf1f 48\r
52e1905d 49 if (Guid == NULL) {\r
50 TokenNumber = ExTokenNumber;\r
58f1099f 51\r
52 //\r
53 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
54 // We have to decrement TokenNumber by 1 to make it usable\r
55 // as the array index.\r
56 //\r
57 TokenNumber--;\r
4f914125 58 ASSERT (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1);\r
52e1905d 59 } else {\r
9d6d8b24 60 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
58f1099f 61\r
62 //\r
63 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
64 // We have to decrement TokenNumber by 1 to make it usable\r
65 // as the array index.\r
66 //\r
67 TokenNumber--;\r
4f914125 68 // EBC compiler is very choosy. It may report warning about comparison\r
69 // between UINTN and 0 . So we add 1 in each size of the \r
70 // comparison.\r
71 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
52e1905d 72 }\r
878ddf1f 73\r
58f1099f 74\r
9d6d8b24 75 LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber];\r
76\r
1de04b4f 77 //\r
78 // We don't support SET for HII and VPD type PCD entry in PEI phase.\r
79 // So we will assert if any register callback for such PCD entry.\r
80 //\r
52e1905d 81 ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0);\r
82 ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0);\r
878ddf1f 83\r
52e1905d 84 GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
878ddf1f 85 ASSERT (GuidHob != NULL);\r
52e1905d 86 \r
87 CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
0653eb89 88 CallbackTable = CallbackTable + (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
878ddf1f 89\r
52e1905d 90 Compare = Register? NULL: CallBackFunction;\r
91 Assign = Register? CallBackFunction: NULL;\r
878ddf1f 92\r
0653eb89 93\r
52e1905d 94 for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
95 if (CallbackTable[Idx] == Compare) {\r
96 CallbackTable[Idx] = Assign;\r
97 return EFI_SUCCESS;\r
98 }\r
99 }\r
878ddf1f 100\r
52e1905d 101 return Register? EFI_OUT_OF_RESOURCES : EFI_NOT_FOUND;\r
878ddf1f 102\r
878ddf1f 103}\r
104\r
105\r
878ddf1f 106\r
878ddf1f 107\r
52e1905d 108/**\r
a7c5092f 109 The function builds the PCD database.\r
878ddf1f 110\r
a7c5092f 111 @param VOID\r
878ddf1f 112\r
52e1905d 113 @retval VOID\r
878ddf1f 114--*/\r
52e1905d 115VOID\r
116BuildPcdDatabase (\r
117 VOID\r
878ddf1f 118 )\r
119{\r
52e1905d 120 PEI_PCD_DATABASE *Database;\r
121 VOID *CallbackFnTable;\r
122 UINTN SizeOfCallbackFnTable;\r
123 \r
124 Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE));\r
878ddf1f 125\r
52e1905d 126 ZeroMem (Database, sizeof (PEI_PCD_DATABASE));\r
878ddf1f 127\r
128 //\r
52e1905d 129 // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE\r
878ddf1f 130 //\r
878ddf1f 131 \r
52e1905d 132 CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit));\r
878ddf1f 133\r
52e1905d 134 SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry);\r
878ddf1f 135\r
52e1905d 136 CallbackFnTable = BuildGuidHob (&gPcdPeiCallbackFnTableHobGuid, SizeOfCallbackFnTable);\r
137 \r
138 ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);\r
139 \r
140 return;\r
878ddf1f 141}\r
142\r
143\r
144\r
145/**\r
52e1905d 146 The function is provided by PCD PEIM and PCD DXE driver to\r
147 do the work of reading a HII variable from variable service.\r
878ddf1f 148\r
a7c5092f 149 @param VariableGuid The Variable GUID.\r
150 @param VariableName The Variable Name.\r
151 @param VariableData The output data.\r
152 @param VariableSize The size of the variable.\r
878ddf1f 153\r
52e1905d 154 @retval EFI_SUCCESS Operation successful.\r
a7c5092f 155 @retval EFI_NOT_FOUND Variablel not found.\r
878ddf1f 156--*/\r
1cc8ee78 157STATIC\r
878ddf1f 158EFI_STATUS\r
52e1905d 159GetHiiVariable (\r
160 IN CONST EFI_GUID *VariableGuid,\r
161 IN UINT16 *VariableName,\r
162 OUT VOID **VariableData,\r
163 OUT UINTN *VariableSize\r
878ddf1f 164 )\r
165{\r
52e1905d 166 UINTN Size;\r
167 EFI_STATUS Status;\r
168 VOID *Buffer;\r
169 EFI_PEI_READ_ONLY_VARIABLE_PPI *VariablePpi;\r
878ddf1f 170\r
84a99d48 171 Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, (VOID **) &VariablePpi);\r
52e1905d 172 ASSERT_EFI_ERROR (Status);\r
878ddf1f 173\r
52e1905d 174 Size = 0;\r
52e1905d 175 Status = VariablePpi->PeiGetVariable (\r
176 GetPeiServicesTablePointer (),\r
177 VariableName,\r
178 (EFI_GUID *) VariableGuid,\r
179 NULL,\r
180 &Size,\r
181 NULL\r
182 );\r
c0e96fed 183 if (Status == EFI_BUFFER_TOO_SMALL) {\r
52e1905d 184\r
52e1905d 185\r
c0e96fed 186 Status = PeiServicesAllocatePool (Size, &Buffer);\r
187 ASSERT_EFI_ERROR (Status);\r
52e1905d 188\r
c0e96fed 189 Status = VariablePpi->PeiGetVariable (\r
190 GetPeiServicesTablePointer (),\r
191 (UINT16 *) VariableName,\r
192 (EFI_GUID *) VariableGuid,\r
193 NULL,\r
194 &Size,\r
195 Buffer\r
196 );\r
197 ASSERT_EFI_ERROR (Status);\r
198\r
199 *VariableSize = Size;\r
200 *VariableData = Buffer;\r
201\r
202 return EFI_SUCCESS;\r
203 } else {\r
204 return EFI_NOT_FOUND;\r
205 }\r
878ddf1f 206\r
878ddf1f 207}\r
208\r
1cc8ee78 209STATIC\r
52e1905d 210UINT32\r
211GetSkuEnabledTokenNumber (\r
212 UINT32 LocalTokenNumber,\r
213 UINTN Size\r
214 ) \r
878ddf1f 215{\r
52e1905d 216 PEI_PCD_DATABASE *PeiPcdDb;\r
217 SKU_HEAD *SkuHead;\r
218 SKU_ID *SkuIdTable;\r
219 INTN i;\r
220 UINT8 *Value;\r
221\r
222 PeiPcdDb = GetPcdDatabase ();\r
223\r
224 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
225\r
226 SkuHead = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
227 Value = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));\r
228 SkuIdTable = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));\r
229 \r
230 for (i = 0; i < SkuIdTable[0]; i++) {\r
231 if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[i + 1]) {\r
232 break;\r
233 }\r
234 }\r
878ddf1f 235\r
1de04b4f 236 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 237 case PCD_TYPE_VPD:\r
1de04b4f 238 Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);\r
4f914125 239 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD);\r
52e1905d 240\r
241 case PCD_TYPE_HII:\r
1de04b4f 242 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);\r
4f914125 243 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);\r
52e1905d 244 \r
1de04b4f 245 case PCD_TYPE_STRING:\r
246 Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]);\r
4f914125 247 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING);\r
1de04b4f 248\r
00b7af13 249 case PCD_TYPE_DATA:\r
52e1905d 250 Value += Size * i;\r
4f914125 251 return (UINT32) (Value - (UINT8 *) PeiPcdDb);\r
1de04b4f 252\r
52e1905d 253 default:\r
254 ASSERT (FALSE);\r
255 }\r
878ddf1f 256\r
52e1905d 257 ASSERT (FALSE);\r
878ddf1f 258\r
52e1905d 259 return 0;\r
260 \r
878ddf1f 261}\r
262\r
263\r
264\r
1cc8ee78 265STATIC\r
52e1905d 266VOID\r
267InvokeCallbackOnSet (\r
4f914125 268 UINTN ExTokenNumber,\r
52e1905d 269 CONST EFI_GUID *Guid, OPTIONAL\r
270 UINTN TokenNumber,\r
271 VOID *Data,\r
272 UINTN Size\r
273 )\r
878ddf1f 274{\r
878ddf1f 275 EFI_HOB_GUID_TYPE *GuidHob;\r
878ddf1f 276 PCD_PPI_CALLBACK *CallbackTable;\r
52e1905d 277 UINTN Idx;\r
878ddf1f 278\r
58f1099f 279 //\r
280 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
281 // We have to decrement TokenNumber by 1 to make it usable\r
282 // as the array index.\r
283 //\r
284 TokenNumber--;\r
285 \r
4f914125 286 if (Guid == NULL) {\r
287 // EBC compiler is very choosy. It may report warning about comparison\r
288 // between UINTN and 0 . So we add 1 in each size of the \r
289 // comparison.\r
290 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
291 }\r
52e1905d 292\r
293 GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
878ddf1f 294 ASSERT (GuidHob != NULL);\r
295 \r
52e1905d 296 CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
878ddf1f 297\r
52e1905d 298 CallbackTable += (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
878ddf1f 299\r
52e1905d 300 for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
301 if (CallbackTable[Idx] != NULL) {\r
302 CallbackTable[Idx] (Guid,\r
303 (Guid == NULL)? TokenNumber: ExTokenNumber,\r
304 Data,\r
305 Size\r
306 );\r
878ddf1f 307 }\r
308 }\r
52e1905d 309 \r
878ddf1f 310}\r
311\r
9d6d8b24 312\r
313\r
1de04b4f 314EFI_STATUS\r
315SetValueWorker (\r
316 IN UINTN TokenNumber,\r
317 IN VOID *Data,\r
318 IN UINTN Size\r
319 )\r
320{\r
321 return SetWorker (TokenNumber, Data, &Size, FALSE);\r
322}\r
323\r
324\r
9d6d8b24 325\r
878ddf1f 326EFI_STATUS\r
52e1905d 327SetWorker (\r
1de04b4f 328 IN UINTN TokenNumber,\r
329 IN OUT VOID *Data,\r
330 IN OUT UINTN *Size,\r
331 IN BOOLEAN PtrType\r
878ddf1f 332 )\r
333{\r
52e1905d 334 UINT32 LocalTokenNumber;\r
335 PEI_PCD_DATABASE *PeiPcdDb;\r
9d6d8b24 336 UINT16 StringTableIdx;\r
337 UINTN Offset;\r
338 VOID *InternalData;\r
1de04b4f 339 UINTN MaxSize;\r
878ddf1f 340\r
f89f5802 341 if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {\r
342 return EFI_UNSUPPORTED;\r
343 }\r
344 \r
58f1099f 345 //\r
346 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
347 // We have to decrement TokenNumber by 1 to make it usable\r
348 // as the array index.\r
349 //\r
350 TokenNumber--;\r
351\r
4f914125 352 // EBC compiler is very choosy. It may report warning about comparison\r
353 // between UINTN and 0 . So we add 1 in each size of the \r
354 // comparison.\r
355 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
52e1905d 356 \r
357 PeiPcdDb = GetPcdDatabase ();\r
878ddf1f 358\r
52e1905d 359 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
878ddf1f 360\r
1de04b4f 361 if (!PtrType) {\r
362 ASSERT (PeiPcdGetSize(TokenNumber + 1) == *Size);\r
52e1905d 363 }\r
878ddf1f 364\r
9d6d8b24 365 //\r
366 // We only invoke the callback function for Dynamic Type PCD Entry.\r
367 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX\r
368 // type PCD entry in ExSetWorker.\r
369 //\r
4f914125 370 if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) {\r
1de04b4f 371 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
9d6d8b24 372 }\r
878ddf1f 373\r
52e1905d 374 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
1de04b4f 375 if (PtrType) {\r
376 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
377 } else {\r
378 MaxSize = *Size;\r
379 }\r
380 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
52e1905d 381 }\r
878ddf1f 382\r
52e1905d 383 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
9d6d8b24 384 InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset);\r
878ddf1f 385 \r
1de04b4f 386 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 387 case PCD_TYPE_VPD:\r
388 case PCD_TYPE_HII:\r
389 {\r
390 ASSERT (FALSE);\r
391 return EFI_INVALID_PARAMETER;\r
392 }\r
878ddf1f 393\r
52e1905d 394 case PCD_TYPE_STRING:\r
1de04b4f 395 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
396 StringTableIdx = *((UINT16 *)InternalData);\r
397 CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size);\r
398 return EFI_SUCCESS;\r
399 } else {\r
400 return EFI_INVALID_PARAMETER;\r
401 }\r
878ddf1f 402\r
52e1905d 403 case PCD_TYPE_DATA:\r
404 {\r
52e1905d 405 if (PtrType) {\r
1de04b4f 406 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
407 CopyMem (InternalData, Data, *Size);\r
408 return EFI_SUCCESS;\r
409 } else {\r
410 return EFI_INVALID_PARAMETER;\r
411 }\r
52e1905d 412 }\r
878ddf1f 413\r
1de04b4f 414 switch (*Size) {\r
52e1905d 415 case sizeof(UINT8):\r
416 *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
417 return EFI_SUCCESS;\r
878ddf1f 418\r
52e1905d 419 case sizeof(UINT16):\r
420 *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
421 return EFI_SUCCESS;\r
878ddf1f 422\r
52e1905d 423 case sizeof(UINT32):\r
424 *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
425 return EFI_SUCCESS;\r
878ddf1f 426\r
52e1905d 427 case sizeof(UINT64):\r
428 *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
429 return EFI_SUCCESS;\r
878ddf1f 430\r
52e1905d 431 default:\r
432 ASSERT (FALSE);\r
433 return EFI_NOT_FOUND;\r
434 }\r
435 }\r
436 \r
878ddf1f 437 }\r
438\r
52e1905d 439 ASSERT (FALSE);\r
440 return EFI_NOT_FOUND;\r
9d6d8b24 441\r
442}\r
443\r
444\r
445\r
1de04b4f 446EFI_STATUS\r
447ExSetValueWorker (\r
448 IN UINTN ExTokenNumber,\r
449 IN CONST EFI_GUID *Guid,\r
450 IN VOID *Data,\r
451 IN UINTN Size\r
452 )\r
453{\r
454 return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE);\r
455}\r
456\r
457\r
9d6d8b24 458\r
459EFI_STATUS\r
460ExSetWorker (\r
1de04b4f 461 IN UINTN ExTokenNumber,\r
462 IN CONST EFI_GUID *Guid,\r
463 IN VOID *Data,\r
464 IN OUT UINTN *Size,\r
465 IN BOOLEAN PtrType\r
9d6d8b24 466 )\r
467{\r
8a43e8dd 468 UINTN TokenNumber;\r
9d6d8b24 469\r
f89f5802 470 if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {\r
471 return EFI_UNSUPPORTED;\r
472 }\r
473\r
9d6d8b24 474 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
475\r
1de04b4f 476 InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size);\r
9d6d8b24 477\r
1de04b4f 478 return SetWorker (TokenNumber, Data, Size, PtrType);\r
9d6d8b24 479\r
9d6d8b24 480}\r
481\r
482\r
483\r
484\r
485VOID *\r
486ExGetWorker (\r
487 IN CONST EFI_GUID *Guid,\r
8a43e8dd 488 IN UINTN ExTokenNumber,\r
9d6d8b24 489 IN UINTN GetSize\r
490 )\r
491{\r
f89f5802 492 if (!FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) {\r
493 ASSERT (FALSE);\r
494 return 0;\r
495 }\r
496 \r
9d6d8b24 497 return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);\r
878ddf1f 498}\r
499\r
500\r
9d6d8b24 501\r
502\r
52e1905d 503VOID *\r
9d6d8b24 504GetWorker (\r
8a43e8dd 505 UINTN TokenNumber,\r
9d6d8b24 506 UINTN GetSize\r
878ddf1f 507 )\r
508{\r
52e1905d 509 UINT32 Offset;\r
510 EFI_GUID *Guid;\r
511 UINT16 *Name;\r
512 VARIABLE_HEAD *VariableHead;\r
513 EFI_STATUS Status;\r
514 UINTN DataSize;\r
515 VOID *Data;\r
516 UINT16 *StringTable;\r
517 UINT16 StringTableIdx;\r
9d6d8b24 518 PEI_PCD_DATABASE *PeiPcdDb;\r
519 UINT32 LocalTokenNumber;\r
1de04b4f 520 UINTN MaxSize;\r
9d6d8b24 521\r
58f1099f 522 //\r
523 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
524 // We have to decrement TokenNumber by 1 to make it usable\r
525 // as the array index.\r
526 //\r
527 TokenNumber--;\r
528\r
4f914125 529 // EBC compiler is very choosy. It may report warning about comparison\r
530 // between UINTN and 0 . So we add 1 in each size of the \r
531 // comparison.\r
532 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
9d6d8b24 533\r
1de04b4f 534 ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));\r
9d6d8b24 535\r
52e1905d 536 PeiPcdDb = GetPcdDatabase ();\r
537\r
9d6d8b24 538 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
539\r
52e1905d 540 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
1de04b4f 541 if (GetSize == 0) {\r
542 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
543 } else {\r
544 MaxSize = GetSize;\r
545 }\r
546 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
52e1905d 547 }\r
878ddf1f 548\r
52e1905d 549 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
550 StringTable = PeiPcdDb->Init.StringTable;\r
551 \r
1de04b4f 552 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 553 case PCD_TYPE_VPD:\r
554 {\r
555 VPD_HEAD *VpdHead;\r
556 VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
4f914125 557 return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
52e1905d 558 }\r
559 \r
560 case PCD_TYPE_HII:\r
561 {\r
562 VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
563 \r
564 Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);\r
565 Name = &StringTable[VariableHead->StringIndex];\r
566\r
567 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
52e1905d 568\r
c0e96fed 569 if (Status == EFI_SUCCESS) {\r
c0e96fed 570 return (VOID *) ((UINT8 *) Data + VariableHead->Offset);\r
571 } else {\r
572 //\r
58f1099f 573 // Return the default value specified by Platform Integrator \r
574 //\r
575 return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset);\r
c0e96fed 576 }\r
52e1905d 577 }\r
878ddf1f 578\r
52e1905d 579 case PCD_TYPE_DATA:\r
580 return (VOID *) ((UINT8 *)PeiPcdDb + Offset);\r
878ddf1f 581\r
52e1905d 582 case PCD_TYPE_STRING:\r
583 StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset);\r
584 return (VOID *) (&StringTable[StringTableIdx]);\r
878ddf1f 585\r
52e1905d 586 default:\r
587 ASSERT (FALSE);\r
588 break;\r
589 \r
590 }\r
878ddf1f 591\r
52e1905d 592 ASSERT (FALSE);\r
593 \r
594 return NULL;\r
595 \r
596}\r
878ddf1f 597\r
878ddf1f 598\r
a7c5092f 599\r
8a43e8dd 600UINTN \r
9d6d8b24 601GetExPcdTokenNumber (\r
52e1905d 602 IN CONST EFI_GUID *Guid,\r
4f914125 603 IN UINTN ExTokenNumber\r
52e1905d 604 )\r
605{\r
606 UINT32 i;\r
607 DYNAMICEX_MAPPING *ExMap;\r
608 EFI_GUID *GuidTable;\r
9d6d8b24 609 EFI_GUID *MatchGuid;\r
610 UINTN MatchGuidIdx;\r
52e1905d 611 PEI_PCD_DATABASE *PeiPcdDb;\r
878ddf1f 612\r
52e1905d 613 PeiPcdDb = GetPcdDatabase();\r
614 \r
615 ExMap = PeiPcdDb->Init.ExMapTable;\r
616 GuidTable = PeiPcdDb->Init.GuidTable;\r
9d6d8b24 617\r
618 MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);\r
bb5545b6 619 //\r
620 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r
621 // error in the BUILD system.\r
622 //\r
9d6d8b24 623 ASSERT (MatchGuid != NULL);\r
624 \r
625 MatchGuidIdx = MatchGuid - GuidTable;\r
52e1905d 626 \r
627 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
628 if ((ExTokenNumber == ExMap[i].ExTokenNumber) && \r
9d6d8b24 629 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
630 return ExMap[i].LocalTokenNumber;\r
52e1905d 631 }\r
632 }\r
633 \r
634 ASSERT (FALSE);\r
635 \r
9d6d8b24 636 return 0;\r
878ddf1f 637}\r
638\r
639\r
640\r
52e1905d 641PEI_PCD_DATABASE *\r
642GetPcdDatabase (\r
643 VOID\r
878ddf1f 644 )\r
645{\r
52e1905d 646 EFI_HOB_GUID_TYPE *GuidHob;\r
878ddf1f 647\r
52e1905d 648 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
649 ASSERT (GuidHob != NULL);\r
650 \r
651 return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
652}\r
878ddf1f 653\r
1de04b4f 654\r
3401c092 655\r
1de04b4f 656SKU_ID *\r
657GetSkuIdArray (\r
658 IN UINTN LocalTokenNumberTableIdx,\r
659 IN PEI_PCD_DATABASE *Database\r
660 )\r
661{\r
662 SKU_HEAD *SkuHead;\r
663 UINTN LocalTokenNumber;\r
664\r
665 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
666\r
667 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);\r
668\r
669 SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
670\r
671 return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset);\r
672 \r
673}\r
674\r
675\r
3401c092 676\r
1de04b4f 677UINTN\r
678GetSizeTableIndex (\r
679 IN UINTN LocalTokenNumberTableIdx,\r
680 IN PEI_PCD_DATABASE *Database\r
681 )\r
682{\r
683 UINTN i;\r
684 UINTN SizeTableIdx;\r
685 UINTN LocalTokenNumber;\r
686 SKU_ID *SkuIdTable;\r
687 \r
688 SizeTableIdx = 0;\r
689\r
690 for (i=0; i<LocalTokenNumberTableIdx; i++) {\r
691 LocalTokenNumber = Database->Init.LocalTokenNumberTable[i];\r
692\r
693 if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {\r
694 //\r
695 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
696 // PCD entry.\r
697 //\r
698 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
699 //\r
700 // We have only one entry for VPD enabled PCD entry:\r
701 // 1) MAX Size.\r
702 // We consider current size is equal to MAX size.\r
703 //\r
704 SizeTableIdx++;\r
705 } else {\r
706 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
707 //\r
708 // We have only two entry for Non-Sku enabled PCD entry:\r
709 // 1) MAX SIZE\r
710 // 2) Current Size\r
711 //\r
712 SizeTableIdx += 2;\r
713 } else {\r
714 //\r
715 // We have these entry for SKU enabled PCD entry\r
716 // 1) MAX SIZE\r
717 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
718 //\r
719 SkuIdTable = GetSkuIdArray (i, Database);\r
720 SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
721 }\r
722 }\r
723 }\r
724\r
725 }\r
726\r
727 return SizeTableIdx;\r
728}\r