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: Module Name:
BiosVideo.h UefiBiosVideo.h
Abstract: Abstract:
Revision History Revision History
--*/ --*/
#ifndef _BIOS_UGA_H #ifndef _BIOS_GRAPHICS_OUTPUT_H
#define _BIOS_UGA_H #define _BIOS_GRAPHICS_OUTPUT_H
#include <Uefi.h> #include <Uefi.h>
@ -34,24 +34,20 @@ Revision History
#include <Protocol/UgaDraw.h> #include <Protocol/UgaDraw.h>
#include <Protocol/VgaMiniPort.h> #include <Protocol/VgaMiniPort.h>
#include <Protocol/Legacy8259.h> #include <Protocol/Legacy8259.h>
#include <Protocol/EdidActive.h>
#include <Protocol/EdidDiscovered.h>
#include <Protocol/DevicePath.h>
#include <Protocol/LegacyBios.h> #include <Protocol/LegacyBios.h>
#include <Library/UefiLib.h> #include <Library/UefiLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h> #include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <IndustryStandard/Pci22.h> #include <IndustryStandard/Pci22.h>
#include "VesaBiosExtensions.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 // 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_VIDEO_COLOR_PLACEMENT;
// //
// BIOS UGA Draw Graphical Mode Data // BIOS Graphics Output Graphical Mode Data
// //
typedef struct { typedef struct {
UINT16 VbeModeNumber; UINT16 VbeModeNumber;
UINT16 BytesPerScanLine; UINT16 BytesPerScanLine;
VOID *LinearFrameBuffer; VOID *LinearFrameBuffer;
UINTN FrameBufferSize;
UINT32 HorizontalResolution; UINT32 HorizontalResolution;
UINT32 VerticalResolution; UINT32 VerticalResolution;
UINT32 ColorDepth;
UINT32 RefreshRate; UINT32 RefreshRate;
UINT32 BitsPerPixel; UINT32 BitsPerPixel;
BIOS_VIDEO_COLOR_PLACEMENT Red; BIOS_VIDEO_COLOR_PLACEMENT Red;
BIOS_VIDEO_COLOR_PLACEMENT Green; BIOS_VIDEO_COLOR_PLACEMENT Green;
BIOS_VIDEO_COLOR_PLACEMENT Blue; BIOS_VIDEO_COLOR_PLACEMENT Blue;
BIOS_VIDEO_COLOR_PLACEMENT Reserved;
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
EFI_PIXEL_BITMASK PixelBitMask;
} BIOS_VIDEO_MODE_DATA; } 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 { typedef struct {
UINTN Signature; UINTN Signature;
@ -92,30 +91,30 @@ typedef struct {
// Consumed Protocols // Consumed Protocols
// //
EFI_PCI_IO_PROTOCOL *PciIo; EFI_PCI_IO_PROTOCOL *PciIo;
//EFI_LEGACY_BIOS_THUNK_PROTOCOL *LegacyBios; EFI_LEGACY_8259_PROTOCOL *Legacy8259;
// //
// Produced Protocols // 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; EFI_VGA_MINI_PORT_PROTOCOL VgaMiniPort;
// //
// General fields // General fields
// //
EFI_EVENT ExitBootServicesEvent;
BOOLEAN VgaCompatible; BOOLEAN VgaCompatible;
BOOLEAN ProduceUgaDraw; BOOLEAN ProduceGraphicsOutput;
EFI_EVENT ExitBootServicesEvent;
// //
// UGA Draw related fields // Graphics Output Protocol related fields
// //
BOOLEAN HardwareNeedsStarting; BOOLEAN HardwareNeedsStarting;
UINTN CurrentMode;
UINTN MaxMode;
BIOS_VIDEO_MODE_DATA *ModeData; BIOS_VIDEO_MODE_DATA *ModeData;
UINT8 *LineBuffer; UINT8 *LineBuffer;
EFI_UGA_PIXEL *VbeFrameBuffer; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer;
UINT8 *VgaFrameBuffer; UINT8 *VgaFrameBuffer;
// //
@ -125,6 +124,7 @@ typedef struct {
EFI_PHYSICAL_ADDRESS PagesBelow1MB; // Buffer for all VBE Information Blocks 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_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_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 VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *VbeCrtcInformationBlock; // 59 bytes. Must be allocated below 1MB
UINTN VbeSaveRestorePages; // Number of 4KB pages in VbeSaveRestoreBuffer UINTN VbeSaveRestorePages; // Number of 4KB pages in VbeSaveRestoreBuffer
EFI_PHYSICAL_ADDRESS VbeSaveRestoreBuffer; // Must be allocated below 1MB EFI_PHYSICAL_ADDRESS VbeSaveRestoreBuffer; // Must be allocated below 1MB
@ -134,10 +134,12 @@ typedef struct {
EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePath;
} BIOS_VIDEO_DEV; } 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 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 // Global Variables
// //
@ -157,21 +159,19 @@ BiosVideoDriverBindingSupported (
) )
/*++ /*++
Routine Description: Routine Description:
Supported. GC_TODO: Add function description
Arguments: Arguments:
This - Pointer to driver binding protocol This - GC_TODO: add argument description
Controller - Controller handle to connect Controller - GC_TODO: add argument description
RemainingDevicePath - A pointer to the remaining portion of a device path RemainingDevicePath - GC_TODO: add argument description
Returns:
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
--*/ --*/
; ;
@ -185,19 +185,19 @@ BiosVideoDriverBindingStart (
) )
/*++ /*++
Routine Description: Routine Description:
Install UGA Draw Protocol onto VGA device handles GC_TODO: Add function description
Arguments: Arguments:
This - Pointer to driver binding protocol This - GC_TODO: add argument description
Controller - Controller handle to connect Controller - GC_TODO: add argument description
RemainingDevicePath - A pointer to the remaining portion of a device path RemainingDevicePath - GC_TODO: add argument description
Returns: Returns:
EFI_STATUS GC_TODO: add return values
--*/ --*/
; ;
@ -212,21 +212,20 @@ BiosVideoDriverBindingStop (
) )
/*++ /*++
Routine Description: Routine Description:
Stop. GC_TODO: Add function description
Arguments: Arguments:
This - Pointer to driver binding protocol This - GC_TODO: add argument description
Controller - Controller handle to connect Controller - GC_TODO: add argument description
NumberOfChilren - Number of children handle created by this driver NumberOfChildren - GC_TODO: add argument description
ChildHandleBuffer - Buffer containing child handle created ChildHandleBuffer - GC_TODO: add argument description
Returns: Returns:
EFI_SUCCESS - Driver disconnected successfully from controller GC_TODO: add return values
EFI_UNSUPPORTED - Cannot find BIOS_VIDEO_DEV structure
--*/ --*/
; ;
@ -240,17 +239,17 @@ BiosVideoCheckForVbe (
) )
/*++ /*++
Routine Description: Routine Description:
Check for VBE device GC_TODO: Add function description
Arguments: Arguments:
BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure BiosVideoPrivate - GC_TODO: add argument description
Returns: Returns:
EFI_SUCCESS - VBE device found GC_TODO: add return values
--*/ --*/
; ;
@ -261,111 +260,147 @@ BiosVideoCheckForVga (
) )
/*++ /*++
Routine Description: Routine Description:
Check for VGA device 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: Arguments:
This - Protocol instance pointer.
BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure 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: Returns:
EFI_SUCCESS - Mode information returned.
EFI_SUCCESS - Standard VGA device found 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.
//
// 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_STATUS EFI_STATUS
EFIAPI EFIAPI
BiosVideoUgaDrawSetMode ( BiosVideoGraphicsOutputSetMode (
IN EFI_UGA_DRAW_PROTOCOL *This, IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This,
IN UINT32 HorizontalResolution, IN UINT32 ModeNumber
IN UINT32 VerticalResolution,
IN UINT32 ColorDepth,
IN UINT32 RefreshRate
) )
/*++ /*++
Routine Description: 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 Returns:
HorizontalResolution - Horizontal Resolution, in pixels EFI_SUCCESS - Graphics mode was changed.
VerticalResolution - Vertical Resolution, in pixels EFI_DEVICE_ERROR - The device had an error and could not complete the request.
ColorDepth - Bit number used to represent color value of a pixel EFI_UNSUPPORTED - ModeNumber is not supported by this device.
RefreshRate - Refresh rate, in Hertz
Returns:
EFI_DEVICE_ERROR - Device error
EFI_SUCCESS - Video mode set successfully
EFI_UNSUPPORTED - Cannot support this video mode
--*/ --*/
; ;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
BiosVideoUgaDrawVbeBlt ( BiosVideoGraphicsOutputVbeBlt (
IN EFI_UGA_DRAW_PROTOCOL *This, IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
IN EFI_UGA_BLT_OPERATION BltOperation, IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX, IN UINTN SourceX,
IN UINTN SourceY, IN UINTN SourceY,
IN UINTN DestinationX, IN UINTN DestinationX,
IN UINTN DestinationY, IN UINTN DestinationY,
IN UINTN Width, IN UINTN Width,
IN UINTN Height, IN UINTN Height,
IN UINTN Delta IN UINTN Delta
) )
/*++ /*++
Routine Description: Routine Description:
UGA draw protocol instance to block transfer for VBE device Graphics Output protocol instance to block transfer for VBE device
Arguments: Arguments:
This - Pointer to UGA draw protocol instance This - Pointer to Graphics Output protocol instance
BltBuffer - The data to transfer to screen BltBuffer - The data to transfer to screen
BltOperation - The operation to perform BltOperation - The operation to perform
SourceX - The X coordinate of the source for BltOperation SourceX - The X coordinate of the source for BltOperation
@ -374,7 +409,7 @@ Arguments:
DestinationY - The Y coordinate of the destination for BltOperation DestinationY - The Y coordinate of the destination for BltOperation
Width - The width of a rectangle in the blt rectangle in pixels Width - The width of a rectangle in the blt rectangle in pixels
Height - The height 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 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. the number of bytes in a row of the BltBuffer.
@ -389,27 +424,27 @@ Returns:
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
BiosVideoUgaDrawVgaBlt ( BiosVideoGraphicsOutputVgaBlt (
IN EFI_UGA_DRAW_PROTOCOL *This, IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
IN EFI_UGA_BLT_OPERATION BltOperation, IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX, IN UINTN SourceX,
IN UINTN SourceY, IN UINTN SourceY,
IN UINTN DestinationX, IN UINTN DestinationX,
IN UINTN DestinationY, IN UINTN DestinationY,
IN UINTN Width, IN UINTN Width,
IN UINTN Height, IN UINTN Height,
IN UINTN Delta IN UINTN Delta
) )
/*++ /*++
Routine Description: Routine Description:
UGA draw protocol instance to block transfer for VGA device Grahpics Output protocol instance to block transfer for VGA device
Arguments: Arguments:
This - Pointer to UGA draw protocol instance This - Pointer to Grahpics Output protocol instance
BltBuffer - The data to transfer to screen BltBuffer - The data to transfer to screen
BltOperation - The operation to perform BltOperation - The operation to perform
SourceX - The X coordinate of the source for BltOperation SourceX - The X coordinate of the source for BltOperation
@ -418,7 +453,7 @@ Arguments:
DestinationY - The Y coordinate of the destination for BltOperation DestinationY - The Y coordinate of the destination for BltOperation
Width - The width of a rectangle in the blt rectangle in pixels Width - The width of a rectangle in the blt rectangle in pixels
Height - The height 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 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. the number of bytes in a row of the BltBuffer.
@ -508,4 +543,22 @@ BiosVideoIsVga (
#define VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER 0x08 #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 #endif

View File

@ -39,14 +39,18 @@
UefiBootServicesTableLib UefiBootServicesTableLib
BaseMemoryLib BaseMemoryLib
UefiDriverEntryPoint UefiDriverEntryPoint
DevicePathLib
[Sources.common] [Sources.common]
BiosVideo.h BiosVideo.h
BiosVideo.c BiosVideo.c
ComponentName.c ComponentName.c
VesaBiosExtensions.h VesaBiosExtensions.h
LegacyBiosThunk.c
[Protocols] [Protocols]
gEfiPciIoProtocolGuid gEfiPciIoProtocolGuid
gEfiVgaMiniPortProtocolGuid gEfiVgaMiniPortProtocolGuid
gEfiLegacy8259ProtocolGuid 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;
}