TianoCore EDK2 master
Loading...
Searching...
No Matches
X86StandaloneMmMemLibInternal.c
Go to the documentation of this file.
1
17#include <PiMm.h>
19#include <Library/HobLib.h>
20
21typedef struct {
23 UINT64 Length;
25
26NON_MM_MEMORY_RANGE *mValidNonMmramRanges;
27UINTN mValidNonMmramCount;
28
29//
30// Maximum support address used to check input buffer
31//
32extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress;
33
38VOID
40 VOID
41 )
42{
43 VOID *Hob;
44 UINT32 RegEax;
45 UINT8 PhysicalAddressBits;
46
47 //
48 // Get physical address bits supported.
49 //
50 Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
51 if (Hob != NULL) {
52 PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
53 } else {
54 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
55 if (RegEax >= 0x80000008) {
56 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
57 PhysicalAddressBits = (UINT8)RegEax;
58 } else {
59 PhysicalAddressBits = 36;
60 }
61 }
62
63 //
64 // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
65 //
66 ASSERT (PhysicalAddressBits <= 52);
67 if (PhysicalAddressBits > 48) {
68 PhysicalAddressBits = 48;
69 }
70
71 //
72 // Save the maximum support address in one global variable
73 //
74 mMmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1);
75 DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress));
76}
77
89VOID
91 IN OUT NON_MM_MEMORY_RANGE *MemoryRange,
92 IN OUT UINTN *MemoryRangeSize
93 )
94{
95 NON_MM_MEMORY_RANGE *MemoryRangeEntry;
96 NON_MM_MEMORY_RANGE *MemoryRangeEnd;
97 NON_MM_MEMORY_RANGE *NewMemoryRangeEntry;
98 NON_MM_MEMORY_RANGE *NextMemoryRangeEntry;
100
101 MemoryRangeEntry = MemoryRange;
102 NewMemoryRangeEntry = MemoryRange;
103 MemoryRangeEnd = (NON_MM_MEMORY_RANGE *)((UINT8 *)MemoryRange + *MemoryRangeSize);
104 while ((UINTN)MemoryRangeEntry < (UINTN)MemoryRangeEnd) {
105 NextMemoryRangeEntry = MemoryRangeEntry + 1;
106
107 do {
108 if (((UINTN)NextMemoryRangeEntry < (UINTN)MemoryRangeEnd) &&
109 ((MemoryRangeEntry->Base + MemoryRangeEntry->Length) >= NextMemoryRangeEntry->Base))
110 {
111 //
112 // Merge the overlapped or continuous ranges.
113 //
114 End = MAX (
115 MemoryRangeEntry->Base + MemoryRangeEntry->Length,
116 NextMemoryRangeEntry->Base + NextMemoryRangeEntry->Length
117 );
118 MemoryRangeEntry->Length = End - MemoryRangeEntry->Base;
119
120 NextMemoryRangeEntry++;
121 continue;
122 } else {
123 //
124 // Copy the processed independent range to the new index location.
125 //
126 CopyMem (NewMemoryRangeEntry, MemoryRangeEntry, sizeof (NON_MM_MEMORY_RANGE));
127 break;
128 }
129 } while (TRUE);
130
131 MemoryRangeEntry = NextMemoryRangeEntry;
132 NewMemoryRangeEntry++;
133 }
134
135 *MemoryRangeSize = (UINTN)NewMemoryRangeEntry - (UINTN)MemoryRange;
136}
137
148INTN
149EFIAPI
151 IN CONST VOID *Buffer1,
152 IN CONST VOID *Buffer2
153 )
154{
155 if (((NON_MM_MEMORY_RANGE *)Buffer1)->Base > ((NON_MM_MEMORY_RANGE *)Buffer2)->Base) {
156 return 1;
157 } else if (((NON_MM_MEMORY_RANGE *)Buffer1)->Base < ((NON_MM_MEMORY_RANGE *)Buffer2)->Base) {
158 return -1;
159 }
160
161 return 0;
162}
163
168VOID
170 VOID
171 )
172{
174 UINTN Count;
175 UINTN Index;
176 UINTN RangeSize;
177 NON_MM_MEMORY_RANGE SortBuffer;
178
179 mValidNonMmramRanges = NULL;
180 mValidNonMmramCount = 0;
181
182 Count = 0;
183 Index = 0;
184 RangeSize = 0;
185
186 //
187 // 1. Get the count.
188 //
189 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
190 while (Hob.Raw != NULL) {
191 Count++;
192 Hob.Raw = GET_NEXT_HOB (Hob);
193 Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
194 }
195
196 //
197 // 2. Store the initial data.
198 //
199 RangeSize = sizeof (NON_MM_MEMORY_RANGE) * Count;
200 mValidNonMmramRanges = (NON_MM_MEMORY_RANGE *)AllocateZeroPool (RangeSize);
201 ASSERT (mValidNonMmramRanges != NULL);
202
203 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
204 while (Hob.Raw != NULL) {
205 mValidNonMmramRanges[Index].Base = Hob.ResourceDescriptor->PhysicalStart;
206 mValidNonMmramRanges[Index].Length = Hob.ResourceDescriptor->ResourceLength;
207 Index++;
208
209 Hob.Raw = GET_NEXT_HOB (Hob);
210 Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
211 }
212
213 ASSERT (Index == Count);
214
215 //
216 // 3. Sort the data.
217 //
218 QuickSort (mValidNonMmramRanges, Count, sizeof (NON_MM_MEMORY_RANGE), (BASE_SORT_COMPARE)NonMmMapCompare, &SortBuffer);
219
220 //
221 // 4. Merge the overlapped or continuous ranges.
222 //
223 MergeOverlappedOrContinuousRanges (mValidNonMmramRanges, &RangeSize);
224 mValidNonMmramCount = RangeSize/sizeof (NON_MM_MEMORY_RANGE);
225}
226
231VOID
233 VOID
234 )
235{
236 if (mValidNonMmramRanges != NULL) {
237 FreePool (mValidNonMmramRanges);
238 }
239}
240
250BOOLEAN
253 IN UINT64 Length
254 )
255{
256 UINTN Index;
257
258 for (Index = 0; Index < mValidNonMmramCount; Index++) {
259 if ((Buffer >= mValidNonMmramRanges[Index].Base) &&
260 (Buffer + Length <= mValidNonMmramRanges[Index].Base + mValidNonMmramRanges[Index].Length))
261 {
262 return TRUE;
263 }
264 }
265
266 return FALSE;
267}
UINT64 UINTN
INT64 INTN
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
Definition: HobLib.c:142
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
INTN(EFIAPI * BASE_SORT_COMPARE)(IN CONST VOID *Buffer1, IN CONST VOID *Buffer2)
Definition: BaseLib.h:3285
VOID EFIAPI QuickSort(IN OUT VOID *BufferToSort, IN CONST UINTN Count, IN CONST UINTN ElementSize, IN BASE_SORT_COMPARE CompareFunction, OUT VOID *BufferOneElement)
Definition: QuickSort.c:36
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#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 MAX(a, b)
Definition: Base.h:992
#define DEBUG(Expression)
Definition: DebugLib.h:434
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuId.c:36
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
INTN EFIAPI NonMmMapCompare(IN CONST VOID *Buffer1, IN CONST VOID *Buffer2)
BOOLEAN MmMemLibIsValidNonMmramRange(IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length)
VOID MmMemLibInitializeValidNonMmramRanges(VOID)
VOID MmMemLibFreeValidNonMmramRanges(VOID)
STATIC VOID MergeOverlappedOrContinuousRanges(IN OUT NON_MM_MEMORY_RANGE *MemoryRange, IN OUT UINTN *MemoryRangeSize)
VOID MmMemLibCalculateMaximumSupportAddress(VOID)
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: PiHob.h:328