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