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