]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/Memhole.c
1.1.07 release
[Ventoy.git] / EDK2 / edk2_mod / edk2-edk2-stable201911 / MdeModulePkg / Application / VtoyUtil / Memhole.c
1 /******************************************************************************
2 * Memhole.c
3 *
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 #include <Uefi.h>
22 #include <Library/DebugLib.h>
23 #include <Library/PrintLib.h>
24 #include <Library/UefiLib.h>
25 #include <Library/BaseMemoryLib.h>
26 #include <Library/DevicePathLib.h>
27 #include <Library/MemoryAllocationLib.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/UefiRuntimeServicesTableLib.h>
30 #include <Library/UefiApplicationEntryPoint.h>
31 #include <Protocol/LoadedImage.h>
32 #include <Guid/FileInfo.h>
33 #include <Guid/FileSystemInfo.h>
34 #include <Protocol/BlockIo.h>
35 #include <Protocol/RamDisk.h>
36 #include <Protocol/SimpleFileSystem.h>
37 #include <VtoyUtil.h>
38
39 STATIC BOOLEAN IsMemContiguous
40 (
41 IN CONST EFI_MEMORY_DESCRIPTOR *Prev,
42 IN CONST EFI_MEMORY_DESCRIPTOR *Curr,
43 IN CONST EFI_MEMORY_DESCRIPTOR *Next
44 )
45 {
46 UINTN Addr1 = 0;
47 UINTN Addr2 = 0;
48
49 if (Prev == NULL || Curr == NULL || Next == NULL)
50 {
51 return FALSE;
52 }
53
54 if (Prev->Type == EfiBootServicesData &&
55 Curr->Type == EfiConventionalMemory &&
56 Next->Type == EfiBootServicesData)
57 {
58 Addr1 = Prev->PhysicalStart + MultU64x64(SIZE_4KB, Prev->NumberOfPages);
59 Addr2 = Curr->PhysicalStart + MultU64x64(SIZE_4KB, Curr->NumberOfPages);
60
61 if (Addr1 == Curr->PhysicalStart && Addr2 == Next->PhysicalStart)
62 {
63 return TRUE;
64 }
65 }
66
67 return FALSE;
68 }
69
70 STATIC EFI_MEMORY_DESCRIPTOR* GetMemDesc
71 (
72 OUT UINTN *pSize,
73 OUT UINTN *pItemSize,
74 OUT UINTN *pDescCount
75 )
76 {
77 UINTN Size = 0;
78 UINTN MapKey = 0;
79 UINTN ItemSize = 0;
80 UINTN DescCount = 0;
81 UINT32 Version = 0;
82 EFI_STATUS Status = EFI_SUCCESS;
83 EFI_MEMORY_DESCRIPTOR *pDesc = NULL;
84 EFI_MEMORY_DESCRIPTOR *Curr = NULL;
85
86 Status = gBS->GetMemoryMap(&Size, pDesc, &MapKey, &ItemSize, &Version);
87 if (EFI_BUFFER_TOO_SMALL != Status)
88 {
89 debug("GetMemoryMap: %r", Status);
90 return NULL;
91 }
92
93 Size += SIZE_1KB;
94 pDesc = AllocatePool(Size);
95 if (!pDesc)
96 {
97 debug("AllocatePool: %lu failed", Size);
98 return NULL;
99 }
100
101 ZeroMem(pDesc, Size);
102
103 Status = gBS->GetMemoryMap(&Size, pDesc, &MapKey, &ItemSize, &Version);
104 if (EFI_ERROR(Status))
105 {
106 debug("GetMemoryMap: %r", Status);
107 FreePool(pDesc);
108 return NULL;
109 }
110
111 Curr = pDesc;
112 while (Curr && Curr < (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)pDesc + Size))
113 {
114 DescCount++;
115 Curr = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Curr + ItemSize);
116 }
117
118 *pSize = Size;
119 *pItemSize = ItemSize;
120 *pDescCount = DescCount;
121
122 debug("GetMemoryMap: ItemSize:%lu Count:%lu", ItemSize, DescCount);
123
124 return pDesc;
125 }
126
127 EFI_STATUS FixWindowsMemhole(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine)
128 {
129 UINTN Size = 0;
130 UINTN ItemSize = 0;
131 UINTN DescCount = 0;
132 UINTN TotalMem = 0;
133 EFI_STATUS Status = EFI_SUCCESS;
134 EFI_PHYSICAL_ADDRESS AllocAddr = 0;
135 EFI_MEMORY_DESCRIPTOR *pDescs = NULL;
136 EFI_MEMORY_DESCRIPTOR *Prev = NULL;
137 EFI_MEMORY_DESCRIPTOR *Next = NULL;
138 EFI_MEMORY_DESCRIPTOR *Curr = NULL;
139
140 (VOID)ImageHandle;
141 (VOID)CmdLine;
142
143 pDescs = GetMemDesc(&Size, &ItemSize, &DescCount);
144 if (!pDescs)
145 {
146 return EFI_NOT_FOUND;
147 }
148
149 if (DescCount < 500)
150 {
151 FreePool(pDescs);
152 Printf("There is no need to fixup (%lu)\n", DescCount);
153 return EFI_SUCCESS;
154 }
155
156 Curr = pDescs;
157 while ((UINT8 *)Curr < (UINT8 *)pDescs + Size)
158 {
159 Next = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Curr + ItemSize);
160
161 if (IsMemContiguous(Prev, Curr, Next))
162 {
163 AllocAddr = Curr->PhysicalStart;
164 Status = gBS->AllocatePages(AllocateAddress, EfiBootServicesData, Curr->NumberOfPages, &AllocAddr);
165 if (EFI_SUCCESS == Status)
166 {
167 TotalMem += MultU64x64(SIZE_4KB, Curr->NumberOfPages);
168 }
169 }
170
171 Prev = Curr;
172 Curr = Next;
173 }
174
175 Printf("Fixup Windows mmap issue OK (%lu)\n", TotalMem);
176
177 return EFI_SUCCESS;
178 }
179