]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Csm/LegacyBiosDxe/Ipf/IpfBootSupport.c
b4cc8d253da4a89412524e09740c4bd3f1d4a711
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / LegacyBiosDxe / Ipf / IpfBootSupport.c
1 /** @file
2
3 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
4
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions
7 of the BSD License which accompanies this distribution. The
8 full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "LegacyBiosInterface.h"
17
18 /**
19 Assign drive number to legacy HDD drives prior to booting an EFI
20 aware OS so the OS can access drives without an EFI driver.
21 Note: BBS compliant drives ARE NOT available until this call by
22 either shell or EFI.
23
24 @param This Protocol instance pointer.
25 @param BbsCount Number of BBS_TABLE structures
26 @param BbsTable List BBS entries
27
28 @retval EFI_SUCCESS Drive numbers assigned
29
30 **/
31 EFI_STATUS
32 EFIAPI
33 LegacyBiosPrepareToBootEfi (
34 IN EFI_LEGACY_BIOS_PROTOCOL *This,
35 OUT UINT16 *BbsCount,
36 OUT BBS_TABLE **BbsTable
37 )
38 {
39 //
40 // Shadow All Opion ROM
41 //
42 LegacyBiosShadowAllLegacyOproms (This);
43 return EFI_SUCCESS;
44 }
45
46
47 /**
48 To boot from an unconventional device like parties and/or execute
49 HDD diagnostics.
50
51 @param This Protocol instance pointer.
52 @param Attributes How to interpret the other input parameters
53 @param BbsEntry The 0-based index into the BbsTable for the
54 parent device.
55 @param BeerData Pointer to the 128 bytes of ram BEER data.
56 @param ServiceAreaData Pointer to the 64 bytes of raw Service Area data.
57 The caller must provide a pointer to the specific
58 Service Area and not the start all Service Areas.
59 EFI_INVALID_PARAMETER if error. Does NOT return if no error.
60
61 **/
62 EFI_STATUS
63 EFIAPI
64 LegacyBiosBootUnconventionalDevice (
65 IN EFI_LEGACY_BIOS_PROTOCOL *This,
66 IN UDC_ATTRIBUTES Attributes,
67 IN UINTN BbsEntry,
68 IN VOID *BeerData,
69 IN VOID *ServiceAreaData
70 )
71 {
72 return EFI_INVALID_PARAMETER;
73 }
74
75
76 /**
77 Attempt to legacy boot the BootOption. If the EFI contexted has been
78 compromised this function will not return.
79
80 @param This Protocol instance pointer.
81 @param BbsDevicePath EFI Device Path from BootXXXX variable.
82 @param LoadOptionsSize Size of LoadOption in size.
83 @param LoadOptions LoadOption from BootXXXX variable
84
85 @retval EFI_SUCCESS Removable media not present
86
87 **/
88 EFI_STATUS
89 EFIAPI
90 LegacyBiosLegacyBoot (
91 IN EFI_LEGACY_BIOS_PROTOCOL *This,
92 IN BBS_BBS_DEVICE_PATH *BbsDevicePath,
93 IN UINT32 LoadOptionsSize,
94 IN VOID *LoadOptions
95 )
96 {
97 return EFI_UNSUPPORTED;
98 }
99
100 /**
101 Build the E820 table.
102
103 @param Private Legacy BIOS Instance data
104 @param Size Size of E820 Table
105
106 @retval EFI_SUCCESS It should always work.
107
108 **/
109 EFI_STATUS
110 LegacyBiosBuildE820 (
111 IN LEGACY_BIOS_INSTANCE *Private,
112 OUT UINTN *Size
113 )
114 {
115 *Size = 0;
116 return EFI_SUCCESS;
117 }
118
119 /**
120 Get all BBS info
121
122 @param This Protocol instance pointer.
123 @param HddCount Number of HDD_INFO structures
124 @param HddInfo Onboard IDE controller information
125 @param BbsCount Number of BBS_TABLE structures
126 @param BbsTable List BBS entries
127
128 @retval EFI_SUCCESS Tables returned
129 @retval EFI_NOT_FOUND resource not found
130 @retval EFI_DEVICE_ERROR can not get BBS table
131
132 **/
133 EFI_STATUS
134 EFIAPI
135 LegacyBiosGetBbsInfo (
136 IN EFI_LEGACY_BIOS_PROTOCOL *This,
137 OUT UINT16 *HddCount,
138 OUT HDD_INFO **HddInfo,
139 OUT UINT16 *BbsCount,
140 OUT BBS_TABLE **BbsTable
141 )
142 {
143 return EFI_UNSUPPORTED;
144 }
145
146 /**
147 Fill in the standard BDA for Keyboard LEDs
148
149 @param This Protocol instance pointer.
150 @param Leds Current LED status
151
152 @retval EFI_SUCCESS It should always work.
153
154 **/
155 EFI_STATUS
156 EFIAPI
157 LegacyBiosUpdateKeyboardLedStatus (
158 IN EFI_LEGACY_BIOS_PROTOCOL *This,
159 IN UINT8 Leds
160 )
161 {
162 return EFI_UNSUPPORTED;
163 }
164
165 /**
166 Relocate this image under 4G memory for IPF.
167
168 @param ImageHandle Handle of driver image.
169 @param SystemTable Pointer to system table.
170
171 @retval EFI_SUCCESS Image successfully relocated.
172 @retval EFI_ABORTED Failed to relocate image.
173
174 **/
175 EFI_STATUS
176 RelocateImageUnder4GIfNeeded (
177 IN EFI_HANDLE ImageHandle,
178 IN EFI_SYSTEM_TABLE *SystemTable
179 )
180 {
181 EFI_STATUS Status;
182 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
183 UINTN NumberOfPages;
184 EFI_PHYSICAL_ADDRESS LoadedImageBase;
185 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
186 EFI_PHYSICAL_ADDRESS MemoryAddress;
187 EFI_HANDLE NewImageHandle;
188
189 Status = gBS->HandleProtocol (
190 ImageHandle,
191 &gEfiLoadedImageProtocolGuid,
192 (VOID *) &LoadedImage
193 );
194
195 if (!EFI_ERROR (Status)) {
196 LoadedImageBase = (EFI_PHYSICAL_ADDRESS) (UINTN) LoadedImage->ImageBase;
197 if (LoadedImageBase > 0xffffffff) {
198 NumberOfPages = (UINTN) (DivU64x32(LoadedImage->ImageSize, EFI_PAGE_SIZE) + 1);
199
200 //
201 // Allocate buffer below 4GB here
202 //
203 Status = AllocateLegacyMemory (
204 AllocateMaxAddress,
205 0x7FFFFFFF,
206 NumberOfPages, // do we have to convert this to pages??
207 &MemoryAddress
208 );
209 if (EFI_ERROR (Status)) {
210 return Status;
211 }
212
213 ZeroMem (&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
214 ImageContext.Handle = (VOID *)(UINTN)LoadedImageBase;
215 ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
216
217 //
218 // Get information about the image being loaded
219 //
220 Status = PeCoffLoaderGetImageInfo (&ImageContext);
221 if (EFI_ERROR (Status)) {
222 return Status;
223 }
224 ImageContext.ImageAddress = (PHYSICAL_ADDRESS)MemoryAddress;
225 //
226 // Align buffer on section boundary
227 //
228 ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
229 ImageContext.ImageAddress &= ~((PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
230
231 //
232 // Load the image to our new buffer
233 //
234 Status = PeCoffLoaderLoadImage (&ImageContext);
235 if (EFI_ERROR (Status)) {
236 gBS->FreePages (MemoryAddress, NumberOfPages);
237 return Status;
238 }
239
240 //
241 // Relocate the image in our new buffer
242 //
243 Status = PeCoffLoaderRelocateImage (&ImageContext);
244 if (EFI_ERROR (Status)) {
245 gBS->FreePages (MemoryAddress, NumberOfPages);
246 return Status;
247 }
248
249 //
250 // Create a new handle with gEfiCallerIdGuid to be used as the ImageHandle fore the reloaded image
251 //
252 NewImageHandle = NULL;
253 Status = gBS->InstallProtocolInterface (
254 &NewImageHandle,
255 &gEfiCallerIdGuid,
256 EFI_NATIVE_INTERFACE,
257 NULL
258 );
259
260 //
261 // Flush the instruction cache so the image data is written before we execute it
262 //
263 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
264
265 Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, SystemTable);
266 if (EFI_ERROR (Status)) {
267 gBS->FreePages (MemoryAddress, NumberOfPages);
268 return Status;
269 }
270 //
271 // return error directly the BS will unload this image
272 //
273 return EFI_ABORTED;
274 }
275 }
276 return EFI_SUCCESS;
277 }