]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Universal/PCD/Dxe/Pcd.c
Added Wordpad recommendation for editor, change ACTIVE_PLATFORM from REQUIRED to...
[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 ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);
204
205 IsPeiDb = (BOOLEAN) (TokenNumber < PEI_LOCAL_TOKEN_NUMBER);
206
207 TokenNumber = IsPeiDb ? TokenNumber :
208 (TokenNumber - PEI_LOCAL_TOKEN_NUMBER);
209
210 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable
211 : mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
212
213 Size = (LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
214
215 if (Size == 0) {
216 //
217 // For pointer type, we need to scan the SIZE_TABLE to get the current size.
218 //
219 return GetPtrTypeSize (TmpTokenNumber, &MaxSize);
220 } else {
221 return Size;
222 }
223
224 }
225
226
227
228 UINT8
229 EFIAPI
230 DxePcdGet8Ex (
231 IN CONST EFI_GUID *Guid,
232 IN UINTN ExTokenNumber
233 )
234 {
235 return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof(UINT8)));
236 }
237
238
239
240 UINT16
241 EFIAPI
242 DxePcdGet16Ex (
243 IN CONST EFI_GUID *Guid,
244 IN UINTN ExTokenNumber
245 )
246 {
247 return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT16)));
248 }
249
250
251
252 UINT32
253 EFIAPI
254 DxePcdGet32Ex (
255 IN CONST EFI_GUID *Guid,
256 IN UINTN ExTokenNumber
257 )
258 {
259 return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT32)));
260 }
261
262
263
264 UINT64
265 EFIAPI
266 DxePcdGet64Ex (
267 IN CONST EFI_GUID *Guid,
268 IN UINTN ExTokenNumber
269 )
270 {
271 return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT64)));
272 }
273
274
275
276 VOID *
277 EFIAPI
278 DxePcdGetPtrEx (
279 IN CONST EFI_GUID *Guid,
280 IN UINTN ExTokenNumber
281 )
282 {
283 return ExGetWorker (Guid, ExTokenNumber, 0);
284 }
285
286
287
288 BOOLEAN
289 EFIAPI
290 DxePcdGetBoolEx (
291 IN CONST EFI_GUID *Guid,
292 IN UINTN ExTokenNumber
293 )
294 {
295 return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof(BOOLEAN)));
296 }
297
298
299
300 UINTN
301 EFIAPI
302 DxePcdGetSizeEx (
303 IN CONST EFI_GUID *Guid,
304 IN UINTN ExTokenNumber
305 )
306 {
307 return DxePcdGetSize(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber));
308 }
309
310
311
312 EFI_STATUS
313 EFIAPI
314 DxePcdSet8 (
315 IN UINTN TokenNumber,
316 IN UINT8 Value
317 )
318 {
319 return SetValueWorker (TokenNumber, &Value, sizeof (Value));
320 }
321
322
323
324 EFI_STATUS
325 EFIAPI
326 DxePcdSet16 (
327 IN UINTN TokenNumber,
328 IN UINT16 Value
329 )
330 {
331 return SetValueWorker (TokenNumber, &Value, sizeof (Value));
332 }
333
334
335
336 EFI_STATUS
337 EFIAPI
338 DxePcdSet32 (
339 IN UINTN TokenNumber,
340 IN UINT32 Value
341 )
342 {
343 return SetValueWorker (TokenNumber, &Value, sizeof (Value));
344 }
345
346
347
348 EFI_STATUS
349 EFIAPI
350 DxePcdSet64 (
351 IN UINTN TokenNumber,
352 IN UINT64 Value
353 )
354 {
355 return SetValueWorker (TokenNumber, &Value, sizeof (Value));
356 }
357
358
359
360 EFI_STATUS
361 EFIAPI
362 DxePcdSetPtr (
363 IN UINTN TokenNumber,
364 IN OUT UINTN *SizeOfBuffer,
365 IN VOID *Buffer
366 )
367 {
368 return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);
369 }
370
371
372
373 EFI_STATUS
374 EFIAPI
375 DxePcdSetBool (
376 IN UINTN TokenNumber,
377 IN BOOLEAN Value
378 )
379 {
380 return SetValueWorker (TokenNumber, &Value, sizeof (Value));
381 }
382
383
384
385 EFI_STATUS
386 EFIAPI
387 DxePcdSet8Ex (
388 IN CONST EFI_GUID *Guid,
389 IN UINTN ExTokenNumber,
390 IN UINT8 Value
391 )
392 {
393 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));
394 }
395
396
397
398 EFI_STATUS
399 EFIAPI
400 DxePcdSet16Ex (
401 IN CONST EFI_GUID *Guid,
402 IN UINTN ExTokenNumber,
403 IN UINT16 Value
404 )
405 {
406 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));
407 }
408
409
410
411 EFI_STATUS
412 EFIAPI
413 DxePcdSet32Ex (
414 IN CONST EFI_GUID *Guid,
415 IN UINTN ExTokenNumber,
416 IN UINT32 Value
417 )
418 {
419 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));
420 }
421
422
423
424 EFI_STATUS
425 EFIAPI
426 DxePcdSet64Ex (
427 IN CONST EFI_GUID *Guid,
428 IN UINTN ExTokenNumber,
429 IN UINT64 Value
430 )
431 {
432 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));
433 }
434
435
436
437 EFI_STATUS
438 EFIAPI
439 DxePcdSetPtrEx (
440 IN CONST EFI_GUID *Guid,
441 IN UINTN ExTokenNumber,
442 IN OUT UINTN *SizeOfBuffer,
443 IN VOID *Buffer
444 )
445 {
446 return ExSetWorker(ExTokenNumber, Guid, Buffer, SizeOfBuffer, TRUE);
447 }
448
449
450
451 EFI_STATUS
452 EFIAPI
453 DxePcdSetBoolEx (
454 IN CONST EFI_GUID *Guid,
455 IN UINTN ExTokenNumber,
456 IN BOOLEAN Value
457 )
458 {
459 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));
460 }
461
462
463
464
465 EFI_STATUS
466 EFIAPI
467 DxeRegisterCallBackOnSet (
468 IN UINTN TokenNumber,
469 IN CONST EFI_GUID *Guid, OPTIONAL
470 IN PCD_PROTOCOL_CALLBACK CallBackFunction
471 )
472 {
473 ASSERT (CallBackFunction != NULL);
474
475 return DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);
476 }
477
478
479
480 EFI_STATUS
481 EFIAPI
482 DxeUnRegisterCallBackOnSet (
483 IN UINTN TokenNumber,
484 IN CONST EFI_GUID *Guid, OPTIONAL
485 IN PCD_PROTOCOL_CALLBACK CallBackFunction
486 )
487 {
488 ASSERT (CallBackFunction != NULL);
489
490 return DxeUnRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);
491 }
492
493
494
495 EFI_STATUS
496 EFIAPI
497 DxePcdGetNextToken (
498 IN CONST EFI_GUID *Guid, OPTIONAL
499 IN OUT UINTN *TokenNumber
500 )
501 {
502 EFI_STATUS Status;
503
504 Status = EFI_NOT_FOUND;
505 //
506 // Scan the local token space
507 //
508 if (Guid == NULL) {
509 if (((*TokenNumber > PEI_NEX_TOKEN_NUMBER) && (*TokenNumber < PEI_LOCAL_TOKEN_NUMBER)) ||
510 ((*TokenNumber > (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER)))) {
511 return EFI_NOT_FOUND;
512 }
513
514 (*TokenNumber)++;
515 if (*TokenNumber > PEI_NEX_TOKEN_NUMBER &&
516 *TokenNumber <= PEI_LOCAL_TOKEN_NUMBER) {
517 //
518 // The first Non-Ex type Token Number for DXE PCD
519 // database is PEI_LOCAL_TOKEN_NUMBER
520 //
521 *TokenNumber = PEI_LOCAL_TOKEN_NUMBER;
522 } else if (*TokenNumber > DXE_NEX_TOKEN_NUMBER + PEI_LOCAL_TOKEN_NUMBER) {
523 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
524 }
525 return EFI_SUCCESS;
526 }
527
528 if (PEI_EXMAP_TABLE_EMPTY && DXE_EXMAP_TABLE_EMPTY) {
529 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
530 return EFI_NOT_FOUND;
531 }
532
533 if (!PEI_EXMAP_TABLE_EMPTY) {
534 Status = ExGetNextTokeNumber (
535 Guid,
536 TokenNumber,
537 mPcdDatabase->PeiDb.Init.GuidTable,
538 sizeof(mPcdDatabase->PeiDb.Init.GuidTable),
539 mPcdDatabase->PeiDb.Init.ExMapTable,
540 sizeof(mPcdDatabase->PeiDb.Init.ExMapTable)
541 );
542 }
543
544 if (Status == EFI_SUCCESS) {
545 return Status;
546 }
547
548 if (!DXE_EXMAP_TABLE_EMPTY) {
549 Status = ExGetNextTokeNumber (
550 Guid,
551 TokenNumber,
552 mPcdDatabase->DxeDb.Init.GuidTable,
553 sizeof(mPcdDatabase->DxeDb.Init.GuidTable),
554 mPcdDatabase->DxeDb.Init.ExMapTable,
555 sizeof(mPcdDatabase->DxeDb.Init.ExMapTable)
556 );
557 }
558
559 return Status;
560 }
561
562
563 EFI_GUID **
564 GetDistinctTokenSpace (
565 IN OUT UINTN *ExMapTableSize,
566 IN DYNAMICEX_MAPPING *ExMapTable,
567 IN EFI_GUID *GuidTable
568 )
569 {
570 EFI_GUID **DistinctTokenSpace;
571 UINTN OldGuidIndex;
572 UINTN TsIdx;
573 UINTN Idx;
574
575
576 DistinctTokenSpace = AllocateZeroPool (*ExMapTableSize * sizeof (EFI_GUID *));
577 ASSERT (DistinctTokenSpace != NULL);
578
579 TsIdx = 0;
580 OldGuidIndex = ExMapTable[0].ExGuidIndex;
581 DistinctTokenSpace[TsIdx] = &GuidTable[OldGuidIndex];
582 for (Idx = 1; Idx < *ExMapTableSize; Idx++) {
583 if (ExMapTable[Idx].ExGuidIndex != OldGuidIndex) {
584 OldGuidIndex = ExMapTable[Idx].ExGuidIndex;
585 DistinctTokenSpace[++TsIdx] = &GuidTable[OldGuidIndex];
586 }
587 }
588
589 //
590 // The total number of Distinct Token Space
591 // is TsIdx + 1 because we use TsIdx as a index
592 // to the DistinctTokenSpace[]
593 //
594 *ExMapTableSize = TsIdx + 1;
595 return DistinctTokenSpace;
596
597 }
598
599 //
600 // Just pre-allocate a memory buffer that is big enough to
601 // host all distinct TokenSpace guid in both
602 // PEI ExMap and DXE ExMap.
603 //
604 STATIC EFI_GUID *TmpTokenSpaceBuffer[PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE] = { 0 };
605
606 EFI_STATUS
607 EFIAPI
608 DxePcdGetNextTokenSpace (
609 IN OUT CONST EFI_GUID **Guid
610 )
611 {
612 UINTN Idx;
613 UINTN Idx2;
614 UINTN Idx3;
615 UINTN PeiTokenSpaceTableSize;
616 UINTN DxeTokenSpaceTableSize;
617 EFI_GUID **PeiTokenSpaceTable;
618 EFI_GUID **DxeTokenSpaceTable;
619 BOOLEAN Match;
620
621 ASSERT (Guid != NULL);
622
623 if (PEI_EXMAP_TABLE_EMPTY && DXE_EXMAP_TABLE_EMPTY) {
624 if (*Guid != NULL) {
625 return EFI_NOT_FOUND;
626 } else {
627 return EFI_SUCCESS;
628 }
629 }
630
631
632 if (TmpTokenSpaceBuffer[0] == NULL) {
633 PeiTokenSpaceTableSize = 0;
634
635 if (!PEI_EXMAP_TABLE_EMPTY) {
636 PeiTokenSpaceTableSize = PEI_EXMAPPING_TABLE_SIZE;
637 PeiTokenSpaceTable = GetDistinctTokenSpace (&PeiTokenSpaceTableSize,
638 mPcdDatabase->PeiDb.Init.ExMapTable,
639 mPcdDatabase->PeiDb.Init.GuidTable
640 );
641 CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID*) * PeiTokenSpaceTableSize);
642 }
643
644 if (!DXE_EXMAP_TABLE_EMPTY) {
645 DxeTokenSpaceTableSize = DXE_EXMAPPING_TABLE_SIZE;
646 DxeTokenSpaceTable = GetDistinctTokenSpace (&DxeTokenSpaceTableSize,
647 mPcdDatabase->DxeDb.Init.ExMapTable,
648 mPcdDatabase->DxeDb.Init.GuidTable
649 );
650
651 //
652 // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable
653 //
654 for (Idx2 = 0, Idx3 = PeiTokenSpaceTableSize; Idx2 < DxeTokenSpaceTableSize; Idx2++) {
655 Match = FALSE;
656 for (Idx = 0; Idx < PeiTokenSpaceTableSize; Idx++) {
657 if (CompareGuid (TmpTokenSpaceBuffer[Idx], DxeTokenSpaceTable[Idx2])) {
658 Match = TRUE;
659 break;
660 }
661 }
662 if (!Match) {
663 TmpTokenSpaceBuffer[Idx3++] = DxeTokenSpaceTable[Idx2];
664 }
665 }
666 }
667 }
668
669 if (*Guid == NULL) {
670 *Guid = TmpTokenSpaceBuffer[0];
671 return EFI_SUCCESS;
672 }
673
674 for (Idx = 0; Idx < (PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE); Idx++) {
675 if(CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) {
676 Idx++;
677 *Guid = TmpTokenSpaceBuffer[Idx];
678 return EFI_SUCCESS;
679 }
680 }
681
682 return EFI_NOT_FOUND;
683
684 }
685
686