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 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 } 278