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