mirror of https://github.com/acidanthera/audk.git
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;
|
|
}
|