]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EdkModulePkg/Universal/PCD/Dxe/Pcd.c
Fixed a bug when input a invalid token number (not ZERO nor a valid token number...
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Dxe / Pcd.c
... / ...
CommitLineData
1/** @file\r
2PCD DXE driver\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: Pcd.c\r
15\r
16**/\r
17\r
18#include "Service.h"\r
19\r
20\r
21PCD_PROTOCOL mPcdInstance = {\r
22 DxePcdSetSku,\r
23\r
24 DxePcdGet8,\r
25 DxePcdGet16,\r
26 DxePcdGet32,\r
27 DxePcdGet64,\r
28 DxePcdGetPtr,\r
29 DxePcdGetBool,\r
30 DxePcdGetSize,\r
31\r
32 DxePcdGet8Ex,\r
33 DxePcdGet16Ex,\r
34 DxePcdGet32Ex,\r
35 DxePcdGet64Ex,\r
36 DxePcdGetPtrEx,\r
37 DxePcdGetBoolEx,\r
38 DxePcdGetSizeEx,\r
39\r
40 DxePcdSet8,\r
41 DxePcdSet16,\r
42 DxePcdSet32,\r
43 DxePcdSet64,\r
44 DxePcdSetPtr,\r
45 DxePcdSetBool,\r
46\r
47 DxePcdSet8Ex,\r
48 DxePcdSet16Ex,\r
49 DxePcdSet32Ex,\r
50 DxePcdSet64Ex,\r
51 DxePcdSetPtrEx,\r
52 DxePcdSetBoolEx,\r
53\r
54 DxeRegisterCallBackOnSet,\r
55 DxeUnRegisterCallBackOnSet,\r
56 DxePcdGetNextToken,\r
57 DxePcdGetNextTokenSpace\r
58};\r
59\r
60\r
61//\r
62// Static global to reduce the code size\r
63//\r
64static EFI_HANDLE NewHandle = NULL;\r
65\r
66EFI_STATUS\r
67EFIAPI\r
68PcdDxeInit (\r
69 IN EFI_HANDLE ImageHandle,\r
70 IN EFI_SYSTEM_TABLE *SystemTable\r
71 )\r
72{\r
73 EFI_STATUS Status;\r
74\r
75 //\r
76 // Make sure the Pcd Protocol is not already installed in the system\r
77 //\r
78\r
79 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gPcdProtocolGuid);\r
80\r
81 BuildPcdDxeDataBase ();\r
82\r
83 //\r
84 // BugBug Check if PcdDatabase is already installed.\r
85 //\r
86 \r
87 Status = gBS->InstallProtocolInterface (\r
88 &NewHandle,\r
89 &gPcdProtocolGuid,\r
90 EFI_NATIVE_INTERFACE,\r
91 &mPcdInstance\r
92 );\r
93\r
94 ASSERT_EFI_ERROR (Status);\r
95\r
96 return EFI_SUCCESS;\r
97\r
98}\r
99\r
100\r
101VOID\r
102EFIAPI\r
103DxePcdSetSku (\r
104 IN UINTN SkuId\r
105 )\r
106{\r
107 mPcdDatabase->PeiDb.Init.SystemSkuId = (SKU_ID) SkuId;\r
108 \r
109 return;\r
110}\r
111\r
112\r
113\r
114UINT8\r
115EFIAPI\r
116DxePcdGet8 (\r
117 IN UINTN TokenNumber\r
118 )\r
119{\r
120 return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8)));\r
121}\r
122\r
123\r
124\r
125UINT16\r
126EFIAPI\r
127DxePcdGet16 (\r
128 IN UINTN TokenNumber\r
129 )\r
130{\r
131 return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16)));\r
132}\r
133\r
134\r
135\r
136UINT32\r
137EFIAPI\r
138DxePcdGet32 (\r
139 IN UINTN TokenNumber\r
140 )\r
141{\r
142 return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32)));\r
143}\r
144\r
145\r
146\r
147UINT64\r
148EFIAPI\r
149DxePcdGet64 (\r
150 IN UINTN TokenNumber\r
151 )\r
152{\r
153 return ReadUnaligned64(GetWorker (TokenNumber, sizeof (UINT64)));\r
154}\r
155\r
156\r
157\r
158VOID *\r
159EFIAPI\r
160DxePcdGetPtr (\r
161 IN UINTN TokenNumber\r
162 )\r
163{\r
164 return GetWorker (TokenNumber, 0);\r
165}\r
166\r
167\r
168\r
169BOOLEAN\r
170EFIAPI\r
171DxePcdGetBool (\r
172 IN UINTN TokenNumber\r
173 )\r
174{\r
175 return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN)));\r
176}\r
177\r
178\r
179\r
180UINTN\r
181EFIAPI\r
182DxePcdGetSize (\r
183 IN UINTN TokenNumber\r
184 )\r
185{\r
186 UINTN Size;\r
187 UINT32 *LocalTokenNumberTable;\r
188 BOOLEAN IsPeiDb;\r
189 UINTN MaxSize;\r
190 UINTN TmpTokenNumber;\r
191 //\r
192 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
193 // We have to decrement TokenNumber by 1 to make it usable\r
194 // as the array index.\r
195 //\r
196 TokenNumber--;\r
197\r
198 //\r
199 // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber\r
200 // \r
201 TmpTokenNumber = TokenNumber;\r
202\r
203 ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);\r
204\r
205 IsPeiDb = (BOOLEAN) (TokenNumber < PEI_LOCAL_TOKEN_NUMBER);\r
206 \r
207 TokenNumber = IsPeiDb ? TokenNumber : \r
208 (TokenNumber - PEI_LOCAL_TOKEN_NUMBER);\r
209\r
210 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable \r
211 : mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
212\r
213 Size = (LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;\r
214\r
215 if (Size == 0) {\r
216 //\r
217 // For pointer type, we need to scan the SIZE_TABLE to get the current size.\r
218 //\r
219 return GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
220 } else {\r
221 return Size;\r
222 }\r
223\r
224}\r
225\r
226\r
227\r
228UINT8\r
229EFIAPI\r
230DxePcdGet8Ex (\r
231 IN CONST EFI_GUID *Guid,\r
232 IN UINTN ExTokenNumber\r
233 )\r
234{\r
235 return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof(UINT8)));\r
236}\r
237\r
238\r
239\r
240UINT16\r
241EFIAPI\r
242DxePcdGet16Ex (\r
243 IN CONST EFI_GUID *Guid,\r
244 IN UINTN ExTokenNumber\r
245 )\r
246{\r
247 return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT16)));\r
248}\r
249\r
250\r
251\r
252UINT32\r
253EFIAPI\r
254DxePcdGet32Ex (\r
255 IN CONST EFI_GUID *Guid,\r
256 IN UINTN ExTokenNumber\r
257 )\r
258{\r
259 return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT32)));\r
260}\r
261\r
262\r
263\r
264UINT64\r
265EFIAPI\r
266DxePcdGet64Ex (\r
267 IN CONST EFI_GUID *Guid,\r
268 IN UINTN ExTokenNumber\r
269 )\r
270{\r
271 return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT64)));\r
272}\r
273\r
274\r
275\r
276VOID *\r
277EFIAPI\r
278DxePcdGetPtrEx (\r
279 IN CONST EFI_GUID *Guid,\r
280 IN UINTN ExTokenNumber\r
281 )\r
282{\r
283 return ExGetWorker (Guid, ExTokenNumber, 0);\r
284}\r
285\r
286\r
287\r
288BOOLEAN\r
289EFIAPI\r
290DxePcdGetBoolEx (\r
291 IN CONST EFI_GUID *Guid,\r
292 IN UINTN ExTokenNumber\r
293 )\r
294{\r
295 return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof(BOOLEAN)));\r
296}\r
297\r
298\r
299\r
300UINTN\r
301EFIAPI\r
302DxePcdGetSizeEx (\r
303 IN CONST EFI_GUID *Guid,\r
304 IN UINTN ExTokenNumber\r
305 )\r
306{\r
307 return DxePcdGetSize(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber));\r
308}\r
309\r
310\r
311\r
312EFI_STATUS\r
313EFIAPI\r
314DxePcdSet8 (\r
315 IN UINTN TokenNumber,\r
316 IN UINT8 Value\r
317 )\r
318{\r
319 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
320}\r
321\r
322\r
323\r
324EFI_STATUS\r
325EFIAPI\r
326DxePcdSet16 (\r
327 IN UINTN TokenNumber,\r
328 IN UINT16 Value\r
329 )\r
330{\r
331 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
332}\r
333\r
334\r
335\r
336EFI_STATUS\r
337EFIAPI\r
338DxePcdSet32 (\r
339 IN UINTN TokenNumber,\r
340 IN UINT32 Value\r
341 )\r
342{\r
343 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
344}\r
345\r
346\r
347\r
348EFI_STATUS\r
349EFIAPI\r
350DxePcdSet64 (\r
351 IN UINTN TokenNumber,\r
352 IN UINT64 Value\r
353 )\r
354{\r
355 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
356}\r
357\r
358\r
359\r
360EFI_STATUS\r
361EFIAPI\r
362DxePcdSetPtr (\r
363 IN UINTN TokenNumber,\r
364 IN OUT UINTN *SizeOfBuffer,\r
365 IN VOID *Buffer\r
366 )\r
367{\r
368 return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);\r
369}\r
370\r
371\r
372\r
373EFI_STATUS\r
374EFIAPI\r
375DxePcdSetBool (\r
376 IN UINTN TokenNumber,\r
377 IN BOOLEAN Value\r
378 )\r
379{\r
380 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
381}\r
382\r
383\r
384\r
385EFI_STATUS\r
386EFIAPI\r
387DxePcdSet8Ex (\r
388 IN CONST EFI_GUID *Guid,\r
389 IN UINTN ExTokenNumber,\r
390 IN UINT8 Value\r
391 )\r
392{\r
393 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
394}\r
395\r
396\r
397\r
398EFI_STATUS\r
399EFIAPI\r
400DxePcdSet16Ex (\r
401 IN CONST EFI_GUID *Guid,\r
402 IN UINTN ExTokenNumber,\r
403 IN UINT16 Value\r
404 )\r
405{\r
406 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
407}\r
408\r
409\r
410\r
411EFI_STATUS\r
412EFIAPI\r
413DxePcdSet32Ex (\r
414 IN CONST EFI_GUID *Guid,\r
415 IN UINTN ExTokenNumber,\r
416 IN UINT32 Value\r
417 )\r
418{\r
419 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
420}\r
421\r
422\r
423\r
424EFI_STATUS\r
425EFIAPI\r
426DxePcdSet64Ex (\r
427 IN CONST EFI_GUID *Guid,\r
428 IN UINTN ExTokenNumber,\r
429 IN UINT64 Value\r
430 )\r
431{\r
432 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
433}\r
434\r
435\r
436\r
437EFI_STATUS\r
438EFIAPI\r
439DxePcdSetPtrEx (\r
440 IN CONST EFI_GUID *Guid,\r
441 IN UINTN ExTokenNumber,\r
442 IN OUT UINTN *SizeOfBuffer,\r
443 IN VOID *Buffer\r
444 )\r
445{\r
446 return ExSetWorker(ExTokenNumber, Guid, Buffer, SizeOfBuffer, TRUE);\r
447}\r
448\r
449\r
450\r
451EFI_STATUS\r
452EFIAPI\r
453DxePcdSetBoolEx (\r
454 IN CONST EFI_GUID *Guid,\r
455 IN UINTN ExTokenNumber,\r
456 IN BOOLEAN Value\r
457 )\r
458{\r
459 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
460}\r
461\r
462\r
463\r
464\r
465EFI_STATUS\r
466EFIAPI\r
467DxeRegisterCallBackOnSet (\r
468 IN UINTN TokenNumber,\r
469 IN CONST EFI_GUID *Guid, OPTIONAL\r
470 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
471 )\r
472{\r
473 ASSERT (CallBackFunction != NULL);\r
474 \r
475 return DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);\r
476}\r
477\r
478\r
479\r
480EFI_STATUS\r
481EFIAPI\r
482DxeUnRegisterCallBackOnSet (\r
483 IN UINTN TokenNumber,\r
484 IN CONST EFI_GUID *Guid, OPTIONAL\r
485 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
486 )\r
487{\r
488 ASSERT (CallBackFunction != NULL);\r
489 \r
490 return DxeUnRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);\r
491}\r
492\r
493\r
494\r
495EFI_STATUS\r
496EFIAPI\r
497DxePcdGetNextToken (\r
498 IN CONST EFI_GUID *Guid, OPTIONAL\r
499 IN OUT UINTN *TokenNumber\r
500 )\r
501{\r
502 EFI_STATUS Status;\r
503\r
504 Status = EFI_NOT_FOUND;\r
505 //\r
506 // Scan the local token space\r
507 //\r
508 if (Guid == NULL) {\r
509 if (((*TokenNumber > PEI_NEX_TOKEN_NUMBER) && (*TokenNumber < PEI_LOCAL_TOKEN_NUMBER)) ||\r
510 ((*TokenNumber > (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER)))) {\r
511 return EFI_NOT_FOUND;\r
512 }\r
513 \r
514 (*TokenNumber)++;\r
515 if (*TokenNumber > PEI_NEX_TOKEN_NUMBER &&\r
516 *TokenNumber <= PEI_LOCAL_TOKEN_NUMBER) {\r
517 //\r
518 // The first Non-Ex type Token Number for DXE PCD \r
519 // database is PEI_LOCAL_TOKEN_NUMBER\r
520 //\r
521 *TokenNumber = PEI_LOCAL_TOKEN_NUMBER;\r
522 } else if (*TokenNumber > DXE_NEX_TOKEN_NUMBER + PEI_LOCAL_TOKEN_NUMBER) {\r
523 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
524 }\r
525 return EFI_SUCCESS;\r
526 }\r
527\r
528 if (PEI_EXMAP_TABLE_EMPTY && DXE_EXMAP_TABLE_EMPTY) {\r
529 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
530 return EFI_NOT_FOUND;\r
531 }\r
532\r
533 if (!PEI_EXMAP_TABLE_EMPTY) {\r
534 Status = ExGetNextTokeNumber (\r
535 Guid,\r
536 TokenNumber,\r
537 mPcdDatabase->PeiDb.Init.GuidTable,\r
538 sizeof(mPcdDatabase->PeiDb.Init.GuidTable),\r
539 mPcdDatabase->PeiDb.Init.ExMapTable,\r
540 sizeof(mPcdDatabase->PeiDb.Init.ExMapTable)\r
541 );\r
542 }\r
543\r
544 if (Status == EFI_SUCCESS) {\r
545 return Status;\r
546 }\r
547\r
548 if (!DXE_EXMAP_TABLE_EMPTY) {\r
549 Status = ExGetNextTokeNumber (\r
550 Guid,\r
551 TokenNumber,\r
552 mPcdDatabase->DxeDb.Init.GuidTable,\r
553 sizeof(mPcdDatabase->DxeDb.Init.GuidTable),\r
554 mPcdDatabase->DxeDb.Init.ExMapTable,\r
555 sizeof(mPcdDatabase->DxeDb.Init.ExMapTable)\r
556 );\r
557 }\r
558\r
559 return Status;\r
560}\r
561\r
562\r
563EFI_GUID **\r
564GetDistinctTokenSpace (\r
565 IN OUT UINTN *ExMapTableSize,\r
566 IN DYNAMICEX_MAPPING *ExMapTable,\r
567 IN EFI_GUID *GuidTable\r
568 )\r
569{\r
570 EFI_GUID **DistinctTokenSpace;\r
571 UINTN OldGuidIndex;\r
572 UINTN TsIdx;\r
573 UINTN Idx;\r
574\r
575\r
576 DistinctTokenSpace = AllocateZeroPool (*ExMapTableSize * sizeof (EFI_GUID *));\r
577 ASSERT (DistinctTokenSpace != NULL);\r
578\r
579 TsIdx = 0;\r
580 OldGuidIndex = ExMapTable[0].ExGuidIndex;\r
581 DistinctTokenSpace[TsIdx] = &GuidTable[OldGuidIndex];\r
582 for (Idx = 1; Idx < *ExMapTableSize; Idx++) {\r
583 if (ExMapTable[Idx].ExGuidIndex != OldGuidIndex) {\r
584 OldGuidIndex = ExMapTable[Idx].ExGuidIndex;\r
585 DistinctTokenSpace[++TsIdx] = &GuidTable[OldGuidIndex];\r
586 }\r
587 }\r
588\r
589 //\r
590 // The total number of Distinct Token Space\r
591 // is TsIdx + 1 because we use TsIdx as a index\r
592 // to the DistinctTokenSpace[]\r
593 //\r
594 *ExMapTableSize = TsIdx + 1;\r
595 return DistinctTokenSpace;\r
596 \r
597}\r
598 \r
599//\r
600// Just pre-allocate a memory buffer that is big enough to\r
601// host all distinct TokenSpace guid in both\r
602// PEI ExMap and DXE ExMap.\r
603//\r
604STATIC EFI_GUID *TmpTokenSpaceBuffer[PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE] = { 0 };\r
605\r
606EFI_STATUS\r
607EFIAPI\r
608DxePcdGetNextTokenSpace (\r
609 IN OUT CONST EFI_GUID **Guid\r
610 )\r
611{\r
612 UINTN Idx;\r
613 UINTN Idx2;\r
614 UINTN Idx3;\r
615 UINTN PeiTokenSpaceTableSize;\r
616 UINTN DxeTokenSpaceTableSize;\r
617 EFI_GUID **PeiTokenSpaceTable;\r
618 EFI_GUID **DxeTokenSpaceTable;\r
619 BOOLEAN Match;\r
620\r
621 ASSERT (Guid != NULL);\r
622 \r
623 if (PEI_EXMAP_TABLE_EMPTY && DXE_EXMAP_TABLE_EMPTY) {\r
624 if (*Guid != NULL) {\r
625 return EFI_NOT_FOUND;\r
626 } else {\r
627 return EFI_SUCCESS;\r
628 }\r
629 }\r
630 \r
631 \r
632 if (TmpTokenSpaceBuffer[0] == NULL) {\r
633 PeiTokenSpaceTableSize = 0;\r
634\r
635 if (!PEI_EXMAP_TABLE_EMPTY) {\r
636 PeiTokenSpaceTableSize = PEI_EXMAPPING_TABLE_SIZE;\r
637 PeiTokenSpaceTable = GetDistinctTokenSpace (&PeiTokenSpaceTableSize,\r
638 mPcdDatabase->PeiDb.Init.ExMapTable,\r
639 mPcdDatabase->PeiDb.Init.GuidTable\r
640 );\r
641 CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID*) * PeiTokenSpaceTableSize);\r
642 }\r
643\r
644 if (!DXE_EXMAP_TABLE_EMPTY) {\r
645 DxeTokenSpaceTableSize = DXE_EXMAPPING_TABLE_SIZE;\r
646 DxeTokenSpaceTable = GetDistinctTokenSpace (&DxeTokenSpaceTableSize,\r
647 mPcdDatabase->DxeDb.Init.ExMapTable,\r
648 mPcdDatabase->DxeDb.Init.GuidTable\r
649 );\r
650\r
651 //\r
652 // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable\r
653 //\r
654 for (Idx2 = 0, Idx3 = PeiTokenSpaceTableSize; Idx2 < DxeTokenSpaceTableSize; Idx2++) {\r
655 Match = FALSE;\r
656 for (Idx = 0; Idx < PeiTokenSpaceTableSize; Idx++) {\r
657 if (CompareGuid (TmpTokenSpaceBuffer[Idx], DxeTokenSpaceTable[Idx2])) {\r
658 Match = TRUE;\r
659 break;\r
660 }\r
661 }\r
662 if (!Match) {\r
663 TmpTokenSpaceBuffer[Idx3++] = DxeTokenSpaceTable[Idx2];\r
664 }\r
665 }\r
666 }\r
667 }\r
668\r
669 if (*Guid == NULL) {\r
670 *Guid = TmpTokenSpaceBuffer[0];\r
671 return EFI_SUCCESS;\r
672 }\r
673 \r
674 for (Idx = 0; Idx < (PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE); Idx++) {\r
675 if(CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) {\r
676 Idx++;\r
677 *Guid = TmpTokenSpaceBuffer[Idx];\r
678 return EFI_SUCCESS;\r
679 }\r
680 }\r
681\r
682 return EFI_NOT_FOUND;\r
683\r
684}\r
685\r
686\r