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