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