Module Name:\r
\r
BiosVideo.c\r
- \r
+\r
Abstract:\r
\r
ConsoleOut Routines that speak VGA.\r
\r
#include "BiosVideo.h"\r
\r
-\r
//\r
// EFI Driver Binding Protocol Instance\r
//\r
\r
UINT8 mVgaBitMaskTable[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };\r
\r
-THUNK_CONTEXT mThunkContext;\r
-\r
-EFI_LEGACY_8259_PROTOCOL *mLegacy8259 = NULL;\r
-\r
-#define EFI_CPU_EFLAGS_IF 0x200\r
-\r
-EFI_UGA_PIXEL mVgaColorToUgaColor[] = {\r
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL mVgaColorToGraphicsOutputColor[] = {\r
{\r
0x00,\r
0x00,\r
}\r
};\r
\r
+//\r
+// Standard timing defined by VESA EDID\r
+//\r
+VESA_BIOS_EXTENSIONS_EDID_TIMING mEstablishedEdidTiming[] = {\r
+ //\r
+ // Established Timing I\r
+ //\r
+ {800, 600, 60},\r
+ {800, 600, 56},\r
+ {640, 480, 75},\r
+ {640, 480, 72},\r
+ {640, 480, 67},\r
+ {640, 480, 60},\r
+ {720, 400, 88},\r
+ {720, 400, 70},\r
+ //\r
+ // Established Timing II\r
+ //\r
+ {1280, 1024, 75},\r
+ {1024, 768, 75},\r
+ {1024, 768, 70},\r
+ {1024, 768, 60},\r
+ {1024, 768, 87},\r
+ {832, 624, 75},\r
+ {800, 600, 75},\r
+ {800, 600, 72},\r
+ //\r
+ // Established Timing III\r
+ //\r
+ {1152, 870, 75}\r
+};\r
+\r
+EFI_STATUS\r
+BiosVideoChildHandleInstall (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ParentHandle,\r
+ IN EFI_PCI_IO_PROTOCOL *ParentPciIo,\r
+ IN EFI_LEGACY_8259_PROTOCOL *ParentLegacy8259,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+BiosVideoChildHandleUninstall (\r
+ EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ EFI_HANDLE Controller,\r
+ EFI_HANDLE Handle\r
+ )\r
+;\r
+\r
VOID\r
-InitializeBiosIntCaller (\r
- VOID\r
- );\r
- \r
-VOID\r
-InitializeInterruptRedirection (\r
- VOID\r
- );\r
- \r
-BOOLEAN\r
-EFIAPI\r
-LegacyBiosInt86 (\r
- IN UINT8 BiosInt,\r
- IN EFI_IA32_REGISTER_SET *Regs\r
- );\r
- \r
+BiosVideoDeviceReleaseResource (\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate\r
+ )\r
+;\r
+\r
EFI_STATUS\r
EFIAPI\r
BiosVideoDriverEntryPoint (\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
/*++\r
- \r
+\r
Routine Description:\r
- \r
+\r
Driver Entry Point.\r
- \r
+\r
Arguments:\r
- \r
+\r
ImageHandle - Handle of driver image.\r
SystemTable - Pointer to system table.\r
- \r
+\r
Returns:\r
- \r
+\r
EFI_STATUS\r
- \r
+\r
--*/\r
{\r
EFI_STATUS Status;\r
&gBiosVideoComponentName,\r
&gBiosVideoComponentName2\r
);\r
-\r
+ \r
return Status;\r
}\r
\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
/*++\r
- \r
+\r
Routine Description:\r
\r
Supported.\r
- \r
+\r
Arguments:\r
\r
This - Pointer to driver binding protocol\r
Controller - Controller handle to connect\r
RemainingDevicePath - A pointer to the remaining portion of a device path\r
- \r
- \r
+\r
+\r
Returns:\r
\r
EFI_STATUS - EFI_SUCCESS:This controller can be managed by this driver,\r
Otherwise, this controller cannot be managed by this driver\r
- \r
+\r
--*/\r
{\r
- EFI_STATUS Status;\r
- EFI_LEGACY_8259_PROTOCOL *Legacy8259;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- \r
- DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingSupported\n"));\r
+ EFI_STATUS Status;\r
+ EFI_LEGACY_8259_PROTOCOL *LegacyBios;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
\r
//\r
- // See if the Legacy BIOS Protocol is available\r
+ // See if the Legacy 8259 Protocol is available\r
//\r
- Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &Legacy8259);\r
+ Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &LegacyBios);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+ \r
//\r
// Open the IO Abstraction(s) needed to perform the supported test\r
//\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingSupported: Fail to open PciIo protocol!\n"));\r
return Status;\r
}\r
- \r
+\r
if (!BiosVideoIsVga (PciIo)) {\r
- DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingSupported: Is not VGA!\n"));\r
Status = EFI_UNSUPPORTED;\r
}\r
\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
\r
return Status;\r
}\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
/*++\r
- \r
+\r
Routine Description:\r
\r
- Install UGA Draw Protocol onto VGA device handles\r
- \r
+ Install Graphics Output Protocol onto VGA device handles\r
+\r
Arguments:\r
\r
This - Pointer to driver binding protocol\r
Controller - Controller handle to connect\r
RemainingDevicePath - A pointer to the remaining portion of a device path\r
- \r
+\r
Returns:\r
\r
EFI_STATUS\r
- \r
+\r
--*/\r
{\r
- EFI_STATUS Status;\r
- BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_LEGACY_8259_PROTOCOL *Legacy8259;\r
\r
- DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart\n"));\r
+ PciIo = NULL;\r
//\r
- // Initialize local variables\r
+ // Prepare for status code\r
//\r
- BiosVideoPrivate = NULL;\r
+ Status = gBS->HandleProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
\r
//\r
- // Allocate the private device structure\r
+ // Open the IO Abstraction(s) needed\r
//\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- sizeof (BIOS_VIDEO_DEV),\r
- (VOID**)&BiosVideoPrivate\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- ZeroMem (BiosVideoPrivate, sizeof (BIOS_VIDEO_DEV));\r
-\r
//\r
// See if the Legacy BIOS Protocol is available\r
//\r
- Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &mLegacy8259);\r
+ Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &Legacy8259);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- \r
+\r
+\r
//\r
- // Prepare for status code\r
+ // Create child handle and install GraphicsOutputProtocol on it\r
//\r
- Status = gBS->HandleProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID**)&BiosVideoPrivate->DevicePath\r
- );\r
+ Status = BiosVideoChildHandleInstall (\r
+ This,\r
+ Controller,\r
+ PciIo,\r
+ Legacy8259,\r
+ ParentDevicePath,\r
+ RemainingDevicePath\r
+ );\r
+\r
+Done:\r
if (EFI_ERROR (Status)) {\r
- goto Done;\r
+ if (PciIo != NULL) {\r
+ //\r
+ // Release PCI I/O Protocols on the controller handle.\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
}\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+BiosVideoDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+\r
+ Stop.\r
+\r
+ Arguments:\r
+\r
+ This - Pointer to driver binding protocol\r
+ Controller - Controller handle to connect\r
+ NumberOfChilren - Number of children handle created by this driver\r
+ ChildHandleBuffer - Buffer containing child handle created\r
+\r
+ Returns:\r
+\r
+ EFI_SUCCESS - Driver disconnected successfully from controller\r
+ EFI_UNSUPPORTED - Cannot find BIOS_VIDEO_DEV structure\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ BOOLEAN AllChildrenStopped;\r
+ UINTN Index;\r
+\r
+ BiosVideoPrivate = NULL;\r
+\r
+ if (NumberOfChildren == 0) {\r
+ //\r
+ // Close PCI I/O protocol on the controller handle\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ AllChildrenStopped = TRUE;\r
+ for (Index = 0; Index < NumberOfChildren; Index++) {\r
+ Status = BiosVideoChildHandleUninstall (This, Controller, ChildHandleBuffer[Index]);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ AllChildrenStopped = FALSE;\r
+ }\r
+ }\r
+\r
+ if (!AllChildrenStopped) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+BiosVideoChildHandleInstall (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ParentHandle,\r
+ IN EFI_PCI_IO_PROTOCOL *ParentPciIo,\r
+ IN EFI_LEGACY_8259_PROTOCOL *ParentLegacy8259,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Install child handles if the Handle supports MBR format.\r
+\r
+Arguments: \r
+ This - Calling context.\r
+ Handle - Parent Handle \r
+ PciIo - Parent PciIo interface\r
+ LegacyBios - Parent LegacyBios interface\r
+ DevicePath - Parent Device Path\r
+\r
+Returns:\r
+ EFI_SUCCESS - If a child handle was added\r
+ other - A child handle was not added\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ ACPI_ADR_DEVICE_PATH AcpiDeviceNode;\r
+\r
//\r
- // Open the IO Abstraction(s) needed\r
+ // Allocate the private device structure for video device\r
//\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &(BiosVideoPrivate->PciIo),\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ sizeof (BIOS_VIDEO_DEV),\r
+ &BiosVideoPrivate\r
);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- \r
- DEBUG ((EFI_D_INFO, "InitializeBiosIntCaller\n"));\r
- InitializeBiosIntCaller();\r
- InitializeInterruptRedirection();\r
- DEBUG ((EFI_D_INFO, "InitializeBiosIntCaller Finished!\n"));\r
- \r
- if (!BiosVideoIsVga (BiosVideoPrivate->PciIo)) {\r
- DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart: not VGA\n"));\r
+\r
+ ZeroMem (BiosVideoPrivate, sizeof (BIOS_VIDEO_DEV));\r
+\r
+ if (!BiosVideoIsVga (ParentPciIo)) {\r
Status = EFI_UNSUPPORTED;\r
goto Done;\r
}\r
\r
- BiosVideoPrivate->VgaCompatible = TRUE; \r
+ BiosVideoPrivate->VgaCompatible = TRUE;\r
+\r
//\r
- // Initialize the private device structure\r
+ // Initialize the child private structure\r
//\r
BiosVideoPrivate->Signature = BIOS_VIDEO_DEV_SIGNATURE;\r
- BiosVideoPrivate->Handle = Controller;\r
+ BiosVideoPrivate->Handle = NULL;\r
\r
/**\r
Status = gBS->CreateEvent (\r
**/\r
\r
//\r
- // Fill in UGA Draw specific mode structures\r
+ // Fill in Graphics Output specific mode structures\r
//\r
BiosVideoPrivate->HardwareNeedsStarting = TRUE;\r
- BiosVideoPrivate->CurrentMode = 0;\r
- BiosVideoPrivate->MaxMode = 0;\r
BiosVideoPrivate->ModeData = NULL;\r
BiosVideoPrivate->LineBuffer = NULL;\r
BiosVideoPrivate->VgaFrameBuffer = NULL;\r
BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR;\r
\r
//\r
- // Assume that UGA Draw will be produced until proven otherwise\r
+ // Assume that Graphics Output Protocol will be produced until proven otherwise\r
+ //\r
+ BiosVideoPrivate->ProduceGraphicsOutput = TRUE;\r
+\r
+ //\r
+ // Child handle need to consume the Legacy Bios protocol\r
//\r
- BiosVideoPrivate->ProduceUgaDraw = TRUE;\r
+ BiosVideoPrivate->Legacy8259 = ParentLegacy8259;\r
\r
//\r
- // Check for VESA BIOS Extensions for modes that are compatible with UGA Draw\r
+ // When check for VBE, PCI I/O protocol is needed, so use parent's protocol interface temporally\r
+ //\r
+ BiosVideoPrivate->PciIo = ParentPciIo;\r
+\r
+ InitializeBiosIntCaller(BiosVideoPrivate);\r
+ InitializeInterruptRedirection(BiosVideoPrivate);\r
+\r
+ //\r
+ // Check for VESA BIOS Extensions for modes that are compatible with Graphics Output\r
//\r
- //CpuDeadLoop();\r
- DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart: Before check VBE!\n"));\r
Status = BiosVideoCheckForVbe (BiosVideoPrivate);\r
- DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart: check VBE status=%r!\n", Status));\r
- \r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart: Fail to check VBE!\n"));\r
//\r
- // The VESA BIOS Extensions are not compatible with UGA Draw, so check for support\r
+ // The VESA BIOS Extensions are not compatible with Graphics Output, so check for support\r
// for the standard 640x480 16 color VGA mode\r
//\r
if (BiosVideoPrivate->VgaCompatible) {\r
if (EFI_ERROR (Status)) {\r
//\r
// Neither VBE nor the standard 640x480 16 color VGA mode are supported, so do\r
- // not produce the UGA Draw protocol. Instead, produce the VGA MiniPort Protocol.\r
+ // not produce the Graphics Output protocol. Instead, produce the VGA MiniPort Protocol.\r
//\r
- BiosVideoPrivate->ProduceUgaDraw = FALSE;\r
+ BiosVideoPrivate->ProduceGraphicsOutput = FALSE;\r
\r
//\r
// INT services are available, so on the 80x25 and 80x50 text mode are supported\r
}\r
}\r
\r
- if (BiosVideoPrivate->ProduceUgaDraw) {\r
- DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart: Produce Uga Draw!\n"));\r
+ if (BiosVideoPrivate->ProduceGraphicsOutput) {\r
+ if (RemainingDevicePath == NULL) {\r
+ ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));\r
+ AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;\r
+ AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;\r
+ AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);\r
+ SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));\r
+\r
+ BiosVideoPrivate->DevicePath = AppendDevicePathNode (\r
+ ParentDevicePath, \r
+ (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode\r
+ );\r
+ } else {\r
+ BiosVideoPrivate->DevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);\r
+ }\r
+\r
//\r
- // Install UGA Draw Protocol\r
+ // Creat child handle and install Graphics Output Protocol,EDID Discovered/Active Protocol\r
//\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Controller,\r
- &gEfiUgaDrawProtocolGuid,\r
- &BiosVideoPrivate->UgaDraw,\r
+ &BiosVideoPrivate->Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ BiosVideoPrivate->DevicePath,\r
+ &gEfiGraphicsOutputProtocolGuid,\r
+ &BiosVideoPrivate->GraphicsOutput,\r
+ &gEfiEdidDiscoveredProtocolGuid,\r
+ &BiosVideoPrivate->EdidDiscovered,\r
+ &gEfiEdidActiveProtocolGuid,\r
+ &BiosVideoPrivate->EdidActive,\r
NULL\r
);\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Open the Parent Handle for the child\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ParentHandle,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &BiosVideoPrivate->PciIo,\r
+ This->DriverBindingHandle,\r
+ BiosVideoPrivate->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ }\r
} else {\r
//\r
// Install VGA Mini Port Protocol\r
//\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Controller,\r
+ &BiosVideoPrivate->Handle,\r
&gEfiVgaMiniPortProtocolGuid,\r
&BiosVideoPrivate->VgaMiniPort,\r
NULL\r
\r
Done:\r
if (EFI_ERROR (Status)) {\r
- if (BiosVideoPrivate != NULL) {\r
- //\r
- // Free mode data\r
- //\r
- if (BiosVideoPrivate->ModeData != NULL) {\r
- gBS->FreePool (BiosVideoPrivate->ModeData);\r
- }\r
- //\r
- // Free memory allocated below 1MB\r
- //\r
- if (BiosVideoPrivate->PagesBelow1MB != 0) {\r
- gBS->FreePages (BiosVideoPrivate->PagesBelow1MB, BiosVideoPrivate->NumberOfPagesBelow1MB);\r
- }\r
-\r
- if (BiosVideoPrivate->PciIo != NULL) {\r
- //\r
- // Release PCI I/O and UGA Draw Protocols on the controller handle.\r
- //\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
- }\r
- //\r
- // Close the ExitBootServices event\r
- //\r
- if (BiosVideoPrivate->ExitBootServicesEvent != NULL) {\r
- gBS->CloseEvent (BiosVideoPrivate->ExitBootServicesEvent);\r
- }\r
- //\r
- // Free private data structure\r
- //\r
- gBS->FreePool (BiosVideoPrivate);\r
- }\r
+ //\r
+ // Free private data structure\r
+ //\r
+ BiosVideoDeviceReleaseResource (BiosVideoPrivate);\r
}\r
\r
return Status;\r
}\r
\r
EFI_STATUS\r
-EFIAPI\r
-BiosVideoDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
+BiosVideoChildHandleUninstall (\r
+ EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ EFI_HANDLE Controller,\r
+ EFI_HANDLE Handle\r
)\r
/*++\r
- \r
- Routine Description:\r
\r
- Stop.\r
- \r
- Arguments:\r
+Routine Description:\r
\r
- This - Pointer to driver binding protocol\r
- Controller - Controller handle to connect\r
- NumberOfChilren - Number of children handle created by this driver\r
- ChildHandleBuffer - Buffer containing child handle created\r
- \r
- Returns:\r
+ Deregister an video child handle and free resources\r
+\r
+Arguments:\r
+\r
+ This - Protocol instance pointer.\r
+ Controller - Video controller handle\r
+ Handle - Video child handle\r
+\r
+Returns:\r
+\r
+ EFI_STATUS\r
\r
- EFI_SUCCESS - Driver disconnected successfully from controller\r
- EFI_UNSUPPORTED - Cannot find BIOS_VIDEO_DEV structure\r
- \r
--*/\r
{\r
- EFI_STATUS Status;\r
- EFI_UGA_DRAW_PROTOCOL *Uga;\r
- EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;\r
- BIOS_VIDEO_DEV *BiosVideoPrivate;\r
- EFI_IA32_REGISTER_SET Regs;\r
+ EFI_STATUS Status;\r
+ EFI_IA32_REGISTER_SET Regs;\r
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
+ EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
\r
BiosVideoPrivate = NULL;\r
\r
Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiUgaDrawProtocolGuid,\r
- (VOID **) &Uga,\r
+ Handle,\r
+ &gEfiGraphicsOutputProtocolGuid,\r
+ (VOID **) &GraphicsOutput,\r
This->DriverBindingHandle,\r
- Controller,\r
+ Handle,\r
EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
);\r
if (!EFI_ERROR (Status)) {\r
- BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (Uga);\r
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);\r
}\r
\r
Status = gBS->OpenProtocol (\r
- Controller,\r
+ Handle,\r
&gEfiVgaMiniPortProtocolGuid,\r
(VOID **) &VgaMiniPort,\r
This->DriverBindingHandle,\r
- Controller,\r
+ Handle,\r
EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
);\r
if (!EFI_ERROR (Status)) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
- if (BiosVideoPrivate->ProduceUgaDraw) {\r
+ //\r
+ // Close PCI I/O protocol that opened by child handle\r
+ //\r
+ Status = gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Handle\r
+ );\r
+\r
+ //\r
+ // Uninstall protocols on child handle\r
+ //\r
+ if (BiosVideoPrivate->ProduceGraphicsOutput) {\r
Status = gBS->UninstallMultipleProtocolInterfaces (\r
- Controller,\r
- &gEfiUgaDrawProtocolGuid,\r
- &BiosVideoPrivate->UgaDraw,\r
+ BiosVideoPrivate->Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ BiosVideoPrivate->DevicePath,\r
+ &gEfiGraphicsOutputProtocolGuid,\r
+ &BiosVideoPrivate->GraphicsOutput,\r
+ &gEfiEdidDiscoveredProtocolGuid,\r
+ &BiosVideoPrivate->EdidDiscovered,\r
+ &gEfiEdidActiveProtocolGuid,\r
+ &BiosVideoPrivate->EdidActive,\r
NULL\r
);\r
} else {\r
Status = gBS->UninstallMultipleProtocolInterfaces (\r
- Controller,\r
+ BiosVideoPrivate->Handle,\r
&gEfiVgaMiniPortProtocolGuid,\r
&BiosVideoPrivate->VgaMiniPort,\r
NULL\r
);\r
}\r
-\r
if (EFI_ERROR (Status)) {\r
+ gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
return Status;\r
}\r
- \r
- gBS->SetMem (&Regs, sizeof (Regs), 0); \r
- \r
+\r
+ gBS->SetMem (&Regs, sizeof (Regs), 0);\r
+\r
//\r
// Set the 80x25 Text VGA Mode\r
//\r
Regs.H.AH = 0x00;\r
Regs.H.AL = 0x03;\r
- LegacyBiosInt86 (0x10, &Regs);\r
-\r
+ LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+ \r
Regs.H.AH = 0x11;\r
Regs.H.AL = 0x14;\r
Regs.H.BL = 0;\r
- LegacyBiosInt86 (0x10, &Regs);\r
-\r
+ LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+ \r
//\r
// Do not disable IO/memory decode since that would prevent legacy ROM from working\r
//\r
+\r
+ //\r
+ // Release all allocated resources\r
+ //\r
+ BiosVideoDeviceReleaseResource (BiosVideoPrivate);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+VOID\r
+BiosVideoDeviceReleaseResource (\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate\r
+ )\r
+/*++\r
+Routing Description:\r
+\r
+ Release resources of an video child device before stopping it.\r
+\r
+Arguments:\r
+\r
+ BiosVideoPrivate - Video child device private data structure\r
+\r
+Returns:\r
+\r
+ NONE\r
+ \r
+---*/\r
+{\r
+ if (BiosVideoPrivate == NULL) {\r
+ return ;\r
+ }\r
+\r
+ //\r
+ // Release all the resourses occupied by the BIOS_VIDEO_DEV\r
+ //\r
+ \r
//\r
// Free VGA Frame Buffer\r
//\r
gBS->FreePages (BiosVideoPrivate->VbeSaveRestoreBuffer, BiosVideoPrivate->VbeSaveRestorePages);\r
}\r
//\r
- // Release PCI I/O and UGA Draw Protocols on the controller handle.\r
+ // Free graphics output protocol occupied resource\r
//\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) {\r
+ if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) {\r
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info);\r
+ }\r
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode);\r
+ }\r
+ //\r
+ // Free EDID discovered protocol occupied resource\r
+ //\r
+ if (BiosVideoPrivate->EdidDiscovered.Edid != NULL) {\r
+ gBS->FreePool (BiosVideoPrivate->EdidDiscovered.Edid);\r
+ }\r
+ //\r
+ // Free EDID active protocol occupied resource\r
+ //\r
+ if (BiosVideoPrivate->EdidActive.Edid != NULL) {\r
+ gBS->FreePool (BiosVideoPrivate->EdidActive.Edid);\r
+ }\r
+\r
+ if (BiosVideoPrivate->DevicePath!= NULL) {\r
+ gBS->FreePool (BiosVideoPrivate->DevicePath);\r
+ }\r
\r
//\r
// Close the ExitBootServices event\r
//\r
- gBS->CloseEvent (BiosVideoPrivate->ExitBootServicesEvent);\r
+ if (BiosVideoPrivate->ExitBootServicesEvent != NULL) {\r
+ gBS->CloseEvent (BiosVideoPrivate->ExitBootServicesEvent);\r
+ }\r
+\r
+ gBS->FreePool (BiosVideoPrivate);\r
+\r
+ return ;\r
+}\r
+\r
+STATIC\r
+UINT32\r
+CalculateEdidKey (\r
+ VESA_BIOS_EXTENSIONS_EDID_TIMING *EdidTiming\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+\r
+ Generate a search key for a specified timing data.\r
+\r
+ Arguments:\r
+\r
+ EdidTiming - Pointer to EDID timing\r
+\r
+ Returns:\r
+ The 32 bit unique key for search.\r
+\r
+--*/\r
+{\r
+ UINT32 Key;\r
\r
//\r
- // Free private data structure\r
+ // Be sure no conflicts for all standard timing defined by VESA.\r
//\r
- gBS->FreePool (BiosVideoPrivate);\r
+ Key = (EdidTiming->HorizontalResolution * 2) + EdidTiming->VerticalResolution;\r
+ return Key;\r
+}\r
\r
- return EFI_SUCCESS;\r
+STATIC\r
+BOOLEAN\r
+ParseEdidData (\r
+ UINT8 *EdidBuffer,\r
+ VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING *ValidEdidTiming\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+\r
+ Parse the Established Timing and Standard Timing in EDID data block.\r
+\r
+ Arguments:\r
+\r
+ EdidBuffer - Pointer to EDID data block\r
+ ValidEdidTiming - Valid EDID timing information\r
+\r
+ Returns:\r
+ TRUE - The EDID data is valid.\r
+ FALSE - The EDID data is invalid.\r
+\r
+--*/\r
+{\r
+ UINT8 CheckSum;\r
+ UINT32 Index;\r
+ UINT32 ValidNumber;\r
+ UINT32 TimingBits;\r
+ UINT8 *BufferIndex;\r
+ UINT16 HorizontalResolution;\r
+ UINT16 VerticalResolution;\r
+ UINT8 AspectRatio;\r
+ UINT8 RefreshRate;\r
+ VESA_BIOS_EXTENSIONS_EDID_TIMING TempTiming;\r
+ VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *EdidDataBlock;\r
+\r
+ EdidDataBlock = (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *) EdidBuffer;\r
+\r
+ //\r
+ // Check the checksum of EDID data\r
+ //\r
+ CheckSum = 0;\r
+ for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE; Index ++) {\r
+ CheckSum = CheckSum + EdidBuffer[Index];\r
+ }\r
+ if (CheckSum != 0) {\r
+ return FALSE;\r
+ }\r
+\r
+ ValidNumber = 0;\r
+ gBS->SetMem (ValidEdidTiming, sizeof (VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING), 0);\r
+\r
+ if ((EdidDataBlock->EstablishedTimings[0] != 0) ||\r
+ (EdidDataBlock->EstablishedTimings[1] != 0) ||\r
+ (EdidDataBlock->EstablishedTimings[2] != 0)\r
+ ) {\r
+ //\r
+ // Established timing data\r
+ //\r
+ TimingBits = EdidDataBlock->EstablishedTimings[0] |\r
+ (EdidDataBlock->EstablishedTimings[1] << 8) |\r
+ ((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ;\r
+ for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) {\r
+ if (TimingBits & 0x1) {\r
+ ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&mEstablishedEdidTiming[Index]);\r
+ ValidNumber ++;\r
+ }\r
+ TimingBits = TimingBits >> 1;\r
+ }\r
+ } else {\r
+ //\r
+ // If no Established timing data, read the standard timing data\r
+ //\r
+ BufferIndex = &EdidDataBlock->StandardTimingIdentification[0];\r
+ for (Index = 0; Index < 8; Index ++) {\r
+ if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){\r
+ //\r
+ // A valid Standard Timing\r
+ //\r
+ HorizontalResolution = BufferIndex[0] * 8 + 248;\r
+ AspectRatio = BufferIndex[1] >> 6;\r
+ switch (AspectRatio) {\r
+ case 0:\r
+ VerticalResolution = HorizontalResolution / 16 * 10;\r
+ break;\r
+ case 1:\r
+ VerticalResolution = HorizontalResolution / 4 * 3;\r
+ break;\r
+ case 2:\r
+ VerticalResolution = HorizontalResolution / 5 * 4;\r
+ break;\r
+ case 3:\r
+ VerticalResolution = HorizontalResolution / 16 * 9;\r
+ break;\r
+ default:\r
+ VerticalResolution = HorizontalResolution / 4 * 3;\r
+ break;\r
+ }\r
+ RefreshRate = (BufferIndex[1] & 0x1f) + 60;\r
+ TempTiming.HorizontalResolution = HorizontalResolution;\r
+ TempTiming.VerticalResolution = VerticalResolution;\r
+ TempTiming.RefreshRate = RefreshRate;\r
+ ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming);\r
+ ValidNumber ++;\r
+ }\r
+ BufferIndex += 2;\r
+ }\r
+ }\r
+\r
+ ValidEdidTiming->ValidNumber = ValidNumber;\r
+ return TRUE;\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+SearchEdidTiming (\r
+ VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING *ValidEdidTiming,\r
+ VESA_BIOS_EXTENSIONS_EDID_TIMING *EdidTiming\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+\r
+ Search a specified Timing in all the valid EDID timings.\r
+\r
+ Arguments:\r
+\r
+ ValidEdidTiming - All valid EDID timing information.\r
+ EdidTiming - The Timing to search for.\r
+\r
+ Returns:\r
+\r
+ TRUE - Found.\r
+ FALSE - Not found.\r
+\r
+--*/\r
+{\r
+ UINT32 Index;\r
+ UINT32 Key;\r
+\r
+ Key = CalculateEdidKey (EdidTiming);\r
+\r
+ for (Index = 0; Index < ValidEdidTiming->ValidNumber; Index ++) {\r
+ if (Key == ValidEdidTiming->Key[Index]) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
}\r
\r
#define PCI_DEVICE_ENABLED (EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE)\r
\r
\r
EFI_STATUS\r
+EFIAPI\r
BiosVideoCheckForVbe (\r
- IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate \r
+ IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate\r
)\r
/*++\r
- \r
+\r
Routine Description:\r
\r
- Check for VBE device \r
- \r
+ Check for VBE device\r
+\r
Arguments:\r
- \r
+\r
BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure\r
- \r
+\r
Returns:\r
- \r
+\r
EFI_SUCCESS - VBE device found\r
- \r
+\r
--*/\r
{\r
- EFI_STATUS Status;\r
- EFI_IA32_REGISTER_SET Regs;\r
- UINT16 *ModeNumberPtr;\r
- BOOLEAN ModeFound;\r
- BIOS_VIDEO_MODE_DATA *ModeBuffer;\r
- UINTN Index;\r
+ EFI_STATUS Status;\r
+ EFI_IA32_REGISTER_SET Regs;\r
+ UINT16 *ModeNumberPtr;\r
+ BOOLEAN ModeFound;\r
+ BOOLEAN EdidFound;\r
+ BIOS_VIDEO_MODE_DATA *ModeBuffer;\r
+ BIOS_VIDEO_MODE_DATA *CurrentModeData;\r
+ UINTN PreferMode;\r
+ UINTN ModeNumber;\r
+ VESA_BIOS_EXTENSIONS_EDID_TIMING Timing;\r
+ VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING ValidEdidTiming;\r
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *GraphicsOutputMode;\r
\r
//\r
// Allocate buffer under 1MB for VBE data structures\r
//\r
BiosVideoPrivate->NumberOfPagesBelow1MB = EFI_SIZE_TO_PAGES (\r
- sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK) + sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK) +\r
+ sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK) +\r
+ sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK) +\r
+ sizeof (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK) +\r
sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK)\r
);\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
+ ZeroMem (&ValidEdidTiming, sizeof (VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING));\r
+\r
//\r
- // Fill in the UGA Draw Protocol\r
+ // Fill in the Graphics Output Protocol\r
//\r
- BiosVideoPrivate->UgaDraw.GetMode = BiosVideoUgaDrawGetMode;\r
- BiosVideoPrivate->UgaDraw.SetMode = BiosVideoUgaDrawSetMode;\r
- BiosVideoPrivate->UgaDraw.Blt = BiosVideoUgaDrawVbeBlt;\r
+ BiosVideoPrivate->GraphicsOutput.QueryMode = BiosVideoGraphicsOutputQueryMode;\r
+ BiosVideoPrivate->GraphicsOutput.SetMode = BiosVideoGraphicsOutputSetMode;\r
+ BiosVideoPrivate->GraphicsOutput.Blt = BiosVideoGraphicsOutputVbeBlt;\r
+ BiosVideoPrivate->GraphicsOutput.Mode = NULL;\r
\r
//\r
// Fill in the VBE related data structures\r
//\r
BiosVideoPrivate->VbeInformationBlock = (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK *) (UINTN) (BiosVideoPrivate->PagesBelow1MB);\r
BiosVideoPrivate->VbeModeInformationBlock = (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeInformationBlock + 1);\r
- BiosVideoPrivate->VbeCrtcInformationBlock = (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeModeInformationBlock + 1);\r
+ BiosVideoPrivate->VbeEdidDataBlock = (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *) (BiosVideoPrivate->VbeModeInformationBlock + 1);\r
+ BiosVideoPrivate->VbeCrtcInformationBlock = (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeEdidDataBlock + 1);\r
BiosVideoPrivate->VbeSaveRestorePages = 0;\r
BiosVideoPrivate->VbeSaveRestoreBuffer = 0;\r
\r
Regs.X.AX = VESA_BIOS_EXTENSIONS_RETURN_CONTROLLER_INFORMATION;\r
gBS->SetMem (BiosVideoPrivate->VbeInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK), 0);\r
BiosVideoPrivate->VbeInformationBlock->VESASignature = VESA_BIOS_EXTENSIONS_VBE2_SIGNATURE;\r
- Regs.X.ES = EFI_SEGMENT ((UINTN)BiosVideoPrivate->VbeInformationBlock);\r
- Regs.X.DI = EFI_OFFSET ((UINTN)BiosVideoPrivate->VbeInformationBlock);\r
-\r
- LegacyBiosInt86 (0x10, &Regs);\r
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeInformationBlock);\r
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeInformationBlock);\r
\r
+ LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+ \r
Status = EFI_DEVICE_ERROR;\r
\r
//\r
if (BiosVideoPrivate->VbeInformationBlock->VESAVersion < VESA_BIOS_EXTENSIONS_VERSION_2_0) {\r
return Status;\r
}\r
+\r
+ //\r
+ // Read EDID information\r
+ //\r
+ gBS->SetMem (&Regs, sizeof (Regs), 0);\r
+ Regs.X.AX = VESA_BIOS_EXTENSIONS_EDID;\r
+ Regs.X.BX = 1;\r
+ Regs.X.CX = 0;\r
+ Regs.X.DX = 0;\r
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeEdidDataBlock);\r
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeEdidDataBlock);\r
+\r
+ LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+ \r
+ //\r
+ // See if the VESA call succeeded\r
+ //\r
+ EdidFound = FALSE;\r
+ if (Regs.X.AX == VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {\r
+ //\r
+ // Parse EDID data structure to retrieve modes supported by monitor\r
+ //\r
+ if (ParseEdidData ((UINT8 *) BiosVideoPrivate->VbeEdidDataBlock, &ValidEdidTiming) == TRUE) {\r
+ EdidFound = TRUE;\r
+\r
+ BiosVideoPrivate->EdidDiscovered.SizeOfEdid = VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE,\r
+ &BiosVideoPrivate->EdidDiscovered.Edid\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ gBS->CopyMem (\r
+ BiosVideoPrivate->EdidDiscovered.Edid,\r
+ BiosVideoPrivate->VbeEdidDataBlock,\r
+ VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE\r
+ );\r
+\r
+ BiosVideoPrivate->EdidActive.SizeOfEdid = VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE,\r
+ &BiosVideoPrivate->EdidActive.Edid\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ gBS->CopyMem (\r
+ BiosVideoPrivate->EdidActive.Edid,\r
+ BiosVideoPrivate->VbeEdidDataBlock,\r
+ VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE\r
+ );\r
+ } else {\r
+ BiosVideoPrivate->EdidDiscovered.SizeOfEdid = 0;\r
+ BiosVideoPrivate->EdidDiscovered.Edid = NULL;\r
+\r
+ BiosVideoPrivate->EdidActive.SizeOfEdid = 0;\r
+ BiosVideoPrivate->EdidActive.Edid = NULL;\r
+ }\r
+ }\r
+\r
//\r
- // Walk through the mode list to see if there is at least one mode the is compatible with the UGA_DRAW protocol\r
+ // Walk through the mode list to see if there is at least one mode the is compatible with the EDID mode\r
//\r
ModeNumberPtr = (UINT16 *)\r
(\r
(((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0xffff0000) >> 12) |\r
((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0x0000ffff)\r
);\r
+\r
+ PreferMode = 0;\r
+ ModeNumber = 0;\r
+\r
for (; *ModeNumberPtr != VESA_BIOS_EXTENSIONS_END_OF_MODE_LIST; ModeNumberPtr++) {\r
//\r
// Make sure this is a mode number defined by the VESA VBE specification. If it isn'tm then skip this mode number.\r
Regs.X.AX = VESA_BIOS_EXTENSIONS_RETURN_MODE_INFORMATION;\r
Regs.X.CX = *ModeNumberPtr;\r
gBS->SetMem (BiosVideoPrivate->VbeModeInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK), 0);\r
- Regs.X.ES = EFI_SEGMENT ((UINTN)BiosVideoPrivate->VbeModeInformationBlock);\r
- Regs.X.DI = EFI_OFFSET ((UINTN)BiosVideoPrivate->VbeModeInformationBlock);\r
-\r
- LegacyBiosInt86 (0x10, &Regs);\r
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeModeInformationBlock);\r
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeModeInformationBlock);\r
\r
+ LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+ \r
//\r
// See if the call succeeded. If it didn't, then try the next mode.\r
//\r
if (BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr == 0) {\r
continue;\r
}\r
+\r
+ if (EdidFound && (ValidEdidTiming.ValidNumber > 0)) {\r
+ //\r
+ // EDID exist, check whether this mode match with any mode in EDID\r
+ //\r
+ Timing.HorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution;\r
+ Timing.VerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution;\r
+ if (SearchEdidTiming (&ValidEdidTiming, &Timing) == FALSE) {\r
+ continue;\r
+ }\r
+ }\r
+\r
//\r
- // See if the resolution is 1024x768, 800x600, or 640x480\r
+ // Select a reasonable mode to be set for current display mode\r
//\r
ModeFound = FALSE;\r
+\r
if (BiosVideoPrivate->VbeModeInformationBlock->XResolution == 1024 &&\r
BiosVideoPrivate->VbeModeInformationBlock->YResolution == 768\r
) {\r
ModeFound = TRUE;\r
}\r
-\r
if (BiosVideoPrivate->VbeModeInformationBlock->XResolution == 800 &&\r
BiosVideoPrivate->VbeModeInformationBlock->YResolution == 600\r
) {\r
ModeFound = TRUE;\r
+ PreferMode = ModeNumber;\r
}\r
-\r
if (BiosVideoPrivate->VbeModeInformationBlock->XResolution == 640 &&\r
BiosVideoPrivate->VbeModeInformationBlock->YResolution == 480\r
) {\r
ModeFound = TRUE;\r
}\r
-\r
- if (!ModeFound) {\r
+ if ((!EdidFound) && (!ModeFound)) {\r
+ //\r
+ // When no EDID exist, only select three possible resolutions, i.e. 1024x768, 800x600, 640x480\r
+ //\r
continue;\r
}\r
+\r
//\r
// Add mode to the list of available modes\r
//\r
- BiosVideoPrivate->MaxMode++;\r
+ ModeNumber ++;\r
Status = gBS->AllocatePool (\r
EfiBootServicesData,\r
- BiosVideoPrivate->MaxMode * sizeof (BIOS_VIDEO_MODE_DATA),\r
+ ModeNumber * sizeof (BIOS_VIDEO_MODE_DATA),\r
(VOID **) &ModeBuffer\r
);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- if (BiosVideoPrivate->MaxMode > 1) {\r
+ if (ModeNumber > 1) {\r
gBS->CopyMem (\r
ModeBuffer,\r
BiosVideoPrivate->ModeData,\r
- (BiosVideoPrivate->MaxMode - 1) * sizeof (BIOS_VIDEO_MODE_DATA)\r
+ (ModeNumber - 1) * sizeof (BIOS_VIDEO_MODE_DATA)\r
);\r
}\r
\r
gBS->FreePool (BiosVideoPrivate->ModeData);\r
}\r
\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].VbeModeNumber = *ModeNumberPtr;\r
+ CurrentModeData = &ModeBuffer[ModeNumber - 1];\r
+ CurrentModeData->VbeModeNumber = *ModeNumberPtr;\r
if (BiosVideoPrivate->VbeInformationBlock->VESAVersion >= VESA_BIOS_EXTENSIONS_VERSION_3_0) {\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->LinBytesPerScanLine;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Red.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRedFieldPosition;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRedMaskSize) - 1);\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->LinBlueFieldPosition;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinBlueMaskSize) - 1);\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Green.Position = BiosVideoPrivate->VbeModeInformationBlock->LinGreenFieldPosition;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinGreenMaskSize) - 1);\r
-\r
+ CurrentModeData->BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->LinBytesPerScanLine;\r
+ CurrentModeData->Red.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRedFieldPosition;\r
+ CurrentModeData->Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRedMaskSize) - 1);\r
+ CurrentModeData->Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->LinBlueFieldPosition;\r
+ CurrentModeData->Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinBlueMaskSize) - 1);\r
+ CurrentModeData->Green.Position = BiosVideoPrivate->VbeModeInformationBlock->LinGreenFieldPosition;\r
+ CurrentModeData->Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinGreenMaskSize) - 1);\r
+ CurrentModeData->Reserved.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRsvdFieldPosition;\r
+ CurrentModeData->Reserved.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRsvdMaskSize) - 1);\r
} else {\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->BytesPerScanLine;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Red.Position = BiosVideoPrivate->VbeModeInformationBlock->RedFieldPosition;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RedMaskSize) - 1);\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->BlueFieldPosition;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->BlueMaskSize) - 1);\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Green.Position = BiosVideoPrivate->VbeModeInformationBlock->GreenFieldPosition;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->GreenMaskSize) - 1);\r
-\r
+ CurrentModeData->BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->BytesPerScanLine;\r
+ CurrentModeData->Red.Position = BiosVideoPrivate->VbeModeInformationBlock->RedFieldPosition;\r
+ CurrentModeData->Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RedMaskSize) - 1);\r
+ CurrentModeData->Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->BlueFieldPosition;\r
+ CurrentModeData->Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->BlueMaskSize) - 1);\r
+ CurrentModeData->Green.Position = BiosVideoPrivate->VbeModeInformationBlock->GreenFieldPosition;\r
+ CurrentModeData->Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->GreenMaskSize) - 1);\r
+ CurrentModeData->Reserved.Position = BiosVideoPrivate->VbeModeInformationBlock->RsvdFieldPosition;\r
+ CurrentModeData->Reserved.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RsvdMaskSize) - 1);\r
}\r
-\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].LinearFrameBuffer = (VOID *) (UINTN)BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].HorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].VerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution;\r
-\r
- if (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel >= 24) {\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].ColorDepth = 32;\r
- } else {\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].ColorDepth = BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel;\r
+ CurrentModeData->PixelFormat = PixelBitMask;\r
+ if ((BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel == 32) &&\r
+ (CurrentModeData->Red.Mask == 0xff) && (CurrentModeData->Green.Mask == 0xff) && (CurrentModeData->Blue.Mask == 0xff)) {\r
+ if ((CurrentModeData->Red.Position == 0) && (CurrentModeData->Green.Position == 8) && (CurrentModeData->Blue.Position == 16)) {\r
+ CurrentModeData->PixelFormat = PixelRedGreenBlueReserved8BitPerColor;\r
+ } else if ((CurrentModeData->Blue.Position == 0) && (CurrentModeData->Green.Position == 8) && (CurrentModeData->Red.Position == 16)) {\r
+ CurrentModeData->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;\r
+ }\r
}\r
+ CurrentModeData->PixelBitMask.RedMask = ((UINT32) CurrentModeData->Red.Mask) << CurrentModeData->Red.Position;\r
+ CurrentModeData->PixelBitMask.GreenMask = ((UINT32) CurrentModeData->Green.Mask) << CurrentModeData->Green.Position;\r
+ CurrentModeData->PixelBitMask.BlueMask = ((UINT32) CurrentModeData->Blue.Mask) << CurrentModeData->Blue.Position;\r
+ CurrentModeData->PixelBitMask.ReservedMask = ((UINT32) CurrentModeData->Reserved.Mask) << CurrentModeData->Reserved.Position;\r
\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].BitsPerPixel = BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel;\r
+ CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN)BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr;\r
+ CurrentModeData->FrameBufferSize = BiosVideoPrivate->VbeInformationBlock->TotalMemory * 64 * 1024;\r
+ CurrentModeData->HorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution;\r
+ CurrentModeData->VerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution;\r
\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].RefreshRate = 60;\r
+ CurrentModeData->BitsPerPixel = BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel;\r
\r
BiosVideoPrivate->ModeData = ModeBuffer;\r
}\r
//\r
- // Check to see if we found any modes that are compatible with UGA DRAW\r
+ // Check to see if we found any modes that are compatible with GRAPHICS OUTPUT\r
//\r
- if (BiosVideoPrivate->MaxMode == 0) {\r
+ if (ModeNumber == 0) {\r
Status = EFI_DEVICE_ERROR;\r
goto Done;\r
}\r
+\r
+ //\r
+ // Allocate buffer for Graphics Output Protocol mode information\r
+ //\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),\r
+ (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ GraphicsOutputMode = BiosVideoPrivate->GraphicsOutput.Mode;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),\r
+ (VOID **) &GraphicsOutputMode->Info\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ GraphicsOutputMode->MaxMode = (UINT32) ModeNumber;\r
+ //\r
+ // Current mode is unknow till now, set it to an invalid mode.\r
+ //\r
+ GraphicsOutputMode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;\r
+\r
//\r
// Find the best mode to initialize\r
//\r
- Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 1024, 768, 32, 60);\r
- //Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 800, 600, 32, 60);\r
+ Status = BiosVideoGraphicsOutputSetMode (&BiosVideoPrivate->GraphicsOutput, (UINT32) PreferMode);\r
if (EFI_ERROR (Status)) {\r
- Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 800, 600, 32, 60);\r
- //Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 1024, 768, 32, 60);\r
- if (EFI_ERROR (Status)) {\r
- Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 640, 480, 32, 60);\r
- for (Index = 0; EFI_ERROR (Status) && Index < BiosVideoPrivate->MaxMode; Index++) {\r
- Status = BiosVideoUgaDrawSetMode (\r
- &BiosVideoPrivate->UgaDraw,\r
- BiosVideoPrivate->ModeData[Index].HorizontalResolution,\r
- BiosVideoPrivate->ModeData[Index].VerticalResolution,\r
- BiosVideoPrivate->ModeData[Index].ColorDepth,\r
- BiosVideoPrivate->ModeData[Index].RefreshRate\r
- );\r
+ for (PreferMode = 0; PreferMode < ModeNumber; PreferMode ++) {\r
+ Status = BiosVideoGraphicsOutputSetMode (\r
+ &BiosVideoPrivate->GraphicsOutput,\r
+ (UINT32) PreferMode\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ break;\r
}\r
}\r
+ if (PreferMode == ModeNumber) {\r
+ //\r
+ // None mode is set successfully.\r
+ //\r
+ goto Done;\r
+ }\r
}\r
\r
Done:\r
if (EFI_ERROR (Status)) {\r
if (BiosVideoPrivate->ModeData != NULL) {\r
gBS->FreePool (BiosVideoPrivate->ModeData);\r
- BiosVideoPrivate->ModeData = NULL;\r
- BiosVideoPrivate->MaxMode = 0;\r
+ }\r
+ if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) {\r
+ if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) {\r
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info);\r
+ }\r
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode);\r
}\r
}\r
\r
}\r
\r
EFI_STATUS\r
+EFIAPI\r
BiosVideoCheckForVga (\r
- IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate \r
+ IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate\r
)\r
/*++\r
- \r
+\r
Routine Description:\r
\r
Check for VGA device\r
- \r
+\r
Arguments:\r
- \r
+\r
BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure\r
- \r
+\r
Returns:\r
- \r
+\r
EFI_SUCCESS - Standard VGA device found\r
- \r
+\r
--*/\r
{\r
EFI_STATUS Status;\r
BIOS_VIDEO_MODE_DATA *ModeBuffer;\r
+ \r
+ //\r
+ // Fill in the Graphics Output Protocol\r
+ //\r
+ BiosVideoPrivate->GraphicsOutput.QueryMode = BiosVideoGraphicsOutputQueryMode;\r
+ BiosVideoPrivate->GraphicsOutput.SetMode = BiosVideoGraphicsOutputSetMode;\r
+ BiosVideoPrivate->GraphicsOutput.Blt = BiosVideoGraphicsOutputVgaBlt;\r
\r
//\r
- // Fill in the UGA Draw Protocol\r
+ // Allocate buffer for Graphics Output Protocol mode information\r
//\r
- BiosVideoPrivate->UgaDraw.GetMode = BiosVideoUgaDrawGetMode;\r
- BiosVideoPrivate->UgaDraw.SetMode = BiosVideoUgaDrawSetMode;\r
- BiosVideoPrivate->UgaDraw.Blt = BiosVideoUgaDrawVgaBlt;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),\r
+ (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),\r
+ (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode->Info\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
\r
//\r
// Add mode to the list of available modes\r
//\r
- BiosVideoPrivate->MaxMode++;\r
+ BiosVideoPrivate->GraphicsOutput.Mode->MaxMode = 1;\r
+\r
Status = gBS->AllocatePool (\r
EfiBootServicesData,\r
- BiosVideoPrivate->MaxMode * sizeof (BIOS_VIDEO_MODE_DATA),\r
+ sizeof (BIOS_VIDEO_MODE_DATA),\r
(VOID **) &ModeBuffer\r
);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (BiosVideoPrivate->MaxMode > 1) {\r
- gBS->CopyMem (\r
- ModeBuffer,\r
- BiosVideoPrivate->ModeData,\r
- (BiosVideoPrivate->MaxMode - 1) * sizeof (BIOS_VIDEO_MODE_DATA)\r
- );\r
- }\r
-\r
- if (BiosVideoPrivate->ModeData != NULL) {\r
- gBS->FreePool (BiosVideoPrivate->ModeData);\r
+ goto Done;\r
}\r
\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].VbeModeNumber = 0x0012;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].BytesPerScanLine = 640;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].LinearFrameBuffer = (VOID *) (UINTN)(0xa0000);\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].HorizontalResolution = 640;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].VerticalResolution = 480;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].ColorDepth = 32;\r
- ModeBuffer[BiosVideoPrivate->MaxMode - 1].RefreshRate = 60;\r
+ ModeBuffer->VbeModeNumber = 0x0012;\r
+ ModeBuffer->BytesPerScanLine = 640;\r
+ ModeBuffer->LinearFrameBuffer = (VOID *) (UINTN) (0xa0000);\r
+ ModeBuffer->FrameBufferSize = 0;\r
+ ModeBuffer->HorizontalResolution = 640;\r
+ ModeBuffer->VerticalResolution = 480;\r
+ ModeBuffer->BitsPerPixel = 8; \r
+ ModeBuffer->PixelFormat = PixelBltOnly;\r
\r
BiosVideoPrivate->ModeData = ModeBuffer;\r
\r
//\r
// Test to see if the Video Adapter support the 640x480 16 color mode\r
//\r
- Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 640, 480, 32, 60);\r
+ BiosVideoPrivate->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;\r
+ Status = BiosVideoGraphicsOutputSetMode (&BiosVideoPrivate->GraphicsOutput, 0);\r
\r
+Done:\r
//\r
// If there was an error, then free the mode structure\r
//\r
if (EFI_ERROR (Status)) {\r
- BiosVideoPrivate->MaxMode = 0;\r
if (BiosVideoPrivate->ModeData != NULL) {\r
gBS->FreePool (BiosVideoPrivate->ModeData);\r
}\r
+ if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) {\r
+ if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) {\r
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info);\r
+ }\r
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode);\r
+ }\r
}\r
-\r
return Status;\r
}\r
//\r
-// UGA Protocol Member Functions for VESA BIOS Extensions\r
+// Graphics Output Protocol Member Functions for VESA BIOS Extensions\r
//\r
EFI_STATUS\r
EFIAPI\r
-BiosVideoUgaDrawGetMode (\r
- IN EFI_UGA_DRAW_PROTOCOL *This,\r
- OUT UINT32 *HorizontalResolution,\r
- OUT UINT32 *VerticalResolution,\r
- OUT UINT32 *ColorDepth,\r
- OUT UINT32 *RefreshRate\r
+BiosVideoGraphicsOutputQueryMode (\r
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
+ IN UINT32 ModeNumber,\r
+ OUT UINTN *SizeOfInfo,\r
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info\r
)\r
/*++\r
\r
Routine Description:\r
\r
- UGA protocol interface to get video mode\r
-\r
-Arguments:\r
-\r
- This - Pointer to UGA draw protocol instance\r
- HorizontalResolution - Horizontal Resolution, in pixels\r
- VerticalResolution - Vertical Resolution, in pixels\r
- ColorDepth - Bit number used to represent color value of a pixel \r
- RefreshRate - Refresh rate, in Hertz\r
+ Graphics Output protocol interface to get video mode\r
\r
-Returns:\r
+ Arguments:\r
+ This - Protocol instance pointer.\r
+ ModeNumber - The mode number to return information on.\r
+ Info - Caller allocated buffer that returns information about ModeNumber.\r
+ SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.\r
\r
- EFI_DEVICE_ERROR - Hardware need starting\r
- EFI_INVALID_PARAMETER - Invalid parameter passed in\r
- EFI_SUCCESS - Video mode query successfully\r
+ Returns:\r
+ EFI_SUCCESS - Mode information returned.\r
+ EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode.\r
+ EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()\r
+ EFI_INVALID_PARAMETER - One of the input args was NULL.\r
\r
--*/\r
{\r
- BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ EFI_STATUS Status;\r
+ BIOS_VIDEO_MODE_DATA *ModeData;\r
\r
- BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (This);\r
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);\r
\r
if (BiosVideoPrivate->HardwareNeedsStarting) {\r
- return EFI_DEVICE_ERROR;\r
+ return EFI_NOT_STARTED;\r
}\r
\r
- if (HorizontalResolution == NULL || VerticalResolution == NULL || ColorDepth == NULL || RefreshRate == NULL) {\r
+ if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- *HorizontalResolution = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].HorizontalResolution;\r
- *VerticalResolution = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].VerticalResolution;\r
- *ColorDepth = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].ColorDepth;\r
- *RefreshRate = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].RefreshRate;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),\r
+ Info\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+\r
+ ModeData = &BiosVideoPrivate->ModeData[ModeNumber];\r
+ (*Info)->Version = 0;\r
+ (*Info)->HorizontalResolution = ModeData->HorizontalResolution;\r
+ (*Info)->VerticalResolution = ModeData->VerticalResolution;\r
+ (*Info)->PixelFormat = ModeData->PixelFormat;\r
+ (*Info)->PixelInformation = ModeData->PixelBitMask;\r
+\r
+ (*Info)->PixelsPerScanLine = (ModeData->BytesPerScanLine * 8) / ModeData->BitsPerPixel;\r
\r
return EFI_SUCCESS;\r
}\r
\r
EFI_STATUS\r
EFIAPI\r
-BiosVideoUgaDrawSetMode (\r
- IN EFI_UGA_DRAW_PROTOCOL *This,\r
- IN UINT32 HorizontalResolution,\r
- IN UINT32 VerticalResolution,\r
- IN UINT32 ColorDepth,\r
- IN UINT32 RefreshRate\r
+BiosVideoGraphicsOutputSetMode (\r
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This,\r
+ IN UINT32 ModeNumber\r
)\r
/*++\r
\r
Routine Description:\r
\r
- UGA draw protocol interface to set video mode\r
-\r
-Arguments:\r
-\r
- This - Pointer to UGA draw protocol instance\r
- HorizontalResolution - Horizontal Resolution, in pixels\r
- VerticalResolution - Vertical Resolution, in pixels\r
- ColorDepth - Bit number used to represent color value of a pixel \r
- RefreshRate - Refresh rate, in Hertz\r
+ Graphics Output protocol interface to set video mode\r
\r
-Returns:\r
+ Arguments:\r
+ This - Protocol instance pointer.\r
+ ModeNumber - The mode number to be set.\r
\r
- EFI_DEVICE_ERROR - Device error\r
- EFI_SUCCESS - Video mode set successfully\r
- EFI_UNSUPPORTED - Cannot support this video mode\r
+ Returns:\r
+ EFI_SUCCESS - Graphics mode was changed.\r
+ EFI_DEVICE_ERROR - The device had an error and could not complete the request.\r
+ EFI_UNSUPPORTED - ModeNumber is not supported by this device.\r
\r
--*/\r
{\r
- EFI_STATUS Status;\r
- BIOS_VIDEO_DEV *BiosVideoPrivate;\r
- UINTN Index;\r
- EFI_IA32_REGISTER_SET Regs;\r
+ EFI_STATUS Status;\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ EFI_IA32_REGISTER_SET Regs;\r
+ BIOS_VIDEO_MODE_DATA *ModeData;\r
\r
- BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (This);\r
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);\r
\r
- for (Index = 0; Index < BiosVideoPrivate->MaxMode; Index++) {\r
+ if (This == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
- if (HorizontalResolution != BiosVideoPrivate->ModeData[Index].HorizontalResolution) {\r
- continue;\r
- }\r
+ if (ModeNumber >= This->Mode->MaxMode) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
\r
- if (VerticalResolution != BiosVideoPrivate->ModeData[Index].VerticalResolution) {\r
- continue;\r
- }\r
+ if (ModeNumber == This->Mode->Mode) {\r
+ return EFI_SUCCESS;\r
+ }\r
\r
- if (ColorDepth != BiosVideoPrivate->ModeData[Index].ColorDepth) {\r
- continue;\r
- }\r
+ ModeData = &BiosVideoPrivate->ModeData[ModeNumber];\r
\r
- if (RefreshRate != BiosVideoPrivate->ModeData[Index].RefreshRate) {\r
- continue;\r
- }\r
+ if (BiosVideoPrivate->LineBuffer) {\r
+ gBS->FreePool (BiosVideoPrivate->LineBuffer);\r
+ }\r
\r
- if (BiosVideoPrivate->LineBuffer) {\r
- gBS->FreePool (BiosVideoPrivate->LineBuffer);\r
- }\r
+ if (BiosVideoPrivate->VgaFrameBuffer) {\r
+ gBS->FreePool (BiosVideoPrivate->VgaFrameBuffer);\r
+ }\r
\r
- if (BiosVideoPrivate->VgaFrameBuffer) {\r
- gBS->FreePool (BiosVideoPrivate->VgaFrameBuffer);\r
- }\r
+ if (BiosVideoPrivate->VbeFrameBuffer) {\r
+ gBS->FreePool (BiosVideoPrivate->VbeFrameBuffer);\r
+ }\r
\r
- if (BiosVideoPrivate->VbeFrameBuffer) {\r
- gBS->FreePool (BiosVideoPrivate->VbeFrameBuffer);\r
- }\r
+ BiosVideoPrivate->LineBuffer = NULL;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ ModeData->BytesPerScanLine,\r
+ &BiosVideoPrivate->LineBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Clear all registers\r
+ //\r
+ gBS->SetMem (&Regs, sizeof (Regs), 0);\r
\r
- BiosVideoPrivate->LineBuffer = NULL;\r
+ if (ModeData->VbeModeNumber < 0x100) {\r
+ //\r
+ // Allocate a working buffer for BLT operations to the VGA frame buffer\r
+ //\r
+ BiosVideoPrivate->VgaFrameBuffer = NULL;\r
Status = gBS->AllocatePool (\r
EfiBootServicesData,\r
- BiosVideoPrivate->ModeData[Index].BytesPerScanLine,\r
- (VOID**)&BiosVideoPrivate->LineBuffer\r
+ 4 * 480 * 80,\r
+ &BiosVideoPrivate->VgaFrameBuffer\r
);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
//\r
- // Clear all registers\r
+ // Set VGA Mode\r
//\r
- gBS->SetMem (&Regs, sizeof (Regs), 0);\r
-\r
- if (BiosVideoPrivate->ModeData[Index].VbeModeNumber < 0x100) {\r
- //\r
- // Allocate a working buffer for BLT operations to the VGA frame buffer\r
- //\r
- BiosVideoPrivate->VgaFrameBuffer = NULL;\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- 4 * 480 * 80,\r
- (VOID**)&BiosVideoPrivate->VgaFrameBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Set VGA Mode\r
- //\r
- Regs.X.AX = BiosVideoPrivate->ModeData[Index].VbeModeNumber;\r
- LegacyBiosInt86 (0x10, &Regs);\r
-\r
- } else {\r
- //\r
- // Allocate a working buffer for BLT operations to the VBE frame buffer\r
- //\r
- BiosVideoPrivate->VbeFrameBuffer = NULL;\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- BiosVideoPrivate->ModeData[Index].BytesPerScanLine * BiosVideoPrivate->ModeData[Index].VerticalResolution,\r
- (VOID**)&BiosVideoPrivate->VbeFrameBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Set VBE mode\r
- //\r
- Regs.X.AX = VESA_BIOS_EXTENSIONS_SET_MODE;\r
- Regs.X.BX = (UINT16) (BiosVideoPrivate->ModeData[Index].VbeModeNumber | VESA_BIOS_EXTENSIONS_MODE_NUMBER_LINEAR_FRAME_BUFFER);\r
- gBS->SetMem (BiosVideoPrivate->VbeCrtcInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK), 0);\r
- Regs.X.ES = EFI_SEGMENT ((UINTN)BiosVideoPrivate->VbeCrtcInformationBlock);\r
- Regs.X.DI = EFI_OFFSET ((UINTN)BiosVideoPrivate->VbeCrtcInformationBlock);\r
- LegacyBiosInt86 (0x10, &Regs);\r
+ Regs.X.AX = ModeData->VbeModeNumber;\r
+ LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
\r
- //\r
- // Check to see if the call succeeded\r
- //\r
- if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Initialize the state of the VbeFrameBuffer\r
- //\r
- Status = BiosVideoPrivate->PciIo->Mem.Read (\r
- BiosVideoPrivate->PciIo,\r
- EfiPciIoWidthUint32,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) (UINTN) BiosVideoPrivate->ModeData[Index].LinearFrameBuffer,\r
- (BiosVideoPrivate->ModeData[Index].BytesPerScanLine * BiosVideoPrivate->ModeData[Index].VerticalResolution) >> 2,\r
- BiosVideoPrivate->VbeFrameBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ } else {\r
+ //\r
+ // Allocate a working buffer for BLT operations to the VBE frame buffer\r
+ //\r
+ BiosVideoPrivate->VbeFrameBuffer = NULL;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ ModeData->BytesPerScanLine * ModeData->VerticalResolution,\r
+ &BiosVideoPrivate->VbeFrameBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Set VBE mode\r
+ //\r
+ Regs.X.AX = VESA_BIOS_EXTENSIONS_SET_MODE;\r
+ Regs.X.BX = (UINT16) (ModeData->VbeModeNumber | VESA_BIOS_EXTENSIONS_MODE_NUMBER_LINEAR_FRAME_BUFFER);\r
+ gBS->SetMem (BiosVideoPrivate->VbeCrtcInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK), 0);\r
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeCrtcInformationBlock);\r
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeCrtcInformationBlock);\r
+ LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+ \r
+ //\r
+ // Check to see if the call succeeded\r
+ //\r
+ if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ //\r
+ // Initialize the state of the VbeFrameBuffer\r
+ //\r
+ Status = BiosVideoPrivate->PciIo->Mem.Read (\r
+ BiosVideoPrivate->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) (UINTN) ModeData->LinearFrameBuffer,\r
+ (ModeData->BytesPerScanLine * ModeData->VerticalResolution) >> 2,\r
+ BiosVideoPrivate->VbeFrameBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
}\r
+ }\r
\r
- BiosVideoPrivate->CurrentMode = Index;\r
+ This->Mode->Mode = ModeNumber;\r
+ This->Mode->Info->Version = 0;\r
+ This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
+ This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;\r
+ This->Mode->Info->PixelFormat = ModeData->PixelFormat;\r
+ This->Mode->Info->PixelInformation = ModeData->PixelBitMask;\r
+ This->Mode->Info->PixelsPerScanLine = (ModeData->BytesPerScanLine * 8) / ModeData->BitsPerPixel;\r
+ This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
\r
- BiosVideoPrivate->HardwareNeedsStarting = FALSE;\r
+ //\r
+ // Frame BufferSize remain unchanged\r
+ //\r
+ This->Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) ModeData->LinearFrameBuffer;\r
+ This->Mode->FrameBufferSize = ModeData->FrameBufferSize;\r
\r
- return EFI_SUCCESS;\r
- }\r
+ BiosVideoPrivate->HardwareNeedsStarting = FALSE;\r
\r
- return EFI_UNSUPPORTED;\r
+ return EFI_SUCCESS;\r
}\r
\r
VOID\r
//\r
EFI_STATUS\r
EFIAPI\r
-BiosVideoUgaDrawVbeBlt (\r
- IN EFI_UGA_DRAW_PROTOCOL *This,\r
- IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL\r
- IN EFI_UGA_BLT_OPERATION BltOperation,\r
- IN UINTN SourceX,\r
- IN UINTN SourceY,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN Width,\r
- IN UINTN Height,\r
- IN UINTN Delta\r
+BiosVideoGraphicsOutputVbeBlt (\r
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL\r
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,\r
+ IN UINTN SourceX,\r
+ IN UINTN SourceY,\r
+ IN UINTN DestinationX,\r
+ IN UINTN DestinationY,\r
+ IN UINTN Width,\r
+ IN UINTN Height,\r
+ IN UINTN Delta\r
)\r
/*++\r
\r
Routine Description:\r
\r
- UGA draw protocol instance to block transfer for VBE device\r
+ Graphics Output protocol instance to block transfer for VBE device\r
\r
Arguments:\r
\r
- This - Pointer to UGA draw protocol instance\r
+ This - Pointer to Graphics Output protocol instance\r
BltBuffer - The data to transfer to screen\r
BltOperation - The operation to perform\r
SourceX - The X coordinate of the source for BltOperation\r
DestinationY - The Y coordinate of the destination for BltOperation\r
Width - The width of a rectangle in the blt rectangle in pixels\r
Height - The height of a rectangle in the blt rectangle in pixels\r
- Delta - Not used for EfiUgaVideoFill and EfiUgaVideoToVideo operation.\r
+ Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.\r
If a Delta of 0 is used, the entire BltBuffer will be operated on.\r
- If a subrectangle of the BltBuffer is used, then Delta represents \r
+ If a subrectangle of the BltBuffer is used, then Delta represents\r
the number of bytes in a row of the BltBuffer.\r
\r
Returns:\r
\r
--*/\r
{\r
- BIOS_VIDEO_DEV *BiosVideoPrivate;\r
- BIOS_VIDEO_MODE_DATA *Mode;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- EFI_TPL OriginalTPL;\r
- UINTN DstY;\r
- UINTN SrcY;\r
- UINTN DstX;\r
- EFI_UGA_PIXEL *Blt;\r
- VOID *MemAddress;\r
- EFI_UGA_PIXEL *VbeFrameBuffer;\r
- UINTN BytesPerScanLine;\r
- UINTN Index;\r
- UINT8 *VbeBuffer;\r
- UINT8 *VbeBuffer1;\r
- UINT8 *BltUint8;\r
- UINT32 VbePixelWidth;\r
- UINT32 Pixel;\r
- UINTN TotalBytes;\r
-\r
- BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (This);\r
- Mode = &BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode];\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ BIOS_VIDEO_MODE_DATA *Mode;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_TPL OriginalTPL;\r
+ UINTN DstY;\r
+ UINTN SrcY;\r
+ UINTN DstX;\r
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
+ VOID *MemAddress;\r
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer;\r
+ UINTN BytesPerScanLine;\r
+ UINTN Index;\r
+ UINT8 *VbeBuffer;\r
+ UINT8 *VbeBuffer1;\r
+ UINT8 *BltUint8;\r
+ UINT32 VbePixelWidth;\r
+ UINT32 Pixel;\r
+ UINTN TotalBytes;\r
+\r
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);\r
+ Mode = &BiosVideoPrivate->ModeData[This->Mode->Mode];\r
PciIo = BiosVideoPrivate->PciIo;\r
\r
VbeFrameBuffer = BiosVideoPrivate->VbeFrameBuffer;\r
BltUint8 = (UINT8 *) BltBuffer;\r
TotalBytes = Width * VbePixelWidth;\r
\r
- if ((BltOperation < EfiUgaVideoFill) || (BltOperation >= EfiUgaBltMax)) {\r
+ if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
// The virtual screen is upside down, as the first row is the bootom row of\r
// the image.\r
//\r
- if (BltOperation == EfiUgaVideoToBltBuffer) {\r
+ if (BltOperation == EfiBltVideoToBltBuffer) {\r
//\r
// Video to BltBuffer: Source is Video, destination is BltBuffer\r
//\r
// the number of bytes in each row can be computed.\r
//\r
if (Delta == 0) {\r
- Delta = Width * sizeof (EFI_UGA_PIXEL);\r
+ Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
}\r
//\r
// We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
\r
switch (BltOperation) {\r
- case EfiUgaVideoToBltBuffer:\r
+ case EfiBltVideoToBltBuffer:\r
for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {\r
- Blt = (EFI_UGA_PIXEL *) (BltUint8 + DstY * Delta + DestinationX * sizeof (EFI_UGA_PIXEL));\r
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + DstY * Delta + DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
//\r
- // Shuffle the packed bytes in the hardware buffer to match EFI_UGA_PIXEL\r
+ // Shuffle the packed bytes in the hardware buffer to match EFI_GRAPHICS_OUTPUT_BLT_PIXEL\r
//\r
VbeBuffer = ((UINT8 *) VbeFrameBuffer + (SrcY * BytesPerScanLine + SourceX * VbePixelWidth));\r
for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {\r
}\r
break;\r
\r
- case EfiUgaVideoToVideo:\r
+ case EfiBltVideoToVideo:\r
for (Index = 0; Index < Height; Index++) {\r
if (DestinationY <= SourceY) {\r
SrcY = SourceY + Index;\r
}\r
break;\r
\r
- case EfiUgaVideoFill:\r
+ case EfiBltVideoFill:\r
VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth);\r
- Blt = (EFI_UGA_PIXEL *) BltUint8;\r
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltUint8;\r
//\r
- // Shuffle the RGB fields in EFI_UGA_PIXEL to match the hardware buffer\r
+ // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer\r
//\r
Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) |\r
(\r
BytesPerScanLine\r
);\r
}\r
-\r
break;\r
\r
- case EfiUgaBltBufferToVideo:\r
+ case EfiBltBufferToVideo:\r
for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {\r
- Blt = (EFI_UGA_PIXEL *) (BltUint8 + (SrcY * Delta) + (SourceX) * sizeof (EFI_UGA_PIXEL));\r
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + (SrcY * Delta) + (SourceX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
VbeBuffer = ((UINT8 *) VbeFrameBuffer + (DstY * BytesPerScanLine + DestinationX * VbePixelWidth));\r
for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {\r
//\r
- // Shuffle the RGB fields in EFI_UGA_PIXEL to match the hardware buffer\r
+ // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer\r
//\r
Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) |\r
((Blt->Green & Mode->Green.Mask) << Mode->Green.Position) |\r
);\r
}\r
break;\r
- default:\r
- break;\r
}\r
\r
gBS->RestoreTPL (OriginalTPL);\r
PciIo,\r
EfiPciIoWidthUint8,\r
EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) (UINTN)Source,\r
+ (UINT64) Source,\r
WidthInBytes,\r
(VOID *) Destination\r
);\r
}\r
\r
VOID\r
-VgaConvertToUgaColor (\r
- UINT8 *MemoryBuffer,\r
- UINTN X,\r
- UINTN Y,\r
- EFI_UGA_PIXEL *BltBuffer\r
+VgaConvertToGraphicsOutputColor (\r
+ UINT8 *MemoryBuffer,\r
+ UINTN X,\r
+ UINTN Y,\r
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer\r
)\r
/*++\r
\r
Routine Description:\r
\r
- Internal routine to convert VGA color to UGA color\r
+ Internal routine to convert VGA color to Grahpics Output color\r
\r
Arguments:\r
\r
MemoryBuffer - Buffer containing VGA color\r
X - The X coordinate of pixel on screen\r
Y - The Y coordinate of pixel on screen\r
- BltBuffer - Buffer to contain converted UGA color\r
+ BltBuffer - Buffer to contain converted Grahpics Output color\r
\r
Returns:\r
\r
}\r
}\r
\r
- *BltBuffer = mVgaColorToUgaColor[Color];\r
+ *BltBuffer = mVgaColorToGraphicsOutputColor[Color];\r
}\r
\r
UINT8\r
VgaConvertColor (\r
- IN EFI_UGA_PIXEL *BltBuffer\r
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer\r
)\r
/*++\r
\r
Routine Description:\r
\r
- Internal routine to convert UGA color to VGA color\r
+ Internal routine to convert Grahpics Output color to VGA color\r
\r
Arguments:\r
\r
- BltBuffer - buffer containing UGA color\r
+ BltBuffer - buffer containing Grahpics Output color\r
\r
Returns:\r
\r
\r
EFI_STATUS\r
EFIAPI\r
-BiosVideoUgaDrawVgaBlt (\r
- IN EFI_UGA_DRAW_PROTOCOL *This,\r
- IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL\r
- IN EFI_UGA_BLT_OPERATION BltOperation,\r
- IN UINTN SourceX,\r
- IN UINTN SourceY,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN Width,\r
- IN UINTN Height,\r
- IN UINTN Delta\r
+BiosVideoGraphicsOutputVgaBlt (\r
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL\r
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,\r
+ IN UINTN SourceX,\r
+ IN UINTN SourceY,\r
+ IN UINTN DestinationX,\r
+ IN UINTN DestinationY,\r
+ IN UINTN Width,\r
+ IN UINTN Height,\r
+ IN UINTN Delta\r
)\r
/*++\r
\r
Routine Description:\r
\r
- UGA draw protocol instance to block transfer for VGA device\r
+ Grahpics Output protocol instance to block transfer for VGA device\r
\r
Arguments:\r
\r
- This - Pointer to UGA draw protocol instance\r
+ This - Pointer to Grahpics Output protocol instance\r
BltBuffer - The data to transfer to screen\r
BltOperation - The operation to perform\r
SourceX - The X coordinate of the source for BltOperation\r
DestinationY - The Y coordinate of the destination for BltOperation\r
Width - The width of a rectangle in the blt rectangle in pixels\r
Height - The height of a rectangle in the blt rectangle in pixels\r
- Delta - Not used for EfiUgaVideoFill and EfiUgaVideoToVideo operation.\r
+ Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.\r
If a Delta of 0 is used, the entire BltBuffer will be operated on.\r
- If a subrectangle of the BltBuffer is used, then Delta represents \r
+ If a subrectangle of the BltBuffer is used, then Delta represents\r
the number of bytes in a row of the BltBuffer.\r
\r
Returns:\r
UINTN Columns;\r
UINTN X;\r
UINTN Y;\r
+ UINTN CurrentMode;\r
\r
- BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (This);\r
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);\r
\r
+ CurrentMode = This->Mode->Mode;\r
PciIo = BiosVideoPrivate->PciIo;\r
- MemAddress = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].LinearFrameBuffer;\r
- BytesPerScanLine = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].BytesPerScanLine >> 3;\r
- BytesPerBitPlane = BytesPerScanLine * BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].VerticalResolution;\r
+ MemAddress = BiosVideoPrivate->ModeData[CurrentMode].LinearFrameBuffer;\r
+ BytesPerScanLine = BiosVideoPrivate->ModeData[CurrentMode].BytesPerScanLine >> 3;\r
+ BytesPerBitPlane = BytesPerScanLine * BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution;\r
VgaFrameBuffer = BiosVideoPrivate->VgaFrameBuffer;\r
\r
- if ((BltOperation < EfiUgaVideoFill) || (BltOperation >= EfiUgaBltMax)) {\r
+ if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
// The virtual screen is upside down, as the first row is the bootom row of\r
// the image.\r
//\r
- if (BltOperation == EfiUgaVideoToBltBuffer) {\r
+ if (BltOperation == EfiBltVideoToBltBuffer) {\r
//\r
// Video to BltBuffer: Source is Video, destination is BltBuffer\r
//\r
- if (SourceY + Height > BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].VerticalResolution) {\r
+ if (SourceY + Height > BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (SourceX + Width > BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].HorizontalResolution) {\r
+ if (SourceX + Width > BiosVideoPrivate->ModeData[CurrentMode].HorizontalResolution) {\r
return EFI_INVALID_PARAMETER;\r
}\r
} else {\r
//\r
// BltBuffer to Video: Source is BltBuffer, destination is Video\r
//\r
- if (DestinationY + Height > BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].VerticalResolution) {\r
+ if (DestinationY + Height > BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (DestinationX + Width > BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].HorizontalResolution) {\r
+ if (DestinationX + Width > BiosVideoPrivate->ModeData[CurrentMode].HorizontalResolution) {\r
return EFI_INVALID_PARAMETER;\r
}\r
}\r
// the number of bytes in each row can be computed.\r
//\r
if (Delta == 0) {\r
- Delta = Width * sizeof (EFI_UGA_PIXEL);\r
+ Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
}\r
//\r
// We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
// Compute some values we need for VGA\r
//\r
switch (BltOperation) {\r
- case EfiUgaVideoToBltBuffer:\r
+ case EfiBltVideoToBltBuffer:\r
\r
SourceOffset = (SourceY << 6) + (SourceY << 4) + (SourceX >> 3);\r
SourceWidth = ((SourceX + Width - 1) >> 3) - (SourceX >> 3) + 1;\r
);\r
\r
//\r
- // Convert VGA Bit Planes to a UGA 32-bit color value\r
+ // Convert VGA Bit Planes to a Graphics Output 32-bit color value\r
//\r
BltBuffer += (DestinationY * (Delta >> 2) + DestinationX);\r
for (Rows = 0, Y = SourceY; Rows < Height; Rows++, Y++, BltBuffer += (Delta >> 2)) {\r
for (Columns = 0, X = SourceX; Columns < Width; Columns++, X++, BltBuffer++) {\r
- VgaConvertToUgaColor (VgaFrameBuffer, X, Y, BltBuffer);\r
+ VgaConvertToGraphicsOutputColor (VgaFrameBuffer, X, Y, BltBuffer);\r
}\r
\r
BltBuffer -= Width;\r
\r
break;\r
\r
- case EfiUgaVideoToVideo:\r
+ case EfiBltVideoToVideo:\r
//\r
// Check for an aligned Video to Video operation\r
//\r
// Program the Mode Register Write mode 1, Read mode 0\r
//\r
WriteGraphicsController (\r
- BiosVideoPrivate->PciIo,\r
+ PciIo,\r
VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,\r
VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_1\r
);\r
PciIo,\r
EfiPciIoWidthUint8,\r
EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) ((UINTN)DestinationAddress + Offset),\r
+ (UINT64) (DestinationAddress + Offset),\r
EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) ((UINTN)SourceAddress + Offset),\r
+ (UINT64) (SourceAddress + Offset),\r
Bytes\r
);\r
}\r
\r
break;\r
\r
- case EfiUgaVideoFill:\r
+ case EfiBltVideoFill:\r
StartAddress = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3));\r
Bytes = ((DestinationX + Width - 1) >> 3) - (DestinationX >> 3);\r
LeftMask = mVgaLeftMaskTable[DestinationX & 0x07];\r
// Program the Mode Register Write mode 2, Read mode 0\r
//\r
WriteGraphicsController (\r
- BiosVideoPrivate->PciIo,\r
+ PciIo,\r
VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,\r
VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2\r
);\r
// Program the Data Rotate/Function Select Register to replace\r
//\r
WriteGraphicsController (\r
- BiosVideoPrivate->PciIo,\r
+ PciIo,\r
VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER,\r
VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE\r
);\r
// Program the BitMask register with the Left column mask\r
//\r
WriteGraphicsController (\r
- BiosVideoPrivate->PciIo,\r
+ PciIo,\r
VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
LeftMask\r
);\r
// Program the BitMask register with the middle column mask of 0xff\r
//\r
WriteGraphicsController (\r
- BiosVideoPrivate->PciIo,\r
+ PciIo,\r
VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
0xff\r
);\r
// Program the BitMask register with the Right column mask\r
//\r
WriteGraphicsController (\r
- BiosVideoPrivate->PciIo,\r
+ PciIo,\r
VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
RightMask\r
);\r
}\r
break;\r
\r
- case EfiUgaBltBufferToVideo:\r
+ case EfiBltBufferToVideo:\r
StartAddress = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3));\r
LeftMask = mVgaBitMaskTable[DestinationX & 0x07];\r
\r
// Program the Mode Register Write mode 2, Read mode 0\r
//\r
WriteGraphicsController (\r
- BiosVideoPrivate->PciIo,\r
+ PciIo,\r
VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,\r
VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2\r
);\r
// Program the Data Rotate/Function Select Register to replace\r
//\r
WriteGraphicsController (\r
- BiosVideoPrivate->PciIo,\r
+ PciIo,\r
VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER,\r
VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE\r
);\r
// Program the BitMask register with the Left column mask\r
//\r
WriteGraphicsController (\r
- BiosVideoPrivate->PciIo,\r
+ PciIo,\r
VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
LeftMask\r
);\r
PciIo,\r
EfiPciIoWidthUint8,\r
EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) (UINTN) Address1,\r
+ (UINT64) Address1,\r
1,\r
&Data\r
);\r
PciIo,\r
EfiPciIoWidthUint8,\r
EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) (UINTN) Address1,\r
+ (UINT64) Address1,\r
1,\r
&BiosVideoPrivate->LineBuffer[Index1]\r
);\r
}\r
}\r
\r
- break;\r
- default:\r
break;\r
}\r
\r
BIOS_VIDEO_DEV *BiosVideoPrivate;\r
EFI_IA32_REGISTER_SET Regs;\r
\r
+ if (This == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
//\r
// Make sure the ModeNumber is a valid value\r
//\r
// Get the device structure for this device\r
//\r
BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS (This);\r
-\r
+ \r
gBS->SetMem (&Regs, sizeof (Regs), 0);\r
\r
switch (ModeNumber) {\r
//\r
Regs.H.AH = 0x00;\r
Regs.H.AL = 0x83;\r
- LegacyBiosInt86 (0x10, &Regs);\r
-\r
+ LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+ \r
Regs.H.AH = 0x11;\r
Regs.H.AL = 0x14;\r
Regs.H.BL = 0;\r
- LegacyBiosInt86 (0x10, &Regs);\r
+ LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+ \r
break;\r
\r
case 1:\r
//\r
Regs.H.AH = 0x00;\r
Regs.H.AL = 0x83;\r
- LegacyBiosInt86 (0x10, &Regs);\r
+ LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+ \r
Regs.H.AH = 0x11;\r
Regs.H.AL = 0x12;\r
Regs.H.BL = 0;\r
- LegacyBiosInt86 (0x10, &Regs);\r
+ LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
break;\r
\r
default:\r
\r
return EFI_SUCCESS;\r
}\r
-\r
-VOID\r
-InitializeBiosIntCaller (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 RealModeBufferSize;\r
- UINT32 ExtraStackSize;\r
- EFI_PHYSICAL_ADDRESS LegacyRegionBase;\r
- \r
- //\r
- // Get LegacyRegion\r
- //\r
- AsmGetThunk16Properties (&RealModeBufferSize, &ExtraStackSize);\r
-\r
- LegacyRegionBase = 0x100000;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES(RealModeBufferSize + ExtraStackSize + 200),\r
- &LegacyRegionBase\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- \r
- mThunkContext.RealModeBuffer = (VOID*)(UINTN)LegacyRegionBase;\r
- mThunkContext.RealModeBufferSize = EFI_PAGES_TO_SIZE (RealModeBufferSize);\r
- mThunkContext.ThunkAttributes = 3;\r
- AsmPrepareThunk16(&mThunkContext);\r
- \r
- //Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &mLegacy8259);\r
- //ASSERT_EFI_ERROR (Status); \r
-}\r
-\r
-VOID\r
-InitializeInterruptRedirection (\r
- VOID\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Initialize interrupt redirection code and entries, because\r
- IDT Vectors 0x68-0x6f must be redirected to IDT Vectors 0x08-0x0f.\r
- Or the interrupt will lost when we do thunk.\r
- NOTE: We do not reset 8259 vector base, because it will cause pending\r
- interrupt lost.\r
-\r
- Arguments:\r
- NONE\r
-\r
- Returns:\r
- NONE\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS LegacyRegionBase;\r
- UINTN LegacyRegionLength;\r
- UINT32 *IdtArray;\r
- UINTN Index;\r
- UINT8 ProtectedModeBaseVector;\r
- UINT32 InterruptRedirectionCode[] = {\r
- 0x90CF08CD, // INT8; IRET; NOP\r
- 0x90CF09CD, // INT9; IRET; NOP\r
- 0x90CF0ACD, // INTA; IRET; NOP\r
- 0x90CF0BCD, // INTB; IRET; NOP\r
- 0x90CF0CCD, // INTC; IRET; NOP\r
- 0x90CF0DCD, // INTD; IRET; NOP\r
- 0x90CF0ECD, // INTE; IRET; NOP\r
- 0x90CF0FCD // INTF; IRET; NOP\r
- };\r
-\r
- //\r
- // Get LegacyRegion\r
- //\r
- LegacyRegionLength = sizeof(InterruptRedirectionCode);\r
- LegacyRegionBase = 0x100000;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES(LegacyRegionLength),\r
- &LegacyRegionBase\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Copy code to legacy region\r
- //\r
- CopyMem ((VOID *)(UINTN)LegacyRegionBase, InterruptRedirectionCode, sizeof (InterruptRedirectionCode));\r
-\r
- //\r
- // Get VectorBase, it should be 0x68\r
- //\r
- Status = mLegacy8259->GetVector (mLegacy8259, Efi8259Irq0, &ProtectedModeBaseVector);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Patch IVT 0x68 ~ 0x6f\r
- //\r
- IdtArray = (UINT32 *) 0;\r
- for (Index = 0; Index < 8; Index++) {\r
- IdtArray[ProtectedModeBaseVector + Index] = ((EFI_SEGMENT (LegacyRegionBase + Index * 4)) << 16) | (EFI_OFFSET (LegacyRegionBase + Index * 4));\r
- }\r
-\r
- return ;\r
-}\r
-\r
-BOOLEAN\r
-EFIAPI\r
-LegacyBiosInt86 (\r
- IN UINT8 BiosInt,\r
- IN EFI_IA32_REGISTER_SET *Regs\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Thunk to 16-bit real mode and execute a software interrupt with a vector \r
- of BiosInt. Regs will contain the 16-bit register context on entry and \r
- exit.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- BiosInt - Processor interrupt vector to invoke\r
- Reg - Register contexted passed into (and returned) from thunk to \r
- 16-bit mode\r
-\r
- Returns:\r
- FALSE - Thunk completed, and there were no BIOS errors in the target code.\r
- See Regs for status.\r
- TRUE - There was a BIOS erro in the target code.\r
-\r
---*/\r
-{\r
- UINTN Status;\r
- UINTN Eflags;\r
- IA32_REGISTER_SET ThunkRegSet;\r
- BOOLEAN Ret;\r
- UINT16 *Stack16;\r
- \r
- Regs->X.Flags.Reserved1 = 1;\r
- Regs->X.Flags.Reserved2 = 0;\r
- Regs->X.Flags.Reserved3 = 0;\r
- Regs->X.Flags.Reserved4 = 0;\r
- Regs->X.Flags.IOPL = 3;\r
- Regs->X.Flags.NT = 0;\r
- Regs->X.Flags.IF = 1;\r
- Regs->X.Flags.TF = 0;\r
- Regs->X.Flags.CF = 0;\r
-\r
- ZeroMem (&ThunkRegSet, sizeof (ThunkRegSet));\r
- ThunkRegSet.E.EDI = Regs->E.EDI;\r
- ThunkRegSet.E.ESI = Regs->E.ESI;\r
- ThunkRegSet.E.EBP = Regs->E.EBP;\r
- ThunkRegSet.E.EBX = Regs->E.EBX;\r
- ThunkRegSet.E.EDX = Regs->E.EDX;\r
- ThunkRegSet.E.ECX = Regs->E.ECX;\r
- ThunkRegSet.E.EAX = Regs->E.EAX;\r
- ThunkRegSet.E.DS = Regs->E.DS;\r
- ThunkRegSet.E.ES = Regs->E.ES;\r
-\r
- CopyMem (&(ThunkRegSet.E.EFLAGS), &(Regs->E.EFlags), sizeof (UINT32));\r
- \r
- //\r
- // The call to Legacy16 is a critical section to EFI\r
- //\r
- Eflags = AsmReadEflags ();\r
- if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
- DisableInterrupts ();\r
- }\r
-\r
- //\r
- // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases.\r
- //\r
- Status = mLegacy8259->SetMode (mLegacy8259, Efi8259LegacyMode, NULL, NULL);\r
- ASSERT_EFI_ERROR (Status);\r
- \r
- Stack16 = (UINT16 *)((UINT8 *) mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize - sizeof (UINT16));\r
- Stack16 -= sizeof (ThunkRegSet.E.EFLAGS) / sizeof (UINT16);\r
- CopyMem (Stack16, &ThunkRegSet.E.EFLAGS, sizeof (ThunkRegSet.E.EFLAGS));\r
-\r
- ThunkRegSet.E.SS = (UINT16) (((UINTN) Stack16 >> 16) << 12);\r
- ThunkRegSet.E.ESP = (UINT16) (UINTN) Stack16;\r
- ThunkRegSet.E.Eip = (UINT16)((UINT32 *)NULL)[BiosInt];\r
- ThunkRegSet.E.CS = (UINT16)(((UINT32 *)NULL)[BiosInt] >> 16);\r
- mThunkContext.RealModeState = &ThunkRegSet;\r
- AsmThunk16 (&mThunkContext);\r
-\r
- //\r
- // Restore protected mode interrupt state\r
- //\r
- Status = mLegacy8259->SetMode (mLegacy8259, Efi8259ProtectedMode, NULL, NULL);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // End critical section\r
- //\r
- if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
- EnableInterrupts ();\r
- }\r
-\r
- Regs->E.EDI = ThunkRegSet.E.EDI; \r
- Regs->E.ESI = ThunkRegSet.E.ESI; \r
- Regs->E.EBP = ThunkRegSet.E.EBP; \r
- Regs->E.EBX = ThunkRegSet.E.EBX; \r
- Regs->E.EDX = ThunkRegSet.E.EDX; \r
- Regs->E.ECX = ThunkRegSet.E.ECX; \r
- Regs->E.EAX = ThunkRegSet.E.EAX;\r
- Regs->E.SS = ThunkRegSet.E.SS;\r
- Regs->E.CS = ThunkRegSet.E.CS; \r
- Regs->E.DS = ThunkRegSet.E.DS; \r
- Regs->E.ES = ThunkRegSet.E.ES;\r
-\r
- CopyMem (&(Regs->E.EFlags), &(ThunkRegSet.E.EFLAGS), sizeof (UINT32));\r
-\r
- Ret = (BOOLEAN) (Regs->E.EFlags.CF == 1);\r
-\r
- return Ret;\r
-}\r
-\r
-\r