Updated MSA by putting Specification element at the end of the header section
[mirror_edk2.git] / EdkNt32Pkg / Pei / PcdEmulator / PcdEmulator.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13 PcdEmulator.c\r
14\r
15Abstract:\r
16 Platform Configuration Database (PCD) Service PEIM\r
17\r
18--*/\r
19\r
20#include <PcdEmulator.h>\r
21\r
22//\r
23// BugBug: PEI early phase does not support global variable!!!\r
24// This is only a temperary solution.\r
25//\r
26\r
27UINTN mSkuId = 0;\r
28\r
29\r
30STATIC EMULATED_PCD_DATABASE_EX *\r
31GetPcdDataBaseEx (\r
32 VOID\r
33) {\r
34 EFI_HOB_GUID_TYPE *GuidHob;\r
35 EMULATED_PCD_DATABASE_EX *EmulatedPcdDatabaseEx;\r
36\r
37 GuidHob = GetFirstGuidHob (&gPcdHobGuid);\r
38 EmulatedPcdDatabaseEx = (EMULATED_PCD_DATABASE_EX *) GET_GUID_HOB_DATA(GuidHob);\r
39\r
40 return EmulatedPcdDatabaseEx;\r
41}\r
42\r
43STATIC UINTN \r
44GetPcdDataBaseExEntryCount (\r
45 EMULATED_PCD_DATABASE_EX * Database\r
46) {\r
47 return Database->Count;\r
48}\r
49\r
50STATIC UINTN \r
51GetPcdDataBaseExSize (\r
52 EMULATED_PCD_DATABASE_EX * Database\r
53) {\r
54 UINTN Size;\r
55 \r
56 Size = sizeof (Database->Count)\r
57 + (sizeof (Database->Entry[0]) * Database->Count);\r
58 \r
59 return Size;\r
60}\r
61\r
62EFI_STATUS\r
63EFIAPI\r
64PcdEmulatorSetSku (\r
65 IN UINTN SkuId\r
66 )\r
67{\r
68 mSkuId = SkuId;\r
69 return EFI_SUCCESS;\r
70}\r
71\r
72UINT8\r
73EFIAPI\r
74PcdEmulatorGet8 (\r
75 IN UINTN TokenNumber\r
76 )\r
77{\r
78 EMULATED_PCD_ENTRY_EX *Pcd;\r
79\r
80 Pcd = GetPcdEntry (TokenNumber);\r
81 ASSERT (Pcd != NULL);\r
82 ASSERT (Pcd->DatumSize == 1);\r
83\r
84 return (UINT8)Pcd->Datum;\r
85}\r
86\r
87UINT16\r
88EFIAPI\r
89PcdEmulatorGet16 (\r
90 IN UINTN TokenNumber\r
91 )\r
92{\r
93 EMULATED_PCD_ENTRY_EX *Pcd;\r
94\r
95 Pcd = GetPcdEntry (TokenNumber);\r
96 ASSERT (Pcd != NULL);\r
97 ASSERT (Pcd->DatumSize == 2);\r
98\r
99 return (UINT16)Pcd->Datum;\r
100}\r
101\r
102UINT32\r
103EFIAPI\r
104PcdEmulatorGet32 (\r
105 IN UINTN TokenNumber\r
106 )\r
107{\r
108 EMULATED_PCD_ENTRY_EX *Pcd;\r
109\r
110 Pcd = GetPcdEntry (TokenNumber);\r
111 ASSERT (Pcd != NULL);\r
112 ASSERT (Pcd->DatumSize == 4);\r
113\r
114 return (UINT32)Pcd->Datum;\r
115}\r
116\r
117UINT64\r
118EFIAPI\r
119PcdEmulatorGet64 (\r
120 IN UINTN TokenNumber\r
121 )\r
122{\r
123 EMULATED_PCD_ENTRY_EX *Pcd;\r
124\r
125 Pcd = GetPcdEntry (TokenNumber);\r
126 ASSERT (Pcd != NULL);\r
127 ASSERT (Pcd->DatumSize == sizeof (UINT64));\r
128\r
129 return (UINT64)Pcd->Datum;\r
130}\r
131\r
132VOID *\r
133EFIAPI\r
134PcdEmulatorGetPtr (\r
135 IN UINTN TokenNumber\r
136 )\r
137{\r
138 EMULATED_PCD_ENTRY_EX *Pcd;\r
139\r
140 Pcd = GetPcdEntry (TokenNumber);\r
141 ASSERT (Pcd != NULL);\r
142\r
143 return (VOID *)(UINTN)Pcd->ExtendedData;\r
144}\r
145\r
146BOOLEAN\r
147EFIAPI\r
148PcdEmulatorGetBoolean (\r
149 IN UINTN TokenNumber\r
150 )\r
151{\r
152 EMULATED_PCD_ENTRY_EX *Pcd;\r
153\r
154 Pcd = GetPcdEntry (TokenNumber);\r
155 ASSERT (Pcd != NULL);\r
156 ASSERT (Pcd->DatumSize == 1);\r
157\r
158 return (BOOLEAN)Pcd->Datum;\r
159}\r
160\r
161UINTN\r
162EFIAPI\r
163PcdEmulatorGetSize (\r
164 IN UINTN TokenNumber\r
165 )\r
166{\r
167 EMULATED_PCD_ENTRY_EX *Pcd;\r
168\r
169 Pcd = GetPcdEntry (TokenNumber);\r
170 ASSERT (Pcd != NULL);\r
171 return Pcd->DatumSize;\r
172}\r
173\r
174UINT8\r
175EFIAPI\r
176PcdEmulatorGet8Ex (\r
177 IN CONST EFI_GUID *PcdDataBaseName,\r
178 IN UINTN TokenNumber\r
179 )\r
180{\r
181 ASSERT (FALSE);\r
182 return 0;\r
183}\r
184\r
185UINT16\r
186EFIAPI\r
187PcdEmulatorGet16Ex (\r
188 IN CONST EFI_GUID *PcdDataBaseName,\r
189 IN UINTN TokenNumber\r
190 )\r
191{\r
192 ASSERT (FALSE);\r
193 return 0;\r
194}\r
195\r
196UINT32\r
197EFIAPI\r
198PcdEmulatorGet32Ex (\r
199 IN CONST EFI_GUID *PcdDataBaseName,\r
200 IN UINTN TokenNumber\r
201 )\r
202{\r
203 ASSERT (FALSE);\r
204 return 0;\r
205}\r
206\r
207UINT64\r
208EFIAPI\r
209PcdEmulatorGet64Ex (\r
210 IN CONST EFI_GUID *PcdDataBaseName,\r
211 IN UINTN TokenNumber\r
212 )\r
213{\r
214 ASSERT (FALSE);\r
215 return 0;\r
216}\r
217\r
218VOID *\r
219EFIAPI\r
220PcdEmulatorGetPtrEx (\r
221 IN CONST EFI_GUID *PcdDataBaseName,\r
222 IN UINTN TokenNumber\r
223 )\r
224{\r
225 ASSERT (FALSE);\r
226 return 0;\r
227}\r
228\r
229BOOLEAN\r
230EFIAPI\r
231PcdEmulatorGetBooleanEx (\r
232 IN CONST EFI_GUID *PcdDataBaseName,\r
233 IN UINTN TokenNumber\r
234 )\r
235{\r
236 ASSERT (FALSE);\r
237 return 0;\r
238}\r
239\r
240UINTN\r
241EFIAPI\r
242PcdEmulatorGetSizeEx (\r
243 IN CONST EFI_GUID *PcdDataBaseName,\r
244 IN UINTN TokenNumber\r
245 )\r
246{\r
247 EMULATED_PCD_ENTRY_EX *Pcd;\r
248\r
249 Pcd = GetPcdEntry (TokenNumber);\r
250 ASSERT (Pcd != NULL);\r
251 return Pcd->DatumSize;\r
252}\r
253\r
254\r
255EFI_STATUS\r
256EFIAPI\r
257PcdEmulatorSet8 (\r
258 IN UINTN TokenNumber,\r
259 IN UINT8 Value\r
260 )\r
261{ \r
262\r
263 EMULATED_PCD_ENTRY_EX *Pcd;\r
264\r
265 Pcd = GetPcdEntry (TokenNumber);\r
266 ASSERT (Pcd != NULL);\r
267\r
268 ASSERT (Pcd->DatumSize == sizeof (UINT8));\r
269\r
270 Pcd->Datum = Value;\r
271\r
272 return EFI_SUCCESS;\r
273}\r
274\r
275EFI_STATUS\r
276EFIAPI\r
277PcdEmulatorSet16 (\r
278 IN UINTN TokenNumber,\r
279 IN UINT16 Value\r
280 )\r
281{ \r
282\r
283 ASSERT (FALSE);\r
284\r
285 return EFI_SUCCESS;\r
286}\r
287\r
288EFI_STATUS\r
289EFIAPI\r
290PcdEmulatorSet32 (\r
291 IN UINTN TokenNumber,\r
292 IN UINT32 Value\r
293 )\r
294{ \r
295\r
296 EMULATED_PCD_ENTRY_EX *Pcd;\r
297\r
298 Pcd = GetPcdEntry (TokenNumber);\r
299 ASSERT (Pcd != NULL);\r
300\r
301 ASSERT (Pcd->DatumSize == sizeof (UINT32));\r
302\r
303 Pcd->Datum = Value;\r
304\r
305 return EFI_SUCCESS;\r
306}\r
307\r
308EFI_STATUS\r
309EFIAPI\r
310PcdEmulatorSet64 (\r
311 IN UINTN TokenNumber,\r
312 IN UINT64 Value\r
313 )\r
314{ \r
315\r
316 ASSERT (FALSE);\r
317\r
318 return EFI_SUCCESS;\r
319}\r
320\r
321EFI_STATUS\r
322EFIAPI\r
323PcdEmulatorSetPtr (\r
324 IN UINTN TokenNumber,\r
325 IN CONST VOID *Value\r
326 )\r
327{ \r
328\r
329 ASSERT (FALSE);\r
330\r
331 return EFI_SUCCESS;\r
332}\r
333\r
334EFI_STATUS\r
335EFIAPI\r
336PcdEmulatorSetBoolean (\r
337 IN UINTN TokenNumber,\r
338 IN BOOLEAN Value\r
339 )\r
340{ \r
341\r
342 ASSERT (FALSE);\r
343\r
344 return EFI_SUCCESS;\r
345}\r
346\r
347EFI_STATUS\r
348EFIAPI\r
349PcdEmulatorSet8Ex (\r
350 IN CONST EFI_GUID *Guid,\r
351 IN UINTN TokenNumber,\r
352 IN UINT8 Value\r
353 )\r
354{ \r
355\r
356 ASSERT (FALSE);\r
357\r
358 return EFI_SUCCESS;\r
359}\r
360\r
361EFI_STATUS\r
362EFIAPI\r
363PcdEmulatorSet16Ex (\r
364 IN CONST EFI_GUID *Guid,\r
365 IN UINTN TokenNumber,\r
366 IN UINT16 Value\r
367 )\r
368{ \r
369\r
370 ASSERT (FALSE);\r
371\r
372 return EFI_SUCCESS;\r
373}\r
374\r
375EFI_STATUS\r
376EFIAPI\r
377PcdEmulatorSet32Ex (\r
378 IN CONST EFI_GUID *Guid,\r
379 IN UINTN TokenNumber,\r
380 IN UINT32 Value\r
381 )\r
382{ \r
383\r
384 ASSERT (FALSE);\r
385\r
386 return EFI_SUCCESS;\r
387}\r
388\r
389EFI_STATUS\r
390EFIAPI\r
391PcdEmulatorSet64Ex (\r
392 IN CONST EFI_GUID *Guid,\r
393 IN UINTN TokenNumber,\r
394 IN UINT64 Value\r
395 )\r
396{ \r
397\r
398 ASSERT (FALSE);\r
399\r
400 return EFI_SUCCESS;\r
401}\r
402\r
403EFI_STATUS\r
404EFIAPI\r
405PcdEmulatorSetPtrEx (\r
406 IN CONST EFI_GUID *Guid,\r
407 IN UINTN TokenNumber,\r
408 IN CONST VOID *Value\r
409 )\r
410{ \r
411\r
412 ASSERT (FALSE);\r
413\r
414 return EFI_SUCCESS;\r
415}\r
416\r
417EFI_STATUS\r
418EFIAPI\r
419PcdEmulatorSetBooleanEx (\r
420 IN CONST EFI_GUID *Guid,\r
421 IN UINTN TokenNumber,\r
422 IN BOOLEAN Value\r
423 )\r
424{ \r
425\r
426 ASSERT (FALSE);\r
427\r
428 return EFI_SUCCESS;\r
429}\r
430\r
431EFI_STATUS\r
432EFIAPI\r
433PcdEmulatorCallBackOnSet (\r
434 IN UINTN TokenNumber,\r
435 IN CONST EFI_GUID *Guid, OPTIONAL\r
436 IN PCD_PPI_CALLBACK CallBackFunction\r
437 )\r
438{\r
439 EMULATED_PCD_ENTRY_EX *Pcd;\r
440\r
441 Pcd = GetPcdEntry (TokenNumber);\r
442 ASSERT (Pcd != NULL);\r
443\r
444 if (Pcd->CallBackListSize == Pcd->CallBackEntries) {\r
445 return EFI_OUT_OF_RESOURCES;\r
446 }\r
447\r
448 Pcd->CallBackList[Pcd->CallBackEntries++] = CallBackFunction;\r
449\r
450 return EFI_SUCCESS;\r
451}\r
452\r
453EFI_STATUS\r
454EFIAPI\r
455PcdEmulatorUnregisterCallBackOnSet (\r
456 IN UINTN TokenNumber,\r
457 IN CONST EFI_GUID *Guid, OPTIONAL\r
458 IN PCD_PPI_CALLBACK CallBackfunction\r
459 )\r
460{\r
461 EMULATED_PCD_ENTRY_EX *Pcd;\r
462 UINT32 Index;\r
463\r
464 Pcd = GetPcdEntry (TokenNumber);\r
465 ASSERT (Pcd != NULL);\r
466\r
467 for (Index = 0; Index < Pcd->CallBackListSize; Index++) {\r
468 if (Pcd->CallBackList[Index] == CallBackfunction) {\r
469 Pcd->CallBackList[Index] = NULL;\r
470 return EFI_SUCCESS;\r
471 }\r
472 }\r
473\r
474 return EFI_NOT_FOUND;\r
475}\r
476\r
477EFI_STATUS\r
478EFIAPI\r
479PcdEmulatorGetNextToken (\r
480 IN CONST EFI_GUID *Guid, OPTIONAL\r
481 IN UINTN *Token\r
482 )\r
483{\r
484 EMULATED_PCD_ENTRY_EX *Pcd;\r
485 EMULATED_PCD_ENTRY_EX *LastPcdEntry;\r
486 EMULATED_PCD_DATABASE_EX *PcdDatabase;\r
487 EMULATED_PCD_ENTRY_EX *PcdEntry;\r
488\r
489 PcdDatabase = GetPcdDataBaseEx (); \r
490 PcdEntry = PcdDatabase->Entry;\r
491\r
492 if (*Token == PCD_INVALID_TOKEN) {\r
493 //\r
494 // BugBug: Due to variable size array, ensure we convert this to a reasonable database\r
495 // that can accomodate array references for simplicity's sake\r
496 *Token = PcdEntry[0].Token;\r
497 return EFI_SUCCESS;\r
498 }\r
499\r
500 Pcd = GetPcdEntry (*Token);\r
501 if (Pcd == NULL) {\r
502 return EFI_NOT_FOUND;\r
503 }\r
504\r
505 LastPcdEntry = PcdEntry + GetPcdDataBaseExEntryCount (PcdDatabase);\r
506 if (++Pcd >= LastPcdEntry) {\r
507 return EFI_NOT_FOUND;\r
508 }\r
509 \r
510 *Token = Pcd->Token;\r
511 return EFI_SUCCESS;\r
512}\r
513\r
514PCD_PPI mPcdPpiInstance = {\r
515 PcdEmulatorSetSku,\r
516\r
517 PcdEmulatorGet8,\r
518 PcdEmulatorGet16, \r
519 PcdEmulatorGet32, \r
520 PcdEmulatorGet64, \r
521 PcdEmulatorGetPtr, \r
522 PcdEmulatorGetBoolean, \r
523 PcdEmulatorGetSize,\r
524\r
525 PcdEmulatorGet8Ex,\r
526 PcdEmulatorGet16Ex, \r
527 PcdEmulatorGet32Ex, \r
528 PcdEmulatorGet64Ex, \r
529 PcdEmulatorGetPtrEx, \r
530 PcdEmulatorGetBooleanEx, \r
531 PcdEmulatorGetSizeEx,\r
532 \r
533 PcdEmulatorSet8,\r
534 PcdEmulatorSet16, \r
535 PcdEmulatorSet32, \r
536 PcdEmulatorSet64, \r
537 PcdEmulatorSetPtr, \r
538 PcdEmulatorSetBoolean, \r
539\r
540 PcdEmulatorSet8Ex,\r
541 PcdEmulatorSet16Ex, \r
542 PcdEmulatorSet32Ex, \r
543 PcdEmulatorSet64Ex, \r
544 PcdEmulatorSetPtrEx, \r
545 PcdEmulatorSetBooleanEx, \r
546\r
547 PcdEmulatorCallBackOnSet,\r
548 PcdEmulatorUnregisterCallBackOnSet,\r
549 PcdEmulatorGetNextToken\r
550};\r
551\r
552STATIC EFI_PEI_PPI_DESCRIPTOR mPpiPCD = {\r
553 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
554 &gPcdPpiGuid,\r
555 &mPcdPpiInstance\r
556};\r
557\r
558EFI_STATUS\r
559EFIAPI\r
560PeimPcdEmulatorEntry (\r
561 IN EFI_FFS_FILE_HEADER *FfsHeader,\r
562 IN EFI_PEI_SERVICES **PeiServices\r
563 )\r
564{\r
565 EFI_STATUS Status;\r
566 UINTN Index;\r
567 UINTN Count;\r
568 UINTN Calculation;\r
569 UINT8 *AllocatedBuffer;\r
570 EMULATED_PCD_DATABASE_EX *EmulatedPcdDatabaseEx;\r
571 EMULATED_PCD_ENTRY_EX *EmulatedPcdEntryEx;\r
572\r
573 //\r
574 // BugBug: Normally, we would read an FFS file for this data\r
575 // We need to remember, that when we read the FFS file, items such as the VariableName will not be encoded as a pointer\r
576 // but as an array of content. In this emulation, our init is encoding this data as a pointer.\r
577 // In the FFS version, we will depend on the proper Entry Count in the FFS data since the structures will\r
578 // now be variable length.\r
579 //\r
580 //\r
581\r
582 //\r
583 // We should now read from the FFS file into the cache - for now, we fake this.\r
584 //\r
585 Count = GetPcdDataBaseSize () / sizeof (EMULATED_PCD_ENTRY);\r
586\r
587 //\r
588 // Let's now determine how big of a buffer we need for our database\r
589 // For the FFS version, we need to calculate/consider the VariableName/ExtendedData size!!!\r
590 //\r
591 Calculation = sizeof (UINTN) + (Count * sizeof (EMULATED_PCD_ENTRY_EX));\r
592\r
593 EmulatedPcdDatabaseEx = (EMULATED_PCD_DATABASE_EX *) BuildGuidHob (&gPcdHobGuid, Calculation);\r
594\r
595 EmulatedPcdDatabaseEx->Count = Count;\r
596 EmulatedPcdEntryEx = EmulatedPcdDatabaseEx->Entry;\r
597\r
598 AllocatedBuffer = AllocatePool (Count * sizeof (PCD_PPI_CALLBACK) * MAX_PCD_CALLBACK);\r
599 ASSERT (AllocatedBuffer != NULL); \r
600\r
601 for (Index = 0; Index < Count; Index++) {\r
602 //\r
603 // Copy from source to our own allocated buffer - normally an FFS read\r
604 //\r
605 (*PeiServices)->CopyMem (\r
606 (VOID *) (EmulatedPcdEntryEx + Index),\r
607 (VOID *) (gEmulatedPcdEntry + Index),\r
608 sizeof (EMULATED_PCD_ENTRY)\r
609 );\r
610\r
611 //\r
612 // All the CallBackList worker functions refer to this CallBackList as CallBackList[CallbackEntry]\r
613 // so we seed the same buffer address here.\r
614 //\r
615 EmulatedPcdEntryEx[Index].CallBackList = (PCD_PPI_CALLBACK *)AllocatedBuffer;\r
616 AllocatedBuffer+= (sizeof (PCD_PPI_CALLBACK) * MAX_PCD_CALLBACK);\r
617 EmulatedPcdEntryEx[Index].CallBackEntries = 0;\r
618 EmulatedPcdEntryEx[Index].CallBackListSize = MAX_PCD_CALLBACK;\r
619 }\r
620\r
621 //\r
622 // Install PCD service PPI\r
623 //\r
624 Status = PeiCoreInstallPpi (&mPpiPCD);\r
625\r
626 ASSERT_EFI_ERROR (Status);\r
627 return Status;\r
628}\r
629\r
630\r
631EMULATED_PCD_ENTRY_EX *\r
632GetPcdEntry (\r
633 IN UINTN TokenNumber\r
634 )\r
635{\r
636 UINTN Index;\r
637 UINTN Count;\r
638 EMULATED_PCD_DATABASE_EX *EmulatedPcdDatabaseEx;\r
639 EMULATED_PCD_ENTRY_EX *EmulatedPcdEntryEx;\r
640\r
641 CpuBreakpoint (); \r
642\r
643 EmulatedPcdDatabaseEx = GetPcdDataBaseEx (); \r
644 //\r
645 // BugBug: This Count will change when we flip over to FFS version\r
646 //\r
647 Count = EmulatedPcdDatabaseEx->Count;\r
648 EmulatedPcdEntryEx = EmulatedPcdDatabaseEx->Entry;\r
649 for (Index = 0; Index < Count; Index++) {\r
650 if (EmulatedPcdEntryEx[Index].Token == TokenNumber) {\r
651 return &EmulatedPcdEntryEx[Index];\r
652 }\r
653 }\r
654 return NULL;\r
655}\r
656\r
657\r