]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / IntelFsp2WrapperPkg / FspWrapperNotifyDxe / LoadBelow4G.c
CommitLineData
cf1d4549
JY
1/** @file\r
2\r
d953f4f1 3Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
cf1d4549 4\r
512e23a3 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
cf1d4549
JY
6\r
7**/\r
8\r
9#include <Uefi.h>\r
10#include <Library/BaseLib.h>\r
11#include <Library/UefiDriverEntryPoint.h>\r
12#include <Library/BaseMemoryLib.h>\r
13#include <Library/DebugLib.h>\r
14#include <Library/PeCoffLib.h>\r
15#include <Library/UefiBootServicesTableLib.h>\r
16#include <Library/DxeServicesLib.h>\r
17#include <Library/CacheMaintenanceLib.h>\r
18#include <Library/UefiLib.h>\r
19\r
20/**\r
21 Relocate this image under 4G memory.\r
22\r
23 @param ImageHandle Handle of driver image.\r
24 @param SystemTable Pointer to system table.\r
25\r
26 @retval EFI_SUCCESS Image successfully relocated.\r
27 @retval EFI_ABORTED Failed to relocate image.\r
28\r
29**/\r
30EFI_STATUS\r
31RelocateImageUnder4GIfNeeded (\r
7c7184e2
MK
32 IN EFI_HANDLE ImageHandle,\r
33 IN EFI_SYSTEM_TABLE *SystemTable\r
cf1d4549
JY
34 )\r
35{\r
7c7184e2
MK
36 EFI_STATUS Status;\r
37 UINT8 *Buffer;\r
38 UINTN BufferSize;\r
39 EFI_HANDLE NewImageHandle;\r
40 UINTN Pages;\r
41 EFI_PHYSICAL_ADDRESS FfsBuffer;\r
42 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
43 VOID *Interface;\r
cf1d4549
JY
44\r
45 //\r
46 // If it is already <4G, no need do relocate\r
47 //\r
48 if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) {\r
49 return EFI_SUCCESS;\r
50 }\r
51\r
52 //\r
53 // If locate gEfiCallerIdGuid success, it means 2nd entry.\r
54 //\r
55 Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface);\r
56 if (!EFI_ERROR (Status)) {\r
57 DEBUG ((DEBUG_INFO, "FspNotifyDxe - 2nd entry\n"));\r
58 return EFI_SUCCESS;\r
59 }\r
60\r
61 DEBUG ((DEBUG_INFO, "FspNotifyDxe - 1st entry\n"));\r
62\r
63 //\r
64 // Here we install a dummy handle\r
65 //\r
66 NewImageHandle = NULL;\r
7c7184e2
MK
67 Status = gBS->InstallProtocolInterface (\r
68 &NewImageHandle,\r
69 &gEfiCallerIdGuid,\r
70 EFI_NATIVE_INTERFACE,\r
71 NULL\r
72 );\r
cf1d4549
JY
73 ASSERT_EFI_ERROR (Status);\r
74\r
75 //\r
76 // Reload image itself to <4G mem\r
77 //\r
7c7184e2 78 Status = GetSectionFromAnyFv (\r
cf1d4549
JY
79 &gEfiCallerIdGuid,\r
80 EFI_SECTION_PE32,\r
81 0,\r
7c7184e2 82 (VOID **)&Buffer,\r
cf1d4549
JY
83 &BufferSize\r
84 );\r
85 ASSERT_EFI_ERROR (Status);\r
86 ImageContext.Handle = Buffer;\r
87 ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
88 //\r
89 // Get information about the image being loaded\r
90 //\r
91 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
92 ASSERT_EFI_ERROR (Status);\r
93 if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {\r
7c7184e2 94 Pages = EFI_SIZE_TO_PAGES ((UINTN)(ImageContext.ImageSize + ImageContext.SectionAlignment));\r
cf1d4549 95 } else {\r
7c7184e2 96 Pages = EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize);\r
cf1d4549 97 }\r
7c7184e2 98\r
cf1d4549 99 FfsBuffer = 0xFFFFFFFF;\r
7c7184e2
MK
100 Status = gBS->AllocatePages (\r
101 AllocateMaxAddress,\r
102 EfiBootServicesCode,\r
103 Pages,\r
104 &FfsBuffer\r
105 );\r
cf1d4549
JY
106 ASSERT_EFI_ERROR (Status);\r
107 ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;\r
108 //\r
0bfb9ee8 109 // Align buffer on section boundary\r
cf1d4549
JY
110 //\r
111 ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;\r
d953f4f1 112 ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);\r
cf1d4549
JY
113 //\r
114 // Load the image to our new buffer\r
115 //\r
116 Status = PeCoffLoaderLoadImage (&ImageContext);\r
117 ASSERT_EFI_ERROR (Status);\r
118\r
119 //\r
120 // Relocate the image in our new buffer\r
121 //\r
122 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
123 ASSERT_EFI_ERROR (Status);\r
124\r
125 //\r
126 // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer\r
127 //\r
128 gBS->FreePool (Buffer);\r
129\r
130 //\r
131 // Flush the instruction cache so the image data is written before we execute it\r
132 //\r
133 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
134\r
135 DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint));\r
7c7184e2 136 Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint))(NewImageHandle, gST);\r
cf1d4549
JY
137 if (EFI_ERROR (Status)) {\r
138 DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status));\r
139 gBS->FreePages (FfsBuffer, Pages);\r
140 }\r
141\r
142 //\r
143 // return error to unload >4G copy, if we already relocate itself to <4G.\r
144 //\r
145 return EFI_ALREADY_STARTED;\r
146}\r