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