Update BiosVideo driver to produce GOP protocol but not UgaDraw protocol which is retired from UEFI specification.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7737 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
klu2 2009-03-01 04:47:53 +00:00
parent fd677afe31
commit 0d92cdc200
4 changed files with 1634 additions and 989 deletions

File diff suppressed because it is too large Load Diff

View File

@ -11,15 +11,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
BiosVideo.h
UefiBiosVideo.h
Abstract:
Revision History
--*/
#ifndef _BIOS_UGA_H
#define _BIOS_UGA_H
#ifndef _BIOS_GRAPHICS_OUTPUT_H
#define _BIOS_GRAPHICS_OUTPUT_H
#include <Uefi.h>
@ -34,24 +34,20 @@ Revision History
#include <Protocol/UgaDraw.h>
#include <Protocol/VgaMiniPort.h>
#include <Protocol/Legacy8259.h>
#include <Protocol/EdidActive.h>
#include <Protocol/EdidDiscovered.h>
#include <Protocol/DevicePath.h>
#include <Protocol/LegacyBios.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <IndustryStandard/Pci22.h>
#include "VesaBiosExtensions.h"
//
// Driver Produced Protocol Prototypes
//
//#include EFI_PROTOCOL_DEFINITION (DriverBinding)
//#include EFI_PROTOCOL_DEFINITION (ComponentName)
//#include EFI_PROTOCOL_DEFINITION (ComponentName2)
//#include EFI_PROTOCOL_DEFINITION (UgaDraw)
//#include EFI_PROTOCOL_DEFINITION (VgaMiniPort)
//
// Packed format support: The number of bits reserved for each of the colors and the actual
@ -63,26 +59,29 @@ typedef struct {
} BIOS_VIDEO_COLOR_PLACEMENT;
//
// BIOS UGA Draw Graphical Mode Data
// BIOS Graphics Output Graphical Mode Data
//
typedef struct {
UINT16 VbeModeNumber;
UINT16 BytesPerScanLine;
VOID *LinearFrameBuffer;
UINTN FrameBufferSize;
UINT32 HorizontalResolution;
UINT32 VerticalResolution;
UINT32 ColorDepth;
UINT32 RefreshRate;
UINT32 BitsPerPixel;
BIOS_VIDEO_COLOR_PLACEMENT Red;
BIOS_VIDEO_COLOR_PLACEMENT Green;
BIOS_VIDEO_COLOR_PLACEMENT Blue;
BIOS_VIDEO_COLOR_PLACEMENT Reserved;
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
EFI_PIXEL_BITMASK PixelBitMask;
} BIOS_VIDEO_MODE_DATA;
//
// BIOS UGA Device Structure
// BIOS video child handle private data Structure
//
#define BIOS_VIDEO_DEV_SIGNATURE SIGNATURE_32 ('B', 'V', 'M', 'p')
#define BIOS_VIDEO_DEV_SIGNATURE SIGNATURE_32 ('B', 'V', 'M', 'p')
typedef struct {
UINTN Signature;
@ -92,30 +91,30 @@ typedef struct {
// Consumed Protocols
//
EFI_PCI_IO_PROTOCOL *PciIo;
//EFI_LEGACY_BIOS_THUNK_PROTOCOL *LegacyBios;
EFI_LEGACY_8259_PROTOCOL *Legacy8259;
//
// Produced Protocols
//
EFI_UGA_DRAW_PROTOCOL UgaDraw;
EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput;
EFI_EDID_DISCOVERED_PROTOCOL EdidDiscovered;
EFI_EDID_ACTIVE_PROTOCOL EdidActive;
EFI_VGA_MINI_PORT_PROTOCOL VgaMiniPort;
//
// General fields
//
EFI_EVENT ExitBootServicesEvent;
BOOLEAN VgaCompatible;
BOOLEAN ProduceUgaDraw;
BOOLEAN ProduceGraphicsOutput;
EFI_EVENT ExitBootServicesEvent;
//
// UGA Draw related fields
// Graphics Output Protocol related fields
//
BOOLEAN HardwareNeedsStarting;
UINTN CurrentMode;
UINTN MaxMode;
BIOS_VIDEO_MODE_DATA *ModeData;
UINT8 *LineBuffer;
EFI_UGA_PIXEL *VbeFrameBuffer;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer;
UINT8 *VgaFrameBuffer;
//
@ -125,6 +124,7 @@ typedef struct {
EFI_PHYSICAL_ADDRESS PagesBelow1MB; // Buffer for all VBE Information Blocks
VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK *VbeInformationBlock; // 0x200 bytes. Must be allocated below 1MB
VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK *VbeModeInformationBlock; // 0x100 bytes. Must be allocated below 1MB
VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *VbeEdidDataBlock; // 0x80 bytes. Must be allocated below 1MB
VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *VbeCrtcInformationBlock; // 59 bytes. Must be allocated below 1MB
UINTN VbeSaveRestorePages; // Number of 4KB pages in VbeSaveRestoreBuffer
EFI_PHYSICAL_ADDRESS VbeSaveRestoreBuffer; // Must be allocated below 1MB
@ -134,10 +134,12 @@ typedef struct {
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
} BIOS_VIDEO_DEV;
#define BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS(a) CR (a, BIOS_VIDEO_DEV, UgaDraw, BIOS_VIDEO_DEV_SIGNATURE)
#define BIOS_VIDEO_DEV_FROM_PCI_IO_THIS(a) CR (a, BIOS_VIDEO_DEV, PciIo, BIOS_VIDEO_DEV_SIGNATURE)
#define BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS(a) CR (a, BIOS_VIDEO_DEV, GraphicsOutput, BIOS_VIDEO_DEV_SIGNATURE)
#define BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS(a) CR (a, BIOS_VIDEO_DEV, VgaMiniPort, BIOS_VIDEO_DEV_SIGNATURE)
#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff
//
// Global Variables
//
@ -156,23 +158,21 @@ BiosVideoDriverBindingSupported (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Supported.
Arguments:
Routine Description:
This - Pointer to driver binding protocol
Controller - Controller handle to connect
RemainingDevicePath - A pointer to the remaining portion of a device path
Returns:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
Controller - GC_TODO: add argument description
RemainingDevicePath - GC_TODO: add argument description
Returns:
GC_TODO: add return values
EFI_STATUS - EFI_SUCCESS:This controller can be managed by this driver,
Otherwise, this controller cannot be managed by this driver
--*/
;
@ -184,21 +184,21 @@ BiosVideoDriverBindingStart (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Install UGA Draw Protocol onto VGA device handles
Arguments:
Routine Description:
This - Pointer to driver binding protocol
Controller - Controller handle to connect
RemainingDevicePath - A pointer to the remaining portion of a device path
Returns:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
Controller - GC_TODO: add argument description
RemainingDevicePath - GC_TODO: add argument description
Returns:
GC_TODO: add return values
EFI_STATUS
--*/
;
@ -211,23 +211,22 @@ BiosVideoDriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Stop.
Arguments:
Routine Description:
This - Pointer to driver binding protocol
Controller - Controller handle to connect
NumberOfChilren - Number of children handle created by this driver
ChildHandleBuffer - Buffer containing child handle created
Returns:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
Controller - GC_TODO: add argument description
NumberOfChildren - GC_TODO: add argument description
ChildHandleBuffer - GC_TODO: add argument description
Returns:
GC_TODO: add return values
EFI_SUCCESS - Driver disconnected successfully from controller
EFI_UNSUPPORTED - Cannot find BIOS_VIDEO_DEV structure
--*/
;
@ -239,19 +238,19 @@ BiosVideoCheckForVbe (
BIOS_VIDEO_DEV *BiosVideoPrivate
)
/*++
Routine Description:
Check for VBE device
Arguments:
BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure
Returns:
EFI_SUCCESS - VBE device found
Routine Description:
GC_TODO: Add function description
Arguments:
BiosVideoPrivate - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
@ -260,112 +259,148 @@ BiosVideoCheckForVga (
BIOS_VIDEO_DEV *BiosVideoPrivate
)
/*++
Routine Description:
Check for VGA device
Routine Description:
GC_TODO: Add function description
Arguments:
BiosVideoPrivate - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
;
STATIC
EFI_STATUS
DeRegisterVideoChildHandle (
EFI_DRIVER_BINDING_PROTOCOL *This,
EFI_HANDLE Controller,
EFI_HANDLE Handle
)
/*++
Routine Description:
Deregister an video child handle and free resources
Arguments:
This - Protocol instance pointer.
Controller - Video controller handle
Handle - Video child handle
Returns:
EFI_STATUS
--*/
;
VOID
BiosVideoDeviceReleaseResource (
BIOS_VIDEO_DEV *BiosVideoChildPrivate
)
/*++
Routing Description:
Release resources of a video child device before stopping it.
Arguments:
BiosVideoChildPrivate - Video child device private data structure
Returns:
NONE
---*/
;
//
// BIOS Graphics Output Protocol functions
//
EFI_STATUS
EFIAPI
BiosVideoGraphicsOutputQueryMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo,
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
)
/*++
Routine Description:
Graphics Output protocol interface to get video mode
Arguments:
BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure
This - Protocol instance pointer.
ModeNumber - The mode number to return information on.
Info - Caller allocated buffer that returns information about ModeNumber.
SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.
Returns:
EFI_SUCCESS - Standard VGA device found
--*/
;
//
// BIOS UGA Draw Protocol functions
//
EFI_STATUS
EFIAPI
BiosVideoUgaDrawGetMode (
IN EFI_UGA_DRAW_PROTOCOL *This,
OUT UINT32 *HorizontalResolution,
OUT UINT32 *VerticalResolution,
OUT UINT32 *ColorDepth,
OUT UINT32 *RefreshRate
)
/*++
Routine Description:
UGA protocol interface to get video mode
Arguments:
This - Pointer to UGA draw protocol instance
HorizontalResolution - Horizontal Resolution, in pixels
VerticalResolution - Vertical Resolution, in pixels
ColorDepth - Bit number used to represent color value of a pixel
RefreshRate - Refresh rate, in Hertz
Returns:
EFI_DEVICE_ERROR - Hardware need starting
EFI_INVALID_PARAMETER - Invalid parameter passed in
EFI_SUCCESS - Video mode query successfully
EFI_SUCCESS - Mode information returned.
EFI_BUFFER_TOO_SMALL - The Info buffer was too small.
EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode.
EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
EFI_INVALID_PARAMETER - One of the input args was NULL.
--*/
;
EFI_STATUS
EFIAPI
BiosVideoUgaDrawSetMode (
IN EFI_UGA_DRAW_PROTOCOL *This,
IN UINT32 HorizontalResolution,
IN UINT32 VerticalResolution,
IN UINT32 ColorDepth,
IN UINT32 RefreshRate
BiosVideoGraphicsOutputSetMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This,
IN UINT32 ModeNumber
)
/*++
Routine Description:
UGA draw protocol interface to set video mode
Graphics Output protocol interface to set video mode
Arguments:
Arguments:
This - Protocol instance pointer.
ModeNumber - The mode number to be set.
This - Pointer to UGA draw protocol instance
HorizontalResolution - Horizontal Resolution, in pixels
VerticalResolution - Vertical Resolution, in pixels
ColorDepth - Bit number used to represent color value of a pixel
RefreshRate - Refresh rate, in Hertz
Returns:
EFI_DEVICE_ERROR - Device error
EFI_SUCCESS - Video mode set successfully
EFI_UNSUPPORTED - Cannot support this video mode
Returns:
EFI_SUCCESS - Graphics mode was changed.
EFI_DEVICE_ERROR - The device had an error and could not complete the request.
EFI_UNSUPPORTED - ModeNumber is not supported by this device.
--*/
;
EFI_STATUS
EFIAPI
BiosVideoUgaDrawVbeBlt (
IN EFI_UGA_DRAW_PROTOCOL *This,
IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL
IN EFI_UGA_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta
BiosVideoGraphicsOutputVbeBlt (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta
)
/*++
Routine Description:
UGA draw protocol instance to block transfer for VBE device
Graphics Output protocol instance to block transfer for VBE device
Arguments:
This - Pointer to UGA draw protocol instance
This - Pointer to Graphics Output protocol instance
BltBuffer - The data to transfer to screen
BltOperation - The operation to perform
SourceX - The X coordinate of the source for BltOperation
@ -374,9 +409,9 @@ Arguments:
DestinationY - The Y coordinate of the destination for BltOperation
Width - The width of a rectangle in the blt rectangle in pixels
Height - The height of a rectangle in the blt rectangle in pixels
Delta - Not used for EfiUgaVideoFill and EfiUgaVideoToVideo operation.
Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
If a Delta of 0 is used, the entire BltBuffer will be operated on.
If a subrectangle of the BltBuffer is used, then Delta represents
If a subrectangle of the BltBuffer is used, then Delta represents
the number of bytes in a row of the BltBuffer.
Returns:
@ -389,27 +424,27 @@ Returns:
EFI_STATUS
EFIAPI
BiosVideoUgaDrawVgaBlt (
IN EFI_UGA_DRAW_PROTOCOL *This,
IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL
IN EFI_UGA_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta
BiosVideoGraphicsOutputVgaBlt (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta
)
/*++
Routine Description:
UGA draw protocol instance to block transfer for VGA device
Grahpics Output protocol instance to block transfer for VGA device
Arguments:
This - Pointer to UGA draw protocol instance
This - Pointer to Grahpics Output protocol instance
BltBuffer - The data to transfer to screen
BltOperation - The operation to perform
SourceX - The X coordinate of the source for BltOperation
@ -418,9 +453,9 @@ Arguments:
DestinationY - The Y coordinate of the destination for BltOperation
Width - The width of a rectangle in the blt rectangle in pixels
Height - The height of a rectangle in the blt rectangle in pixels
Delta - Not used for EfiUgaVideoFill and EfiUgaVideoToVideo operation.
Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
If a Delta of 0 is used, the entire BltBuffer will be operated on.
If a subrectangle of the BltBuffer is used, then Delta represents
If a subrectangle of the BltBuffer is used, then Delta represents
the number of bytes in a row of the BltBuffer.
Returns:
@ -508,4 +543,22 @@ BiosVideoIsVga (
#define VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER 0x08
VOID
InitializeBiosIntCaller (
IN BIOS_VIDEO_DEV *BiosDev
);
VOID
InitializeInterruptRedirection (
IN BIOS_VIDEO_DEV *BiosDev
);
BOOLEAN
EFIAPI
LegacyBiosInt86 (
IN BIOS_VIDEO_DEV *BiosDev,
IN UINT8 BiosInt,
IN EFI_IA32_REGISTER_SET *Regs
);
#endif

View File

@ -39,14 +39,18 @@
UefiBootServicesTableLib
BaseMemoryLib
UefiDriverEntryPoint
DevicePathLib
[Sources.common]
BiosVideo.h
BiosVideo.c
ComponentName.c
VesaBiosExtensions.h
LegacyBiosThunk.c
[Protocols]
gEfiPciIoProtocolGuid
gEfiVgaMiniPortProtocolGuid
gEfiLegacy8259ProtocolGuid
gEfiEdidDiscoveredProtocolGuid
gEfiEdidActiveProtocolGuid

View File

@ -0,0 +1,224 @@
#include "BiosVideo.h"
#define EFI_CPU_EFLAGS_IF 0x200
THUNK_CONTEXT mThunkContext;
VOID
InitializeBiosIntCaller (
IN BIOS_VIDEO_DEV *BiosDev
)
{
EFI_STATUS Status;
UINT32 RealModeBufferSize;
UINT32 ExtraStackSize;
EFI_PHYSICAL_ADDRESS LegacyRegionBase;
//
// Get LegacyRegion
//
AsmGetThunk16Properties (&RealModeBufferSize, &ExtraStackSize);
LegacyRegionBase = 0x100000;
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiACPIMemoryNVS,
EFI_SIZE_TO_PAGES(RealModeBufferSize + ExtraStackSize + 200),
&LegacyRegionBase
);
ASSERT_EFI_ERROR (Status);
mThunkContext.RealModeBuffer = (VOID*)(UINTN)LegacyRegionBase;
mThunkContext.RealModeBufferSize = EFI_PAGES_TO_SIZE (RealModeBufferSize);
mThunkContext.ThunkAttributes = 3;
AsmPrepareThunk16(&mThunkContext);
}
VOID
InitializeInterruptRedirection (
IN BIOS_VIDEO_DEV *BiosDev
)
/*++
Routine Description:
Initialize interrupt redirection code and entries, because
IDT Vectors 0x68-0x6f must be redirected to IDT Vectors 0x08-0x0f.
Or the interrupt will lost when we do thunk.
NOTE: We do not reset 8259 vector base, because it will cause pending
interrupt lost.
Arguments:
NONE
Returns:
NONE
--*/
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS LegacyRegionBase;
UINTN LegacyRegionLength;
UINT32 *IdtArray;
UINTN Index;
UINT8 ProtectedModeBaseVector;
UINT32 InterruptRedirectionCode[] = {
0x90CF08CD, // INT8; IRET; NOP
0x90CF09CD, // INT9; IRET; NOP
0x90CF0ACD, // INTA; IRET; NOP
0x90CF0BCD, // INTB; IRET; NOP
0x90CF0CCD, // INTC; IRET; NOP
0x90CF0DCD, // INTD; IRET; NOP
0x90CF0ECD, // INTE; IRET; NOP
0x90CF0FCD // INTF; IRET; NOP
};
//
// Get LegacyRegion
//
LegacyRegionLength = sizeof(InterruptRedirectionCode);
LegacyRegionBase = 0x100000;
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiACPIMemoryNVS,
EFI_SIZE_TO_PAGES(LegacyRegionLength),
&LegacyRegionBase
);
ASSERT_EFI_ERROR (Status);
//
// Copy code to legacy region
//
CopyMem ((VOID *)(UINTN)LegacyRegionBase, InterruptRedirectionCode, sizeof (InterruptRedirectionCode));
//
// Get VectorBase, it should be 0x68
//
Status = BiosDev->Legacy8259->GetVector (BiosDev->Legacy8259, Efi8259Irq0, &ProtectedModeBaseVector);
ASSERT_EFI_ERROR (Status);
//
// Patch IVT 0x68 ~ 0x6f
//
IdtArray = (UINT32 *) 0;
for (Index = 0; Index < 8; Index++) {
IdtArray[ProtectedModeBaseVector + Index] = ((EFI_SEGMENT (LegacyRegionBase + Index * 4)) << 16) | (EFI_OFFSET (LegacyRegionBase + Index * 4));
}
return ;
}
BOOLEAN
EFIAPI
LegacyBiosInt86 (
IN BIOS_VIDEO_DEV *BiosDev,
IN UINT8 BiosInt,
IN EFI_IA32_REGISTER_SET *Regs
)
/*++
Routine Description:
Thunk to 16-bit real mode and execute a software interrupt with a vector
of BiosInt. Regs will contain the 16-bit register context on entry and
exit.
Arguments:
This - Protocol instance pointer.
BiosInt - Processor interrupt vector to invoke
Reg - Register contexted passed into (and returned) from thunk to
16-bit mode
Returns:
FALSE - Thunk completed, and there were no BIOS errors in the target code.
See Regs for status.
TRUE - There was a BIOS erro in the target code.
--*/
{
UINTN Status;
UINTN Eflags;
IA32_REGISTER_SET ThunkRegSet;
BOOLEAN Ret;
UINT16 *Stack16;
Regs->X.Flags.Reserved1 = 1;
Regs->X.Flags.Reserved2 = 0;
Regs->X.Flags.Reserved3 = 0;
Regs->X.Flags.Reserved4 = 0;
Regs->X.Flags.IOPL = 3;
Regs->X.Flags.NT = 0;
Regs->X.Flags.IF = 1;
Regs->X.Flags.TF = 0;
Regs->X.Flags.CF = 0;
ZeroMem (&ThunkRegSet, sizeof (ThunkRegSet));
ThunkRegSet.E.EDI = Regs->E.EDI;
ThunkRegSet.E.ESI = Regs->E.ESI;
ThunkRegSet.E.EBP = Regs->E.EBP;
ThunkRegSet.E.EBX = Regs->E.EBX;
ThunkRegSet.E.EDX = Regs->E.EDX;
ThunkRegSet.E.ECX = Regs->E.ECX;
ThunkRegSet.E.EAX = Regs->E.EAX;
ThunkRegSet.E.DS = Regs->E.DS;
ThunkRegSet.E.ES = Regs->E.ES;
CopyMem (&(ThunkRegSet.E.EFLAGS), &(Regs->E.EFlags), sizeof (UINT32));
//
// The call to Legacy16 is a critical section to EFI
//
Eflags = AsmReadEflags ();
if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {
DisableInterrupts ();
}
//
// Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases.
//
Status = BiosDev->Legacy8259->SetMode (BiosDev->Legacy8259, Efi8259LegacyMode, NULL, NULL);
ASSERT_EFI_ERROR (Status);
Stack16 = (UINT16 *)((UINT8 *) mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize - sizeof (UINT16));
Stack16 -= sizeof (ThunkRegSet.E.EFLAGS) / sizeof (UINT16);
CopyMem (Stack16, &ThunkRegSet.E.EFLAGS, sizeof (ThunkRegSet.E.EFLAGS));
ThunkRegSet.E.SS = (UINT16) (((UINTN) Stack16 >> 16) << 12);
ThunkRegSet.E.ESP = (UINT16) (UINTN) Stack16;
ThunkRegSet.E.Eip = (UINT16)((UINT32 *)NULL)[BiosInt];
ThunkRegSet.E.CS = (UINT16)(((UINT32 *)NULL)[BiosInt] >> 16);
mThunkContext.RealModeState = &ThunkRegSet;
AsmThunk16 (&mThunkContext);
//
// Restore protected mode interrupt state
//
Status = BiosDev->Legacy8259->SetMode (BiosDev->Legacy8259, Efi8259ProtectedMode, NULL, NULL);
ASSERT_EFI_ERROR (Status);
//
// End critical section
//
if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {
EnableInterrupts ();
}
Regs->E.EDI = ThunkRegSet.E.EDI;
Regs->E.ESI = ThunkRegSet.E.ESI;
Regs->E.EBP = ThunkRegSet.E.EBP;
Regs->E.EBX = ThunkRegSet.E.EBX;
Regs->E.EDX = ThunkRegSet.E.EDX;
Regs->E.ECX = ThunkRegSet.E.ECX;
Regs->E.EAX = ThunkRegSet.E.EAX;
Regs->E.SS = ThunkRegSet.E.SS;
Regs->E.CS = ThunkRegSet.E.CS;
Regs->E.DS = ThunkRegSet.E.DS;
Regs->E.ES = ThunkRegSet.E.ES;
CopyMem (&(Regs->E.EFlags), &(ThunkRegSet.E.EFLAGS), sizeof (UINT32));
Ret = (BOOLEAN) (Regs->E.EFlags.CF == 1);
return Ret;
}