IntelFspWrapperPkg: Refine casting expression result to bigger size
[mirror_edk2.git] / IntelFspWrapperPkg / FspNotifyDxe / LoadBelow4G.c
CommitLineData
00899456
JY
1/** @file\r
2\r
bcee1b9f 3Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
00899456
JY
4\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions\r
7of the BSD License which accompanies this distribution. The\r
8full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <Uefi.h>\r
17#include <Library/BaseLib.h>\r
18#include <Library/UefiDriverEntryPoint.h>\r
19#include <Library/BaseMemoryLib.h>\r
20#include <Library/DebugLib.h>\r
21#include <Library/PeCoffLib.h>\r
22#include <Library/UefiBootServicesTableLib.h>\r
23#include <Library/DxeServicesLib.h>\r
24#include <Library/CacheMaintenanceLib.h>\r
25#include <Library/UefiLib.h>\r
26\r
27/**\r
28 Relocate this image under 4G memory.\r
29\r
30 @param ImageHandle Handle of driver image.\r
31 @param SystemTable Pointer to system table.\r
32\r
33 @retval EFI_SUCCESS Image successfully relocated.\r
34 @retval EFI_ABORTED Failed to relocate image.\r
35\r
36**/\r
37EFI_STATUS\r
38RelocateImageUnder4GIfNeeded (\r
39 IN EFI_HANDLE ImageHandle,\r
40 IN EFI_SYSTEM_TABLE *SystemTable\r
41 )\r
42{\r
43 EFI_STATUS Status;\r
44 UINT8 *Buffer;\r
45 UINTN BufferSize;\r
46 EFI_HANDLE NewImageHandle;\r
47 UINTN Pages;\r
48 EFI_PHYSICAL_ADDRESS FfsBuffer;\r
49 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
50 VOID *Interface;\r
51\r
52 //\r
53 // If it is already <4G, no need do relocate\r
54 //\r
55 if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) {\r
56 return EFI_SUCCESS;\r
57 }\r
58\r
59 //\r
60 // If locate gEfiCallerIdGuid success, it means 2nd entry.\r
61 //\r
62 Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface);\r
63 if (!EFI_ERROR (Status)) {\r
64 DEBUG ((EFI_D_INFO, "FspNotifyDxe - 2nd entry\n"));\r
65 return EFI_SUCCESS;\r
66 }\r
67\r
68 DEBUG ((EFI_D_INFO, "FspNotifyDxe - 1st entry\n"));\r
69\r
70 //\r
71 // Here we install a dummy handle\r
72 //\r
73 NewImageHandle = NULL;\r
74 Status = gBS->InstallProtocolInterface (\r
75 &NewImageHandle,\r
76 &gEfiCallerIdGuid,\r
77 EFI_NATIVE_INTERFACE,\r
78 NULL\r
79 );\r
80 ASSERT_EFI_ERROR (Status);\r
81\r
82 //\r
83 // Reload image itself to <4G mem\r
84 //\r
85 Status = GetSectionFromAnyFv (\r
86 &gEfiCallerIdGuid,\r
87 EFI_SECTION_PE32,\r
88 0,\r
89 (VOID **) &Buffer,\r
90 &BufferSize\r
91 );\r
92 ASSERT_EFI_ERROR (Status);\r
93 ImageContext.Handle = Buffer;\r
94 ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
95 //\r
96 // Get information about the image being loaded\r
97 //\r
98 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
99 ASSERT_EFI_ERROR (Status);\r
100 if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {\r
101 Pages = EFI_SIZE_TO_PAGES ((UINTN) (ImageContext.ImageSize + ImageContext.SectionAlignment));\r
102 } else {\r
103 Pages = EFI_SIZE_TO_PAGES ((UINTN) ImageContext.ImageSize);\r
104 }\r
105 FfsBuffer = 0xFFFFFFFF;\r
106 Status = gBS->AllocatePages (\r
107 AllocateMaxAddress,\r
108 EfiBootServicesCode,\r
109 Pages,\r
110 &FfsBuffer\r
111 );\r
112 ASSERT_EFI_ERROR (Status);\r
113 ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;\r
114 //\r
b9ca25cb 115 // Align buffer on section boundary\r
00899456
JY
116 //\r
117 ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;\r
bcee1b9f 118 ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);\r
00899456
JY
119 //\r
120 // Load the image to our new buffer\r
121 //\r
122 Status = PeCoffLoaderLoadImage (&ImageContext);\r
123 ASSERT_EFI_ERROR (Status);\r
124\r
125 //\r
126 // Relocate the image in our new buffer\r
127 //\r
128 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
129 ASSERT_EFI_ERROR (Status);\r
130\r
131 //\r
132 // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer\r
133 //\r
134 gBS->FreePool (Buffer);\r
135\r
136 //\r
137 // Flush the instruction cache so the image data is written before we execute it\r
138 //\r
139 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
140\r
141 DEBUG ((EFI_D_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint));\r
142 Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, gST);\r
143 if (EFI_ERROR (Status)) {\r
144 DEBUG ((EFI_D_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status));\r
145 gBS->FreePages (FfsBuffer, Pages);\r
146 }\r
147\r
148 //\r
149 // return error to unload >4G copy, if we already relocate itself to <4G.\r
150 //\r
151 return EFI_ALREADY_STARTED;\r
152}\r