]>
Commit | Line | Data |
---|---|---|
c4e76d2f MX |
1 | /** @file\r |
2 | \r | |
3 | Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r | |
4 | \r | |
5 | SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
6 | \r | |
7 | **/\r | |
8 | #include <Library/BaseLib.h>\r | |
9 | #include <Library/BaseMemoryLib.h>\r | |
10 | #include <Library/DebugLib.h>\r | |
11 | #include <Library/MemoryAllocationLib.h>\r | |
47b95215 | 12 | #include <Library/MemEncryptSevLib.h>\r |
c4e76d2f | 13 | #include <Library/MemEncryptTdxLib.h>\r |
47b95215 | 14 | #include <Library/PcdLib.h>\r |
c4e76d2f MX |
15 | #include <Library/UefiBootServicesTableLib.h>\r |
16 | #include "IoMmuInternal.h"\r | |
17 | \r | |
18 | extern BOOLEAN mReservedSharedMemSupported;\r | |
19 | \r | |
20 | #define SIZE_OF_MEM_RANGE(MemRange) (MemRange->HeaderSize + MemRange->DataSize)\r | |
21 | \r | |
22 | #define RESERVED_MEM_BITMAP_4K_MASK 0xf\r | |
23 | #define RESERVED_MEM_BITMAP_32K_MASK 0xff0\r | |
24 | #define RESERVED_MEM_BITMAP_128K_MASK 0x3000\r | |
25 | #define RESERVED_MEM_BITMAP_1M_MASK 0x40000\r | |
26 | #define RESERVED_MEM_BITMAP_2M_MASK 0x180000\r | |
27 | #define RESERVED_MEM_BITMAP_MASK 0x1fffff\r | |
28 | \r | |
29 | /**\r | |
30 | * mReservedMemRanges describes the layout of the reserved memory.\r | |
31 | * The reserved memory consists of disfferent size of memory region.\r | |
32 | * The pieces of memory with the same size are managed by one entry\r | |
33 | * in the mReservedMemRanges. All the pieces of memories are managed by\r | |
34 | * mReservedMemBitmap which is a UINT32. It means it can manage at most\r | |
35 | * 32 pieces of memory. Because of the layout of CommonBuffer\r | |
36 | * (1-page header + n-page data), a piece of reserved memory consists of\r | |
37 | * 2 parts: Header + Data.\r | |
38 | *\r | |
39 | * So put all these together, mReservedMemRanges and mReservedMemBitmap\r | |
40 | * are designed to manage the reserved memory.\r | |
41 | *\r | |
42 | * Use the second entry of mReservedMemRanges as an example.\r | |
43 | * { RESERVED_MEM_BITMAP_32K_MASK, 4, 8, SIZE_32KB, SIZE_4KB, 0 },\r | |
44 | * - RESERVED_MEM_BITMAP_32K_MASK is 0xff0. It means bit4-11 in mReservedMemBitmap\r | |
45 | * is reserved for 32K size memory.\r | |
46 | * - 4 is the shift of mReservedMemBitmap.\r | |
47 | * - 8 means there are 8 pieces of 32K size memory.\r | |
48 | * - SIZE_32KB indicates the size of Data part.\r | |
49 | * - SIZE_4KB is the size of Header part.\r | |
50 | * - 0 is the start address of this memory range which will be populated when\r | |
51 | * the reserved memory is initialized.\r | |
52 | *\r | |
53 | * The size and count of the memory region are derived from the experience. For\r | |
54 | * a typical grub boot, there are about 5100 IoMmu/DMA operation. Most of these\r | |
55 | * DMA operation require the memory with size less than 32K (~5080). But we find\r | |
56 | * in grub boot there may be 2 DMA operation which require for the memory larger\r | |
57 | * than 1M. And these 2 DMA operation occur concurrently. So we reserve 2 pieces\r | |
58 | * of memory with size of SIZE_2MB. This is for the best boot performance.\r | |
59 | *\r | |
60 | * If all the reserved memory are exausted, then it will fall back to the legacy\r | |
61 | * memory allocation as before.\r | |
62 | */\r | |
63 | STATIC IOMMU_RESERVED_MEM_RANGE mReservedMemRanges[] = {\r | |
64 | { RESERVED_MEM_BITMAP_4K_MASK, 0, 4, SIZE_4KB, SIZE_4KB, 0 },\r | |
65 | { RESERVED_MEM_BITMAP_32K_MASK, 4, 8, SIZE_32KB, SIZE_4KB, 0 },\r | |
66 | { RESERVED_MEM_BITMAP_128K_MASK, 12, 2, SIZE_128KB, SIZE_4KB, 0 },\r | |
67 | { RESERVED_MEM_BITMAP_1M_MASK, 14, 1, SIZE_1MB, SIZE_4KB, 0 },\r | |
68 | { RESERVED_MEM_BITMAP_2M_MASK, 15, 2, SIZE_2MB, SIZE_4KB, 0 },\r | |
69 | };\r | |
70 | \r | |
71 | //\r | |
72 | // Bitmap of the allocation of reserved memory.\r | |
73 | //\r | |
74 | STATIC UINT32 mReservedMemBitmap = 0;\r | |
75 | \r | |
76 | //\r | |
77 | // Start address of the reserved memory region.\r | |
78 | //\r | |
79 | STATIC EFI_PHYSICAL_ADDRESS mReservedSharedMemAddress = 0;\r | |
80 | \r | |
81 | //\r | |
82 | // Total size of the reserved memory region.\r | |
83 | //\r | |
84 | STATIC UINT32 mReservedSharedMemSize = 0;\r | |
85 | \r | |
86 | /**\r | |
87 | * Calculate the size of reserved memory.\r | |
88 | *\r | |
89 | * @retval UINT32 Size of the reserved memory\r | |
90 | */\r | |
91 | STATIC\r | |
92 | UINT32\r | |
93 | CalcuateReservedMemSize (\r | |
94 | VOID\r | |
95 | )\r | |
96 | {\r | |
97 | UINT32 Index;\r | |
98 | IOMMU_RESERVED_MEM_RANGE *MemRange;\r | |
99 | \r | |
100 | if (mReservedSharedMemSize != 0) {\r | |
101 | return mReservedSharedMemSize;\r | |
102 | }\r | |
103 | \r | |
104 | for (Index = 0; Index < ARRAY_SIZE (mReservedMemRanges); Index++) {\r | |
105 | MemRange = &mReservedMemRanges[Index];\r | |
106 | mReservedSharedMemSize += (SIZE_OF_MEM_RANGE (MemRange) * MemRange->Slots);\r | |
107 | }\r | |
108 | \r | |
109 | return mReservedSharedMemSize;\r | |
110 | }\r | |
111 | \r | |
112 | /**\r | |
113 | * Allocate a memory region and convert it to be shared. This memory region will be\r | |
114 | * used in the DMA operation.\r | |
115 | *\r | |
116 | * The pre-alloc memory contains pieces of memory regions with different size. The\r | |
117 | * allocation of the shared memory regions are indicated by a 32-bit bitmap (mReservedMemBitmap).\r | |
118 | *\r | |
119 | * The memory regions are consumed by IoMmuAllocateBuffer (in which CommonBuffer is allocated) and\r | |
120 | * IoMmuMap (in which bounce buffer is allocated).\r | |
121 | *\r | |
122 | * The CommonBuffer contains 2 parts, one page for CommonBufferHeader which is private memory,\r | |
123 | * the other part is shared memory. So the layout of a piece of memory region after initialization\r | |
124 | * looks like:\r | |
125 | *\r | |
126 | * |------------|----------------------------|\r | |
127 | * | Header | Data | <-- a piece of pre-alloc memory region\r | |
128 | * | 4k, private| 4k/32k/128k/etc, shared |\r | |
129 | * |-----------------------------------------|\r | |
130 | *\r | |
131 | * @retval EFI_SUCCESS Successfully initialize the reserved memory.\r | |
132 | * @retval EFI_UNSUPPORTED This feature is not supported.\r | |
133 | */\r | |
134 | EFI_STATUS\r | |
135 | IoMmuInitReservedSharedMem (\r | |
136 | VOID\r | |
137 | )\r | |
138 | {\r | |
139 | EFI_STATUS Status;\r | |
140 | UINT32 Index1, Index2;\r | |
141 | UINTN TotalPages;\r | |
142 | IOMMU_RESERVED_MEM_RANGE *MemRange;\r | |
143 | EFI_PHYSICAL_ADDRESS PhysicalAddress;\r | |
47b95215 | 144 | UINT64 SharedAddress;\r |
c4e76d2f MX |
145 | \r |
146 | if (!mReservedSharedMemSupported) {\r | |
147 | return EFI_UNSUPPORTED;\r | |
148 | }\r | |
149 | \r | |
150 | TotalPages = EFI_SIZE_TO_PAGES (CalcuateReservedMemSize ());\r | |
151 | \r | |
152 | PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePages (TotalPages);\r | |
153 | DEBUG ((\r | |
154 | DEBUG_VERBOSE,\r | |
155 | "%a: ReservedMem (%d pages) address = 0x%llx\n",\r | |
156 | __FUNCTION__,\r | |
157 | TotalPages,\r | |
158 | PhysicalAddress\r | |
159 | ));\r | |
160 | \r | |
161 | mReservedMemBitmap = 0;\r | |
162 | mReservedSharedMemAddress = PhysicalAddress;\r | |
163 | \r | |
164 | for (Index1 = 0; Index1 < ARRAY_SIZE (mReservedMemRanges); Index1++) {\r | |
165 | MemRange = &mReservedMemRanges[Index1];\r | |
166 | MemRange->StartAddressOfMemRange = PhysicalAddress;\r | |
167 | \r | |
168 | for (Index2 = 0; Index2 < MemRange->Slots; Index2++) {\r | |
47b95215 TL |
169 | SharedAddress = (UINT64)(UINTN)(MemRange->StartAddressOfMemRange + Index2 * SIZE_OF_MEM_RANGE (MemRange) + MemRange->HeaderSize);\r |
170 | \r | |
171 | if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) {\r | |
172 | Status = MemEncryptSevClearPageEncMask (\r | |
173 | 0,\r | |
174 | SharedAddress,\r | |
175 | EFI_SIZE_TO_PAGES (MemRange->DataSize)\r | |
176 | );\r | |
177 | ASSERT (!EFI_ERROR (Status));\r | |
178 | } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {\r | |
179 | Status = MemEncryptTdxSetPageSharedBit (\r | |
180 | 0,\r | |
181 | SharedAddress,\r | |
182 | EFI_SIZE_TO_PAGES (MemRange->DataSize)\r | |
183 | );\r | |
184 | ASSERT (!EFI_ERROR (Status));\r | |
185 | } else {\r | |
186 | ASSERT (FALSE);\r | |
187 | }\r | |
c4e76d2f MX |
188 | }\r |
189 | \r | |
190 | PhysicalAddress += (MemRange->Slots * SIZE_OF_MEM_RANGE (MemRange));\r | |
191 | }\r | |
192 | \r | |
193 | return EFI_SUCCESS;\r | |
194 | }\r | |
195 | \r | |
196 | /**\r | |
197 | * Release the pre-alloc shared memory.\r | |
198 | *\r | |
199 | * @retval EFI_SUCCESS Successfully release the shared memory\r | |
200 | */\r | |
201 | EFI_STATUS\r | |
202 | IoMmuReleaseReservedSharedMem (\r | |
203 | BOOLEAN MemoryMapLocked\r | |
204 | )\r | |
205 | {\r | |
206 | EFI_STATUS Status;\r | |
207 | UINT32 Index1, Index2;\r | |
208 | IOMMU_RESERVED_MEM_RANGE *MemRange;\r | |
47b95215 | 209 | UINT64 SharedAddress;\r |
c4e76d2f MX |
210 | \r |
211 | if (!mReservedSharedMemSupported) {\r | |
212 | return EFI_SUCCESS;\r | |
213 | }\r | |
214 | \r | |
215 | for (Index1 = 0; Index1 < ARRAY_SIZE (mReservedMemRanges); Index1++) {\r | |
216 | MemRange = &mReservedMemRanges[Index1];\r | |
217 | for (Index2 = 0; Index2 < MemRange->Slots; Index2++) {\r | |
47b95215 TL |
218 | SharedAddress = (UINT64)(UINTN)(MemRange->StartAddressOfMemRange + Index2 * SIZE_OF_MEM_RANGE (MemRange) + MemRange->HeaderSize);\r |
219 | \r | |
220 | if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) {\r | |
221 | Status = MemEncryptSevSetPageEncMask (\r | |
222 | 0,\r | |
223 | SharedAddress,\r | |
224 | EFI_SIZE_TO_PAGES (MemRange->DataSize)\r | |
225 | );\r | |
226 | ASSERT (!EFI_ERROR (Status));\r | |
227 | } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) {\r | |
228 | Status = MemEncryptTdxClearPageSharedBit (\r | |
229 | 0,\r | |
230 | SharedAddress,\r | |
231 | EFI_SIZE_TO_PAGES (MemRange->DataSize)\r | |
232 | );\r | |
233 | ASSERT (!EFI_ERROR (Status));\r | |
234 | } else {\r | |
235 | ASSERT (FALSE);\r | |
236 | }\r | |
c4e76d2f MX |
237 | }\r |
238 | }\r | |
239 | \r | |
240 | if (!MemoryMapLocked) {\r | |
241 | FreePages ((VOID *)(UINTN)mReservedSharedMemAddress, EFI_SIZE_TO_PAGES (CalcuateReservedMemSize ()));\r | |
242 | mReservedSharedMemAddress = 0;\r | |
243 | mReservedMemBitmap = 0;\r | |
244 | }\r | |
245 | \r | |
246 | mReservedSharedMemSupported = FALSE;\r | |
247 | \r | |
248 | return EFI_SUCCESS;\r | |
249 | }\r | |
250 | \r | |
251 | /**\r | |
252 | * Allocate from the reserved memory pool.\r | |
253 | * If the reserved shared memory is exausted or there is no suitalbe size, it turns\r | |
254 | * to the LegacyAllocateBuffer.\r | |
255 | *\r | |
256 | * @param Type Allocate type\r | |
257 | * @param MemoryType The memory type to be allocated\r | |
258 | * @param Pages Pages to be allocated.\r | |
259 | * @param ReservedMemBitmap Bitmap of the allocated memory region\r | |
260 | * @param PhysicalAddress Pointer to the data part of allocated memory region\r | |
261 | *\r | |
262 | * @retval EFI_SUCCESS Successfully allocate the buffer\r | |
263 | * @retval Other As the error code indicates\r | |
264 | */\r | |
265 | STATIC\r | |
266 | EFI_STATUS\r | |
267 | InternalAllocateBuffer (\r | |
268 | IN EFI_ALLOCATE_TYPE Type,\r | |
269 | IN EFI_MEMORY_TYPE MemoryType,\r | |
270 | IN UINTN Pages,\r | |
271 | IN OUT UINT32 *ReservedMemBitmap,\r | |
272 | IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress\r | |
273 | )\r | |
274 | {\r | |
275 | UINT32 MemBitmap;\r | |
276 | UINT8 Index;\r | |
277 | IOMMU_RESERVED_MEM_RANGE *MemRange;\r | |
278 | UINTN PagesOfLastMemRange;\r | |
279 | \r | |
280 | *ReservedMemBitmap = 0;\r | |
281 | \r | |
282 | if (Pages == 0) {\r | |
283 | ASSERT (FALSE);\r | |
284 | return EFI_INVALID_PARAMETER;\r | |
285 | }\r | |
286 | \r | |
287 | if (!mReservedSharedMemSupported) {\r | |
288 | goto LegacyAllocateBuffer;\r | |
289 | }\r | |
290 | \r | |
291 | if (mReservedSharedMemAddress == 0) {\r | |
292 | goto LegacyAllocateBuffer;\r | |
293 | }\r | |
294 | \r | |
295 | PagesOfLastMemRange = 0;\r | |
296 | \r | |
297 | for (Index = 0; Index < ARRAY_SIZE (mReservedMemRanges); Index++) {\r | |
298 | if ((Pages > PagesOfLastMemRange) && (Pages <= EFI_SIZE_TO_PAGES (mReservedMemRanges[Index].DataSize))) {\r | |
299 | break;\r | |
300 | }\r | |
301 | \r | |
302 | PagesOfLastMemRange = EFI_SIZE_TO_PAGES (mReservedMemRanges[Index].DataSize);\r | |
303 | }\r | |
304 | \r | |
305 | if (Index == ARRAY_SIZE (mReservedMemRanges)) {\r | |
306 | // There is no suitable size of reserved memory. Turn to legacy allocate.\r | |
307 | goto LegacyAllocateBuffer;\r | |
308 | }\r | |
309 | \r | |
310 | MemRange = &mReservedMemRanges[Index];\r | |
311 | \r | |
312 | if ((mReservedMemBitmap & MemRange->BitmapMask) == MemRange->BitmapMask) {\r | |
313 | // The reserved memory is exausted. Turn to legacy allocate.\r | |
314 | goto LegacyAllocateBuffer;\r | |
315 | }\r | |
316 | \r | |
317 | MemBitmap = (mReservedMemBitmap & MemRange->BitmapMask) >> MemRange->Shift;\r | |
318 | \r | |
319 | for (Index = 0; Index < MemRange->Slots; Index++) {\r | |
320 | if ((MemBitmap & (UINT8)(1<<Index)) == 0) {\r | |
321 | break;\r | |
322 | }\r | |
323 | }\r | |
324 | \r | |
325 | ASSERT (Index != MemRange->Slots);\r | |
326 | \r | |
327 | *PhysicalAddress = MemRange->StartAddressOfMemRange + Index * SIZE_OF_MEM_RANGE (MemRange) + MemRange->HeaderSize;\r | |
328 | *ReservedMemBitmap = (UINT32)(1 << (Index + MemRange->Shift));\r | |
329 | \r | |
330 | DEBUG ((\r | |
331 | DEBUG_VERBOSE,\r | |
332 | "%a: range-size: %lx, start-address=0x%llx, pages=0x%llx, bits=0x%lx, bitmap: %lx => %lx\n",\r | |
333 | __FUNCTION__,\r | |
334 | MemRange->DataSize,\r | |
335 | *PhysicalAddress,\r | |
336 | Pages,\r | |
337 | *ReservedMemBitmap,\r | |
338 | mReservedMemBitmap,\r | |
339 | mReservedMemBitmap | *ReservedMemBitmap\r | |
340 | ));\r | |
341 | \r | |
342 | return EFI_SUCCESS;\r | |
343 | \r | |
344 | LegacyAllocateBuffer:\r | |
345 | \r | |
346 | *ReservedMemBitmap = 0;\r | |
347 | return gBS->AllocatePages (Type, MemoryType, Pages, PhysicalAddress);\r | |
348 | }\r | |
349 | \r | |
350 | /**\r | |
351 | * Allocate reserved shared memory for bounce buffer.\r | |
352 | *\r | |
353 | * @param Type Allocate type\r | |
354 | * @param MemoryType The memory type to be allocated\r | |
355 | * @param MapInfo Pointer to the MAP_INFO\r | |
356 | *\r | |
357 | * @retval EFI_SUCCESS Successfully allocate the bounce buffer\r | |
358 | * @retval Other As the error code indicates\r | |
359 | \r | |
360 | */\r | |
361 | EFI_STATUS\r | |
362 | IoMmuAllocateBounceBuffer (\r | |
363 | IN EFI_ALLOCATE_TYPE Type,\r | |
364 | IN EFI_MEMORY_TYPE MemoryType,\r | |
365 | IN OUT MAP_INFO *MapInfo\r | |
366 | )\r | |
367 | {\r | |
368 | EFI_STATUS Status;\r | |
369 | UINT32 ReservedMemBitmap;\r | |
370 | \r | |
371 | ReservedMemBitmap = 0;\r | |
372 | Status = InternalAllocateBuffer (\r | |
373 | Type,\r | |
374 | MemoryType,\r | |
375 | MapInfo->NumberOfPages,\r | |
376 | &ReservedMemBitmap,\r | |
377 | &MapInfo->PlainTextAddress\r | |
378 | );\r | |
379 | MapInfo->ReservedMemBitmap = ReservedMemBitmap;\r | |
380 | mReservedMemBitmap |= ReservedMemBitmap;\r | |
381 | \r | |
382 | ASSERT (Status == EFI_SUCCESS);\r | |
383 | \r | |
384 | return Status;\r | |
385 | }\r | |
386 | \r | |
387 | /**\r | |
388 | * Free the bounce buffer allocated in IoMmuAllocateBounceBuffer.\r | |
389 | *\r | |
390 | * @param MapInfo Pointer to the MAP_INFO\r | |
391 | * @return EFI_SUCCESS Successfully free the bounce buffer.\r | |
392 | */\r | |
393 | EFI_STATUS\r | |
394 | IoMmuFreeBounceBuffer (\r | |
395 | IN OUT MAP_INFO *MapInfo\r | |
396 | )\r | |
397 | {\r | |
398 | if (MapInfo->ReservedMemBitmap == 0) {\r | |
399 | gBS->FreePages (MapInfo->PlainTextAddress, MapInfo->NumberOfPages);\r | |
400 | } else {\r | |
401 | DEBUG ((\r | |
402 | DEBUG_VERBOSE,\r | |
403 | "%a: PlainTextAddress=0x%Lx, bits=0x%Lx, bitmap: %Lx => %Lx\n",\r | |
404 | __FUNCTION__,\r | |
405 | MapInfo->PlainTextAddress,\r | |
406 | MapInfo->ReservedMemBitmap,\r | |
407 | mReservedMemBitmap,\r | |
408 | mReservedMemBitmap & ((UINT32)(~MapInfo->ReservedMemBitmap))\r | |
409 | ));\r | |
410 | MapInfo->PlainTextAddress = 0;\r | |
411 | mReservedMemBitmap &= (UINT32)(~MapInfo->ReservedMemBitmap);\r | |
412 | MapInfo->ReservedMemBitmap = 0;\r | |
413 | }\r | |
414 | \r | |
415 | return EFI_SUCCESS;\r | |
416 | }\r | |
417 | \r | |
418 | /**\r | |
419 | * Allocate CommonBuffer from pre-allocated shared memory.\r | |
420 | *\r | |
421 | * @param MemoryType Memory type\r | |
422 | * @param CommonBufferPages Pages of CommonBuffer\r | |
423 | * @param PhysicalAddress Allocated physical address\r | |
424 | * @param ReservedMemBitmap Bitmap which indicates the allocation of reserved memory\r | |
425 | *\r | |
426 | * @retval EFI_SUCCESS Successfully allocate the common buffer\r | |
427 | * @retval Other As the error code indicates\r | |
428 | */\r | |
429 | EFI_STATUS\r | |
430 | IoMmuAllocateCommonBuffer (\r | |
431 | IN EFI_MEMORY_TYPE MemoryType,\r | |
432 | IN UINTN CommonBufferPages,\r | |
433 | OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress,\r | |
434 | OUT UINT32 *ReservedMemBitmap\r | |
435 | )\r | |
436 | {\r | |
437 | EFI_STATUS Status;\r | |
438 | \r | |
439 | Status = InternalAllocateBuffer (\r | |
440 | AllocateMaxAddress,\r | |
441 | MemoryType,\r | |
442 | CommonBufferPages,\r | |
443 | ReservedMemBitmap,\r | |
444 | PhysicalAddress\r | |
445 | );\r | |
446 | ASSERT (Status == EFI_SUCCESS);\r | |
447 | \r | |
448 | mReservedMemBitmap |= *ReservedMemBitmap;\r | |
449 | \r | |
450 | if (*ReservedMemBitmap != 0) {\r | |
451 | *PhysicalAddress -= SIZE_4KB;\r | |
452 | }\r | |
453 | \r | |
454 | return Status;\r | |
455 | }\r | |
456 | \r | |
457 | /**\r | |
458 | * Free CommonBuffer which is allocated by IoMmuAllocateCommonBuffer().\r | |
459 | *\r | |
460 | * @param CommonBufferHeader Pointer to the CommonBufferHeader\r | |
461 | * @param CommonBufferPages Pages of CommonBuffer\r | |
462 | *\r | |
463 | * @retval EFI_SUCCESS Successfully free the common buffer\r | |
464 | * @retval Other As the error code indicates\r | |
465 | */\r | |
466 | EFI_STATUS\r | |
467 | IoMmuFreeCommonBuffer (\r | |
468 | IN COMMON_BUFFER_HEADER *CommonBufferHeader,\r | |
469 | IN UINTN CommonBufferPages\r | |
470 | )\r | |
471 | {\r | |
472 | if (!mReservedSharedMemSupported) {\r | |
473 | goto LegacyFreeCommonBuffer;\r | |
474 | }\r | |
475 | \r | |
476 | if (CommonBufferHeader->ReservedMemBitmap == 0) {\r | |
477 | goto LegacyFreeCommonBuffer;\r | |
478 | }\r | |
479 | \r | |
480 | DEBUG ((\r | |
481 | DEBUG_VERBOSE,\r | |
482 | "%a: CommonBuffer=0x%Lx, bits=0x%Lx, bitmap: %Lx => %Lx\n",\r | |
483 | __FUNCTION__,\r | |
484 | (UINT64)(UINTN)CommonBufferHeader + SIZE_4KB,\r | |
485 | CommonBufferHeader->ReservedMemBitmap,\r | |
486 | mReservedMemBitmap,\r | |
487 | mReservedMemBitmap & ((UINT32)(~CommonBufferHeader->ReservedMemBitmap))\r | |
488 | ));\r | |
489 | \r | |
490 | mReservedMemBitmap &= (UINT32)(~CommonBufferHeader->ReservedMemBitmap);\r | |
491 | return EFI_SUCCESS;\r | |
492 | \r | |
493 | LegacyFreeCommonBuffer:\r | |
494 | return gBS->FreePages ((UINTN)CommonBufferHeader, CommonBufferPages);\r | |
495 | }\r |