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