• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3 Copyright (c) 2006 - 2014, 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
LegacyBiosPrepareToBootEfi(IN EFI_LEGACY_BIOS_PROTOCOL * This,OUT UINT16 * BbsCount,OUT BBS_TABLE ** BbsTable)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
LegacyBiosBootUnconventionalDevice(IN EFI_LEGACY_BIOS_PROTOCOL * This,IN UDC_ATTRIBUTES Attributes,IN UINTN BbsEntry,IN VOID * BeerData,IN VOID * ServiceAreaData)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
LegacyBiosLegacyBoot(IN EFI_LEGACY_BIOS_PROTOCOL * This,IN BBS_BBS_DEVICE_PATH * BbsDevicePath,IN UINT32 LoadOptionsSize,IN VOID * LoadOptions)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
LegacyBiosBuildE820(IN LEGACY_BIOS_INSTANCE * Private,OUT UINTN * Size)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
LegacyBiosGetBbsInfo(IN EFI_LEGACY_BIOS_PROTOCOL * This,OUT UINT16 * HddCount,OUT HDD_INFO ** HddInfo,OUT UINT16 * BbsCount,OUT BBS_TABLE ** BbsTable)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
LegacyBiosUpdateKeyboardLedStatus(IN EFI_LEGACY_BIOS_PROTOCOL * This,IN UINT8 Leds)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
RelocateImageUnder4GIfNeeded(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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 }
278