Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Eric Dong <Eric.Dong@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15778 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			278 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			278 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| 
 | |
| Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
 | |
| 
 | |
| This program and the accompanying materials
 | |
| are licensed and made available under the terms and conditions
 | |
| of the BSD License which accompanies this distribution.  The
 | |
| full text of the license may be found at
 | |
| http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "LegacyBiosInterface.h"
 | |
| 
 | |
| /**
 | |
|   Assign drive number to legacy HDD drives prior to booting an EFI
 | |
|   aware OS so the OS can access drives without an EFI driver.
 | |
|   Note: BBS compliant drives ARE NOT available until this call by
 | |
|   either shell or EFI.
 | |
| 
 | |
|   @param  This                    Protocol instance pointer.
 | |
|   @param  BbsCount                Number of BBS_TABLE structures
 | |
|   @param  BbsTable                List BBS entries
 | |
| 
 | |
|   @retval EFI_SUCCESS             Drive numbers assigned
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| LegacyBiosPrepareToBootEfi (
 | |
|   IN EFI_LEGACY_BIOS_PROTOCOL         *This,
 | |
|   OUT UINT16                          *BbsCount,
 | |
|   OUT BBS_TABLE                       **BbsTable
 | |
|   )
 | |
| {
 | |
|   //
 | |
|   // Shadow All Opion ROM
 | |
|   //
 | |
|   LegacyBiosShadowAllLegacyOproms (This);
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   To boot from an unconventional device like parties and/or execute
 | |
|   HDD diagnostics.
 | |
| 
 | |
|   @param  This                    Protocol instance pointer.
 | |
|   @param  Attributes              How to interpret the other input parameters
 | |
|   @param  BbsEntry                The 0-based index into the BbsTable for the
 | |
|                                   parent  device.
 | |
|   @param  BeerData                Pointer to the 128 bytes of ram BEER data.
 | |
|   @param  ServiceAreaData         Pointer to the 64 bytes of raw Service Area data.
 | |
|                                   The caller must provide a pointer to the specific
 | |
|                                   Service Area and not the start all Service Areas.
 | |
|  EFI_INVALID_PARAMETER if error. Does NOT return if no error.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| LegacyBiosBootUnconventionalDevice (
 | |
|   IN EFI_LEGACY_BIOS_PROTOCOL         *This,
 | |
|   IN UDC_ATTRIBUTES                   Attributes,
 | |
|   IN UINTN                            BbsEntry,
 | |
|   IN VOID                             *BeerData,
 | |
|   IN VOID                             *ServiceAreaData
 | |
|   )
 | |
| {
 | |
|   return EFI_INVALID_PARAMETER;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Attempt to legacy boot the BootOption. If the EFI contexted has been
 | |
|   compromised this function will not return.
 | |
| 
 | |
|   @param  This                    Protocol instance pointer.
 | |
|   @param  BbsDevicePath           EFI Device Path from BootXXXX variable.
 | |
|   @param  LoadOptionsSize         Size of LoadOption in size.
 | |
|   @param  LoadOptions             LoadOption from BootXXXX variable
 | |
| 
 | |
|   @retval EFI_SUCCESS             Removable media not present
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| LegacyBiosLegacyBoot (
 | |
|   IN EFI_LEGACY_BIOS_PROTOCOL           *This,
 | |
|   IN  BBS_BBS_DEVICE_PATH               *BbsDevicePath,
 | |
|   IN  UINT32                            LoadOptionsSize,
 | |
|   IN  VOID                              *LoadOptions
 | |
|   )
 | |
| {
 | |
|   return EFI_UNSUPPORTED;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Build the E820 table.
 | |
| 
 | |
|   @param  Private  Legacy BIOS Instance data
 | |
|   @param  Size     Size of E820 Table
 | |
| 
 | |
|   @retval EFI_SUCCESS It should always work.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| LegacyBiosBuildE820 (
 | |
|   IN  LEGACY_BIOS_INSTANCE    *Private,
 | |
|   OUT UINTN                   *Size
 | |
|   )
 | |
| {
 | |
|   *Size = 0;
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get all BBS info
 | |
| 
 | |
|   @param  This                    Protocol instance pointer.
 | |
|   @param  HddCount                Number of HDD_INFO structures
 | |
|   @param  HddInfo                 Onboard IDE controller information
 | |
|   @param  BbsCount                Number of BBS_TABLE structures
 | |
|   @param  BbsTable                List BBS entries
 | |
| 
 | |
|   @retval EFI_SUCCESS             Tables returned
 | |
|   @retval EFI_NOT_FOUND           resource not found
 | |
|   @retval EFI_DEVICE_ERROR        can not get BBS table
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| LegacyBiosGetBbsInfo (
 | |
|   IN EFI_LEGACY_BIOS_PROTOCOL         *This,
 | |
|   OUT UINT16                          *HddCount,
 | |
|   OUT HDD_INFO                        **HddInfo,
 | |
|   OUT UINT16                          *BbsCount,
 | |
|   OUT BBS_TABLE                       **BbsTable
 | |
|   )
 | |
| {
 | |
|   return EFI_UNSUPPORTED;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Fill in the standard BDA for Keyboard LEDs
 | |
| 
 | |
|   @param  This         Protocol instance pointer.
 | |
|   @param  Leds         Current LED status
 | |
| 
 | |
|   @retval EFI_SUCCESS  It should always work.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| LegacyBiosUpdateKeyboardLedStatus (
 | |
|   IN EFI_LEGACY_BIOS_PROTOCOL           *This,
 | |
|   IN  UINT8                             Leds
 | |
|   )
 | |
| {
 | |
|   return EFI_UNSUPPORTED;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Relocate this image under 4G memory for IPF.
 | |
| 
 | |
|   @param  ImageHandle  Handle of driver image.
 | |
|   @param  SystemTable  Pointer to system table.
 | |
| 
 | |
|   @retval EFI_SUCCESS  Image successfully relocated.
 | |
|   @retval EFI_ABORTED  Failed to relocate image.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| RelocateImageUnder4GIfNeeded (
 | |
|   IN EFI_HANDLE           ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE     *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                         Status;
 | |
|   EFI_LOADED_IMAGE_PROTOCOL          *LoadedImage;
 | |
|   UINTN                              NumberOfPages;
 | |
|   EFI_PHYSICAL_ADDRESS               LoadedImageBase;
 | |
|   PE_COFF_LOADER_IMAGE_CONTEXT       ImageContext;
 | |
|   EFI_PHYSICAL_ADDRESS               MemoryAddress;
 | |
|   EFI_HANDLE                         NewImageHandle;
 | |
| 
 | |
|   Status = gBS->HandleProtocol (
 | |
|                     ImageHandle,
 | |
|                     &gEfiLoadedImageProtocolGuid,
 | |
|                     (VOID *) &LoadedImage
 | |
|                     );
 | |
| 
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     LoadedImageBase = (EFI_PHYSICAL_ADDRESS) (UINTN) LoadedImage->ImageBase;
 | |
|     if (LoadedImageBase > 0xffffffff) {
 | |
|       NumberOfPages = (UINTN) (DivU64x32(LoadedImage->ImageSize, EFI_PAGE_SIZE) + 1);
 | |
| 
 | |
|       //
 | |
|       // Allocate buffer below 4GB here
 | |
|       //
 | |
|       Status = AllocateLegacyMemory (
 | |
|                 AllocateMaxAddress,
 | |
|                 0x7FFFFFFF,
 | |
|                 NumberOfPages,  // do we have to convert this to pages??
 | |
|                 &MemoryAddress
 | |
|                 );
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       ZeroMem (&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
 | |
|       ImageContext.Handle    = (VOID *)(UINTN)LoadedImageBase;
 | |
|       ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
 | |
| 
 | |
|       //
 | |
|       // Get information about the image being loaded
 | |
|       //
 | |
|       Status = PeCoffLoaderGetImageInfo (&ImageContext);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         return Status;
 | |
|       }
 | |
|       ImageContext.ImageAddress = (PHYSICAL_ADDRESS)MemoryAddress;
 | |
|       //
 | |
|       // Align buffer on section boundry
 | |
|       //
 | |
|       ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
 | |
|      ImageContext.ImageAddress &= ~((PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
 | |
| 
 | |
|       //
 | |
|       // Load the image to our new buffer
 | |
|       //
 | |
|       Status = PeCoffLoaderLoadImage (&ImageContext);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         gBS->FreePages (MemoryAddress, NumberOfPages);
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       // Relocate the image in our new buffer
 | |
|       //
 | |
|       Status = PeCoffLoaderRelocateImage (&ImageContext);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         gBS->FreePages (MemoryAddress, NumberOfPages);
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       // Create a new handle with gEfiCallerIdGuid to be used as the ImageHandle fore the reloaded image
 | |
|       // 
 | |
|       NewImageHandle = NULL;
 | |
|       Status = gBS->InstallProtocolInterface (
 | |
|                       &NewImageHandle,
 | |
|                       &gEfiCallerIdGuid,
 | |
|                       EFI_NATIVE_INTERFACE,
 | |
|                       NULL
 | |
|                       );
 | |
| 
 | |
|       //
 | |
|       // Flush the instruction cache so the image data is written before we execute it
 | |
|       //
 | |
|       InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
 | |
| 
 | |
|       Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, SystemTable);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         gBS->FreePages (MemoryAddress, NumberOfPages);
 | |
|         return Status;
 | |
|       }
 | |
|       //
 | |
|       // return error directly the BS will unload this image
 | |
|       //
 | |
|       return EFI_ABORTED;
 | |
|     }
 | |
|   }
 | |
|   return EFI_SUCCESS;
 | |
| }
 |