1 /******************************************************************************
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
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.
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.
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/>.
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>
39 STATIC BOOLEAN IsMemContiguous
41 IN CONST EFI_MEMORY_DESCRIPTOR
*Prev
,
42 IN CONST EFI_MEMORY_DESCRIPTOR
*Curr
,
43 IN CONST EFI_MEMORY_DESCRIPTOR
*Next
49 if (Prev
== NULL
|| Curr
== NULL
|| Next
== NULL
)
54 if (Prev
->Type
== EfiBootServicesData
&&
55 Curr
->Type
== EfiConventionalMemory
&&
56 Next
->Type
== EfiBootServicesData
)
58 Addr1
= Prev
->PhysicalStart
+ MultU64x64(SIZE_4KB
, Prev
->NumberOfPages
);
59 Addr2
= Curr
->PhysicalStart
+ MultU64x64(SIZE_4KB
, Curr
->NumberOfPages
);
61 if (Addr1
== Curr
->PhysicalStart
&& Addr2
== Next
->PhysicalStart
)
70 STATIC EFI_MEMORY_DESCRIPTOR
* GetMemDesc
82 EFI_STATUS Status
= EFI_SUCCESS
;
83 EFI_MEMORY_DESCRIPTOR
*pDesc
= NULL
;
84 EFI_MEMORY_DESCRIPTOR
*Curr
= NULL
;
86 Status
= gBS
->GetMemoryMap(&Size
, pDesc
, &MapKey
, &ItemSize
, &Version
);
87 if (EFI_BUFFER_TOO_SMALL
!= Status
)
89 debug("GetMemoryMap: %r", Status
);
94 pDesc
= AllocatePool(Size
);
97 debug("AllocatePool: %lu failed", Size
);
101 ZeroMem(pDesc
, Size
);
103 Status
= gBS
->GetMemoryMap(&Size
, pDesc
, &MapKey
, &ItemSize
, &Version
);
104 if (EFI_ERROR(Status
))
106 debug("GetMemoryMap: %r", Status
);
112 while (Curr
&& Curr
< (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)pDesc
+ Size
))
115 Curr
= (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)Curr
+ ItemSize
);
119 *pItemSize
= ItemSize
;
120 *pDescCount
= DescCount
;
122 debug("GetMemoryMap: ItemSize:%lu Count:%lu", ItemSize
, DescCount
);
127 EFI_STATUS
FixWindowsMemhole(IN EFI_HANDLE ImageHandle
, IN CONST CHAR16
*CmdLine
)
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
;
143 pDescs
= GetMemDesc(&Size
, &ItemSize
, &DescCount
);
146 return EFI_NOT_FOUND
;
152 Printf("There is no need to fixup (%lu)\n", DescCount
);
157 while ((UINT8
*)Curr
< (UINT8
*)pDescs
+ Size
)
159 Next
= (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)Curr
+ ItemSize
);
161 if (IsMemContiguous(Prev
, Curr
, Next
))
163 AllocAddr
= Curr
->PhysicalStart
;
164 Status
= gBS
->AllocatePages(AllocateAddress
, EfiBootServicesData
, Curr
->NumberOfPages
, &AllocAddr
);
165 if (EFI_SUCCESS
== Status
)
167 TotalMem
+= MultU64x64(SIZE_4KB
, Curr
->NumberOfPages
);
175 Printf("Fixup Windows mmap issue OK (%lu)\n", TotalMem
);