TianoCore EDK2 master
Loading...
Searching...
No Matches
Gcd.c
Go to the documentation of this file.
1
11#include <Pi/PiDxeCis.h>
12#include <Pi/PiHob.h>
13#include "DxeMain.h"
14#include "Gcd.h"
15#include "Mem/HeapGuard.h"
16
17#define MINIMUM_INITIAL_MEMORY_SIZE 0x10000
18
19#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
20 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
21 EFI_RESOURCE_ATTRIBUTE_TESTED | \
22 EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | \
23 EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | \
24 EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | \
25 EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED | \
26 EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \
27 EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \
28 EFI_RESOURCE_ATTRIBUTE_64_BIT_IO | \
29 EFI_RESOURCE_ATTRIBUTE_PERSISTENT )
30
31#define TESTED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
32 EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
33 EFI_RESOURCE_ATTRIBUTE_TESTED )
34
35#define INITIALIZED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT |\
36 EFI_RESOURCE_ATTRIBUTE_INITIALIZED )
37
38#define PRESENT_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT)
39
40//
41// Module Variables
42//
43EFI_LOCK mGcdMemorySpaceLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
44EFI_LOCK mGcdIoSpaceLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
45LIST_ENTRY mGcdMemorySpaceMap = INITIALIZE_LIST_HEAD_VARIABLE (mGcdMemorySpaceMap);
46LIST_ENTRY mGcdIoSpaceMap = INITIALIZE_LIST_HEAD_VARIABLE (mGcdIoSpaceMap);
47
48EFI_GCD_MAP_ENTRY mGcdMemorySpaceMapEntryTemplate = {
49 EFI_GCD_MAP_SIGNATURE,
50 {
51 NULL,
52 NULL
53 },
54 0,
55 0,
56 0,
57 0,
60 NULL,
61 NULL
62};
63
64EFI_GCD_MAP_ENTRY mGcdIoSpaceMapEntryTemplate = {
65 EFI_GCD_MAP_SIGNATURE,
66 {
67 NULL,
68 NULL
69 },
70 0,
71 0,
72 0,
73 0,
76 NULL,
77 NULL
78};
79
80GCD_ATTRIBUTE_CONVERSION_ENTRY mAttributeConversionTable[] = {
81 { EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE, EFI_MEMORY_UC, TRUE },
82 { EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED, EFI_MEMORY_UCE, TRUE },
83 { EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE, EFI_MEMORY_WC, TRUE },
84 { EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE, EFI_MEMORY_WT, TRUE },
85 { EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE, EFI_MEMORY_WB, TRUE },
86 { EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE, EFI_MEMORY_RP, TRUE },
87 { EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE, EFI_MEMORY_WP, TRUE },
88 { EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE, EFI_MEMORY_XP, TRUE },
89 { EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE, EFI_MEMORY_RO, TRUE },
90 { EFI_RESOURCE_ATTRIBUTE_PRESENT, EFI_MEMORY_PRESENT, FALSE },
91 { EFI_RESOURCE_ATTRIBUTE_INITIALIZED, EFI_MEMORY_INITIALIZED, FALSE },
92 { EFI_RESOURCE_ATTRIBUTE_TESTED, EFI_MEMORY_TESTED, FALSE },
93 { EFI_RESOURCE_ATTRIBUTE_PERSISTABLE, EFI_MEMORY_NV, TRUE },
94 { EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE, EFI_MEMORY_MORE_RELIABLE, TRUE },
95 { EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE, EFI_MEMORY_SP, TRUE },
96 { 0, 0, FALSE }
97};
98
103 "NonExist ", // EfiGcdMemoryTypeNonExistent
104 "Reserved ", // EfiGcdMemoryTypeReserved
105 "SystemMem", // EfiGcdMemoryTypeSystemMemory
106 "MMIO ", // EfiGcdMemoryTypeMemoryMappedIo
107 "PersisMem", // EfiGcdMemoryTypePersistent
108 "MoreRelia", // EfiGcdMemoryTypeMoreReliable
109 "Unaccepte", // EfiGcdMemoryTypeUnaccepted
110 "Unknown " // EfiGcdMemoryTypeMaximum
111};
112
117 "NonExist", // EfiGcdIoTypeNonExistent
118 "Reserved", // EfiGcdIoTypeReserved
119 "I/O ", // EfiGcdIoTypeIo
120 "Unknown " // EfiGcdIoTypeMaximum
121};
122
127 "AnySearchBottomUp ", // EfiGcdAllocateAnySearchBottomUp
128 "MaxAddressSearchBottomUp ", // EfiGcdAllocateMaxAddressSearchBottomUp
129 "AtAddress ", // EfiGcdAllocateAddress
130 "AnySearchTopDown ", // EfiGcdAllocateAnySearchTopDown
131 "MaxAddressSearchTopDown ", // EfiGcdAllocateMaxAddressSearchTopDown
132 "Unknown " // EfiGcdMaxAllocateType
133};
134
142VOID
143EFIAPI
145 BOOLEAN InitialMap
146 )
147{
149 EFI_STATUS Status;
150 UINTN NumberOfDescriptors;
151 EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
152 UINTN Index;
153
154 Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
155 ASSERT (Status == EFI_SUCCESS && MemorySpaceMap != NULL);
156
157 if (InitialMap) {
158 DEBUG ((DEBUG_GCD, "GCD:Initial GCD Memory Space Map\n"));
159 }
160
161 DEBUG ((DEBUG_GCD, "GCDMemType Range Capabilities Attributes \n"));
162 DEBUG ((DEBUG_GCD, "========== ================================= ================ ================\n"));
163 for (Index = 0; Index < NumberOfDescriptors; Index++) {
164 DEBUG ((
165 DEBUG_GCD,
166 "%a %016lx-%016lx %016lx %016lx%c\n",
167 mGcdMemoryTypeNames[MIN (MemorySpaceMap[Index].GcdMemoryType, EfiGcdMemoryTypeMaximum)],
168 MemorySpaceMap[Index].BaseAddress,
169 MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - 1,
170 MemorySpaceMap[Index].Capabilities,
171 MemorySpaceMap[Index].Attributes,
172 MemorySpaceMap[Index].ImageHandle == NULL ? ' ' : '*'
173 ));
174 }
175
176 DEBUG ((DEBUG_GCD, "\n"));
177 FreePool (MemorySpaceMap);
179}
180
188VOID
189EFIAPI
191 BOOLEAN InitialMap
192 )
193{
195 EFI_STATUS Status;
196 UINTN NumberOfDescriptors;
197 EFI_GCD_IO_SPACE_DESCRIPTOR *IoSpaceMap;
198 UINTN Index;
199
200 Status = CoreGetIoSpaceMap (&NumberOfDescriptors, &IoSpaceMap);
201 ASSERT (Status == EFI_SUCCESS && IoSpaceMap != NULL);
202
203 if (InitialMap) {
204 DEBUG ((DEBUG_GCD, "GCD:Initial GCD I/O Space Map\n"));
205 }
206
207 DEBUG ((DEBUG_GCD, "GCDIoType Range \n"));
208 DEBUG ((DEBUG_GCD, "========== =================================\n"));
209 for (Index = 0; Index < NumberOfDescriptors; Index++) {
210 DEBUG ((
211 DEBUG_GCD,
212 "%a %016lx-%016lx%c\n",
213 mGcdIoTypeNames[MIN (IoSpaceMap[Index].GcdIoType, EfiGcdIoTypeMaximum)],
214 IoSpaceMap[Index].BaseAddress,
215 IoSpaceMap[Index].BaseAddress + IoSpaceMap[Index].Length - 1,
216 IoSpaceMap[Index].ImageHandle == NULL ? ' ' : '*'
217 ));
218 }
219
220 DEBUG ((DEBUG_GCD, "\n"));
221 FreePool (IoSpaceMap);
223}
224
234VOID
236 IN UINT64 Attributes
237 )
238{
239 ASSERT (
240 ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED) == 0) ||
241 ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE) != 0)
242 );
243 ASSERT (
244 ((Attributes & EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED) == 0) ||
245 ((Attributes & EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE) != 0)
246 );
247 ASSERT (
248 ((Attributes & EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED) == 0) ||
249 ((Attributes & EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE) != 0)
250 );
251 ASSERT (
252 ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED) == 0) ||
253 ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE) != 0)
254 );
255 ASSERT (
256 ((Attributes & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) == 0) ||
257 ((Attributes & EFI_RESOURCE_ATTRIBUTE_PERSISTABLE) != 0)
258 );
259}
260
265VOID
267 VOID
268 )
269{
270 CoreAcquireLock (&mGcdMemorySpaceLock);
271}
272
277VOID
279 VOID
280 )
281{
282 CoreReleaseLock (&mGcdMemorySpaceLock);
283}
284
289VOID
291 VOID
292 )
293{
294 CoreAcquireLock (&mGcdIoSpaceLock);
295}
296
301VOID
303 VOID
304 )
305{
306 CoreReleaseLock (&mGcdIoSpaceLock);
307}
308
309//
310// GCD Initialization Worker Functions
311//
312
325UINT64
327 IN UINT64 Value,
328 IN UINTN Alignment,
329 IN BOOLEAN RoundUp
330 )
331{
332 UINT64 AlignmentMask;
333
334 AlignmentMask = LShiftU64 (1, Alignment) - 1;
335 if (RoundUp) {
336 Value += AlignmentMask;
337 }
338
339 return Value & (~AlignmentMask);
340}
341
350UINT64
352 IN UINT64 Value
353 )
354{
355 return AlignValue (Value, EFI_PAGE_SHIFT, TRUE);
356}
357
366UINT64
368 IN UINT64 Value
369 )
370{
371 return AlignValue (Value, EFI_PAGE_SHIFT, FALSE);
372}
373
374//
375// GCD Memory Space Worker Functions
376//
377
390 IN OUT EFI_GCD_MAP_ENTRY **TopEntry,
391 IN OUT EFI_GCD_MAP_ENTRY **BottomEntry
392 )
393{
394 //
395 // Set to mOnGuarding to TRUE before memory allocation. This will make sure
396 // that the entry memory is not "guarded" by HeapGuard. Otherwise it might
397 // cause problem when it's freed (if HeapGuard is enabled).
398 //
399 mOnGuarding = TRUE;
400 *TopEntry = AllocateZeroPool (sizeof (EFI_GCD_MAP_ENTRY));
401 mOnGuarding = FALSE;
402 if (*TopEntry == NULL) {
403 return EFI_OUT_OF_RESOURCES;
404 }
405
406 mOnGuarding = TRUE;
407 *BottomEntry = AllocateZeroPool (sizeof (EFI_GCD_MAP_ENTRY));
408 mOnGuarding = FALSE;
409 if (*BottomEntry == NULL) {
410 CoreFreePool (*TopEntry);
411 return EFI_OUT_OF_RESOURCES;
412 }
413
414 return EFI_SUCCESS;
415}
416
433 IN LIST_ENTRY *Link,
434 IN EFI_GCD_MAP_ENTRY *Entry,
435 IN EFI_PHYSICAL_ADDRESS BaseAddress,
436 IN UINT64 Length,
437 IN EFI_GCD_MAP_ENTRY *TopEntry,
438 IN EFI_GCD_MAP_ENTRY *BottomEntry
439 )
440{
441 ASSERT (Length != 0);
442
443 if (BaseAddress > Entry->BaseAddress) {
444 ASSERT (BottomEntry->Signature == 0);
445
446 CopyMem (BottomEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY));
447 Entry->BaseAddress = BaseAddress;
448 BottomEntry->EndAddress = BaseAddress - 1;
449 InsertTailList (Link, &BottomEntry->Link);
450 }
451
452 if ((BaseAddress + Length - 1) < Entry->EndAddress) {
453 ASSERT (TopEntry->Signature == 0);
454
455 CopyMem (TopEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY));
456 TopEntry->BaseAddress = BaseAddress + Length;
457 Entry->EndAddress = BaseAddress + Length - 1;
458 InsertHeadList (Link, &TopEntry->Link);
459 }
460
461 return EFI_SUCCESS;
462}
463
478 IN LIST_ENTRY *Link,
479 IN BOOLEAN Forward,
480 IN LIST_ENTRY *Map
481 )
482{
483 LIST_ENTRY *AdjacentLink;
484 EFI_GCD_MAP_ENTRY *Entry;
485 EFI_GCD_MAP_ENTRY *AdjacentEntry;
486
487 //
488 // Get adjacent entry
489 //
490 if (Forward) {
491 AdjacentLink = Link->ForwardLink;
492 } else {
493 AdjacentLink = Link->BackLink;
494 }
495
496 //
497 // If AdjacentLink is the head of the list, then no merge can be performed
498 //
499 if (AdjacentLink == Map) {
500 return EFI_SUCCESS;
501 }
502
503 Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
504 AdjacentEntry = CR (AdjacentLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
505
506 if (Entry->Capabilities != AdjacentEntry->Capabilities) {
507 return EFI_UNSUPPORTED;
508 }
509
510 if (Entry->Attributes != AdjacentEntry->Attributes) {
511 return EFI_UNSUPPORTED;
512 }
513
514 if (Entry->GcdMemoryType != AdjacentEntry->GcdMemoryType) {
515 return EFI_UNSUPPORTED;
516 }
517
518 if (Entry->GcdIoType != AdjacentEntry->GcdIoType) {
519 return EFI_UNSUPPORTED;
520 }
521
522 if (Entry->ImageHandle != AdjacentEntry->ImageHandle) {
523 return EFI_UNSUPPORTED;
524 }
525
526 if (Entry->DeviceHandle != AdjacentEntry->DeviceHandle) {
527 return EFI_UNSUPPORTED;
528 }
529
530 if (Forward) {
531 Entry->EndAddress = AdjacentEntry->EndAddress;
532 } else {
533 Entry->BaseAddress = AdjacentEntry->BaseAddress;
534 }
535
536 RemoveEntryList (AdjacentLink);
537 CoreFreePool (AdjacentEntry);
538
539 return EFI_SUCCESS;
540}
541
556 IN EFI_GCD_MAP_ENTRY *TopEntry,
557 IN EFI_GCD_MAP_ENTRY *BottomEntry,
558 IN LIST_ENTRY *StartLink,
559 IN LIST_ENTRY *EndLink,
560 IN LIST_ENTRY *Map
561 )
562{
563 LIST_ENTRY *Link;
564
565 if (TopEntry->Signature == 0) {
566 CoreFreePool (TopEntry);
567 }
568
569 if (BottomEntry->Signature == 0) {
570 CoreFreePool (BottomEntry);
571 }
572
573 Link = StartLink;
574 while (Link != EndLink->ForwardLink) {
575 CoreMergeGcdMapEntry (Link, FALSE, Map);
576 Link = Link->ForwardLink;
577 }
578
579 CoreMergeGcdMapEntry (EndLink, TRUE, Map);
580
581 return EFI_SUCCESS;
582}
583
601 IN EFI_PHYSICAL_ADDRESS BaseAddress,
602 IN UINT64 Length,
603 OUT LIST_ENTRY **StartLink,
604 OUT LIST_ENTRY **EndLink,
605 IN LIST_ENTRY *Map
606 )
607{
608 LIST_ENTRY *Link;
609 EFI_GCD_MAP_ENTRY *Entry;
610
611 ASSERT (Length != 0);
612
613 *StartLink = NULL;
614 *EndLink = NULL;
615
616 Link = Map->ForwardLink;
617 while (Link != Map) {
618 Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
619 if ((BaseAddress >= Entry->BaseAddress) && (BaseAddress <= Entry->EndAddress)) {
620 *StartLink = Link;
621 }
622
623 if (*StartLink != NULL) {
624 if (((BaseAddress + Length - 1) >= Entry->BaseAddress) &&
625 ((BaseAddress + Length - 1) <= Entry->EndAddress))
626 {
627 *EndLink = Link;
628 return EFI_SUCCESS;
629 }
630 }
631
632 Link = Link->ForwardLink;
633 }
634
635 return EFI_NOT_FOUND;
636}
637
646UINTN
648 IN LIST_ENTRY *Map
649 )
650{
651 UINTN Count;
652 LIST_ENTRY *Link;
653
654 Count = 0;
655 Link = Map->ForwardLink;
656 while (Link != Map) {
657 Count++;
658 Link = Link->ForwardLink;
659 }
660
661 return Count;
662}
663
672UINT64
674 UINT64 Attributes
675 )
676{
677 UINT64 CpuArchAttributes;
678
679 CpuArchAttributes = Attributes & EFI_MEMORY_ATTRIBUTE_MASK;
680
681 if ((Attributes & EFI_MEMORY_UC) == EFI_MEMORY_UC) {
682 CpuArchAttributes |= EFI_MEMORY_UC;
683 } else if ((Attributes & EFI_MEMORY_WC) == EFI_MEMORY_WC) {
684 CpuArchAttributes |= EFI_MEMORY_WC;
685 } else if ((Attributes & EFI_MEMORY_WT) == EFI_MEMORY_WT) {
686 CpuArchAttributes |= EFI_MEMORY_WT;
687 } else if ((Attributes & EFI_MEMORY_WB) == EFI_MEMORY_WB) {
688 CpuArchAttributes |= EFI_MEMORY_WB;
689 } else if ((Attributes & EFI_MEMORY_UCE) == EFI_MEMORY_UCE) {
690 CpuArchAttributes |= EFI_MEMORY_UCE;
691 } else if ((Attributes & EFI_MEMORY_WP) == EFI_MEMORY_WP) {
692 CpuArchAttributes |= EFI_MEMORY_WP;
693 }
694
695 return CpuArchAttributes;
696}
697
724 IN UINTN Operation,
725 IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
726 IN EFI_GCD_IO_TYPE GcdIoType,
727 IN EFI_PHYSICAL_ADDRESS BaseAddress,
728 IN UINT64 Length,
729 IN UINT64 Capabilities,
730 IN UINT64 Attributes
731 )
732{
733 EFI_STATUS Status;
734 LIST_ENTRY *Map;
735 LIST_ENTRY *Link;
736 EFI_GCD_MAP_ENTRY *Entry;
737 EFI_GCD_MAP_ENTRY *TopEntry;
738 EFI_GCD_MAP_ENTRY *BottomEntry;
739 LIST_ENTRY *StartLink;
740 LIST_ENTRY *EndLink;
741 UINT64 CpuArchAttributes;
742
743 if (Length == 0) {
744 DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));
745 return EFI_INVALID_PARAMETER;
746 }
747
748 Map = NULL;
749 if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {
751 Map = &mGcdMemorySpaceMap;
752 } else if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {
754 Map = &mGcdIoSpaceMap;
755 } else {
756 ASSERT (FALSE);
757 }
758
759 //
760 // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length
761 //
762 Status = CoreSearchGcdMapEntry (BaseAddress, Length, &StartLink, &EndLink, Map);
763 if (EFI_ERROR (Status)) {
764 Status = EFI_UNSUPPORTED;
765
766 goto Done;
767 }
768
769 ASSERT (StartLink != NULL && EndLink != NULL);
770
771 //
772 // Verify that the list of descriptors are unallocated non-existent memory.
773 //
774 Link = StartLink;
775 while (Link != EndLink->ForwardLink) {
776 Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
777 switch (Operation) {
778 //
779 // Add operations
780 //
781 case GCD_ADD_MEMORY_OPERATION:
782 if ((Entry->GcdMemoryType != EfiGcdMemoryTypeNonExistent) ||
783 (Entry->ImageHandle != NULL))
784 {
785 Status = EFI_ACCESS_DENIED;
786 goto Done;
787 }
788
789 break;
790 case GCD_ADD_IO_OPERATION:
791 if ((Entry->GcdIoType != EfiGcdIoTypeNonExistent) ||
792 (Entry->ImageHandle != NULL))
793 {
794 Status = EFI_ACCESS_DENIED;
795 goto Done;
796 }
797
798 break;
799 //
800 // Free operations
801 //
802 case GCD_FREE_MEMORY_OPERATION:
803 case GCD_FREE_IO_OPERATION:
804 if (Entry->ImageHandle == NULL) {
805 Status = EFI_NOT_FOUND;
806 goto Done;
807 }
808
809 break;
810 //
811 // Remove operations
812 //
813 case GCD_REMOVE_MEMORY_OPERATION:
814 if (Entry->GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
815 Status = EFI_NOT_FOUND;
816 goto Done;
817 }
818
819 if (Entry->ImageHandle != NULL) {
820 Status = EFI_ACCESS_DENIED;
821 goto Done;
822 }
823
824 break;
825 case GCD_REMOVE_IO_OPERATION:
826 if (Entry->GcdIoType == EfiGcdIoTypeNonExistent) {
827 Status = EFI_NOT_FOUND;
828 goto Done;
829 }
830
831 if (Entry->ImageHandle != NULL) {
832 Status = EFI_ACCESS_DENIED;
833 goto Done;
834 }
835
836 break;
837 //
838 // Set attributes operation
839 //
840 case GCD_SET_ATTRIBUTES_MEMORY_OPERATION:
841 if ((Attributes & EFI_MEMORY_RUNTIME) != 0) {
842 if (((BaseAddress & EFI_PAGE_MASK) != 0) || ((Length & EFI_PAGE_MASK) != 0)) {
843 Status = EFI_INVALID_PARAMETER;
844 goto Done;
845 }
846 }
847
848 if ((Entry->Capabilities & Attributes) != Attributes) {
849 Status = EFI_UNSUPPORTED;
850 goto Done;
851 }
852
853 break;
854 //
855 // Set capabilities operation
856 //
857 case GCD_SET_CAPABILITIES_MEMORY_OPERATION:
858 if (((BaseAddress & EFI_PAGE_MASK) != 0) || ((Length & EFI_PAGE_MASK) != 0)) {
859 Status = EFI_INVALID_PARAMETER;
860
861 goto Done;
862 }
863
864 //
865 // Current attributes must still be supported with new capabilities
866 //
867 if ((Capabilities & Entry->Attributes) != Entry->Attributes) {
868 Status = EFI_UNSUPPORTED;
869 goto Done;
870 }
871
872 break;
873 }
874
875 Link = Link->ForwardLink;
876 }
877
878 //
879 // Allocate work space to perform this operation
880 //
881 Status = CoreAllocateGcdMapEntry (&TopEntry, &BottomEntry);
882 if (EFI_ERROR (Status)) {
883 Status = EFI_OUT_OF_RESOURCES;
884 goto Done;
885 }
886
887 ASSERT (TopEntry != NULL && BottomEntry != NULL);
888
889 //
890 // Initialize CpuArchAttributes to suppress incorrect compiler/analyzer warnings.
891 //
892 CpuArchAttributes = 0;
893 if (Operation == GCD_SET_ATTRIBUTES_MEMORY_OPERATION) {
894 //
895 // Call CPU Arch Protocol to attempt to set attributes on the range
896 //
897 CpuArchAttributes = ConverToCpuArchAttributes (Attributes);
898 //
899 // CPU arch attributes include page attributes and cache attributes.
900 // Only page attributes supports to be cleared, but not cache attributes.
901 // Caller is expected to use GetMemorySpaceDescriptor() to get the current
902 // attributes, AND/OR attributes, and then calls SetMemorySpaceAttributes()
903 // to set the new attributes.
904 // So 0 CPU arch attributes should not happen as memory should always have
905 // a cache attribute (no matter UC or WB, etc).
906 //
907 // Here, 0 CPU arch attributes will be filtered to be compatible with the
908 // case that caller just calls SetMemorySpaceAttributes() with none CPU
909 // arch attributes (for example, RUNTIME) as the purpose of the case is not
910 // to clear CPU arch attributes.
911 //
912 if (CpuArchAttributes != 0) {
913 if (gCpu == NULL) {
914 Status = EFI_NOT_AVAILABLE_YET;
915 } else {
916 Status = gCpu->SetMemoryAttributes (
917 gCpu,
918 BaseAddress,
919 Length,
920 CpuArchAttributes
921 );
922 }
923
924 if (EFI_ERROR (Status)) {
925 CoreFreePool (TopEntry);
926 CoreFreePool (BottomEntry);
927 goto Done;
928 }
929 }
930 }
931
932 //
933 // Convert/Insert the list of descriptors from StartLink to EndLink
934 //
935 Link = StartLink;
936 while (Link != EndLink->ForwardLink) {
937 Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
938 CoreInsertGcdMapEntry (Link, Entry, BaseAddress, Length, TopEntry, BottomEntry);
939 switch (Operation) {
940 //
941 // Add operations
942 //
943 case GCD_ADD_MEMORY_OPERATION:
944 Entry->GcdMemoryType = GcdMemoryType;
945 if (GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {
946 Entry->Capabilities = Capabilities | EFI_MEMORY_RUNTIME | EFI_MEMORY_PORT_IO;
947 } else {
948 Entry->Capabilities = Capabilities | EFI_MEMORY_RUNTIME;
949 }
950
951 break;
952 case GCD_ADD_IO_OPERATION:
953 Entry->GcdIoType = GcdIoType;
954 break;
955 //
956 // Free operations
957 //
958 case GCD_FREE_MEMORY_OPERATION:
959 case GCD_FREE_IO_OPERATION:
960 Entry->ImageHandle = NULL;
961 Entry->DeviceHandle = NULL;
962 break;
963 //
964 // Remove operations
965 //
966 case GCD_REMOVE_MEMORY_OPERATION:
967 Entry->GcdMemoryType = EfiGcdMemoryTypeNonExistent;
968 Entry->Capabilities = 0;
969 break;
970 case GCD_REMOVE_IO_OPERATION:
971 Entry->GcdIoType = EfiGcdIoTypeNonExistent;
972 break;
973 //
974 // Set attributes operation
975 //
976 case GCD_SET_ATTRIBUTES_MEMORY_OPERATION:
977 if (CpuArchAttributes == 0) {
978 //
979 // Keep original CPU arch attributes when caller just calls
980 // SetMemorySpaceAttributes() with none CPU arch attributes (for example, RUNTIME).
981 //
982 Attributes |= (Entry->Attributes & (EFI_CACHE_ATTRIBUTE_MASK | EFI_MEMORY_ATTRIBUTE_MASK));
983 }
984
985 Entry->Attributes = Attributes;
986 break;
987 //
988 // Set capabilities operation
989 //
990 case GCD_SET_CAPABILITIES_MEMORY_OPERATION:
991 Entry->Capabilities = Capabilities;
992
993 // Only SystemMemory and MoreReliable memory is in gMemoryMap
994 // so only attempt to update the attributes there if this is
995 // a relevant GCD type
996 if ((Entry->GcdMemoryType == EfiGcdMemoryTypeSystemMemory) ||
997 (Entry->GcdMemoryType == EfiGcdMemoryTypeMoreReliable))
998 {
1000 BaseAddress,
1001 RShiftU64 (Length, EFI_PAGE_SHIFT),
1002 Capabilities & (~EFI_MEMORY_RUNTIME)
1003 );
1004 }
1005
1006 break;
1007 }
1008
1009 Link = Link->ForwardLink;
1010 }
1011
1012 //
1013 // Cleanup
1014 //
1015 Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);
1016
1017Done:
1018 DEBUG ((DEBUG_GCD, " Status = %r\n", Status));
1019
1020 if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {
1023 }
1024
1025 if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {
1028 }
1029
1030 return Status;
1031}
1032
1050 IN UINTN Operation,
1051 IN EFI_GCD_MAP_ENTRY *Entry,
1052 IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
1053 IN EFI_GCD_IO_TYPE GcdIoType
1054 )
1055{
1056 if (Entry->ImageHandle != NULL) {
1057 return EFI_NOT_FOUND;
1058 }
1059
1060 switch (Operation) {
1061 case GCD_ALLOCATE_MEMORY_OPERATION:
1062 if (Entry->GcdMemoryType != GcdMemoryType) {
1063 return EFI_NOT_FOUND;
1064 }
1065
1066 break;
1067 case GCD_ALLOCATE_IO_OPERATION:
1068 if (Entry->GcdIoType != GcdIoType) {
1069 return EFI_NOT_FOUND;
1070 }
1071
1072 break;
1073 default:
1074 return EFI_UNSUPPORTED;
1075 }
1076
1077 return EFI_SUCCESS;
1078}
1079
1100 IN UINTN Operation,
1101 IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType,
1102 IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
1103 IN EFI_GCD_IO_TYPE GcdIoType,
1104 IN UINTN Alignment,
1105 IN UINT64 Length,
1106 IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
1107 IN EFI_HANDLE ImageHandle,
1108 IN EFI_HANDLE DeviceHandle OPTIONAL
1109 )
1110{
1111 EFI_STATUS Status;
1112 EFI_PHYSICAL_ADDRESS AlignmentMask;
1113 EFI_PHYSICAL_ADDRESS MaxAddress;
1114 LIST_ENTRY *Map;
1115 LIST_ENTRY *Link;
1116 LIST_ENTRY *SubLink;
1117 EFI_GCD_MAP_ENTRY *Entry;
1118 EFI_GCD_MAP_ENTRY *TopEntry;
1119 EFI_GCD_MAP_ENTRY *BottomEntry;
1120 LIST_ENTRY *StartLink;
1121 LIST_ENTRY *EndLink;
1122 BOOLEAN Found;
1123
1124 //
1125 // Make sure parameters are valid
1126 //
1127 if ((UINT32)GcdAllocateType >= EfiGcdMaxAllocateType) {
1128 DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));
1129 return EFI_INVALID_PARAMETER;
1130 }
1131
1132 if ((UINT32)GcdMemoryType >= EfiGcdMemoryTypeMaximum) {
1133 DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));
1134 return EFI_INVALID_PARAMETER;
1135 }
1136
1137 if ((UINT32)GcdIoType >= EfiGcdIoTypeMaximum) {
1138 DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));
1139 return EFI_INVALID_PARAMETER;
1140 }
1141
1142 if (BaseAddress == NULL) {
1143 DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));
1144 return EFI_INVALID_PARAMETER;
1145 }
1146
1147 if (ImageHandle == NULL) {
1148 DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));
1149 return EFI_INVALID_PARAMETER;
1150 }
1151
1152 if (Alignment >= 64) {
1153 DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_NOT_FOUND));
1154 return EFI_NOT_FOUND;
1155 }
1156
1157 if (Length == 0) {
1158 DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER));
1159 return EFI_INVALID_PARAMETER;
1160 }
1161
1162 Map = NULL;
1163 if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {
1165 Map = &mGcdMemorySpaceMap;
1166 } else if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {
1168 Map = &mGcdIoSpaceMap;
1169 } else {
1170 ASSERT (FALSE);
1171 }
1172
1173 Found = FALSE;
1174 StartLink = NULL;
1175 EndLink = NULL;
1176 //
1177 // Compute alignment bit mask
1178 //
1179 AlignmentMask = LShiftU64 (1, Alignment) - 1;
1180
1181 if (GcdAllocateType == EfiGcdAllocateAddress) {
1182 //
1183 // Verify that the BaseAddress passed in is aligned correctly
1184 //
1185 if ((*BaseAddress & AlignmentMask) != 0) {
1186 Status = EFI_NOT_FOUND;
1187 goto Done;
1188 }
1189
1190 //
1191 // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length
1192 //
1193 Status = CoreSearchGcdMapEntry (*BaseAddress, Length, &StartLink, &EndLink, Map);
1194 if (EFI_ERROR (Status)) {
1195 Status = EFI_NOT_FOUND;
1196 goto Done;
1197 }
1198
1199 ASSERT (StartLink != NULL && EndLink != NULL);
1200
1201 //
1202 // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.
1203 //
1204 Link = StartLink;
1205 while (Link != EndLink->ForwardLink) {
1206 Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
1207 Link = Link->ForwardLink;
1208 Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);
1209 if (EFI_ERROR (Status)) {
1210 goto Done;
1211 }
1212 }
1213
1214 Found = TRUE;
1215 } else {
1216 Entry = CR (Map->BackLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
1217
1218 //
1219 // Compute the maximum address to use in the search algorithm
1220 //
1221 if ((GcdAllocateType == EfiGcdAllocateMaxAddressSearchBottomUp) ||
1222 (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown))
1223 {
1224 MaxAddress = *BaseAddress;
1225 } else {
1226 MaxAddress = Entry->EndAddress;
1227 }
1228
1229 //
1230 // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.
1231 //
1232 if ((GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown) ||
1233 (GcdAllocateType == EfiGcdAllocateAnySearchTopDown))
1234 {
1235 Link = Map->BackLink;
1236 } else {
1237 Link = Map->ForwardLink;
1238 }
1239
1240 while (Link != Map) {
1241 Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
1242
1243 if ((GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown) ||
1244 (GcdAllocateType == EfiGcdAllocateAnySearchTopDown))
1245 {
1246 Link = Link->BackLink;
1247 } else {
1248 Link = Link->ForwardLink;
1249 }
1250
1251 Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);
1252 if (EFI_ERROR (Status)) {
1253 continue;
1254 }
1255
1256 if ((GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown) ||
1257 (GcdAllocateType == EfiGcdAllocateAnySearchTopDown))
1258 {
1259 if ((Entry->BaseAddress + Length) > MaxAddress) {
1260 continue;
1261 }
1262
1263 if (Length > (Entry->EndAddress + 1)) {
1264 Status = EFI_NOT_FOUND;
1265 goto Done;
1266 }
1267
1268 if (Entry->EndAddress > MaxAddress) {
1269 *BaseAddress = MaxAddress;
1270 } else {
1271 *BaseAddress = Entry->EndAddress;
1272 }
1273
1274 *BaseAddress = (*BaseAddress + 1 - Length) & (~AlignmentMask);
1275 } else {
1276 *BaseAddress = (Entry->BaseAddress + AlignmentMask) & (~AlignmentMask);
1277 if ((*BaseAddress + Length - 1) > MaxAddress) {
1278 Status = EFI_NOT_FOUND;
1279 goto Done;
1280 }
1281 }
1282
1283 //
1284 // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length
1285 //
1286 Status = CoreSearchGcdMapEntry (*BaseAddress, Length, &StartLink, &EndLink, Map);
1287 if (EFI_ERROR (Status)) {
1288 Status = EFI_NOT_FOUND;
1289 goto Done;
1290 }
1291
1292 ASSERT (StartLink != NULL && EndLink != NULL);
1293
1294 Link = StartLink;
1295 //
1296 // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.
1297 //
1298 Found = TRUE;
1299 SubLink = StartLink;
1300 while (SubLink != EndLink->ForwardLink) {
1301 Entry = CR (SubLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
1302 Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);
1303 if (EFI_ERROR (Status)) {
1304 Link = SubLink;
1305 Found = FALSE;
1306 break;
1307 }
1308
1309 SubLink = SubLink->ForwardLink;
1310 }
1311
1312 if (Found) {
1313 break;
1314 }
1315 }
1316 }
1317
1318 if (!Found) {
1319 Status = EFI_NOT_FOUND;
1320 goto Done;
1321 }
1322
1323 //
1324 // Allocate work space to perform this operation
1325 //
1326 Status = CoreAllocateGcdMapEntry (&TopEntry, &BottomEntry);
1327 if (EFI_ERROR (Status)) {
1328 Status = EFI_OUT_OF_RESOURCES;
1329 goto Done;
1330 }
1331
1332 ASSERT (TopEntry != NULL && BottomEntry != NULL);
1333
1334 //
1335 // Convert/Insert the list of descriptors from StartLink to EndLink
1336 //
1337 Link = StartLink;
1338 while (Link != EndLink->ForwardLink) {
1339 Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
1340 CoreInsertGcdMapEntry (Link, Entry, *BaseAddress, Length, TopEntry, BottomEntry);
1341 Entry->ImageHandle = ImageHandle;
1342 Entry->DeviceHandle = DeviceHandle;
1343 Link = Link->ForwardLink;
1344 }
1345
1346 //
1347 // Cleanup
1348 //
1349 Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);
1350
1351Done:
1352 DEBUG ((DEBUG_GCD, " Status = %r", Status));
1353 if (!EFI_ERROR (Status)) {
1354 DEBUG ((DEBUG_GCD, " (BaseAddress = %016lx)", *BaseAddress));
1355 }
1356
1357 DEBUG ((DEBUG_GCD, "\n"));
1358
1359 if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {
1362 }
1363
1364 if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {
1367 }
1368
1369 return Status;
1370}
1371
1386 IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
1387 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1388 IN UINT64 Length,
1389 IN UINT64 Capabilities
1390 )
1391{
1392 DEBUG ((DEBUG_GCD, "GCD:AddMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
1393 DEBUG ((DEBUG_GCD, " GcdMemoryType = %a\n", mGcdMemoryTypeNames[MIN (GcdMemoryType, EfiGcdMemoryTypeMaximum)]));
1394 DEBUG ((DEBUG_GCD, " Capabilities = %016lx\n", Capabilities));
1395
1396 //
1397 // Make sure parameters are valid
1398 //
1399 if ((GcdMemoryType <= EfiGcdMemoryTypeNonExistent) || (GcdMemoryType >= EfiGcdMemoryTypeMaximum)) {
1400 return EFI_INVALID_PARAMETER;
1401 }
1402
1403 return CoreConvertSpace (GCD_ADD_MEMORY_OPERATION, GcdMemoryType, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, Capabilities, 0);
1404}
1405
1406//
1407// GCD Core Services
1408//
1409
1428EFIAPI
1430 IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType,
1431 IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
1432 IN UINTN Alignment,
1433 IN UINT64 Length,
1434 IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
1435 IN EFI_HANDLE ImageHandle,
1436 IN EFI_HANDLE DeviceHandle OPTIONAL
1437 )
1438{
1439 if (BaseAddress != NULL) {
1440 DEBUG ((DEBUG_GCD, "GCD:AllocateMemorySpace(Base=%016lx,Length=%016lx)\n", *BaseAddress, Length));
1441 } else {
1442 DEBUG ((DEBUG_GCD, "GCD:AllocateMemorySpace(Base=<NULL>,Length=%016lx)\n", Length));
1443 }
1444
1445 DEBUG ((DEBUG_GCD, " GcdAllocateType = %a\n", mGcdAllocationTypeNames[MIN (GcdAllocateType, EfiGcdMaxAllocateType)]));
1446 DEBUG ((DEBUG_GCD, " GcdMemoryType = %a\n", mGcdMemoryTypeNames[MIN (GcdMemoryType, EfiGcdMemoryTypeMaximum)]));
1447 DEBUG ((DEBUG_GCD, " Alignment = %016lx\n", LShiftU64 (1, Alignment)));
1448 DEBUG ((DEBUG_GCD, " ImageHandle = %p\n", ImageHandle));
1449 DEBUG ((DEBUG_GCD, " DeviceHandle = %p\n", DeviceHandle));
1450
1451 return CoreAllocateSpace (
1452 GCD_ALLOCATE_MEMORY_OPERATION,
1453 GcdAllocateType,
1454 GcdMemoryType,
1455 (EFI_GCD_IO_TYPE)0,
1456 Alignment,
1457 Length,
1458 BaseAddress,
1459 ImageHandle,
1460 DeviceHandle
1461 );
1462}
1463
1477EFIAPI
1479 IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
1480 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1481 IN UINT64 Length,
1482 IN UINT64 Capabilities
1483 )
1484{
1485 EFI_STATUS Status;
1486 EFI_PHYSICAL_ADDRESS PageBaseAddress;
1487 UINT64 PageLength;
1488
1489 Status = CoreInternalAddMemorySpace (GcdMemoryType, BaseAddress, Length, Capabilities);
1490
1491 if (!EFI_ERROR (Status) && ((GcdMemoryType == EfiGcdMemoryTypeSystemMemory) || (GcdMemoryType == EfiGcdMemoryTypeMoreReliable))) {
1492 PageBaseAddress = PageAlignAddress (BaseAddress);
1493 PageLength = PageAlignLength (BaseAddress + Length - PageBaseAddress);
1494
1495 Status = CoreAllocateMemorySpace (
1497 GcdMemoryType,
1498 EFI_PAGE_SHIFT,
1499 PageLength,
1500 &PageBaseAddress,
1501 gDxeCoreImageHandle,
1502 NULL
1503 );
1504
1505 if (!EFI_ERROR (Status)) {
1508 PageBaseAddress,
1509 RShiftU64 (PageLength, EFI_PAGE_SHIFT),
1510 Capabilities
1511 );
1512 } else {
1513 for ( ; PageLength != 0; PageLength -= EFI_PAGE_SIZE, PageBaseAddress += EFI_PAGE_SIZE) {
1514 Status = CoreAllocateMemorySpace (
1516 GcdMemoryType,
1517 EFI_PAGE_SHIFT,
1518 EFI_PAGE_SIZE,
1519 &PageBaseAddress,
1520 gDxeCoreImageHandle,
1521 NULL
1522 );
1523
1524 if (!EFI_ERROR (Status)) {
1527 PageBaseAddress,
1528 1,
1529 Capabilities
1530 );
1531 }
1532 }
1533 }
1534 }
1535
1536 return Status;
1537}
1538
1550EFIAPI
1552 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1553 IN UINT64 Length
1554 )
1555{
1556 DEBUG ((DEBUG_GCD, "GCD:FreeMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
1557
1558 return CoreConvertSpace (GCD_FREE_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, 0, 0);
1559}
1560
1572EFIAPI
1574 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1575 IN UINT64 Length
1576 )
1577{
1578 DEBUG ((DEBUG_GCD, "GCD:RemoveMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
1579
1580 return CoreConvertSpace (GCD_REMOVE_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, 0, 0);
1581}
1582
1590VOID
1593 IN EFI_GCD_MAP_ENTRY *Entry
1594 )
1595{
1596 Descriptor->BaseAddress = Entry->BaseAddress;
1597 Descriptor->Length = Entry->EndAddress - Entry->BaseAddress + 1;
1598 Descriptor->Capabilities = Entry->Capabilities;
1599 Descriptor->Attributes = Entry->Attributes;
1600 Descriptor->GcdMemoryType = Entry->GcdMemoryType;
1601 Descriptor->ImageHandle = Entry->ImageHandle;
1602 Descriptor->DeviceHandle = Entry->DeviceHandle;
1603}
1604
1616EFIAPI
1618 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1620 )
1621{
1622 EFI_STATUS Status;
1623 LIST_ENTRY *StartLink;
1624 LIST_ENTRY *EndLink;
1625 EFI_GCD_MAP_ENTRY *Entry;
1626
1627 //
1628 // Make sure parameters are valid
1629 //
1630 if (Descriptor == NULL) {
1631 return EFI_INVALID_PARAMETER;
1632 }
1633
1635
1636 //
1637 // Search for the list of descriptors that contain BaseAddress
1638 //
1639 Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdMemorySpaceMap);
1640 if (EFI_ERROR (Status)) {
1641 Status = EFI_NOT_FOUND;
1642 } else {
1643 ASSERT (StartLink != NULL && EndLink != NULL);
1644 //
1645 // Copy the contents of the found descriptor into Descriptor
1646 //
1647 Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
1648 BuildMemoryDescriptor (Descriptor, Entry);
1649 }
1650
1652
1653 return Status;
1654}
1655
1679EFIAPI
1681 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1682 IN UINT64 Length,
1683 IN UINT64 Attributes
1684 )
1685{
1686 DEBUG ((DEBUG_GCD, "GCD:SetMemorySpaceAttributes(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
1687 DEBUG ((DEBUG_GCD, " Attributes = %016lx\n", Attributes));
1688
1689 return CoreConvertSpace (GCD_SET_ATTRIBUTES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, 0, Attributes);
1690}
1691
1710EFIAPI
1712 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1713 IN UINT64 Length,
1714 IN UINT64 Capabilities
1715 )
1716{
1717 DEBUG ((DEBUG_GCD, "GCD:CoreSetMemorySpaceCapabilities(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
1718 DEBUG ((DEBUG_GCD, " Capabilities = %016lx\n", Capabilities));
1719
1720 return CoreConvertSpace (GCD_SET_CAPABILITIES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, Capabilities, 0);
1721}
1722
1736EFIAPI
1738 OUT UINTN *NumberOfDescriptors,
1739 OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR **MemorySpaceMap
1740 )
1741{
1742 LIST_ENTRY *Link;
1743 EFI_GCD_MAP_ENTRY *Entry;
1745 UINTN DescriptorCount;
1746
1747 //
1748 // Make sure parameters are valid
1749 //
1750 if (NumberOfDescriptors == NULL) {
1751 return EFI_INVALID_PARAMETER;
1752 }
1753
1754 if (MemorySpaceMap == NULL) {
1755 return EFI_INVALID_PARAMETER;
1756 }
1757
1758 *NumberOfDescriptors = 0;
1759 *MemorySpaceMap = NULL;
1760
1761 //
1762 // Take the lock, for entering the loop with the lock held.
1763 //
1765 while (TRUE) {
1766 //
1767 // Count descriptors. It might be done more than once because the
1768 // AllocatePool() called below has to be running outside the GCD lock.
1769 //
1770 DescriptorCount = CoreCountGcdMapEntry (&mGcdMemorySpaceMap);
1771 if ((DescriptorCount == *NumberOfDescriptors) && (*MemorySpaceMap != NULL)) {
1772 //
1773 // Fill in the MemorySpaceMap if no memory space map change.
1774 //
1775 Descriptor = *MemorySpaceMap;
1776 Link = mGcdMemorySpaceMap.ForwardLink;
1777 while (Link != &mGcdMemorySpaceMap) {
1778 Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
1779 BuildMemoryDescriptor (Descriptor, Entry);
1780 Descriptor++;
1781 Link = Link->ForwardLink;
1782 }
1783
1784 //
1785 // We're done; exit the loop with the lock held.
1786 //
1787 break;
1788 }
1789
1790 //
1791 // Release the lock before memory allocation, because it might cause
1792 // GCD lock conflict in one of calling path in AllocatPool().
1793 //
1795
1796 //
1797 // Allocate memory to store the MemorySpaceMap. Note it might be already
1798 // allocated if there's map descriptor change during memory allocation at
1799 // last time.
1800 //
1801 if (*MemorySpaceMap != NULL) {
1802 FreePool (*MemorySpaceMap);
1803 }
1804
1805 *MemorySpaceMap = AllocatePool (
1806 DescriptorCount *
1808 );
1809 if (*MemorySpaceMap == NULL) {
1810 *NumberOfDescriptors = 0;
1811 return EFI_OUT_OF_RESOURCES;
1812 }
1813
1814 //
1815 // Save the descriptor count got before for another round of check to make
1816 // sure we won't miss any, since we have code running outside the GCD lock.
1817 //
1818 *NumberOfDescriptors = DescriptorCount;
1819 //
1820 // Re-acquire the lock, for the next iteration.
1821 //
1823 }
1824
1825 //
1826 // We exited the loop with the lock held, release it.
1827 //
1829
1830 return EFI_SUCCESS;
1831}
1832
1845EFIAPI
1847 IN EFI_GCD_IO_TYPE GcdIoType,
1848 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1849 IN UINT64 Length
1850 )
1851{
1852 DEBUG ((DEBUG_GCD, "GCD:AddIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
1853 DEBUG ((DEBUG_GCD, " GcdIoType = %a\n", mGcdIoTypeNames[MIN (GcdIoType, EfiGcdIoTypeMaximum)]));
1854
1855 //
1856 // Make sure parameters are valid
1857 //
1858 if ((GcdIoType <= EfiGcdIoTypeNonExistent) || (GcdIoType >= EfiGcdIoTypeMaximum)) {
1859 return EFI_INVALID_PARAMETER;
1860 }
1861
1862 return CoreConvertSpace (GCD_ADD_IO_OPERATION, (EFI_GCD_MEMORY_TYPE)0, GcdIoType, BaseAddress, Length, 0, 0);
1863}
1864
1883EFIAPI
1885 IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType,
1886 IN EFI_GCD_IO_TYPE GcdIoType,
1887 IN UINTN Alignment,
1888 IN UINT64 Length,
1889 IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
1890 IN EFI_HANDLE ImageHandle,
1891 IN EFI_HANDLE DeviceHandle OPTIONAL
1892 )
1893{
1894 if (BaseAddress != NULL) {
1895 DEBUG ((DEBUG_GCD, "GCD:AllocateIoSpace(Base=%016lx,Length=%016lx)\n", *BaseAddress, Length));
1896 } else {
1897 DEBUG ((DEBUG_GCD, "GCD:AllocateIoSpace(Base=<NULL>,Length=%016lx)\n", Length));
1898 }
1899
1900 DEBUG ((DEBUG_GCD, " GcdAllocateType = %a\n", mGcdAllocationTypeNames[MIN (GcdAllocateType, EfiGcdMaxAllocateType)]));
1901 DEBUG ((DEBUG_GCD, " GcdIoType = %a\n", mGcdIoTypeNames[MIN (GcdIoType, EfiGcdIoTypeMaximum)]));
1902 DEBUG ((DEBUG_GCD, " Alignment = %016lx\n", LShiftU64 (1, Alignment)));
1903 DEBUG ((DEBUG_GCD, " ImageHandle = %p\n", ImageHandle));
1904 DEBUG ((DEBUG_GCD, " DeviceHandle = %p\n", DeviceHandle));
1905
1906 return CoreAllocateSpace (
1907 GCD_ALLOCATE_IO_OPERATION,
1908 GcdAllocateType,
1910 GcdIoType,
1911 Alignment,
1912 Length,
1913 BaseAddress,
1914 ImageHandle,
1915 DeviceHandle
1916 );
1917}
1918
1930EFIAPI
1932 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1933 IN UINT64 Length
1934 )
1935{
1936 DEBUG ((DEBUG_GCD, "GCD:FreeIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
1937
1938 return CoreConvertSpace (GCD_FREE_IO_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, 0, 0);
1939}
1940
1952EFIAPI
1954 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1955 IN UINT64 Length
1956 )
1957{
1958 DEBUG ((DEBUG_GCD, "GCD:RemoveIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
1959
1960 return CoreConvertSpace (GCD_REMOVE_IO_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, 0, 0);
1961}
1962
1970VOID
1972 IN EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor,
1973 IN EFI_GCD_MAP_ENTRY *Entry
1974 )
1975{
1976 Descriptor->BaseAddress = Entry->BaseAddress;
1977 Descriptor->Length = Entry->EndAddress - Entry->BaseAddress + 1;
1978 Descriptor->GcdIoType = Entry->GcdIoType;
1979 Descriptor->ImageHandle = Entry->ImageHandle;
1980 Descriptor->DeviceHandle = Entry->DeviceHandle;
1981}
1982
1994EFIAPI
1996 IN EFI_PHYSICAL_ADDRESS BaseAddress,
1998 )
1999{
2000 EFI_STATUS Status;
2001 LIST_ENTRY *StartLink;
2002 LIST_ENTRY *EndLink;
2003 EFI_GCD_MAP_ENTRY *Entry;
2004
2005 //
2006 // Make sure parameters are valid
2007 //
2008 if (Descriptor == NULL) {
2009 return EFI_INVALID_PARAMETER;
2010 }
2011
2013
2014 //
2015 // Search for the list of descriptors that contain BaseAddress
2016 //
2017 Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdIoSpaceMap);
2018 if (EFI_ERROR (Status)) {
2019 Status = EFI_NOT_FOUND;
2020 } else {
2021 ASSERT (StartLink != NULL && EndLink != NULL);
2022 //
2023 // Copy the contents of the found descriptor into Descriptor
2024 //
2025 Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
2026 BuildIoDescriptor (Descriptor, Entry);
2027 }
2028
2030
2031 return Status;
2032}
2033
2046EFIAPI
2048 OUT UINTN *NumberOfDescriptors,
2049 OUT EFI_GCD_IO_SPACE_DESCRIPTOR **IoSpaceMap
2050 )
2051{
2052 EFI_STATUS Status;
2053 LIST_ENTRY *Link;
2054 EFI_GCD_MAP_ENTRY *Entry;
2055 EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor;
2056
2057 //
2058 // Make sure parameters are valid
2059 //
2060 if (NumberOfDescriptors == NULL) {
2061 return EFI_INVALID_PARAMETER;
2062 }
2063
2064 if (IoSpaceMap == NULL) {
2065 return EFI_INVALID_PARAMETER;
2066 }
2067
2069
2070 //
2071 // Count the number of descriptors
2072 //
2073 *NumberOfDescriptors = CoreCountGcdMapEntry (&mGcdIoSpaceMap);
2074
2075 //
2076 // Allocate the IoSpaceMap
2077 //
2078 *IoSpaceMap = AllocatePool (*NumberOfDescriptors * sizeof (EFI_GCD_IO_SPACE_DESCRIPTOR));
2079 if (*IoSpaceMap == NULL) {
2080 Status = EFI_OUT_OF_RESOURCES;
2081 goto Done;
2082 }
2083
2084 //
2085 // Fill in the IoSpaceMap
2086 //
2087 Descriptor = *IoSpaceMap;
2088 Link = mGcdIoSpaceMap.ForwardLink;
2089 while (Link != &mGcdIoSpaceMap) {
2090 Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
2091 BuildIoDescriptor (Descriptor, Entry);
2092 Descriptor++;
2093 Link = Link->ForwardLink;
2094 }
2095
2096 Status = EFI_SUCCESS;
2097
2098Done:
2100 return Status;
2101}
2102
2114UINT64
2116 EFI_GCD_MEMORY_TYPE GcdMemoryType,
2117 UINT64 Attributes
2118 )
2119{
2120 UINT64 Capabilities;
2122
2123 //
2124 // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask
2125 //
2126 for (Capabilities = 0, Conversion = mAttributeConversionTable; Conversion->Attribute != 0; Conversion++) {
2127 if (Conversion->Memory || ((GcdMemoryType != EfiGcdMemoryTypeSystemMemory) && (GcdMemoryType != EfiGcdMemoryTypeMoreReliable))) {
2128 if (Attributes & Conversion->Attribute) {
2129 Capabilities |= Conversion->Capability;
2130 }
2131 }
2132 }
2133
2134 return Capabilities;
2135}
2136
2143UINT64
2145 VOID
2146 )
2147{
2148 UINTN Index;
2149 UINT64 TotalSize;
2150
2151 //
2152 // Loop through each memory type in the order specified by the gMemoryTypeInformation[] array
2153 //
2154 TotalSize = 0;
2155 for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {
2156 TotalSize += LShiftU64 (gMemoryTypeInformation[Index].NumberOfPages, EFI_PAGE_SHIFT);
2157 }
2158
2159 return TotalSize;
2160}
2161
2171VOID
2173 IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
2174 IN OUT UINT64 *Length,
2175 IN EFI_HOB_MEMORY_ALLOCATION *MemoryHob
2176 )
2177{
2178 EFI_PHYSICAL_ADDRESS TopAddress;
2179 EFI_PHYSICAL_ADDRESS AllocatedTop;
2180 EFI_PHYSICAL_ADDRESS LowerBase;
2181 UINT64 LowerSize;
2182 EFI_PHYSICAL_ADDRESS UpperBase;
2183 UINT64 UpperSize;
2184
2185 TopAddress = *BaseAddress + *Length;
2186 while (MemoryHob != NULL) {
2187 AllocatedTop = MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength;
2188
2189 if ((MemoryHob->AllocDescriptor.MemoryBaseAddress >= *BaseAddress) &&
2190 (AllocatedTop <= TopAddress))
2191 {
2192 LowerBase = *BaseAddress;
2193 LowerSize = MemoryHob->AllocDescriptor.MemoryBaseAddress - *BaseAddress;
2194 UpperBase = AllocatedTop;
2195 UpperSize = TopAddress - AllocatedTop;
2196
2197 if (LowerSize != 0) {
2198 FindLargestFreeRegion (&LowerBase, &LowerSize, (EFI_HOB_MEMORY_ALLOCATION *)GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (MemoryHob)));
2199 }
2200
2201 if (UpperSize != 0) {
2202 FindLargestFreeRegion (&UpperBase, &UpperSize, (EFI_HOB_MEMORY_ALLOCATION *)GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (MemoryHob)));
2203 }
2204
2205 if (UpperSize >= LowerSize) {
2206 *Length = UpperSize;
2207 *BaseAddress = UpperBase;
2208 } else {
2209 *Length = LowerSize;
2210 *BaseAddress = LowerBase;
2211 }
2212
2213 return;
2214 }
2215
2216 MemoryHob = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (MemoryHob));
2217 }
2218}
2219
2237 IN VOID **HobStart,
2238 OUT EFI_PHYSICAL_ADDRESS *MemoryBaseAddress,
2239 OUT UINT64 *MemoryLength
2240 )
2241{
2243 EFI_MEMORY_TYPE_INFORMATION *EfiMemoryTypeInformation;
2244 UINTN DataSize;
2245 BOOLEAN Found;
2247 EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
2248 EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob;
2249 EFI_HOB_RESOURCE_DESCRIPTOR *MemoryTypeInformationResourceHob;
2250 UINTN Count;
2251 EFI_PHYSICAL_ADDRESS BaseAddress;
2252 UINT64 Length;
2253 UINT64 Attributes;
2254 UINT64 Capabilities;
2255 EFI_PHYSICAL_ADDRESS TestedMemoryBaseAddress;
2256 UINT64 TestedMemoryLength;
2257 EFI_PHYSICAL_ADDRESS HighAddress;
2258 EFI_HOB_GUID_TYPE *GuidHob;
2259 UINT32 ReservedCodePageNumber;
2260 UINT64 MinimalMemorySizeNeeded;
2261
2262 //
2263 // Point at the first HOB. This must be the PHIT HOB.
2264 //
2265 Hob.Raw = *HobStart;
2266 ASSERT (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_HANDOFF);
2267
2268 //
2269 // Initialize the spin locks and maps in the memory services.
2270 // Also fill in the memory services into the EFI Boot Services Table
2271 //
2273
2274 //
2275 // Initialize Local Variables
2276 //
2277 PhitResourceHob = NULL;
2278 ResourceHob = NULL;
2279 BaseAddress = 0;
2280 Length = 0;
2281 Attributes = 0;
2282
2283 //
2284 // Cache the PHIT HOB for later use
2285 //
2286 PhitHob = Hob.HandoffInformationTable;
2287
2288 if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) {
2289 ReservedCodePageNumber = PcdGet32 (PcdLoadFixAddressRuntimeCodePageNumber);
2290 ReservedCodePageNumber += PcdGet32 (PcdLoadFixAddressBootTimeCodePageNumber);
2291
2292 //
2293 // cache the Top address for loading modules at Fixed Address
2294 //
2295 gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress = PhitHob->EfiMemoryTop
2296 + EFI_PAGES_TO_SIZE (ReservedCodePageNumber);
2297 }
2298
2299 //
2300 // See if a Memory Type Information HOB is available
2301 //
2302 MemoryTypeInformationResourceHob = NULL;
2303 GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid);
2304 if (GuidHob != NULL) {
2305 EfiMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob);
2306 DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
2307 if ((EfiMemoryTypeInformation != NULL) && (DataSize > 0) && (DataSize <= (EfiMaxMemoryType + 1) * sizeof (EFI_MEMORY_TYPE_INFORMATION))) {
2308 CopyMem (&gMemoryTypeInformation, EfiMemoryTypeInformation, DataSize);
2309
2310 //
2311 // Look for Resource Descriptor HOB with a ResourceType of System Memory
2312 // and an Owner GUID of gEfiMemoryTypeInformationGuid. If more than 1 is
2313 // found, then set MemoryTypeInformationResourceHob to NULL.
2314 //
2315 Count = 0;
2316 for (Hob.Raw = *HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
2317 if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
2318 continue;
2319 }
2320
2321 ResourceHob = Hob.ResourceDescriptor;
2322 if (!CompareGuid (&ResourceHob->Owner, &gEfiMemoryTypeInformationGuid)) {
2323 continue;
2324 }
2325
2326 Count++;
2327 if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
2328 continue;
2329 }
2330
2331 if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
2332 continue;
2333 }
2334
2335 if (ResourceHob->ResourceLength >= CalculateTotalMemoryBinSizeNeeded ()) {
2336 MemoryTypeInformationResourceHob = ResourceHob;
2337 }
2338 }
2339
2340 if (Count > 1) {
2341 MemoryTypeInformationResourceHob = NULL;
2342 }
2343 }
2344 }
2345
2346 //
2347 // Include the total memory bin size needed to make sure memory bin could be allocated successfully.
2348 //
2349 MinimalMemorySizeNeeded = MINIMUM_INITIAL_MEMORY_SIZE + CalculateTotalMemoryBinSizeNeeded ();
2350
2351 //
2352 // Find the Resource Descriptor HOB that contains PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop
2353 //
2354 Found = FALSE;
2355 for (Hob.Raw = *HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
2356 //
2357 // Skip all HOBs except Resource Descriptor HOBs
2358 //
2359 if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
2360 continue;
2361 }
2362
2363 //
2364 // Skip Resource Descriptor HOBs that do not describe tested system memory
2365 //
2366 ResourceHob = Hob.ResourceDescriptor;
2367 if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
2368 continue;
2369 }
2370
2371 if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
2372 continue;
2373 }
2374
2375 //
2376 // Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop
2377 //
2378 if (PhitHob->EfiFreeMemoryBottom < ResourceHob->PhysicalStart) {
2379 continue;
2380 }
2381
2382 if (PhitHob->EfiFreeMemoryTop > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) {
2383 continue;
2384 }
2385
2386 //
2387 // Cache the resource descriptor HOB for the memory region described by the PHIT HOB
2388 //
2389 PhitResourceHob = ResourceHob;
2390 Found = TRUE;
2391
2392 //
2393 // If a Memory Type Information Resource HOB was found and is the same
2394 // Resource HOB that describes the PHIT HOB, then ignore the Memory Type
2395 // Information Resource HOB.
2396 //
2397 if (MemoryTypeInformationResourceHob == PhitResourceHob) {
2398 MemoryTypeInformationResourceHob = NULL;
2399 }
2400
2401 //
2402 // Compute range between PHIT EfiMemoryTop and the end of the Resource Descriptor HOB
2403 //
2404 Attributes = PhitResourceHob->ResourceAttribute;
2405 BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);
2406 Length = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);
2407 FindLargestFreeRegion (&BaseAddress, &Length, (EFI_HOB_MEMORY_ALLOCATION *)GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION));
2408 if (Length < MinimalMemorySizeNeeded) {
2409 //
2410 // If that range is not large enough to intialize the DXE Core, then
2411 // Compute range between PHIT EfiFreeMemoryBottom and PHIT EfiFreeMemoryTop
2412 //
2413 BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom);
2414 Length = PageAlignLength (PhitHob->EfiFreeMemoryTop - BaseAddress);
2415 // This region is required to have no memory allocation inside it, skip check for entries in HOB List
2416 if (Length < MinimalMemorySizeNeeded) {
2417 //
2418 // If that range is not large enough to intialize the DXE Core, then
2419 // Compute range between the start of the Resource Descriptor HOB and the start of the HOB List
2420 //
2421 BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);
2422 Length = PageAlignLength ((UINT64)((UINTN)*HobStart - BaseAddress));
2423 FindLargestFreeRegion (&BaseAddress, &Length, (EFI_HOB_MEMORY_ALLOCATION *)GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION));
2424 }
2425 }
2426
2427 break;
2428 }
2429
2430 //
2431 // Assert if a resource descriptor HOB for the memory region described by the PHIT was not found
2432 //
2433 ASSERT (Found);
2434
2435 //
2436 // Take the range in the resource descriptor HOB for the memory region described
2437 // by the PHIT as higher priority if it is big enough. It can make the memory bin
2438 // allocated to be at the same memory region with PHIT that has more better compatibility
2439 // to avoid memory fragmentation for some code practices assume and allocate <4G ACPI memory.
2440 //
2441 if (Length < MinimalMemorySizeNeeded) {
2442 //
2443 // Search all the resource descriptor HOBs from the highest possible addresses down for a memory
2444 // region that is big enough to initialize the DXE core. Always skip the PHIT Resource HOB
2445 // and the Memory Type Information Resource HOB. The max address must be within the physically
2446 // addressable range for the processor.
2447 //
2448 HighAddress = MAX_ALLOC_ADDRESS;
2449 for (Hob.Raw = *HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
2450 //
2451 // Skip the Resource Descriptor HOB that contains the PHIT
2452 //
2453 if (Hob.ResourceDescriptor == PhitResourceHob) {
2454 continue;
2455 }
2456
2457 //
2458 // Skip the Resource Descriptor HOB that contains Memory Type Information bins
2459 //
2460 if (Hob.ResourceDescriptor == MemoryTypeInformationResourceHob) {
2461 continue;
2462 }
2463
2464 //
2465 // Skip all HOBs except Resource Descriptor HOBs
2466 //
2467 if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
2468 continue;
2469 }
2470
2471 //
2472 // Skip Resource Descriptor HOBs that do not describe tested system memory below MAX_ALLOC_ADDRESS
2473 //
2474 ResourceHob = Hob.ResourceDescriptor;
2475 if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
2476 continue;
2477 }
2478
2479 if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
2480 continue;
2481 }
2482
2483 if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > (EFI_PHYSICAL_ADDRESS)MAX_ALLOC_ADDRESS) {
2484 continue;
2485 }
2486
2487 //
2488 // Skip Resource Descriptor HOBs that are below a previously found Resource Descriptor HOB
2489 //
2490 if ((HighAddress != (EFI_PHYSICAL_ADDRESS)MAX_ALLOC_ADDRESS) && (ResourceHob->PhysicalStart <= HighAddress)) {
2491 continue;
2492 }
2493
2494 //
2495 // Skip Resource Descriptor HOBs that are not large enough to initilize the DXE Core
2496 //
2497 TestedMemoryBaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);
2498 TestedMemoryLength = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - TestedMemoryBaseAddress);
2499 FindLargestFreeRegion (&TestedMemoryBaseAddress, &TestedMemoryLength, (EFI_HOB_MEMORY_ALLOCATION *)GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION));
2500 if (TestedMemoryLength < MinimalMemorySizeNeeded) {
2501 continue;
2502 }
2503
2504 //
2505 // Save the range described by the Resource Descriptor that is large enough to initilize the DXE Core
2506 //
2507 BaseAddress = TestedMemoryBaseAddress;
2508 Length = TestedMemoryLength;
2509 Attributes = ResourceHob->ResourceAttribute;
2510 HighAddress = ResourceHob->PhysicalStart;
2511 }
2512 }
2513
2514 DEBUG ((DEBUG_INFO, "CoreInitializeMemoryServices:\n"));
2515 DEBUG ((DEBUG_INFO, " BaseAddress - 0x%lx Length - 0x%lx MinimalMemorySizeNeeded - 0x%lx\n", BaseAddress, Length, MinimalMemorySizeNeeded));
2516
2517 //
2518 // If no memory regions are found that are big enough to initialize the DXE core, then ASSERT().
2519 //
2520 ASSERT (Length >= MinimalMemorySizeNeeded);
2521
2522 //
2523 // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask
2524 //
2525 if ((Attributes & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) == EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) {
2527 } else {
2529 }
2530
2531 if (MemoryTypeInformationResourceHob != NULL) {
2532 //
2533 // If a Memory Type Information Resource HOB was found, then use the address
2534 // range of the Memory Type Information Resource HOB as the preferred
2535 // address range for the Memory Type Information bins.
2536 //
2538 MemoryTypeInformationResourceHob->PhysicalStart,
2539 MemoryTypeInformationResourceHob->ResourceLength
2540 );
2541 }
2542
2543 //
2544 // Declare the very first memory region, so the EFI Memory Services are available.
2545 //
2548 BaseAddress,
2549 RShiftU64 (Length, EFI_PAGE_SHIFT),
2550 Capabilities
2551 );
2552
2553 *MemoryBaseAddress = BaseAddress;
2554 *MemoryLength = Length;
2555
2556 return EFI_SUCCESS;
2557}
2558
2575 IN OUT VOID **HobStart,
2576 IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress,
2577 IN UINT64 MemoryLength
2578 )
2579{
2581 VOID *NewHobList;
2583 UINT8 SizeOfMemorySpace;
2584 UINT8 SizeOfIoSpace;
2585 EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
2586 EFI_PHYSICAL_ADDRESS BaseAddress;
2587 UINT64 Length;
2588 EFI_STATUS Status;
2589 EFI_GCD_MAP_ENTRY *Entry;
2590 EFI_GCD_MEMORY_TYPE GcdMemoryType;
2591 EFI_GCD_IO_TYPE GcdIoType;
2593 EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
2594 EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob;
2595 UINTN NumberOfDescriptors;
2596 EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
2597 UINTN Index;
2598 UINT64 Capabilities;
2599 EFI_HOB_CPU *CpuHob;
2600 EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMapHobList;
2601
2602 //
2603 // Cache the PHIT HOB for later use
2604 //
2605 PhitHob = (EFI_HOB_HANDOFF_INFO_TABLE *)(*HobStart);
2606
2607 //
2608 // Get the number of address lines in the I/O and Memory space for the CPU
2609 //
2610 CpuHob = GetFirstHob (EFI_HOB_TYPE_CPU);
2611 ASSERT (CpuHob != NULL);
2612 SizeOfMemorySpace = CpuHob->SizeOfMemorySpace;
2613 SizeOfIoSpace = CpuHob->SizeOfIoSpace;
2614
2615 //
2616 // Initialize the GCD Memory Space Map
2617 //
2618 Entry = AllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdMemorySpaceMapEntryTemplate);
2619 ASSERT (Entry != NULL);
2620
2621 Entry->EndAddress = LShiftU64 (1, SizeOfMemorySpace) - 1;
2622
2623 InsertHeadList (&mGcdMemorySpaceMap, &Entry->Link);
2624
2626
2627 //
2628 // Initialize the GCD I/O Space Map
2629 //
2630 Entry = AllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdIoSpaceMapEntryTemplate);
2631 ASSERT (Entry != NULL);
2632
2633 Entry->EndAddress = LShiftU64 (1, SizeOfIoSpace) - 1;
2634
2635 InsertHeadList (&mGcdIoSpaceMap, &Entry->Link);
2636
2638
2639 //
2640 // Walk the HOB list and add all resource descriptors to the GCD
2641 //
2642 for (Hob.Raw = *HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
2643 GcdMemoryType = EfiGcdMemoryTypeNonExistent;
2644 GcdIoType = EfiGcdIoTypeNonExistent;
2645
2646 if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
2647 ResourceHob = Hob.ResourceDescriptor;
2648
2649 switch (ResourceHob->ResourceType) {
2650 case EFI_RESOURCE_SYSTEM_MEMORY:
2651 if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES) {
2652 if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) == EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) {
2653 GcdMemoryType = EfiGcdMemoryTypeMoreReliable;
2654 } else {
2655 GcdMemoryType = EfiGcdMemoryTypeSystemMemory;
2656 }
2657 }
2658
2659 if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == INITIALIZED_MEMORY_ATTRIBUTES) {
2660 GcdMemoryType = EfiGcdMemoryTypeReserved;
2661 }
2662
2663 if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == PRESENT_MEMORY_ATTRIBUTES) {
2664 GcdMemoryType = EfiGcdMemoryTypeReserved;
2665 }
2666
2667 if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) == EFI_RESOURCE_ATTRIBUTE_PERSISTENT) {
2668 GcdMemoryType = EfiGcdMemoryTypePersistent;
2669 }
2670
2671 break;
2672 case EFI_RESOURCE_MEMORY_MAPPED_IO:
2673 case EFI_RESOURCE_FIRMWARE_DEVICE:
2674 GcdMemoryType = EfiGcdMemoryTypeMemoryMappedIo;
2675 break;
2676 case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:
2677 case EFI_RESOURCE_MEMORY_RESERVED:
2678 GcdMemoryType = EfiGcdMemoryTypeReserved;
2679 break;
2680 case EFI_RESOURCE_MEMORY_UNACCEPTED:
2681 GcdMemoryType = EfiGcdMemoryTypeUnaccepted;
2682 break;
2683 case EFI_RESOURCE_IO:
2684 GcdIoType = EfiGcdIoTypeIo;
2685 break;
2686 case EFI_RESOURCE_IO_RESERVED:
2687 GcdIoType = EfiGcdIoTypeReserved;
2688 break;
2689 }
2690
2691 if (GcdMemoryType != EfiGcdMemoryTypeNonExistent) {
2692 //
2693 // Validate the Resource HOB Attributes
2694 //
2696
2697 //
2698 // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask
2699 //
2701 GcdMemoryType,
2702 ResourceHob->ResourceAttribute
2703 );
2704
2706 GcdMemoryType,
2707 ResourceHob->PhysicalStart,
2708 ResourceHob->ResourceLength,
2709 Capabilities
2710 );
2711 }
2712
2713 if (GcdIoType != EfiGcdIoTypeNonExistent) {
2714 Status = CoreAddIoSpace (
2715 GcdIoType,
2716 ResourceHob->PhysicalStart,
2717 ResourceHob->ResourceLength
2718 );
2719 }
2720 }
2721 }
2722
2723 //
2724 // Allocate first memory region from the GCD by the DXE core
2725 //
2726 Status = CoreGetMemorySpaceDescriptor (MemoryBaseAddress, &Descriptor);
2727 if (!EFI_ERROR (Status)) {
2728 ASSERT (
2731 );
2732 Status = CoreAllocateMemorySpace (
2734 Descriptor.GcdMemoryType,
2735 0,
2736 MemoryLength,
2737 &MemoryBaseAddress,
2738 gDxeCoreImageHandle,
2739 NULL
2740 );
2741 }
2742
2743 //
2744 // Walk the HOB list and allocate all memory space that is consumed by memory allocation HOBs,
2745 // and Firmware Volume HOBs. Also update the EFI Memory Map with the memory allocation HOBs.
2746 //
2747 for (Hob.Raw = *HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
2748 if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
2749 MemoryHob = Hob.MemoryAllocation;
2750 BaseAddress = MemoryHob->AllocDescriptor.MemoryBaseAddress;
2751 Status = CoreGetMemorySpaceDescriptor (BaseAddress, &Descriptor);
2752 if (!EFI_ERROR (Status)) {
2753 Status = CoreAllocateMemorySpace (
2755 Descriptor.GcdMemoryType,
2756 0,
2757 MemoryHob->AllocDescriptor.MemoryLength,
2758 &BaseAddress,
2759 gDxeCoreImageHandle,
2760 NULL
2761 );
2762 if (!EFI_ERROR (Status) &&
2765 {
2767 MemoryHob->AllocDescriptor.MemoryType,
2769 RShiftU64 (MemoryHob->AllocDescriptor.MemoryLength, EFI_PAGE_SHIFT),
2770 Descriptor.Capabilities & (~EFI_MEMORY_RUNTIME)
2771 );
2772 }
2773 }
2774 }
2775
2776 if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) {
2777 FirmwareVolumeHob = Hob.FirmwareVolume;
2778 BaseAddress = FirmwareVolumeHob->BaseAddress;
2779 Status = CoreAllocateMemorySpace (
2782 0,
2783 FirmwareVolumeHob->Length,
2784 &BaseAddress,
2785 gDxeCoreImageHandle,
2786 NULL
2787 );
2788 }
2789 }
2790
2791 //
2792 // Add and allocate the remaining unallocated system memory to the memory services.
2793 //
2794 Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
2795 ASSERT (Status == EFI_SUCCESS);
2796
2797 MemorySpaceMapHobList = NULL;
2798 for (Index = 0; Index < NumberOfDescriptors; Index++) {
2799 if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeSystemMemory) ||
2800 (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMoreReliable))
2801 {
2802 if (MemorySpaceMap[Index].ImageHandle == NULL) {
2803 BaseAddress = PageAlignAddress (MemorySpaceMap[Index].BaseAddress);
2804 Length = PageAlignLength (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - BaseAddress);
2805 if ((Length == 0) || (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length < BaseAddress)) {
2806 continue;
2807 }
2808
2809 if (((UINTN)MemorySpaceMap[Index].BaseAddress <= (UINTN)(*HobStart)) &&
2810 ((UINTN)(MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) >= (UINTN)PhitHob->EfiFreeMemoryBottom))
2811 {
2812 //
2813 // Skip the memory space that covers HOB List, it should be processed
2814 // after HOB List relocation to avoid the resources allocated by others
2815 // to corrupt HOB List before its relocation.
2816 //
2817 MemorySpaceMapHobList = &MemorySpaceMap[Index];
2818 continue;
2819 }
2820
2823 BaseAddress,
2824 RShiftU64 (Length, EFI_PAGE_SHIFT),
2825 MemorySpaceMap[Index].Capabilities & (~EFI_MEMORY_RUNTIME)
2826 );
2827 Status = CoreAllocateMemorySpace (
2829 MemorySpaceMap[Index].GcdMemoryType,
2830 0,
2831 Length,
2832 &BaseAddress,
2833 gDxeCoreImageHandle,
2834 NULL
2835 );
2836 }
2837 }
2838 }
2839
2840 //
2841 // Relocate HOB List to an allocated pool buffer.
2842 // The relocation should be at after all the tested memory resources added
2843 // (except the memory space that covers HOB List) to the memory services,
2844 // because the memory resource found in CoreInitializeMemoryServices()
2845 // may have not enough remaining resource for HOB List.
2846 //
2847 NewHobList = AllocateCopyPool (
2848 (UINTN)PhitHob->EfiFreeMemoryBottom - (UINTN)(*HobStart),
2849 *HobStart
2850 );
2851 ASSERT (NewHobList != NULL);
2852
2853 *HobStart = NewHobList;
2854 gHobList = NewHobList;
2855
2856 if (MemorySpaceMapHobList != NULL) {
2857 //
2858 // Add and allocate the memory space that covers HOB List to the memory services
2859 // after HOB List relocation.
2860 //
2861 BaseAddress = PageAlignAddress (MemorySpaceMapHobList->BaseAddress);
2862 Length = PageAlignLength (MemorySpaceMapHobList->BaseAddress + MemorySpaceMapHobList->Length - BaseAddress);
2865 BaseAddress,
2866 RShiftU64 (Length, EFI_PAGE_SHIFT),
2867 MemorySpaceMapHobList->Capabilities & (~EFI_MEMORY_RUNTIME)
2868 );
2869 Status = CoreAllocateMemorySpace (
2871 MemorySpaceMapHobList->GcdMemoryType,
2872 0,
2873 Length,
2874 &BaseAddress,
2875 gDxeCoreImageHandle,
2876 NULL
2877 );
2878 }
2879
2880 CoreFreePool (MemorySpaceMap);
2881
2882 return EFI_SUCCESS;
2883}
UINT64 UINTN
#define MAX_ALLOC_ADDRESS
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
Definition: HobLib.c:142
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
Definition: BaseLib.h:2904
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID * gHobList
VOID CoreAddMemoryDescriptor(IN EFI_MEMORY_TYPE Type, IN EFI_PHYSICAL_ADDRESS Start, IN UINT64 NumberOfPages, IN UINT64 Attribute)
Definition: Page.c:653
VOID CoreUpdateMemoryAttributes(IN EFI_PHYSICAL_ADDRESS Start, IN UINT64 NumberOfPages, IN UINT64 NewAttributes)
Definition: Page.c:1099
VOID CoreAcquireLock(IN EFI_LOCK *Lock)
Definition: Library.c:59
VOID CoreReleaseLock(IN EFI_LOCK *Lock)
Definition: Library.c:80
VOID CoreSetMemoryTypeInformationRange(IN EFI_PHYSICAL_ADDRESS Start, IN UINT64 Length)
Definition: Page.c:547
VOID CoreInitializePool(VOID)
Definition: Pool.c:115
EFI_STATUS EFIAPI CoreFreePool(IN VOID *Buffer)
Definition: Pool.c:591
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_STATUS EFIAPI CoreFreeIoSpace(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: Gcd.c:1931
EFI_STATUS CoreCleanupGcdMapEntry(IN EFI_GCD_MAP_ENTRY *TopEntry, IN EFI_GCD_MAP_ENTRY *BottomEntry, IN LIST_ENTRY *StartLink, IN LIST_ENTRY *EndLink, IN LIST_ENTRY *Map)
Definition: Gcd.c:555
EFI_STATUS EFIAPI CoreGetIoSpaceDescriptor(IN EFI_PHYSICAL_ADDRESS BaseAddress, OUT EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor)
Definition: Gcd.c:1995
VOID EFIAPI CoreDumpGcdIoSpaceMap(BOOLEAN InitialMap)
Definition: Gcd.c:190
EFI_STATUS CoreAllocateSpaceCheckEntry(IN UINTN Operation, IN EFI_GCD_MAP_ENTRY *Entry, IN EFI_GCD_MEMORY_TYPE GcdMemoryType, IN EFI_GCD_IO_TYPE GcdIoType)
Definition: Gcd.c:1049
VOID FindLargestFreeRegion(IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, IN OUT UINT64 *Length, IN EFI_HOB_MEMORY_ALLOCATION *MemoryHob)
Definition: Gcd.c:2172
UINT64 AlignValue(IN UINT64 Value, IN UINTN Alignment, IN BOOLEAN RoundUp)
Definition: Gcd.c:326
EFI_STATUS CoreAllocateSpace(IN UINTN Operation, IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType, IN EFI_GCD_MEMORY_TYPE GcdMemoryType, IN EFI_GCD_IO_TYPE GcdIoType, IN UINTN Alignment, IN UINT64 Length, IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, IN EFI_HANDLE ImageHandle, IN EFI_HANDLE DeviceHandle OPTIONAL)
Definition: Gcd.c:1099
UINT64 CoreConvertResourceDescriptorHobAttributesToCapabilities(EFI_GCD_MEMORY_TYPE GcdMemoryType, UINT64 Attributes)
Definition: Gcd.c:2115
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 * mGcdIoTypeNames[]
Definition: Gcd.c:116
EFI_STATUS EFIAPI CoreGetIoSpaceMap(OUT UINTN *NumberOfDescriptors, OUT EFI_GCD_IO_SPACE_DESCRIPTOR **IoSpaceMap)
Definition: Gcd.c:2047
EFI_STATUS EFIAPI CoreGetMemorySpaceDescriptor(IN EFI_PHYSICAL_ADDRESS BaseAddress, OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor)
Definition: Gcd.c:1617
EFI_STATUS EFIAPI CoreAddMemorySpace(IN EFI_GCD_MEMORY_TYPE GcdMemoryType, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Capabilities)
Definition: Gcd.c:1478
VOID CoreAcquireGcdMemoryLock(VOID)
Definition: Gcd.c:266
EFI_STATUS CoreInitializeMemoryServices(IN VOID **HobStart, OUT EFI_PHYSICAL_ADDRESS *MemoryBaseAddress, OUT UINT64 *MemoryLength)
Definition: Gcd.c:2236
UINT64 CalculateTotalMemoryBinSizeNeeded(VOID)
Definition: Gcd.c:2144
EFI_STATUS CoreConvertSpace(IN UINTN Operation, IN EFI_GCD_MEMORY_TYPE GcdMemoryType, IN EFI_GCD_IO_TYPE GcdIoType, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Capabilities, IN UINT64 Attributes)
Definition: Gcd.c:723
EFI_STATUS CoreMergeGcdMapEntry(IN LIST_ENTRY *Link, IN BOOLEAN Forward, IN LIST_ENTRY *Map)
Definition: Gcd.c:477
EFI_STATUS EFIAPI CoreFreeMemorySpace(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: Gcd.c:1551
EFI_STATUS EFIAPI CoreRemoveMemorySpace(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: Gcd.c:1573
EFI_STATUS CoreInitializeGcdServices(IN OUT VOID **HobStart, IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress, IN UINT64 MemoryLength)
Definition: Gcd.c:2574
EFI_STATUS CoreInsertGcdMapEntry(IN LIST_ENTRY *Link, IN EFI_GCD_MAP_ENTRY *Entry, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN EFI_GCD_MAP_ENTRY *TopEntry, IN EFI_GCD_MAP_ENTRY *BottomEntry)
Definition: Gcd.c:432
EFI_STATUS EFIAPI CoreSetMemorySpaceCapabilities(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Capabilities)
Definition: Gcd.c:1711
UINT64 PageAlignLength(IN UINT64 Value)
Definition: Gcd.c:367
EFI_STATUS EFIAPI CoreAddIoSpace(IN EFI_GCD_IO_TYPE GcdIoType, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: Gcd.c:1846
VOID EFIAPI CoreDumpGcdMemorySpaceMap(BOOLEAN InitialMap)
Definition: Gcd.c:144
EFI_STATUS EFIAPI CoreSetMemorySpaceAttributes(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
Definition: Gcd.c:1680
VOID BuildMemoryDescriptor(IN OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor, IN EFI_GCD_MAP_ENTRY *Entry)
Definition: Gcd.c:1591
EFI_STATUS EFIAPI CoreGetMemorySpaceMap(OUT UINTN *NumberOfDescriptors, OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR **MemorySpaceMap)
Definition: Gcd.c:1737
EFI_STATUS CoreInternalAddMemorySpace(IN EFI_GCD_MEMORY_TYPE GcdMemoryType, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Capabilities)
Definition: Gcd.c:1385
UINT64 PageAlignAddress(IN UINT64 Value)
Definition: Gcd.c:351
VOID CoreAcquireGcdIoLock(VOID)
Definition: Gcd.c:290
UINT64 ConverToCpuArchAttributes(UINT64 Attributes)
Definition: Gcd.c:673
VOID CoreValidateResourceDescriptorHobAttributes(IN UINT64 Attributes)
Definition: Gcd.c:235
VOID BuildIoDescriptor(IN EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor, IN EFI_GCD_MAP_ENTRY *Entry)
Definition: Gcd.c:1971
EFI_STATUS EFIAPI CoreAllocateIoSpace(IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType, IN EFI_GCD_IO_TYPE GcdIoType, IN UINTN Alignment, IN UINT64 Length, IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, IN EFI_HANDLE ImageHandle, IN EFI_HANDLE DeviceHandle OPTIONAL)
Definition: Gcd.c:1884
VOID CoreReleaseGcdMemoryLock(VOID)
Definition: Gcd.c:278
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 * mGcdAllocationTypeNames[]
Definition: Gcd.c:126
EFI_STATUS EFIAPI CoreRemoveIoSpace(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: Gcd.c:1953
EFI_STATUS CoreAllocateGcdMapEntry(IN OUT EFI_GCD_MAP_ENTRY **TopEntry, IN OUT EFI_GCD_MAP_ENTRY **BottomEntry)
Definition: Gcd.c:389
UINTN CoreCountGcdMapEntry(IN LIST_ENTRY *Map)
Definition: Gcd.c:647
VOID CoreReleaseGcdIoLock(VOID)
Definition: Gcd.c:302
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 * mGcdMemoryTypeNames[]
Definition: Gcd.c:102
EFI_STATUS CoreSearchGcdMapEntry(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, OUT LIST_ENTRY **StartLink, OUT LIST_ENTRY **EndLink, IN LIST_ENTRY *Map)
Definition: Gcd.c:600
EFI_STATUS EFIAPI CoreAllocateMemorySpace(IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType, IN EFI_GCD_MEMORY_TYPE GcdMemoryType, IN UINTN Alignment, IN UINT64 Length, IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, IN EFI_HANDLE ImageHandle, IN EFI_HANDLE DeviceHandle OPTIONAL)
Definition: Gcd.c:1429
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
EFI_GCD_MEMORY_TYPE
Definition: PiDxeCis.h:21
@ EfiGcdMemoryTypeReserved
Definition: PiDxeCis.h:32
@ EfiGcdMemoryTypeNonExistent
Definition: PiDxeCis.h:26
@ EfiGcdMemoryTypePersistent
Definition: PiDxeCis.h:49
@ EfiGcdMemoryTypeMoreReliable
Definition: PiDxeCis.h:58
@ EfiGcdMemoryTypeUnaccepted
Definition: PiDxeCis.h:63
@ EfiGcdMemoryTypeSystemMemory
Definition: PiDxeCis.h:38
@ EfiGcdMemoryTypeMemoryMappedIo
Definition: PiDxeCis.h:44
EFI_GCD_ALLOCATE_TYPE
Definition: PiDxeCis.h:92
@ EfiGcdAllocateMaxAddressSearchBottomUp
Definition: PiDxeCis.h:102
@ EfiGcdAllocateMaxAddressSearchTopDown
Definition: PiDxeCis.h:117
@ EfiGcdAllocateAnySearchTopDown
Definition: PiDxeCis.h:112
@ EfiGcdAllocateAddress
Definition: PiDxeCis.h:107
EFI_GCD_IO_TYPE
Definition: PiDxeCis.h:70
@ EfiGcdIoTypeNonExistent
Definition: PiDxeCis.h:75
@ EfiGcdIoTypeReserved
Definition: PiDxeCis.h:80
@ EfiGcdIoTypeIo
Definition: PiDxeCis.h:85
#define EFI_NOT_AVAILABLE_YET
Definition: PiMultiPhase.h:54
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
#define EFI_INITIALIZE_LOCK_VARIABLE(Priority)
Definition: UefiLib.h:313
@ EfiConventionalMemory
EFI_GCD_MEMORY_TYPE GcdMemoryType
Definition: PiDxeCis.h:152
EFI_PHYSICAL_ADDRESS BaseAddress
Definition: PiDxeCis.h:130
UINT8 SizeOfIoSpace
Definition: PiHob.h:451
UINT8 SizeOfMemorySpace
Definition: PiHob.h:447
EFI_PHYSICAL_ADDRESS BaseAddress
Definition: PiHob.h:364
EFI_PHYSICAL_ADDRESS EfiFreeMemoryBottom
Definition: PiHob.h:92
EFI_PHYSICAL_ADDRESS EfiMemoryTop
Definition: PiHob.h:79
EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop
Definition: PiHob.h:88
EFI_PHYSICAL_ADDRESS MemoryBaseAddress
Definition: PiHob.h:119
EFI_MEMORY_TYPE MemoryType
Definition: PiHob.h:131
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor
Definition: PiHob.h:153
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: PiHob.h:328
EFI_RESOURCE_TYPE ResourceType
Definition: PiHob.h:320
EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute
Definition: PiHob.h:324
EFI_PHYSICAL_ADDRESS DxeCodeTopAddress
The top address below which the Dxe runtime code and below which the Dxe runtime/boot code and PEI co...
UINT32 Type
EFI memory type defined in UEFI specification.