--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2008, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ BiosVideo.c\r
+ \r
+Abstract:\r
+\r
+ ConsoleOut Routines that speak VGA.\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "BiosVideo.h"\r
+\r
+\r
+//\r
+// EFI Driver Binding Protocol Instance\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gBiosVideoDriverBinding = {\r
+ BiosVideoDriverBindingSupported,\r
+ BiosVideoDriverBindingStart,\r
+ BiosVideoDriverBindingStop,\r
+ 0x3,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+//\r
+// Global lookup tables for VGA graphics modes\r
+//\r
+UINT8 mVgaLeftMaskTable[] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 };\r
+\r
+UINT8 mVgaRightMaskTable[] = { 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };\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
+ {\r
+ 0x00,\r
+ 0x00,\r
+ 0x00,\r
+ 0x00\r
+ },\r
+ {\r
+ 0x98,\r
+ 0x00,\r
+ 0x00,\r
+ 0x00\r
+ },\r
+ {\r
+ 0x00,\r
+ 0x98,\r
+ 0x00,\r
+ 0x00\r
+ },\r
+ {\r
+ 0x98,\r
+ 0x98,\r
+ 0x00,\r
+ 0x00\r
+ },\r
+ {\r
+ 0x00,\r
+ 0x00,\r
+ 0x98,\r
+ 0x00\r
+ },\r
+ {\r
+ 0x98,\r
+ 0x00,\r
+ 0x98,\r
+ 0x00\r
+ },\r
+ {\r
+ 0x00,\r
+ 0x98,\r
+ 0x98,\r
+ 0x00\r
+ },\r
+ {\r
+ 0x98,\r
+ 0x98,\r
+ 0x98,\r
+ 0x00\r
+ },\r
+ {\r
+ 0x10,\r
+ 0x10,\r
+ 0x10,\r
+ 0x00\r
+ },\r
+ {\r
+ 0xff,\r
+ 0x10,\r
+ 0x10,\r
+ 0x00\r
+ },\r
+ {\r
+ 0x10,\r
+ 0xff,\r
+ 0x10,\r
+ 0x00\r
+ },\r
+ {\r
+ 0xff,\r
+ 0xff,\r
+ 0x10,\r
+ 0x00\r
+ },\r
+ {\r
+ 0x10,\r
+ 0x10,\r
+ 0xff,\r
+ 0x00\r
+ },\r
+ {\r
+ 0xf0,\r
+ 0x10,\r
+ 0xff,\r
+ 0x00\r
+ },\r
+ {\r
+ 0x10,\r
+ 0xff,\r
+ 0xff,\r
+ 0x00\r
+ },\r
+ {\r
+ 0xff,\r
+ 0xff,\r
+ 0xff,\r
+ 0x00\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
+EFI_STATUS\r
+EFIAPI\r
+BiosVideoDriverEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Driver Entry Point.\r
+ \r
+ Arguments:\r
+ \r
+ ImageHandle - Handle of driver image.\r
+ SystemTable - Pointer to system table.\r
+ \r
+ Returns:\r
+ \r
+ EFI_STATUS\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EfiLibInstallDriverBindingComponentName2 (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gBiosVideoDriverBinding,\r
+ ImageHandle,\r
+ &gBiosVideoComponentName,\r
+ &gBiosVideoComponentName2\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+BiosVideoExitBootServices (\r
+ EFI_EVENT Event,\r
+ VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Callback function for exit boot service event\r
+\r
+Arguments:\r
+\r
+ Event - EFI_EVENT structure\r
+ Context - Event context\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+/*\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ EFI_IA32_REGISTER_SET Regs;\r
+\r
+ //\r
+ // Get our context\r
+ //\r
+ BiosVideoPrivate = (BIOS_VIDEO_DEV *) Context;\r
+\r
+ //\r
+ // Set the 80x25 Text VGA Mode\r
+ //\r
+ Regs.H.AH = 0x00;\r
+ Regs.H.AL = 0x83;\r
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);\r
+\r
+ Regs.H.AH = 0x11;\r
+ Regs.H.AL = 0x14;\r
+ Regs.H.BL = 0;\r
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);\r
+*/\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+BiosVideoDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+\r
+ Supported.\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 - EFI_SUCCESS:This controller can be managed by this driver,\r
+ Otherwise, this controller cannot be managed by this driver\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
+\r
+ //\r
+ // See if the Legacy BIOS Protocol is available\r
+ //\r
+ Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &Legacy8259);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Open the IO Abstraction(s) needed to perform the supported test\r
+ //\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
+ DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingSupported: Fail to open PciIo protocol!\n"));\r
+ return Status;\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
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+BiosVideoDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+\r
+ Install UGA Draw 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
+ Returns:\r
+\r
+ EFI_STATUS\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+\r
+ DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart\n"));\r
+ //\r
+ // Initialize local variables\r
+ //\r
+ BiosVideoPrivate = NULL;\r
+\r
+ //\r
+ // Allocate the private device structure\r
+ //\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
+ 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
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ \r
+ //\r
+ // Prepare for status code\r
+ //\r
+ Status = gBS->HandleProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ &BiosVideoPrivate->DevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ //\r
+ // Open the IO Abstraction(s) needed\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
+ );\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
+ Status = EFI_UNSUPPORTED;\r
+ goto Done;\r
+ }\r
+ \r
+ BiosVideoPrivate->VgaCompatible = TRUE; \r
+ //\r
+ // Initialize the private device structure\r
+ //\r
+ BiosVideoPrivate->Signature = BIOS_VIDEO_DEV_SIGNATURE;\r
+ BiosVideoPrivate->Handle = Controller;\r
+\r
+ /**\r
+ Status = gBS->CreateEvent (\r
+ EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,\r
+ EFI_TPL_NOTIFY,\r
+ BiosVideoExitBootServices,\r
+ BiosVideoPrivate,\r
+ &BiosVideoPrivate->ExitBootServicesEvent\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ **/\r
+ \r
+ //\r
+ // Fill in UGA Draw 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->VbeFrameBuffer = NULL;\r
+\r
+ //\r
+ // Fill in the VGA Mini Port Protocol fields\r
+ //\r
+ BiosVideoPrivate->VgaMiniPort.SetMode = BiosVideoVgaMiniPortSetMode;\r
+ BiosVideoPrivate->VgaMiniPort.VgaMemoryOffset = 0xb8000;\r
+ BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterOffset = 0x3d4;\r
+ BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterOffset = 0x3d5;\r
+ BiosVideoPrivate->VgaMiniPort.VgaMemoryBar = EFI_PCI_IO_PASS_THROUGH_BAR;\r
+ BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR;\r
+ BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR;\r
+\r
+ //\r
+ // Assume that UGA Draw will be produced until proven otherwise\r
+ //\r
+ BiosVideoPrivate->ProduceUgaDraw = TRUE;\r
+\r
+ //\r
+ // Check for VESA BIOS Extensions for modes that are compatible with UGA Draw\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
+ // for the standard 640x480 16 color VGA mode\r
+ //\r
+ if (BiosVideoPrivate->VgaCompatible) {\r
+ Status = BiosVideoCheckForVga (BiosVideoPrivate);\r
+ }\r
+\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
+ //\r
+ BiosVideoPrivate->ProduceUgaDraw = FALSE;\r
+\r
+ //\r
+ // INT services are available, so on the 80x25 and 80x50 text mode are supported\r
+ //\r
+ BiosVideoPrivate->VgaMiniPort.MaxMode = 2;\r
+ }\r
+ }\r
+\r
+ if (BiosVideoPrivate->ProduceUgaDraw) {\r
+ DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart: Produce Uga Draw!\n"));\r
+ //\r
+ // Install UGA Draw Protocol\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Controller,\r
+ &gEfiUgaDrawProtocolGuid,\r
+ &BiosVideoPrivate->UgaDraw,\r
+ NULL\r
+ );\r
+ } else {\r
+ //\r
+ // Install VGA Mini Port Protocol\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Controller,\r
+ &gEfiVgaMiniPortProtocolGuid,\r
+ &BiosVideoPrivate->VgaMiniPort,\r
+ NULL\r
+ );\r
+ }\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
+\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
+ EFI_UGA_DRAW_PROTOCOL *Uga;\r
+ EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ EFI_IA32_REGISTER_SET Regs;\r
+\r
+ BiosVideoPrivate = NULL;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiUgaDrawProtocolGuid,\r
+ (VOID **) &Uga,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (Uga);\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiVgaMiniPortProtocolGuid,\r
+ (VOID **) &VgaMiniPort,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS (VgaMiniPort);\r
+ }\r
+\r
+ if (BiosVideoPrivate == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (BiosVideoPrivate->ProduceUgaDraw) {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ Controller,\r
+ &gEfiUgaDrawProtocolGuid,\r
+ &BiosVideoPrivate->UgaDraw,\r
+ NULL\r
+ );\r
+ } else {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ Controller,\r
+ &gEfiVgaMiniPortProtocolGuid,\r
+ &BiosVideoPrivate->VgaMiniPort,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\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
+ Regs.H.AH = 0x11;\r
+ Regs.H.AL = 0x14;\r
+ Regs.H.BL = 0;\r
+ LegacyBiosInt86 (0x10, &Regs);\r
+\r
+ //\r
+ // Do not disable IO/memory decode since that would prevent legacy ROM from working\r
+ //\r
+ //\r
+ // Free VGA Frame Buffer\r
+ //\r
+ if (BiosVideoPrivate->VgaFrameBuffer != NULL) {\r
+ gBS->FreePool (BiosVideoPrivate->VgaFrameBuffer);\r
+ }\r
+ //\r
+ // Free VBE Frame Buffer\r
+ //\r
+ if (BiosVideoPrivate->VbeFrameBuffer != NULL) {\r
+ gBS->FreePool (BiosVideoPrivate->VbeFrameBuffer);\r
+ }\r
+ //\r
+ // Free line buffer\r
+ //\r
+ if (BiosVideoPrivate->LineBuffer != NULL) {\r
+ gBS->FreePool (BiosVideoPrivate->LineBuffer);\r
+ }\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->VbeSaveRestorePages != 0) {\r
+ gBS->FreePages (BiosVideoPrivate->VbeSaveRestoreBuffer, BiosVideoPrivate->VbeSaveRestorePages);\r
+ }\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
+ gBS->CloseEvent (BiosVideoPrivate->ExitBootServicesEvent);\r
+\r
+ //\r
+ // Free private data structure\r
+ //\r
+ gBS->FreePool (BiosVideoPrivate);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+#define PCI_DEVICE_ENABLED (EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE)\r
+\r
+\r
+BOOLEAN\r
+BiosVideoIsVga (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ BOOLEAN VgaCompatible;\r
+ PCI_TYPE00 Pci;\r
+\r
+ VgaCompatible = FALSE;\r
+\r
+ //\r
+ // Read the PCI Configuration Header\r
+ //\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0,\r
+ sizeof (Pci) / sizeof (UINT32),\r
+ &Pci\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return VgaCompatible;\r
+ }\r
+\r
+ //\r
+ // See if this is a VGA compatible controller or not\r
+ //\r
+ if ((Pci.Hdr.Command & PCI_DEVICE_ENABLED) == PCI_DEVICE_ENABLED) {\r
+ if (Pci.Hdr.ClassCode[2] == PCI_CLASS_OLD && Pci.Hdr.ClassCode[1] == PCI_CLASS_OLD_VGA) {\r
+ //\r
+ // Base Class 0x00 Sub-Class 0x01 - Backward compatible VGA device\r
+ //\r
+ VgaCompatible = TRUE;\r
+ }\r
+\r
+ if (Pci.Hdr.ClassCode[2] == PCI_CLASS_DISPLAY && Pci.Hdr.ClassCode[1] == PCI_CLASS_DISPLAY_VGA && Pci.Hdr.ClassCode[0] == 0x00) {\r
+ //\r
+ // Base Class 3 Sub-Class 0 Programming interface 0 - VGA compatible Display controller\r
+ //\r
+ VgaCompatible = TRUE;\r
+ }\r
+ }\r
+\r
+ return VgaCompatible;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+BiosVideoCheckForVbe (\r
+ IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate \r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+\r
+ Check for VBE device \r
+ \r
+ Arguments:\r
+ \r
+ BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS - VBE device found\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
+\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_CRTC_INFORMATION_BLOCK)\r
+ );\r
+\r
+ BiosVideoPrivate->PagesBelow1MB = 0x00100000 - 1;\r
+\r
+ Status = gBS->AllocatePages (\r
+ AllocateMaxAddress,\r
+ EfiBootServicesData,\r
+ BiosVideoPrivate->NumberOfPagesBelow1MB,\r
+ &BiosVideoPrivate->PagesBelow1MB\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Fill in the UGA Draw Protocol\r
+ //\r
+ BiosVideoPrivate->UgaDraw.GetMode = BiosVideoUgaDrawGetMode;\r
+ BiosVideoPrivate->UgaDraw.SetMode = BiosVideoUgaDrawSetMode;\r
+ BiosVideoPrivate->UgaDraw.Blt = BiosVideoUgaDrawVbeBlt;\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->VbeSaveRestorePages = 0;\r
+ BiosVideoPrivate->VbeSaveRestoreBuffer = 0;\r
+\r
+ //\r
+ // Test to see if the Video Adapter is compliant with VBE 3.0\r
+ //\r
+ gBS->SetMem (&Regs, sizeof (Regs), 0);\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
+\r
+ Status = EFI_DEVICE_ERROR;\r
+\r
+ //\r
+ // See if the VESA call succeeded\r
+ //\r
+ if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Check for 'VESA' signature\r
+ //\r
+ if (BiosVideoPrivate->VbeInformationBlock->VESASignature != VESA_BIOS_EXTENSIONS_VESA_SIGNATURE) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Check to see if this is VBE 2.0 or higher\r
+ //\r
+ if (BiosVideoPrivate->VbeInformationBlock->VESAVersion < VESA_BIOS_EXTENSIONS_VERSION_2_0) {\r
+ return Status;\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
+ //\r
+ ModeNumberPtr = (UINT16 *)\r
+ (\r
+ (((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0xffff0000) >> 12) |\r
+ ((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0x0000ffff)\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
+ //\r
+ if ((*ModeNumberPtr & VESA_BIOS_EXTENSIONS_MODE_NUMBER_VESA) == 0) {\r
+ continue;\r
+ }\r
+ //\r
+ // Get the information about the mode\r
+ //\r
+ gBS->SetMem (&Regs, sizeof (Regs), 0);\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
+\r
+ //\r
+ // See if the call succeeded. If it didn't, then try the next mode.\r
+ //\r
+ if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {\r
+ continue;\r
+ }\r
+ //\r
+ // See if the mode supports color. If it doesn't then try the next mode.\r
+ //\r
+ if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_COLOR) == 0) {\r
+ continue;\r
+ }\r
+ //\r
+ // See if the mode supports graphics. If it doesn't then try the next mode.\r
+ //\r
+ if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_GRAPHICS) == 0) {\r
+ continue;\r
+ }\r
+ //\r
+ // See if the mode supports a linear frame buffer. If it doesn't then try the next mode.\r
+ //\r
+ if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER) == 0) {\r
+ continue;\r
+ }\r
+ //\r
+ // See if the mode supports 32 bit color. If it doesn't then try the next mode.\r
+ // 32 bit mode can be implemented by 24 Bits Per Pixels. Also make sure the\r
+ // number of bits per pixel is a multiple of 8 or more than 32 bits per pixel\r
+ //\r
+ if (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel < 24) {\r
+ continue;\r
+ }\r
+\r
+ if (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel > 32) {\r
+ continue;\r
+ }\r
+\r
+ if ((BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel % 8) != 0) {\r
+ continue;\r
+ }\r
+ //\r
+ // See if the physical base pointer for the linear mode is valid. If it isn't then try the next mode.\r
+ //\r
+ if (BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr == 0) {\r
+ continue;\r
+ }\r
+ //\r
+ // See if the resolution is 1024x768, 800x600, or 640x480\r
+ //\r
+ ModeFound = FALSE;\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
+ }\r
+\r
+ if (BiosVideoPrivate->VbeModeInformationBlock->XResolution == 640 &&\r
+ BiosVideoPrivate->VbeModeInformationBlock->YResolution == 480\r
+ ) {\r
+ ModeFound = TRUE;\r
+ }\r
+\r
+ if (!ModeFound) {\r
+ continue;\r
+ }\r
+ //\r
+ // Add mode to the list of available modes\r
+ //\r
+ BiosVideoPrivate->MaxMode++;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ BiosVideoPrivate->MaxMode * 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
+ 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
+ }\r
+\r
+ ModeBuffer[BiosVideoPrivate->MaxMode - 1].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
+ } 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
+ }\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
+ }\r
+\r
+ ModeBuffer[BiosVideoPrivate->MaxMode - 1].BitsPerPixel = BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel;\r
+\r
+ ModeBuffer[BiosVideoPrivate->MaxMode - 1].RefreshRate = 60;\r
+\r
+ BiosVideoPrivate->ModeData = ModeBuffer;\r
+ }\r
+ //\r
+ // Check to see if we found any modes that are compatible with UGA DRAW\r
+ //\r
+ if (BiosVideoPrivate->MaxMode == 0) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\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
+ 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
+ }\r
+ }\r
+ }\r
+\r
+Done:\r
+ //\r
+ // If there was an error, then free the mode structure\r
+ //\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
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+BiosVideoCheckForVga (\r
+ IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate \r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+\r
+ Check for VGA device\r
+ \r
+ Arguments:\r
+ \r
+ BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS - Standard VGA device found\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ BIOS_VIDEO_MODE_DATA *ModeBuffer;\r
+\r
+ //\r
+ // Fill in the UGA Draw Protocol\r
+ //\r
+ BiosVideoPrivate->UgaDraw.GetMode = BiosVideoUgaDrawGetMode;\r
+ BiosVideoPrivate->UgaDraw.SetMode = BiosVideoUgaDrawSetMode;\r
+ BiosVideoPrivate->UgaDraw.Blt = BiosVideoUgaDrawVgaBlt;\r
+\r
+ //\r
+ // Add mode to the list of available modes\r
+ //\r
+ BiosVideoPrivate->MaxMode++;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ BiosVideoPrivate->MaxMode * 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
+ }\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
+\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
+\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
+ }\r
+\r
+ return Status;\r
+}\r
+//\r
+// UGA 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
+ )\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
+\r
+Returns:\r
+\r
+ EFI_DEVICE_ERROR - Hardware need starting\r
+ EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+ EFI_SUCCESS - Video mode query successfully\r
+\r
+--*/\r
+{\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+\r
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (This);\r
+\r
+ if (BiosVideoPrivate->HardwareNeedsStarting) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ if (HorizontalResolution == NULL || VerticalResolution == NULL || ColorDepth == NULL || RefreshRate == NULL) {\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
+\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
+ )\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
+\r
+Returns:\r
+\r
+ EFI_DEVICE_ERROR - Device error\r
+ EFI_SUCCESS - Video mode set successfully\r
+ EFI_UNSUPPORTED - Cannot support this video mode\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ UINTN Index;\r
+ EFI_IA32_REGISTER_SET Regs;\r
+\r
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (This);\r
+\r
+ for (Index = 0; Index < BiosVideoPrivate->MaxMode; Index++) {\r
+\r
+ if (HorizontalResolution != BiosVideoPrivate->ModeData[Index].HorizontalResolution) {\r
+ continue;\r
+ }\r
+\r
+ if (VerticalResolution != BiosVideoPrivate->ModeData[Index].VerticalResolution) {\r
+ continue;\r
+ }\r
+\r
+ if (ColorDepth != BiosVideoPrivate->ModeData[Index].ColorDepth) {\r
+ continue;\r
+ }\r
+\r
+ if (RefreshRate != BiosVideoPrivate->ModeData[Index].RefreshRate) {\r
+ continue;\r
+ }\r
+\r
+ if (BiosVideoPrivate->LineBuffer) {\r
+ gBS->FreePool (BiosVideoPrivate->LineBuffer);\r
+ }\r
+\r
+ if (BiosVideoPrivate->VgaFrameBuffer) {\r
+ gBS->FreePool (BiosVideoPrivate->VgaFrameBuffer);\r
+ }\r
+\r
+ if (BiosVideoPrivate->VbeFrameBuffer) {\r
+ gBS->FreePool (BiosVideoPrivate->VbeFrameBuffer);\r
+ }\r
+\r
+ BiosVideoPrivate->LineBuffer = NULL;\r
+ Status = gBS->AllocatePool (\r
+ EfiBootServicesData,\r
+ BiosVideoPrivate->ModeData[Index].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
+ 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
+ &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
+ &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
+\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
+ }\r
+\r
+ BiosVideoPrivate->CurrentMode = Index;\r
+\r
+ BiosVideoPrivate->HardwareNeedsStarting = FALSE;\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+VOID\r
+CopyVideoBuffer (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT8 *VbeBuffer,\r
+ IN VOID *MemAddress,\r
+ IN UINTN DestinationX,\r
+ IN UINTN DestinationY,\r
+ IN UINTN TotalBytes,\r
+ IN UINT32 VbePixelWidth,\r
+ IN UINTN BytesPerScanLine\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Update physical frame buffer, copy 4 bytes block, then copy remaining bytes.\r
+\r
+Arguments:\r
+\r
+ PciIo - The pointer of EFI_PCI_IO_PROTOCOL\r
+ VbeBuffer - The data to transfer to screen\r
+ MemAddress - Physical frame buffer base address\r
+ DestinationX - The X coordinate of the destination for BltOperation\r
+ DestinationY - The Y coordinate of the destination for BltOperation\r
+ TotalBytes - The total bytes of copy\r
+ VbePixelWidth - Bytes per pixel\r
+ BytesPerScanLine - Bytes per scan line\r
+\r
+Returns:\r
+\r
+ None.\r
+\r
+--*/\r
+{\r
+ UINTN FrameBufferAddr;\r
+ UINTN CopyBlockNum;\r
+ UINTN RemainingBytes;\r
+ UINTN UnalignedBytes;\r
+ EFI_STATUS Status;\r
+\r
+ FrameBufferAddr = (UINTN) MemAddress + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth;\r
+\r
+ //\r
+ // If TotalBytes is less than 4 bytes, only start byte copy.\r
+ //\r
+ if (TotalBytes < 4) {\r
+ Status = PciIo->Mem.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) FrameBufferAddr,\r
+ TotalBytes,\r
+ VbeBuffer\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ return;\r
+ }\r
+\r
+ //\r
+ // If VbeBuffer is not 4-byte aligned, start byte copy.\r
+ //\r
+ UnalignedBytes = (4 - ((UINTN) VbeBuffer & 0x3)) & 0x3;\r
+\r
+ if (UnalignedBytes != 0) {\r
+ Status = PciIo->Mem.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) FrameBufferAddr,\r
+ UnalignedBytes,\r
+ VbeBuffer\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ FrameBufferAddr += UnalignedBytes;\r
+ VbeBuffer += UnalignedBytes;\r
+ }\r
+\r
+ //\r
+ // Calculate 4-byte block count and remaining bytes.\r
+ //\r
+ CopyBlockNum = (TotalBytes - UnalignedBytes) >> 2;\r
+ RemainingBytes = (TotalBytes - UnalignedBytes) & 3;\r
+\r
+ //\r
+ // Copy 4-byte block and remaining bytes to physical frame buffer.\r
+ //\r
+ if (CopyBlockNum != 0) {\r
+ Status = PciIo->Mem.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) FrameBufferAddr,\r
+ CopyBlockNum,\r
+ VbeBuffer\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ if (RemainingBytes != 0) {\r
+ FrameBufferAddr += (CopyBlockNum << 2);\r
+ VbeBuffer += (CopyBlockNum << 2);\r
+ Status = PciIo->Mem.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) FrameBufferAddr,\r
+ RemainingBytes,\r
+ VbeBuffer\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+}\r
+\r
+//\r
+// BUGBUG : Add Blt for 16 bit color, 15 bit color, and 8 bit color modes\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
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ UGA draw protocol instance to block transfer for VBE device\r
+\r
+Arguments:\r
+\r
+ This - Pointer to UGA draw 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
+ SourceY - The Y coordinate of the source for BltOperation\r
+ DestinationX - The X coordinate of the destination 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
+ 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
+ the number of bytes in a row of the BltBuffer.\r
+\r
+Returns:\r
+\r
+ EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+ EFI_SUCCESS - Blt operation success\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
+ PciIo = BiosVideoPrivate->PciIo;\r
+\r
+ VbeFrameBuffer = BiosVideoPrivate->VbeFrameBuffer;\r
+ MemAddress = Mode->LinearFrameBuffer;\r
+ BytesPerScanLine = Mode->BytesPerScanLine;\r
+ VbePixelWidth = Mode->BitsPerPixel / 8;\r
+ BltUint8 = (UINT8 *) BltBuffer;\r
+ TotalBytes = Width * VbePixelWidth;\r
+\r
+ if ((BltOperation < EfiUgaVideoFill) || (BltOperation >= EfiUgaBltMax)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Width == 0 || Height == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // We need to fill the Virtual Screen buffer with the blt data.\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
+ //\r
+ // Video to BltBuffer: Source is Video, destination is BltBuffer\r
+ //\r
+ if (SourceY + Height > Mode->VerticalResolution) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (SourceX + Width > Mode->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 > Mode->VerticalResolution) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (DestinationX + Width > Mode->HorizontalResolution) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ //\r
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta\r
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,\r
+ // the number of bytes in each row can be computed.\r
+ //\r
+ if (Delta == 0) {\r
+ Delta = Width * sizeof (EFI_UGA_PIXEL);\r
+ }\r
+ //\r
+ // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
+ // We would not want a timer based event (Cursor, ...) to come in while we are\r
+ // doing this operation.\r
+ //\r
+ OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ switch (BltOperation) {\r
+ case EfiUgaVideoToBltBuffer:\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
+ //\r
+ // Shuffle the packed bytes in the hardware buffer to match EFI_UGA_PIXEL\r
+ //\r
+ VbeBuffer = ((UINT8 *) VbeFrameBuffer + (SrcY * BytesPerScanLine + SourceX * VbePixelWidth));\r
+ for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {\r
+ Pixel = *(UINT32 *) (VbeBuffer);\r
+ Blt->Red = (UINT8) ((Pixel >> Mode->Red.Position) & Mode->Red.Mask);\r
+ Blt->Blue = (UINT8) ((Pixel >> Mode->Blue.Position) & Mode->Blue.Mask);\r
+ Blt->Green = (UINT8) ((Pixel >> Mode->Green.Position) & Mode->Green.Mask);\r
+ Blt->Reserved = 0;\r
+ Blt++;\r
+ VbeBuffer += VbePixelWidth;\r
+ }\r
+\r
+ }\r
+ break;\r
+\r
+ case EfiUgaVideoToVideo:\r
+ for (Index = 0; Index < Height; Index++) {\r
+ if (DestinationY <= SourceY) {\r
+ SrcY = SourceY + Index;\r
+ DstY = DestinationY + Index;\r
+ } else {\r
+ SrcY = SourceY + Height - Index - 1;\r
+ DstY = DestinationY + Height - Index - 1;\r
+ }\r
+\r
+ VbeBuffer = ((UINT8 *) VbeFrameBuffer + DstY * BytesPerScanLine + DestinationX * VbePixelWidth);\r
+ VbeBuffer1 = ((UINT8 *) VbeFrameBuffer + SrcY * BytesPerScanLine + SourceX * VbePixelWidth);\r
+\r
+ gBS->CopyMem (\r
+ VbeBuffer,\r
+ VbeBuffer1,\r
+ TotalBytes\r
+ );\r
+\r
+ //\r
+ // Update physical frame buffer.\r
+ //\r
+ CopyVideoBuffer (\r
+ PciIo,\r
+ VbeBuffer,\r
+ MemAddress,\r
+ DestinationX,\r
+ DstY,\r
+ TotalBytes,\r
+ VbePixelWidth,\r
+ BytesPerScanLine\r
+ );\r
+ }\r
+ break;\r
+\r
+ case EfiUgaVideoFill:\r
+ VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth);\r
+ Blt = (EFI_UGA_PIXEL *) BltUint8;\r
+ //\r
+ // Shuffle the RGB fields in EFI_UGA_PIXEL to match the hardware buffer\r
+ //\r
+ Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) |\r
+ (\r
+ (Blt->Green & Mode->Green.Mask) <<\r
+ Mode->Green.Position\r
+ ) |\r
+ ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position);\r
+\r
+ for (Index = 0; Index < Width; Index++) {\r
+ gBS->CopyMem (\r
+ VbeBuffer,\r
+ &Pixel,\r
+ VbePixelWidth\r
+ );\r
+ VbeBuffer += VbePixelWidth;\r
+ }\r
+\r
+ VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth);\r
+ for (DstY = DestinationY + 1; DstY < (Height + DestinationY); DstY++) {\r
+ gBS->CopyMem (\r
+ (VOID *) ((UINTN) VbeFrameBuffer + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth),\r
+ VbeBuffer,\r
+ TotalBytes\r
+ );\r
+ }\r
+ for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {\r
+ //\r
+ // Update physical frame buffer.\r
+ //\r
+ CopyVideoBuffer (\r
+ PciIo,\r
+ VbeBuffer,\r
+ MemAddress,\r
+ DestinationX,\r
+ DstY,\r
+ TotalBytes,\r
+ VbePixelWidth,\r
+ BytesPerScanLine\r
+ );\r
+ }\r
+\r
+ break;\r
+\r
+ case EfiUgaBltBufferToVideo:\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
+ 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
+ //\r
+ Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) |\r
+ ((Blt->Green & Mode->Green.Mask) << Mode->Green.Position) |\r
+ ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position);\r
+ gBS->CopyMem (\r
+ VbeBuffer,\r
+ &Pixel,\r
+ VbePixelWidth\r
+ );\r
+ Blt++;\r
+ VbeBuffer += VbePixelWidth;\r
+ }\r
+\r
+ VbeBuffer = ((UINT8 *) VbeFrameBuffer + (DstY * BytesPerScanLine + DestinationX * VbePixelWidth));\r
+\r
+ //\r
+ // Update physical frame buffer.\r
+ //\r
+ CopyVideoBuffer (\r
+ PciIo,\r
+ VbeBuffer,\r
+ MemAddress,\r
+ DestinationX,\r
+ DstY,\r
+ TotalBytes,\r
+ VbePixelWidth,\r
+ BytesPerScanLine\r
+ );\r
+ }\r
+ break;\r
+ }\r
+\r
+ gBS->RestoreTPL (OriginalTPL);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+VOID\r
+WriteGraphicsController (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINTN Address,\r
+ IN UINTN Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Write graphics controller registers\r
+\r
+Arguments:\r
+\r
+ PciIo - Pointer to PciIo protocol instance of the controller\r
+ Address - Register address\r
+ Data - Data to be written to register\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ Address = Address | (Data << 8);\r
+ PciIo->Io.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ VGA_GRAPHICS_CONTROLLER_ADDRESS_REGISTER,\r
+ 1,\r
+ &Address\r
+ );\r
+}\r
+\r
+VOID\r
+VgaReadBitPlanes (\r
+ EFI_PCI_IO_PROTOCOL *PciIo,\r
+ UINT8 *HardwareBuffer,\r
+ UINT8 *MemoryBuffer,\r
+ UINTN WidthInBytes,\r
+ UINTN Height\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read the four bit plane of VGA frame buffer\r
+\r
+Arguments:\r
+\r
+ PciIo - Pointer to PciIo protocol instance of the controller\r
+ HardwareBuffer - Hardware VGA frame buffer address\r
+ MemoryBuffer - Memory buffer address\r
+ WidthInBytes - Number of bytes in a line to read\r
+ Height - Height of the area to read\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINTN BitPlane;\r
+ UINTN Rows;\r
+ UINTN FrameBufferOffset;\r
+ UINT8 *Source;\r
+ UINT8 *Destination;\r
+\r
+ //\r
+ // Program the Mode Register Write mode 0, Read mode 0\r
+ //\r
+ WriteGraphicsController (\r
+ PciIo,\r
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,\r
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_0\r
+ );\r
+\r
+ for (BitPlane = 0, FrameBufferOffset = 0;\r
+ BitPlane < VGA_NUMBER_OF_BIT_PLANES;\r
+ BitPlane++, FrameBufferOffset += VGA_BYTES_PER_BIT_PLANE\r
+ ) {\r
+ //\r
+ // Program the Read Map Select Register to select the correct bit plane\r
+ //\r
+ WriteGraphicsController (\r
+ PciIo,\r
+ VGA_GRAPHICS_CONTROLLER_READ_MAP_SELECT_REGISTER,\r
+ BitPlane\r
+ );\r
+\r
+ Source = HardwareBuffer;\r
+ Destination = MemoryBuffer + FrameBufferOffset;\r
+\r
+ for (Rows = 0; Rows < Height; Rows++, Source += VGA_BYTES_PER_SCAN_LINE, Destination += VGA_BYTES_PER_SCAN_LINE) {\r
+ PciIo->Mem.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Source,\r
+ WidthInBytes,\r
+ (VOID *) Destination\r
+ );\r
+ }\r
+ }\r
+}\r
+\r
+VOID\r
+VgaConvertToUgaColor (\r
+ UINT8 *MemoryBuffer,\r
+ UINTN X,\r
+ UINTN Y,\r
+ EFI_UGA_PIXEL *BltBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Internal routine to convert VGA color to UGA 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
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINTN Mask;\r
+ UINTN Bit;\r
+ UINTN Color;\r
+\r
+ MemoryBuffer += ((Y << 6) + (Y << 4) + (X >> 3));\r
+ Mask = mVgaBitMaskTable[X & 0x07];\r
+ for (Bit = 0x01, Color = 0; Bit < 0x10; Bit <<= 1, MemoryBuffer += VGA_BYTES_PER_BIT_PLANE) {\r
+ if (*MemoryBuffer & Mask) {\r
+ Color |= Bit;\r
+ }\r
+ }\r
+\r
+ *BltBuffer = mVgaColorToUgaColor[Color];\r
+}\r
+\r
+UINT8\r
+VgaConvertColor (\r
+ IN EFI_UGA_PIXEL *BltBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Internal routine to convert UGA color to VGA color\r
+\r
+Arguments:\r
+\r
+ BltBuffer - buffer containing UGA color\r
+\r
+Returns:\r
+\r
+ Converted VGA color\r
+\r
+--*/\r
+{\r
+ UINT8 Color;\r
+\r
+ Color = (UINT8) ((BltBuffer->Blue >> 7) | ((BltBuffer->Green >> 6) & 0x02) | ((BltBuffer->Red >> 5) & 0x04));\r
+ if ((BltBuffer->Red + BltBuffer->Green + BltBuffer->Blue) > 0x180) {\r
+ Color |= 0x08;\r
+ }\r
+\r
+ return Color;\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
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ UGA draw protocol instance to block transfer for VGA device\r
+\r
+Arguments:\r
+\r
+ This - Pointer to UGA draw 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
+ SourceY - The Y coordinate of the source for BltOperation\r
+ DestinationX - The X coordinate of the destination 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
+ 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
+ the number of bytes in a row of the BltBuffer.\r
+\r
+Returns:\r
+\r
+ EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+ EFI_SUCCESS - Blt operation success\r
+\r
+--*/\r
+{\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ EFI_TPL OriginalTPL;\r
+ UINT8 *MemAddress;\r
+ UINTN BytesPerScanLine;\r
+ UINTN BytesPerBitPlane;\r
+ UINTN Bit;\r
+ UINTN Index;\r
+ UINTN Index1;\r
+ UINTN StartAddress;\r
+ UINTN Bytes;\r
+ UINTN Offset;\r
+ UINT8 LeftMask;\r
+ UINT8 RightMask;\r
+ UINTN Address;\r
+ UINTN AddressFix;\r
+ UINT8 *Address1;\r
+ UINT8 *SourceAddress;\r
+ UINT8 *DestinationAddress;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT8 Data;\r
+ UINT8 PixelColor;\r
+ UINT8 *VgaFrameBuffer;\r
+ UINTN SourceOffset;\r
+ UINTN SourceWidth;\r
+ UINTN Rows;\r
+ UINTN Columns;\r
+ UINTN X;\r
+ UINTN Y;\r
+\r
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (This);\r
+\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
+ VgaFrameBuffer = BiosVideoPrivate->VgaFrameBuffer;\r
+\r
+ if ((BltOperation < EfiUgaVideoFill) || (BltOperation >= EfiUgaBltMax)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Width == 0 || Height == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // We need to fill the Virtual Screen buffer with the blt data.\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
+ //\r
+ // Video to BltBuffer: Source is Video, destination is BltBuffer\r
+ //\r
+ if (SourceY + Height > BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].VerticalResolution) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (SourceX + Width > BiosVideoPrivate->ModeData[BiosVideoPrivate->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
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (DestinationX + Width > BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].HorizontalResolution) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ //\r
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta\r
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,\r
+ // the number of bytes in each row can be computed.\r
+ //\r
+ if (Delta == 0) {\r
+ Delta = Width * sizeof (EFI_UGA_PIXEL);\r
+ }\r
+ //\r
+ // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
+ // We would not want a timer based event (Cursor, ...) to come in while we are\r
+ // doing this operation.\r
+ //\r
+ OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+ //\r
+ // Compute some values we need for VGA\r
+ //\r
+ switch (BltOperation) {\r
+ case EfiUgaVideoToBltBuffer:\r
+\r
+ SourceOffset = (SourceY << 6) + (SourceY << 4) + (SourceX >> 3);\r
+ SourceWidth = ((SourceX + Width - 1) >> 3) - (SourceX >> 3) + 1;\r
+\r
+ //\r
+ // Read all the pixels in the 4 bit planes into a memory buffer that looks like the VGA buffer\r
+ //\r
+ VgaReadBitPlanes (\r
+ PciIo,\r
+ MemAddress + SourceOffset,\r
+ VgaFrameBuffer + SourceOffset,\r
+ SourceWidth,\r
+ Height\r
+ );\r
+\r
+ //\r
+ // Convert VGA Bit Planes to a UGA 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
+ }\r
+\r
+ BltBuffer -= Width;\r
+ }\r
+\r
+ break;\r
+\r
+ case EfiUgaVideoToVideo:\r
+ //\r
+ // Check for an aligned Video to Video operation\r
+ //\r
+ if ((SourceX & 0x07) == 0x00 && (DestinationX & 0x07) == 0x00 && (Width & 0x07) == 0x00) {\r
+ //\r
+ // Program the Mode Register Write mode 1, Read mode 0\r
+ //\r
+ WriteGraphicsController (\r
+ BiosVideoPrivate->PciIo,\r
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,\r
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_1\r
+ );\r
+\r
+ SourceAddress = (UINT8 *) (MemAddress + (SourceY << 6) + (SourceY << 4) + (SourceX >> 3));\r
+ DestinationAddress = (UINT8 *) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3));\r
+ Bytes = Width >> 3;\r
+ for (Index = 0, Offset = 0; Index < Height; Index++, Offset += BytesPerScanLine) {\r
+ PciIo->CopyMem (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) (DestinationAddress + Offset),\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) (SourceAddress + Offset),\r
+ Bytes\r
+ );\r
+ }\r
+ } else {\r
+ SourceOffset = (SourceY << 6) + (SourceY << 4) + (SourceX >> 3);\r
+ SourceWidth = ((SourceX + Width - 1) >> 3) - (SourceX >> 3) + 1;\r
+\r
+ //\r
+ // Read all the pixels in the 4 bit planes into a memory buffer that looks like the VGA buffer\r
+ //\r
+ VgaReadBitPlanes (\r
+ PciIo,\r
+ MemAddress + SourceOffset,\r
+ VgaFrameBuffer + SourceOffset,\r
+ SourceWidth,\r
+ Height\r
+ );\r
+ }\r
+\r
+ break;\r
+\r
+ case EfiUgaVideoFill:\r
+ StartAddress = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3));\r
+ Bytes = ((DestinationX + Width - 1) >> 3) - (DestinationX >> 3);\r
+ LeftMask = mVgaLeftMaskTable[DestinationX & 0x07];\r
+ RightMask = mVgaRightMaskTable[(DestinationX + Width - 1) & 0x07];\r
+ if (Bytes == 0) {\r
+ LeftMask &= RightMask;\r
+ RightMask = 0;\r
+ }\r
+\r
+ if (LeftMask == 0xff) {\r
+ StartAddress--;\r
+ Bytes++;\r
+ LeftMask = 0;\r
+ }\r
+\r
+ if (RightMask == 0xff) {\r
+ Bytes++;\r
+ RightMask = 0;\r
+ }\r
+\r
+ PixelColor = VgaConvertColor (BltBuffer);\r
+\r
+ //\r
+ // Program the Mode Register Write mode 2, Read mode 0\r
+ //\r
+ WriteGraphicsController (\r
+ BiosVideoPrivate->PciIo,\r
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,\r
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2\r
+ );\r
+\r
+ //\r
+ // Program the Data Rotate/Function Select Register to replace\r
+ //\r
+ WriteGraphicsController (\r
+ BiosVideoPrivate->PciIo,\r
+ VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER,\r
+ VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE\r
+ );\r
+\r
+ if (LeftMask != 0) {\r
+ //\r
+ // Program the BitMask register with the Left column mask\r
+ //\r
+ WriteGraphicsController (\r
+ BiosVideoPrivate->PciIo,\r
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
+ LeftMask\r
+ );\r
+\r
+ for (Index = 0, Address = StartAddress; Index < Height; Index++, Address += BytesPerScanLine) {\r
+ //\r
+ // Read data from the bit planes into the latches\r
+ //\r
+ PciIo->Mem.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Address,\r
+ 1,\r
+ &Data\r
+ );\r
+ //\r
+ // Write the lower 4 bits of PixelColor to the bit planes in the pixels enabled by BitMask\r
+ //\r
+ PciIo->Mem.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Address,\r
+ 1,\r
+ &PixelColor\r
+ );\r
+ }\r
+ }\r
+\r
+ if (Bytes > 1) {\r
+ //\r
+ // Program the BitMask register with the middle column mask of 0xff\r
+ //\r
+ WriteGraphicsController (\r
+ BiosVideoPrivate->PciIo,\r
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
+ 0xff\r
+ );\r
+\r
+ for (Index = 0, Address = StartAddress + 1; Index < Height; Index++, Address += BytesPerScanLine) {\r
+ PciIo->Mem.Write (\r
+ PciIo,\r
+ EfiPciIoWidthFillUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Address,\r
+ Bytes - 1,\r
+ &PixelColor\r
+ );\r
+ }\r
+ }\r
+\r
+ if (RightMask != 0) {\r
+ //\r
+ // Program the BitMask register with the Right column mask\r
+ //\r
+ WriteGraphicsController (\r
+ BiosVideoPrivate->PciIo,\r
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
+ RightMask\r
+ );\r
+\r
+ for (Index = 0, Address = StartAddress + Bytes; Index < Height; Index++, Address += BytesPerScanLine) {\r
+ //\r
+ // Read data from the bit planes into the latches\r
+ //\r
+ PciIo->Mem.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Address,\r
+ 1,\r
+ &Data\r
+ );\r
+ //\r
+ // Write the lower 4 bits of PixelColor to the bit planes in the pixels enabled by BitMask\r
+ //\r
+ PciIo->Mem.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Address,\r
+ 1,\r
+ &PixelColor\r
+ );\r
+ }\r
+ }\r
+ break;\r
+\r
+ case EfiUgaBltBufferToVideo:\r
+ StartAddress = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3));\r
+ LeftMask = mVgaBitMaskTable[DestinationX & 0x07];\r
+\r
+ //\r
+ // Program the Mode Register Write mode 2, Read mode 0\r
+ //\r
+ WriteGraphicsController (\r
+ BiosVideoPrivate->PciIo,\r
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,\r
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2\r
+ );\r
+\r
+ //\r
+ // Program the Data Rotate/Function Select Register to replace\r
+ //\r
+ WriteGraphicsController (\r
+ BiosVideoPrivate->PciIo,\r
+ VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER,\r
+ VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE\r
+ );\r
+\r
+ for (Index = 0, Address = StartAddress; Index < Height; Index++, Address += BytesPerScanLine) {\r
+ for (Index1 = 0; Index1 < Width; Index1++) {\r
+ BiosVideoPrivate->LineBuffer[Index1] = VgaConvertColor (&BltBuffer[(SourceY + Index) * (Delta >> 2) + SourceX + Index1]);\r
+ }\r
+ AddressFix = Address;\r
+\r
+ for (Bit = 0; Bit < 8; Bit++) {\r
+ //\r
+ // Program the BitMask register with the Left column mask\r
+ //\r
+ WriteGraphicsController (\r
+ BiosVideoPrivate->PciIo,\r
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
+ LeftMask\r
+ );\r
+\r
+ for (Index1 = Bit, Address1 = (UINT8 *) AddressFix; Index1 < Width; Index1 += 8, Address1++) {\r
+ //\r
+ // Read data from the bit planes into the latches\r
+ //\r
+ PciIo->Mem.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Address1,\r
+ 1,\r
+ &Data\r
+ );\r
+\r
+ PciIo->Mem.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ (UINT64) Address1,\r
+ 1,\r
+ &BiosVideoPrivate->LineBuffer[Index1]\r
+ );\r
+ }\r
+\r
+ LeftMask = (UINT8) (LeftMask >> 1);\r
+ if (LeftMask == 0) {\r
+ LeftMask = 0x80;\r
+ AddressFix++;\r
+ }\r
+ }\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ gBS->RestoreTPL (OriginalTPL);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+//\r
+// VGA Mini Port Protocol Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+BiosVideoVgaMiniPortSetMode (\r
+ IN EFI_VGA_MINI_PORT_PROTOCOL *This,\r
+ IN UINTN ModeNumber\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ VgaMiniPort protocol interface to set mode\r
+\r
+Arguments:\r
+\r
+ This - Pointer to VgaMiniPort protocol instance\r
+ ModeNumber - The index of the mode\r
+\r
+Returns:\r
+\r
+ EFI_UNSUPPORTED - The requested mode is not supported\r
+ EFI_SUCCESS - The requested mode is set successfully\r
+\r
+--*/\r
+{\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate;\r
+ EFI_IA32_REGISTER_SET Regs;\r
+\r
+ //\r
+ // Make sure the ModeNumber is a valid value\r
+ //\r
+ if (ModeNumber >= This->MaxMode) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ //\r
+ // Get the device structure for this device\r
+ //\r
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS (This);\r
+\r
+ gBS->SetMem (&Regs, sizeof (Regs), 0);\r
+\r
+ switch (ModeNumber) {\r
+ case 0:\r
+ //\r
+ // Set the 80x25 Text VGA Mode\r
+ //\r
+ Regs.H.AH = 0x00;\r
+ Regs.H.AL = 0x83;\r
+ LegacyBiosInt86 (0x10, &Regs);\r
+\r
+ Regs.H.AH = 0x11;\r
+ Regs.H.AL = 0x14;\r
+ Regs.H.BL = 0;\r
+ LegacyBiosInt86 (0x10, &Regs);\r
+ break;\r
+\r
+ case 1:\r
+ //\r
+ // Set the 80x50 Text VGA Mode\r
+ //\r
+ Regs.H.AH = 0x00;\r
+ Regs.H.AL = 0x83;\r
+ LegacyBiosInt86 (0x10, &Regs);\r
+ Regs.H.AH = 0x11;\r
+ Regs.H.AL = 0x12;\r
+ Regs.H.BL = 0;\r
+ LegacyBiosInt86 (0x10, &Regs);\r
+ break;\r
+\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+ }\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
+ UINT32 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
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ BiosVideo.h\r
+ \r
+Abstract: \r
+\r
+Revision History\r
+--*/\r
+\r
+#ifndef _BIOS_UGA_H\r
+#define _BIOS_UGA_H\r
+\r
+#include <Uefi.h>\r
+\r
+//\r
+// Driver Consumed Protocol Prototypes\r
+//\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/PciIo.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/ComponentName2.h>\r
+#include <Protocol/UgaDraw.h>\r
+#include <Protocol/VgaMiniPort.h>\r
+#include <Protocol/Legacy8259.h>\r
+#include <Protocol/LegacyBios.h>\r
+\r
+#include <Library/UefiLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+#include <IndustryStandard/Pci22.h>\r
+\r
+#include "VesaBiosExtensions.h"\r
+//\r
+// Driver Produced Protocol Prototypes\r
+//\r
+//#include EFI_PROTOCOL_DEFINITION (DriverBinding)\r
+//#include EFI_PROTOCOL_DEFINITION (ComponentName)\r
+//#include EFI_PROTOCOL_DEFINITION (ComponentName2)\r
+//#include EFI_PROTOCOL_DEFINITION (UgaDraw)\r
+//#include EFI_PROTOCOL_DEFINITION (VgaMiniPort)\r
+\r
+//\r
+// Packed format support: The number of bits reserved for each of the colors and the actual\r
+// position of RGB in the frame buffer is specified in the VBE Mode information\r
+//\r
+typedef struct {\r
+ UINT8 Position; // Position of the color\r
+ UINT8 Mask; // The number of bits expressed as a mask\r
+} BIOS_VIDEO_COLOR_PLACEMENT;\r
+\r
+//\r
+// BIOS UGA Draw Graphical Mode Data\r
+//\r
+typedef struct {\r
+ UINT16 VbeModeNumber;\r
+ UINT16 BytesPerScanLine;\r
+ VOID *LinearFrameBuffer;\r
+ UINT32 HorizontalResolution;\r
+ UINT32 VerticalResolution;\r
+ UINT32 ColorDepth;\r
+ UINT32 RefreshRate;\r
+ UINT32 BitsPerPixel;\r
+ BIOS_VIDEO_COLOR_PLACEMENT Red;\r
+ BIOS_VIDEO_COLOR_PLACEMENT Green;\r
+ BIOS_VIDEO_COLOR_PLACEMENT Blue;\r
+} BIOS_VIDEO_MODE_DATA;\r
+\r
+//\r
+// BIOS UGA Device Structure\r
+//\r
+#define BIOS_VIDEO_DEV_SIGNATURE SIGNATURE_32 ('B', 'V', 'M', 'p')\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ EFI_HANDLE Handle;\r
+\r
+ //\r
+ // Consumed Protocols\r
+ //\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ //EFI_LEGACY_BIOS_THUNK_PROTOCOL *LegacyBios;\r
+\r
+ //\r
+ // Produced Protocols\r
+ //\r
+ EFI_UGA_DRAW_PROTOCOL UgaDraw;\r
+ EFI_VGA_MINI_PORT_PROTOCOL VgaMiniPort;\r
+\r
+ //\r
+ // General fields\r
+ //\r
+ EFI_EVENT ExitBootServicesEvent;\r
+ BOOLEAN VgaCompatible;\r
+ BOOLEAN ProduceUgaDraw;\r
+\r
+ //\r
+ // UGA Draw related fields\r
+ //\r
+ BOOLEAN HardwareNeedsStarting;\r
+ UINTN CurrentMode;\r
+ UINTN MaxMode;\r
+ BIOS_VIDEO_MODE_DATA *ModeData;\r
+ UINT8 *LineBuffer;\r
+ EFI_UGA_PIXEL *VbeFrameBuffer;\r
+ UINT8 *VgaFrameBuffer;\r
+\r
+ //\r
+ // VESA Bios Extensions related fields\r
+ //\r
+ UINTN NumberOfPagesBelow1MB; // Number of 4KB pages in PagesBelow1MB\r
+ EFI_PHYSICAL_ADDRESS PagesBelow1MB; // Buffer for all VBE Information Blocks\r
+ VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK *VbeInformationBlock; // 0x200 bytes. Must be allocated below 1MB\r
+ VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK *VbeModeInformationBlock; // 0x100 bytes. Must be allocated below 1MB\r
+ VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *VbeCrtcInformationBlock; // 59 bytes. Must be allocated below 1MB\r
+ UINTN VbeSaveRestorePages; // Number of 4KB pages in VbeSaveRestoreBuffer\r
+ EFI_PHYSICAL_ADDRESS VbeSaveRestoreBuffer; // Must be allocated below 1MB\r
+ //\r
+ // Status code\r
+ //\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+} BIOS_VIDEO_DEV;\r
+\r
+#define BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS(a) CR (a, BIOS_VIDEO_DEV, UgaDraw, BIOS_VIDEO_DEV_SIGNATURE)\r
+\r
+#define BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS(a) CR (a, BIOS_VIDEO_DEV, VgaMiniPort, BIOS_VIDEO_DEV_SIGNATURE)\r
+\r
+//\r
+// Global Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL gBiosVideoDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL gBiosVideoComponentName;\r
+extern EFI_COMPONENT_NAME2_PROTOCOL gBiosVideoComponentName2;\r
+\r
+//\r
+// Driver Binding Protocol functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+BiosVideoDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+\r
+ Supported.\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 - 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\r
+EFIAPI\r
+BiosVideoDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+\r
+ Install UGA Draw 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
+ Returns:\r
+\r
+ EFI_STATUS\r
+ \r
+--*/\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
+\r
+//\r
+// Private worker functions\r
+//\r
+EFI_STATUS\r
+BiosVideoCheckForVbe (\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+\r
+ Check for VBE device \r
+ \r
+ Arguments:\r
+ \r
+ BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS - VBE device found\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+BiosVideoCheckForVga (\r
+ BIOS_VIDEO_DEV *BiosVideoPrivate\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+\r
+ Check for VGA device\r
+ \r
+ Arguments:\r
+ \r
+ BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS - Standard VGA device found\r
+ \r
+--*/\r
+;\r
+\r
+//\r
+// BIOS UGA Draw Protocol functions\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
+ )\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
+\r
+Returns:\r
+\r
+ EFI_DEVICE_ERROR - Hardware need starting\r
+ EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+ EFI_SUCCESS - Video mode query successfully\r
+\r
+--*/\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
+ )\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
+\r
+Returns:\r
+\r
+ EFI_DEVICE_ERROR - Device error\r
+ EFI_SUCCESS - Video mode set successfully\r
+ EFI_UNSUPPORTED - Cannot support this video mode\r
+\r
+--*/\r
+;\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
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ UGA draw protocol instance to block transfer for VBE device\r
+\r
+Arguments:\r
+\r
+ This - Pointer to UGA draw 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
+ SourceY - The Y coordinate of the source for BltOperation\r
+ DestinationX - The X coordinate of the destination 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
+ 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
+ the number of bytes in a row of the BltBuffer.\r
+\r
+Returns:\r
+\r
+ EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+ EFI_SUCCESS - Blt operation success\r
+\r
+--*/\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
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ UGA draw protocol instance to block transfer for VGA device\r
+\r
+Arguments:\r
+\r
+ This - Pointer to UGA draw 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
+ SourceY - The Y coordinate of the source for BltOperation\r
+ DestinationX - The X coordinate of the destination 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
+ 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
+ the number of bytes in a row of the BltBuffer.\r
+\r
+Returns:\r
+\r
+ EFI_INVALID_PARAMETER - Invalid parameter passed in\r
+ EFI_SUCCESS - Blt operation success\r
+\r
+--*/\r
+;\r
+\r
+//\r
+// BIOS VGA Mini Port Protocol functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+BiosVideoVgaMiniPortSetMode (\r
+ IN EFI_VGA_MINI_PORT_PROTOCOL *This,\r
+ IN UINTN ModeNumber\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ VgaMiniPort protocol interface to set mode\r
+\r
+Arguments:\r
+\r
+ This - Pointer to VgaMiniPort protocol instance\r
+ ModeNumber - The index of the mode\r
+\r
+Returns:\r
+\r
+ EFI_UNSUPPORTED - The requested mode is not supported\r
+ EFI_SUCCESS - The requested mode is set successfully\r
+\r
+--*/\r
+;\r
+\r
+\r
+BOOLEAN\r
+BiosVideoIsVga (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo\r
+ )\r
+;\r
+\r
+\r
+//\r
+// Standard VGA Definitions\r
+//\r
+#define VGA_HORIZONTAL_RESOLUTION 640\r
+#define VGA_VERTICAL_RESOLUTION 480\r
+#define VGA_NUMBER_OF_BIT_PLANES 4\r
+#define VGA_PIXELS_PER_BYTE 8\r
+#define VGA_BYTES_PER_SCAN_LINE (VGA_HORIZONTAL_RESOLUTION / VGA_PIXELS_PER_BYTE)\r
+#define VGA_BYTES_PER_BIT_PLANE (VGA_VERTICAL_RESOLUTION * VGA_BYTES_PER_SCAN_LINE)\r
+\r
+#define VGA_GRAPHICS_CONTROLLER_ADDRESS_REGISTER 0x3ce\r
+#define VGA_GRAPHICS_CONTROLLER_DATA_REGISTER 0x3cf\r
+\r
+#define VGA_GRAPHICS_CONTROLLER_SET_RESET_REGISTER 0x00\r
+\r
+#define VGA_GRAPHICS_CONTROLLER_ENABLE_SET_RESET_REGISTER 0x01\r
+\r
+#define VGA_GRAPHICS_CONTROLLER_COLOR_COMPARE_REGISTER 0x02\r
+\r
+#define VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER 0x03\r
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE 0x00\r
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_AND 0x08\r
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_OR 0x10\r
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_XOR 0x18\r
+\r
+#define VGA_GRAPHICS_CONTROLLER_READ_MAP_SELECT_REGISTER 0x04\r
+\r
+#define VGA_GRAPHICS_CONTROLLER_MODE_REGISTER 0x05\r
+#define VGA_GRAPHICS_CONTROLLER_READ_MODE_0 0x00\r
+#define VGA_GRAPHICS_CONTROLLER_READ_MODE_1 0x08\r
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_0 0x00\r
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_1 0x01\r
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2 0x02\r
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_3 0x03\r
+\r
+#define VGA_GRAPHICS_CONTROLLER_MISCELLANEOUS_REGISTER 0x06\r
+\r
+#define VGA_GRAPHICS_CONTROLLER_COLOR_DONT_CARE_REGISTER 0x07\r
+\r
+#define VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER 0x08\r
+\r
+#endif\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ VesaBiosExtensions.h\r
+\r
+Abstract:\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#ifndef _VESA_BIOS_EXTENSIONS_H\r
+#define _VESA_BIOS_EXTENSIONS_H\r
+\r
+//\r
+// Turn on byte packing of data structures\r
+//\r
+#pragma pack(1)\r
+//\r
+// VESA BIOS Extensions status codes\r
+//\r
+#define VESA_BIOS_EXTENSIONS_STATUS_SUCCESS 0x004f\r
+\r
+//\r
+// VESA BIOS Extensions Services\r
+//\r
+#define VESA_BIOS_EXTENSIONS_RETURN_CONTROLLER_INFORMATION 0x4f00\r
+\r
+/*++\r
+\r
+ Routine Description:\r
+ Function 00 : Return Controller Information\r
+\r
+ Arguments:\r
+ Inputs:\r
+ AX = 0x4f00\r
+ ES:DI = Pointer to buffer to place VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK structure\r
+ Outputs:\r
+ AX = Return Status\r
+\r
+--*/\r
+#define VESA_BIOS_EXTENSIONS_RETURN_MODE_INFORMATION 0x4f01\r
+\r
+/*++\r
+\r
+ Routine Description:\r
+ Function 01 : Return Mode Information\r
+\r
+ Arguments:\r
+ Inputs:\r
+ AX = 0x4f01\r
+ CX = Mode Number\r
+ ES:DI = Pointer to buffer to place VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK structure\r
+ Outputs:\r
+ AX = Return Status\r
+\r
+--*/\r
+#define VESA_BIOS_EXTENSIONS_SET_MODE 0x4f02\r
+\r
+/*++\r
+\r
+ Routine Description:\r
+ Function 02 : Set Mode\r
+\r
+ Arguments:\r
+ Inputs:\r
+ AX = 0x4f02\r
+ BX = Desired mode to set\r
+ D0-D8 = Mode Number\r
+ D9-D10 = Reserved (must be 0)\r
+ D11 = 0 - Use current default refresh rate\r
+ = 1 - Use user specfieid CRTC values for refresh rate\r
+ D12-D13 = Reserved (must be 0)\r
+ D14 = 0 - Use windowed frame buffer model\r
+ = 1 - Use linear/flat frame buffer model\r
+ D15 = 0 - Clear display memory\r
+ = 1 - Don't clear display memory\r
+ ES:DI = Pointer to buffer to the VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK structure\r
+ Outputs:\r
+ AX = Return Status\r
+\r
+--*/\r
+#define VESA_BIOS_EXTENSIONS_RETURN_CURRENT_MODE 0x4f03\r
+\r
+/*++\r
+\r
+ Routine Description:\r
+ Function 03 : Return Current Mode\r
+\r
+ Arguments:\r
+ Inputs:\r
+ AX = 0x4f03\r
+ Outputs:\r
+ AX = Return Status\r
+ BX = Current mode\r
+ D0-D13 = Mode Number\r
+ D14 = 0 - Windowed frame buffer model\r
+ = 1 - Linear/flat frame buffer model\r
+ D15 = 0 - Memory cleared at last mode set\r
+ = 1 - Memory not cleared at last mode set\r
+\r
+--*/\r
+#define VESA_BIOS_EXTENSIONS_SAVE_RESTORE_STATE 0x4f04\r
+\r
+/*++\r
+\r
+ Routine Description:\r
+ Function 04 : Save/Restore State\r
+\r
+ Arguments:\r
+ Inputs:\r
+ AX = 0x4f03\r
+ DL = 0x00 - Return Save/Restore State buffer size\r
+ = 0x01 - Save State\r
+ = 0x02 - Restore State\r
+ CX = Requested Status\r
+ D0 = Save/Restore controller hardware state\r
+ D1 = Save/Restore BIOS data state\r
+ D2 = Save/Restore DAC state\r
+ D3 = Save/Restore Regsiter state\r
+ ES:BX = Pointer to buffer if DL=1 or DL=2\r
+ Outputs:\r
+ AX = Return Status\r
+ BX = Number of 64 byte blocks to hold the state buffer if DL=0\r
+\r
+--*/\r
+#define VESA_BIOS_EXTENSIONS_EDID 0x4f15\r
+\r
+/*++\r
+\r
+ Routine Description:\r
+ Function 15 : implement VBE/DDC service\r
+\r
+ Arguments:\r
+ Inputs:\r
+ AX = 0x4f15\r
+ BL = 0x00 - Report VBE/DDC Capabilities\r
+ CX = 0x00 - Controller unit number (00 = primary controller)\r
+ ES:DI = Null pointer, must be 0:0 in version 1.0\r
+ Outputs:\r
+ AX = Return Status\r
+ BH = Approx. time in seconds, rounded up, to transfer one EDID block(128 bytes)\r
+ BL = DDC level supported\r
+ D0 = 0 DDC1 not supported\r
+ = 1 DDC1 supported\r
+ D1 = 0 DDC2 not supported\r
+ = 1 DDC2 supported\r
+ D2 = 0 Screen not blanked during data transfer\r
+ = 1 Screen blanked during data transfer\r
+\r
+ Inputs:\r
+ AX = 0x4f15\r
+ BL = 0x01 - Read EDID\r
+ CX = 0x00 - Controller unit number (00 = primary controller)\r
+ DX = 0x00 - EDID block number\r
+ ES:DI = Pointer to buffer in which the EDID block is returned\r
+ Outputs:\r
+ AX = Return Status\r
+--*/\r
+\r
+//\r
+// Timing data from EDID data block\r
+//\r
+#define VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE 128\r
+#define VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER 17\r
+\r
+typedef struct {\r
+ UINT16 HorizontalResolution;\r
+ UINT16 VerticalResolution;\r
+ UINT16 RefreshRate;\r
+} VESA_BIOS_EXTENSIONS_EDID_TIMING;\r
+\r
+typedef struct {\r
+ UINT32 ValidNumber;\r
+ UINT32 Key[VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER];\r
+} VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING;\r
+\r
+typedef struct {\r
+ UINT8 Header[8]; //EDID header "00 FF FF FF FF FF FF 00"\r
+ UINT16 ManufactureName; //EISA 3-character ID\r
+ UINT16 ProductCode; //Vendor assigned code\r
+ UINT32 SerialNumber; //32-bit serial number\r
+ UINT8 WeekOfManufacture; //Week number\r
+ UINT8 YearOfManufacture; //Year\r
+ UINT8 EdidVersion; //EDID Structure Version\r
+ UINT8 EdidRevision; //EDID Structure Revision\r
+ UINT8 VideoInputDefinition;\r
+ UINT8 MaxHorizontalImageSize; //cm\r
+ UINT8 MaxVerticalImageSize; //cm\r
+ UINT8 DisplayTransferCharacteristic;\r
+ UINT8 FeatureSupport;\r
+ UINT8 RedGreenLowBits; //Rx1 Rx0 Ry1 Ry0 Gx1 Gx0 Gy1Gy0\r
+ UINT8 BlueWhiteLowBits; //Bx1 Bx0 By1 By0 Wx1 Wx0 Wy1 Wy0\r
+ UINT8 RedX; //Red-x Bits 9 - 2\r
+ UINT8 RedY; //Red-y Bits 9 - 2\r
+ UINT8 GreenX; //Green-x Bits 9 - 2\r
+ UINT8 GreenY; //Green-y Bits 9 - 2\r
+ UINT8 BlueX; //Blue-x Bits 9 - 2\r
+ UINT8 BlueY; //Blue-y Bits 9 - 2\r
+ UINT8 WhiteX; //White-x Bits 9 - 2\r
+ UINT8 WhiteY; //White-x Bits 9 - 2\r
+ UINT8 EstablishedTimings[3];\r
+ UINT8 StandardTimingIdentification[16];\r
+ UINT8 DetailedTimingDescriptions[72];\r
+ UINT8 ExtensionFlag; //Number of (optional) 128-byte EDID extension blocks to follow\r
+ UINT8 Checksum;\r
+} VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK;\r
+\r
+//\r
+// Super VGA Information Block\r
+//\r
+typedef struct {\r
+ UINT32 VESASignature; // 'VESA' 4 byte signature\r
+ UINT16 VESAVersion; // VBE version number\r
+ UINT32 OEMStringPtr; // Pointer to OEM string\r
+ UINT32 Capabilities; // Capabilities of video card\r
+ UINT32 VideoModePtr; // Pointer to an array of 16-bit supported modes values terminated by 0xFFFF\r
+ UINT16 TotalMemory; // Number of 64kb memory blocks\r
+ UINT16 OemSoftwareRev; // VBE implementation Software revision\r
+ UINT32 OemVendorNamePtr; // VbeFarPtr to Vendor Name String\r
+ UINT32 OemProductNamePtr; // VbeFarPtr to Product Name String\r
+ UINT32 OemProductRevPtr; // VbeFarPtr to Product Revision String\r
+ UINT8 Reserved[222]; // Reserved for VBE implementation scratch area\r
+ UINT8 OemData[256]; // Data area for OEM strings. Pad to 512 byte block size\r
+} VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK;\r
+\r
+//\r
+// Super VGA Information Block VESASignature values\r
+//\r
+#define VESA_BIOS_EXTENSIONS_VESA_SIGNATURE SIGNATURE_32 ('V', 'E', 'S', 'A')\r
+#define VESA_BIOS_EXTENSIONS_VBE2_SIGNATURE SIGNATURE_32 ('V', 'B', 'E', '2')\r
+\r
+//\r
+// Super VGA Information Block VESAVersion values\r
+//\r
+#define VESA_BIOS_EXTENSIONS_VERSION_1_2 0x0102\r
+#define VESA_BIOS_EXTENSIONS_VERSION_2_0 0x0200\r
+#define VESA_BIOS_EXTENSIONS_VERSION_3_0 0x0300\r
+\r
+//\r
+// Super VGA Information Block Capabilities field bit defintions\r
+//\r
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_8_BIT_DAC 0x01 // 0: DAC width is fixed at 6 bits/color\r
+// 1: DAC width switchable to 8 bits/color\r
+//\r
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_NOT_VGA 0x02 // 0: Controller is VGA compatible\r
+// 1: Controller is not VGA compatible\r
+//\r
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_NOT_NORMAL_RAMDAC 0x04 // 0: Normal RAMDAC operation\r
+// 1: Use blank bit in function 9 to program RAMDAC\r
+//\r
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_STEREOSCOPIC 0x08 // 0: No hardware stereoscopic signal support\r
+// 1: Hardware stereoscopic signal support\r
+//\r
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_VESA_EVC 0x10 // 0: Stero signaling supported via external VESA stereo connector\r
+// 1: Stero signaling supported via VESA EVC connector\r
+//\r
+// Super VGA mode number bite field definitions\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_VESA 0x0100 // 0: Not a VESA defined VBE mode\r
+// 1: A VESA defined VBE mode\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_REFRESH_CONTROL_USER 0x0800 // 0: Use current BIOS default referesh rate\r
+// 1: Use the user specified CRTC values for refresh rate\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_LINEAR_FRAME_BUFFER 0x4000 // 0: Use a banked/windowed frame buffer\r
+// 1: Use a linear/flat frame buffer\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_PRESERVE_MEMORY 0x8000 // 0: Clear display memory\r
+// 1: Preseve display memory\r
+//\r
+// Super VGA Information Block mode list terminator value\r
+//\r
+#define VESA_BIOS_EXTENSIONS_END_OF_MODE_LIST 0xffff\r
+\r
+//\r
+// Window Function\r
+//\r
+typedef\r
+VOID\r
+(*VESA_BIOS_EXTENSIONS_WINDOW_FUNCTION) (\r
+ VOID\r
+ );\r
+\r
+//\r
+// Super VGA Mode Information Block\r
+//\r
+typedef struct {\r
+ //\r
+ // Manadory fields for all VESA Bios Extensions revisions\r
+ //\r
+ UINT16 ModeAttributes; // Mode attributes\r
+ UINT8 WinAAttributes; // Window A attributes\r
+ UINT8 WinBAttributes; // Window B attributes\r
+ UINT16 WinGranularity; // Window granularity in k\r
+ UINT16 WinSize; // Window size in k\r
+ UINT16 WinASegment; // Window A segment\r
+ UINT16 WinBSegment; // Window B segment\r
+ UINT32 WindowFunction; // Pointer to window function\r
+ UINT16 BytesPerScanLine; // Bytes per scanline\r
+ //\r
+ // Manadory fields for VESA Bios Extensions 1.2 and above\r
+ //\r
+ UINT16 XResolution; // Horizontal resolution\r
+ UINT16 YResolution; // Vertical resolution\r
+ UINT8 XCharSize; // Character cell width\r
+ UINT8 YCharSize; // Character cell height\r
+ UINT8 NumberOfPlanes; // Number of memory planes\r
+ UINT8 BitsPerPixel; // Bits per pixel\r
+ UINT8 NumberOfBanks; // Number of CGA style banks\r
+ UINT8 MemoryModel; // Memory model type\r
+ UINT8 BankSize; // Size of CGA style banks\r
+ UINT8 NumberOfImagePages; // Number of images pages\r
+ UINT8 Reserved1; // Reserved\r
+ UINT8 RedMaskSize; // Size of direct color red mask\r
+ UINT8 RedFieldPosition; // Bit posn of lsb of red mask\r
+ UINT8 GreenMaskSize; // Size of direct color green mask\r
+ UINT8 GreenFieldPosition; // Bit posn of lsb of green mask\r
+ UINT8 BlueMaskSize; // Size of direct color blue mask\r
+ UINT8 BlueFieldPosition; // Bit posn of lsb of blue mask\r
+ UINT8 RsvdMaskSize; // Size of direct color res mask\r
+ UINT8 RsvdFieldPosition; // Bit posn of lsb of res mask\r
+ UINT8 DirectColorModeInfo; // Direct color mode attributes\r
+ //\r
+ // Manadory fields for VESA Bios Extensions 2.0 and above\r
+ //\r
+ UINT32 PhysBasePtr; // Physical Address for flat memory frame buffer\r
+ UINT32 Reserved2; // Reserved\r
+ UINT16 Reserved3; // Reserved\r
+ //\r
+ // Manadory fields for VESA Bios Extensions 3.0 and above\r
+ //\r
+ UINT16 LinBytesPerScanLine; // Bytes/scan line for linear modes\r
+ UINT8 BnkNumberOfImagePages; // Number of images for banked modes\r
+ UINT8 LinNumberOfImagePages; // Number of images for linear modes\r
+ UINT8 LinRedMaskSize; // Size of direct color red mask (linear mode)\r
+ UINT8 LinRedFieldPosition; // Bit posiiton of lsb of red mask (linear modes)\r
+ UINT8 LinGreenMaskSize; // Size of direct color green mask (linear mode)\r
+ UINT8 LinGreenFieldPosition; // Bit posiiton of lsb of green mask (linear modes)\r
+ UINT8 LinBlueMaskSize; // Size of direct color blue mask (linear mode)\r
+ UINT8 LinBlueFieldPosition; // Bit posiiton of lsb of blue mask (linear modes)\r
+ UINT8 LinRsvdMaskSize; // Size of direct color reserved mask (linear mode)\r
+ UINT8 LinRsvdFieldPosition; // Bit posiiton of lsb of reserved mask (linear modes)\r
+ UINT32 MaxPixelClock; // Maximum pixel clock (in Hz) for graphics mode\r
+ UINT8 Pad[190]; // Pad to 256 byte block size\r
+} VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK;\r
+\r
+//\r
+// Super VGA Mode Information Block ModeAttributes field bit defintions\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_HARDWARE 0x0001 // 0: Mode not supported in handware\r
+// 1: Mode supported in handware\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_TTY 0x0004 // 0: TTY Output functions not supported by BIOS\r
+// 1: TTY Output functions supported by BIOS\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_COLOR 0x0008 // 0: Monochrome mode\r
+// 1: Color mode\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_GRAPHICS 0x0010 // 0: Text mode\r
+// 1: Graphics mode\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NOT_VGA 0x0020 // 0: VGA compatible mode\r
+// 1: Not a VGA compatible mode\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NOT_WINDOWED 0x0040 // 0: VGA compatible windowed memory mode\r
+// 1: Not a VGA compatible windowed memory mode\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER 0x0080 // 0: No linear fram buffer mode available\r
+// 1: Linear frame buffer mode available\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_DOUBLE_SCAN 0x0100 // 0: No double scan mode available\r
+// 1: Double scan mode available\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_INTERLACED 0x0200 // 0: No interlaced mode is available\r
+// 1: Interlaced mode is available\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NO_TRIPPLE_BUFFER 0x0400 // 0: No hardware triple buffer mode support available\r
+// 1: Hardware triple buffer mode support available\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_STEREOSCOPIC 0x0800 // 0: No hardware steroscopic display support\r
+// 1: Hardware steroscopic display support\r
+//\r
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_DUAL_DISPLAY 0x1000 // 0: No dual display start address support\r
+// 1: Dual display start address support\r
+//\r
+// Super VGA Mode Information Block WinAAttribite/WinBAttributes field bit defintions\r
+//\r
+#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_RELOCATABLE 0x01 // 0: Single non-relocatable window only\r
+// 1: Relocatable window(s) are supported\r
+//\r
+#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_READABLE 0x02 // 0: Window is not readable\r
+// 1: Window is readable\r
+//\r
+#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_WRITABLE 0x04 // 0: Window is not writable\r
+// 1: Window is writable\r
+//\r
+// Super VGA Mode Information Block DirectColorMode field bit defintions\r
+//\r
+#define VESA_BIOS_EXTENSIONS_DIRECT_COLOR_MODE_PROG_COLOR_RAMP 0x01 // 0: Color ram is fixed\r
+// 1: Color ramp is programmable\r
+//\r
+#define VESA_BIOS_EXTENSIONS_DIRECT_COLOR_MODE_RSVD_USABLE 0x02 // 0: Bits in Rsvd field are reserved\r
+// 1: Bits in Rsdv field are usable\r
+//\r
+// Super VGA Memory Models\r
+//\r
+typedef enum {\r
+ memPL = 3, // Planar memory model\r
+ memPK = 4, // Packed pixel memory model\r
+ memRGB= 6, // Direct color RGB memory model\r
+ memYUV= 7, // Direct color YUV memory model\r
+} VESA_BIOS_EXTENSIONS_MEMORY_MODELS;\r
+\r
+//\r
+// Super VGA CRTC Information Block\r
+//\r
+typedef struct {\r
+ UINT16 HorizontalTotal; // Horizontal total in pixels\r
+ UINT16 HorizontalSyncStart; // Horizontal sync start in pixels\r
+ UINT16 HorizontalSyncEnd; // Horizontal sync end in pixels\r
+ UINT16 VericalTotal; // Vertical total in pixels\r
+ UINT16 VericalSyncStart; // Vertical sync start in pixels\r
+ UINT16 VericalSyncEnd; // Vertical sync end in pixels\r
+ UINT8 Flags; // Flags (Interlaced/DoubleScan/etc).\r
+ UINT32 PixelClock; // Pixel clock in units of Hz\r
+ UINT16 RefreshRate; // Refresh rate in units of 0.01 Hz\r
+ UINT8 Reserved[40]; // Pad\r
+} VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK;\r
+\r
+#define VESA_BIOS_EXTENSIONS_CRTC_FLAGS_DOUBLE_SCAN 0x01 // 0: Graphics mode is not souble scanned\r
+// 1: Graphics mode is double scanned\r
+//\r
+#define VESA_BIOS_EXTENSIONS_CRTC_FLAGSINTERLACED 0x02 // 0: Graphics mode is not interlaced\r
+// 1: Graphics mode is interlaced\r
+//\r
+#define VESA_BIOS_EXTENSIONS_CRTC_HORIZONTAL_SYNC_NEGATIVE 0x04 // 0: Horizontal sync polarity is positive(+)\r
+// 0: Horizontal sync polarity is negative(-)\r
+//\r
+#define VESA_BIOS_EXTENSIONS_CRTC_VERITICAL_SYNC_NEGATIVE 0x08 // 0: Verical sync polarity is positive(+)\r
+// 0: Verical sync polarity is negative(-)\r
+//\r
+// Turn off byte packing of data structures\r
+//\r
+#pragma pack()\r
+\r
+#endif\r