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