From 87f8ccbe19e09b6ece2c72bb70add08d0cc627f7 Mon Sep 17 00:00:00 2001 From: qhuang8 Date: Fri, 23 Nov 2007 03:05:33 +0000 Subject: [PATCH] Port CirrusLogic5430 from EDK II code base. Add GOP, Component Name 2, Efi driver supported EFI version protocol support. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4322 6f19259b-4bc3-4df7-8a09-765794883524 --- .../CirrusLogic5430Dxe/CirrusLogic5430.c | 803 ++++++++++++++++++ .../CirrusLogic5430Dxe/CirrusLogic5430.h | 409 +++++++++ .../CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf | 75 ++ .../CirrusLogic5430GraphicsOutput.c | 525 ++++++++++++ .../CirrusLogic5430UgaDraw.c | 427 ++++++++++ .../CirrusLogic5430Dxe/ComponentName.c | 240 ++++++ .../DriverSupportedEfiVersion.c | 20 + OptionRomPkg/OptionRomPkg.dec | 2 + OptionRomPkg/OptionRomPkg.dsc | 1 + OptionRomPkg/ReadMe.txt | 22 +- 10 files changed, 2514 insertions(+), 10 deletions(-) create mode 100644 OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c create mode 100644 OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h create mode 100644 OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf create mode 100644 OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c create mode 100644 OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c create mode 100644 OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c create mode 100644 OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c new file mode 100644 index 0000000000..bfa121b019 --- /dev/null +++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c @@ -0,0 +1,803 @@ +/** @file + Cirrus Logic 5430 Controller Driver. + This driver is a sample implementation of the UGA Draw and Graphics Output + Protocols for the Cirrus Logic 5430 family of PCI video controllers. + This driver is only usable in the EFI pre-boot environment. + This sample is intended to show how the UGA Draw and Graphics output Protocol + is able to function. + The UGA I/O Protocol is not implemented in this sample. + A fully compliant EFI UGA driver requires both + the UGA Draw and the UGA I/O Protocol. Please refer to Microsoft's + documentation on UGA for details on how to write a UGA driver that is able + to function both in the EFI pre-boot environment and from the OS runtime. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +// +// Cirrus Logic 5430 Controller Driver +// +#include "CirrusLogic5430.h" + +EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding = { + CirrusLogic5430ControllerDriverSupported, + CirrusLogic5430ControllerDriverStart, + CirrusLogic5430ControllerDriverStop, + 0x10, + NULL, + NULL +}; + +/// +/// Generic Attribute Controller Register Settings +/// +UINT8 AttributeController[21] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00 +}; + +/// +/// Generic Graphics Controller Register Settings +/// +UINT8 GraphicsController[9] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF +}; + +// +// 640 x 480 x 256 color @ 60 Hertz +// +UINT8 Crtc_640_480_256_60[28] = { + 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3, + 0xff, 0x00, 0x00, 0x22 +}; + +UINT16 Seq_640_480_256_60[15] = { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e +}; + +// +// 800 x 600 x 256 color @ 60 Hertz +// +UINT8 Crtc_800_600_256_60[28] = { + 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3, + 0xFF, 0x00, 0x00, 0x22 +}; + +UINT16 Seq_800_600_256_60[15] = { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e +}; + +// +// 1024 x 768 x 256 color @ 60 Hertz +// +UINT8 Crtc_1024_768_256_60[28] = { + 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3, + 0xFF, 0x4A, 0x00, 0x22 +}; + +UINT16 Seq_1024_768_256_60[15] = { + 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, + 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e +}; + +/// +/// Table of supported video modes +/// +CIRRUS_LOGIC_5430_VIDEO_MODES CirrusLogic5430VideoModes[] = { + { 640, 480, 8, 60, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 }, + { 800, 600, 8, 60, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef }, + { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef } +}; + +/** + CirrusLogic5430ControllerDriverSupported + + TODO: This - add argument and description to function comment + TODO: Controller - add argument and description to function comment + TODO: RemainingDevicePath - add argument and description to function comment +**/ +EFI_STATUS +EFIAPI +CirrusLogic5430ControllerDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 Pci; + + // + // Open the PCI I/O Protocol + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Read the PCI Configuration Header from the PCI Device + // + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + Status = EFI_UNSUPPORTED; + // + // See if the I/O enable is on. Most systems only allow one VGA device to be turned on + // at a time, so see if this is one that is turned on. + // + // if (((Pci.Hdr.Command & 0x01) == 0x01)) { + // + // See if this is a Cirrus Logic PCI controller + // + if (Pci.Hdr.VendorId == CIRRUS_LOGIC_VENDOR_ID) { + // + // See if this is a 5430 or a 5446 PCI controller + // + if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID) { + Status = EFI_SUCCESS; + } + + if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID) { + Status = EFI_SUCCESS; + } + + if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) { + Status = EFI_SUCCESS; + } + } + +Done: + // + // Close the PCI I/O Protocol + // + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return Status; +} + +/** + CirrusLogic5430ControllerDriverStart + + TODO: This - add argument and description to function comment + TODO: Controller - add argument and description to function comment + TODO: RemainingDevicePath - add argument and description to function comment +**/ +EFI_STATUS +EFIAPI +CirrusLogic5430ControllerDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private; + + // + // Allocate Private context data for UGA Draw inteface. + // + Private = AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA)); + if (Private == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + // + // Set up context record + // + Private->Signature = CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE; + Private->Handle = Controller; + + // + // Open PCI I/O Protocol + // + Status = gBS->OpenProtocol ( + Private->Handle, + &gEfiPciIoProtocolGuid, + (VOID **) &Private->PciIo, + This->DriverBindingHandle, + Private->Handle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + goto Error; + } + + Status = Private->PciIo->Attributes ( + Private->PciIo, + EfiPciIoAttributeOperationEnable, + EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO, + NULL + ); + if (EFI_ERROR (Status)) { + goto Error; + } + + if (FeaturePcdGet (PcdSupportUga)) { + // + // Start the UGA Draw software stack. + // + Status = CirrusLogic5430UgaDrawConstructor (Private); + ASSERT_EFI_ERROR (Status); + if (FeaturePcdGet (PcdSupportGop)) { + Status = CirrusLogic5430GraphicsOutputConstructor (Private); + ASSERT_EFI_ERROR (Status); + + Status = gBS->InstallMultipleProtocolInterfaces ( + &Private->Handle, + &gEfiUgaDrawProtocolGuid, + &Private->UgaDraw, + &gEfiGraphicsOutputProtocolGuid, + &Private->GraphicsOutput, + NULL + ); + } else { + Status = gBS->InstallMultipleProtocolInterfaces ( + &Private->Handle, + &gEfiUgaDrawProtocolGuid, + &Private->UgaDraw, + NULL + ); + + } + } else { + if (FeaturePcdGet (PcdSupportGop)) { + Status = CirrusLogic5430GraphicsOutputConstructor (Private); + ASSERT_EFI_ERROR (Status); + + Status = gBS->InstallMultipleProtocolInterfaces ( + &Private->Handle, + &gEfiGraphicsOutputProtocolGuid, + &Private->GraphicsOutput, + NULL + ); + + } else { + // + // This driver must support eithor GOP or UGA or both. + // + ASSERT (FALSE); + Status = EFI_UNSUPPORTED; + } + } + + +Error: + if (EFI_ERROR (Status)) { + if (Private) { + if (Private->PciIo) { + Private->PciIo->Attributes ( + Private->PciIo, + EfiPciIoAttributeOperationDisable, + EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO, + NULL + ); + } + } + + // + // Close the PCI I/O Protocol + // + gBS->CloseProtocol ( + Private->Handle, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Private->Handle + ); + if (Private) { + gBS->FreePool (Private); + } + } + + return Status; +} + +/** + CirrusLogic5430ControllerDriverStop + + TODO: This - add argument and description to function comment + TODO: Controller - add argument and description to function comment + TODO: NumberOfChildren - add argument and description to function comment + TODO: ChildHandleBuffer - add argument and description to function comment + TODO: EFI_SUCCESS - add return value to function comment +**/ +EFI_STATUS +EFIAPI +CirrusLogic5430ControllerDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_UGA_DRAW_PROTOCOL *UgaDraw; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + + EFI_STATUS Status; + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private; + + if (FeaturePcdGet (PcdSupportUga)) { + Status = gBS->OpenProtocol ( + Controller, + &gEfiUgaDrawProtocolGuid, + (VOID **) &UgaDraw, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Get our private context information + // + Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw); + CirrusLogic5430UgaDrawDestructor (Private); + + if (FeaturePcdGet (PcdSupportGop)) { + CirrusLogic5430GraphicsOutputDestructor (Private); + // + // Remove the UGA and GOP protocol interface from the system + // + Status = gBS->UninstallMultipleProtocolInterfaces ( + Private->Handle, + &gEfiUgaDrawProtocolGuid, + &Private->UgaDraw, + &gEfiGraphicsOutputProtocolGuid, + &Private->GraphicsOutput, + NULL + ); + } else { + // + // Remove the UGA Draw interface from the system + // + Status = gBS->UninstallMultipleProtocolInterfaces ( + Private->Handle, + &gEfiUgaDrawProtocolGuid, + &Private->UgaDraw, + NULL + ); + } + } else { + Status = gBS->OpenProtocol ( + Controller, + &gEfiGraphicsOutputProtocolGuid, + (VOID **) &GraphicsOutput, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get our private context information + // + Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput); + + CirrusLogic5430GraphicsOutputDestructor (Private); + // + // Remove the GOP protocol interface from the system + // + Status = gBS->UninstallMultipleProtocolInterfaces ( + Private->Handle, + &gEfiUgaDrawProtocolGuid, + &Private->UgaDraw, + &gEfiGraphicsOutputProtocolGuid, + &Private->GraphicsOutput, + NULL + ); + } + + if (EFI_ERROR (Status)) { + return Status; + } + + + // + // Shutdown the hardware + // + Private->PciIo->Attributes ( + Private->PciIo, + EfiPciIoAttributeOperationDisable, + EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO, + NULL + ); + + // + // Close the PCI I/O Protocol + // + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + // + // Free our instance data + // + gBS->FreePool (Private); + + return EFI_SUCCESS; +} + +/** + CirrusLogic5430UgaDrawDestructor + + TODO: Private - add argument and description to function comment + TODO: EFI_SUCCESS - add return value to function comment +**/ +EFI_STATUS +CirrusLogic5430UgaDrawDestructor ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private + ) +{ + return EFI_SUCCESS; +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Address TODO: add argument description + @param Data TODO: add argument description + + TODO: add return values + +**/ +VOID +outb ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN Address, + UINT8 Data + ) +{ + Private->PciIo->Io.Write ( + Private->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Address TODO: add argument description + @param Data TODO: add argument description + + TODO: add return values + +**/ +VOID +outw ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN Address, + UINT16 Data + ) +{ + Private->PciIo->Io.Write ( + Private->PciIo, + EfiPciIoWidthUint16, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Address TODO: add argument description + + TODO: add return values + +**/ +UINT8 +inb ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN Address + ) +{ + UINT8 Data; + + Private->PciIo->Io.Read ( + Private->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); + return Data; +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Address TODO: add argument description + + TODO: add return values + +**/ +UINT16 +inw ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN Address + ) +{ + UINT16 Data; + + Private->PciIo->Io.Read ( + Private->PciIo, + EfiPciIoWidthUint16, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); + return Data; +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Index TODO: add argument description + @param Red TODO: add argument description + @param Green TODO: add argument description + @param Blue TODO: add argument description + + TODO: add return values + +**/ +VOID +SetPaletteColor ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN Index, + UINT8 Red, + UINT8 Green, + UINT8 Blue + ) +{ + outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index); + outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2)); + outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2)); + outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2)); +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + + TODO: add return values + +**/ +VOID +SetDefaultPalette ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private + ) +{ + UINTN Index; + UINTN RedIndex; + UINTN GreenIndex; + UINTN BlueIndex; + + Index = 0; + for (RedIndex = 0; RedIndex < 8; RedIndex++) { + for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) { + for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) { + SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6)); + Index++; + } + } + } +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + + TODO: add return values + +**/ +STATIC +VOID +ClearScreen ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private + ) +{ + UINT32 Color; + + Color = 0; + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthFillUint32, + 0, + 0, + 0x100000 >> 2, + &Color + ); +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + + TODO: add return values + +**/ +VOID +DrawLogo ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN ScreenWidth, + UINTN ScreenHeight + ) +{ + UINTN Offset; + UINTN X; + UINTN Y; + UINT8 Color; + + Offset = 0; + for (Y = 0; Y < ScreenHeight; Y++) { + for (X = 0; X < ScreenWidth; X++) { + Color = (UINT8) (256 * (X + Y) / (ScreenWidth + ScreenHeight)); + Private->LineBuffer[X] = Color; + } + + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthUint32, + 0, + Offset + (Y * ScreenWidth), + ScreenWidth >> 2, + Private->LineBuffer + ); + } +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param ModeData TODO: add argument description + + TODO: add return values + +**/ +VOID +InitializeGraphicsMode ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + CIRRUS_LOGIC_5430_VIDEO_MODES *ModeData + ) +{ + UINT8 Byte; + UINTN Index; + + outw (Private, SEQ_ADDRESS_REGISTER, 0x1206); + outw (Private, SEQ_ADDRESS_REGISTER, 0x0012); + + for (Index = 0; Index < 15; Index++) { + outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]); + } + + outb (Private, SEQ_ADDRESS_REGISTER, 0x0f); + Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30); + outb (Private, SEQ_DATA_REGISTER, Byte); + + outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506); + outw (Private, SEQ_ADDRESS_REGISTER, 0x0300); + outw (Private, CRTC_ADDRESS_REGISTER, 0x2011); + + for (Index = 0; Index < 28; Index++) { + outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index)); + } + + for (Index = 0; Index < 9; Index++) { + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index)); + } + + inb (Private, INPUT_STATUS_1_REGISTER); + + for (Index = 0; Index < 21; Index++) { + outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index); + outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]); + } + + outb (Private, ATT_ADDRESS_REGISTER, 0x20); + + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b); + outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff); + + SetDefaultPalette (Private); + ClearScreen (Private); +} + +EFI_STATUS +EFIAPI +InitializeCirrusLogic5430 ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gCirrusLogic5430DriverBinding, + ImageHandle, + &gCirrusLogic5430ComponentName, + &gCirrusLogic5430ComponentName2 + ); + ASSERT_EFI_ERROR (Status); + + // + // Install EFI Driver Supported EFI Version Protocol required for + // EFI drivers that are on PCI and other plug in cards. + // + gCirrusLogic5430DriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion); + Status = gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gEfiDriverSupportedEfiVersionProtocolGuid, + &gCirrusLogic5430DriverSupportedEfiVersion, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h new file mode 100644 index 0000000000..c8fcd703fd --- /dev/null +++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h @@ -0,0 +1,409 @@ +/** @file + Cirrus Logic 5430 Controller Driver + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +// +// Cirrus Logic 5430 Controller Driver +// + +#ifndef _CIRRUS_LOGIC_5430_H_ +#define _CIRRUS_LOGIC_5430_H_ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +// +// Cirrus Logic 5430 PCI Configuration Header values +// +#define CIRRUS_LOGIC_VENDOR_ID 0x1013 +#define CIRRUS_LOGIC_5430_DEVICE_ID 0x00a8 +#define CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID 0x00a0 +#define CIRRUS_LOGIC_5446_DEVICE_ID 0x00b8 + +// +// Cirrus Logic Graphical Mode Data +// +#define CIRRUS_LOGIC_5430_MODE_COUNT 3 + +typedef struct { + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + UINT32 ColorDepth; + UINT32 RefreshRate; +} CIRRUS_LOGIC_5430_MODE_DATA; + +#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff + +// +// Cirrus Logic 5440 Private Data Structure +// +#define CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('C', 'L', '5', '4') + +typedef struct { + UINT64 Signature; + EFI_HANDLE Handle; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_UGA_DRAW_PROTOCOL UgaDraw; + EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput; + UINTN CurrentMode; + UINTN MaxMode; + CIRRUS_LOGIC_5430_MODE_DATA ModeData[CIRRUS_LOGIC_5430_MODE_COUNT]; + UINT8 *LineBuffer; + BOOLEAN HardwareNeedsStarting; +} CIRRUS_LOGIC_5430_PRIVATE_DATA; + +/// +/// Video Mode structure +/// +typedef struct { + UINT32 Width; + UINT32 Height; + UINT32 ColorDepth; + UINT32 RefreshRate; + UINT8 *CrtcSettings; + UINT16 *SeqSettings; + UINT8 MiscSetting; +} CIRRUS_LOGIC_5430_VIDEO_MODES; + +#define CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS(a) \ + CR(a, CIRRUS_LOGIC_5430_PRIVATE_DATA, UgaDraw, CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE) + +#define CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \ + CR(a, CIRRUS_LOGIC_5430_PRIVATE_DATA, GraphicsOutput, CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE) + + +// +// Global Variables +// +extern UINT8 AttributeController[]; +extern UINT8 GraphicsController[]; +extern UINT8 Crtc_640_480_256_60[]; +extern UINT16 Seq_640_480_256_60[]; +extern UINT8 Crtc_800_600_256_60[]; +extern UINT16 Seq_800_600_256_60[]; +extern UINT8 Crtc_1024_768_256_60[]; +extern UINT16 Seq_1024_768_256_60[]; +extern CIRRUS_LOGIC_5430_VIDEO_MODES CirrusLogic5430VideoModes[]; +extern EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gCirrusLogic5430ComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gCirrusLogic5430ComponentName2; +extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gCirrusLogic5430DriverSupportedEfiVersion; + +// +// Io Registers defined by VGA +// +#define CRTC_ADDRESS_REGISTER 0x3d4 +#define CRTC_DATA_REGISTER 0x3d5 +#define SEQ_ADDRESS_REGISTER 0x3c4 +#define SEQ_DATA_REGISTER 0x3c5 +#define GRAPH_ADDRESS_REGISTER 0x3ce +#define GRAPH_DATA_REGISTER 0x3cf +#define ATT_ADDRESS_REGISTER 0x3c0 +#define MISC_OUTPUT_REGISTER 0x3c2 +#define INPUT_STATUS_1_REGISTER 0x3da +#define DAC_PIXEL_MASK_REGISTER 0x3c6 +#define PALETTE_INDEX_REGISTER 0x3c8 +#define PALETTE_DATA_REGISTER 0x3c9 + +// +// UGA Draw Hardware abstraction internal worker functions +// +EFI_STATUS +CirrusLogic5430UgaDrawConstructor ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private + ) +; + +EFI_STATUS +CirrusLogic5430UgaDrawDestructor ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private + ) +; + +// +// Graphics Output Hardware abstraction internal worker functions +// +EFI_STATUS +CirrusLogic5430GraphicsOutputConstructor ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private + ) +; + +EFI_STATUS +CirrusLogic5430GraphicsOutputDestructor ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private + ) +; + + +// +// EFI_DRIVER_BINDING_PROTOCOL Protocol Interface +// +/** + TODO: Add function description + + @param This TODO: add argument description + @param Controller TODO: add argument description + @param RemainingDevicePath TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +CirrusLogic5430ControllerDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param Controller TODO: add argument description + @param RemainingDevicePath TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +CirrusLogic5430ControllerDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +/** + TODO: Add function description + + @param This TODO: add argument description + @param Controller TODO: add argument description + @param NumberOfChildren TODO: add argument description + @param ChildHandleBuffer TODO: add argument description + + TODO: add return values + +**/ +EFI_STATUS +EFIAPI +CirrusLogic5430ControllerDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +; + +// +// EFI Component Name Functions +// +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 3066 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +CirrusLogic5430ComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 3066 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +CirrusLogic5430ComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + + +// +// Local Function Prototypes +// +VOID +InitializeGraphicsMode ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + CIRRUS_LOGIC_5430_VIDEO_MODES *ModeData + ); + +VOID +SetPaletteColor ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN Index, + UINT8 Red, + UINT8 Green, + UINT8 Blue + ); + +VOID +SetDefaultPalette ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private + ); + +VOID +DrawLogo ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN ScreenWidth, + UINTN ScreenHeight + ); + +VOID +outb ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN Address, + UINT8 Data + ); + +VOID +outw ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN Address, + UINT16 Data + ); + +UINT8 +inb ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN Address + ); + +UINT16 +inw ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, + UINTN Address + ); + +#endif diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf new file mode 100644 index 0000000000..a540feff29 --- /dev/null +++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf @@ -0,0 +1,75 @@ +#/** @file +# Component description file for CirrusLogic5430 module +# +# Cirrus Logic 5430 Controller Driver.This driver is a sample implementation +# of the UGA Draw Protocol for the Cirrus Logic 5430 family of PCI video controllers. +# This driver is only usable in the EFI pre-boot environment. This sample is +# intended to show how the UGA Draw Protocol is able to function. The UGA I/O +# Protocol is not implemented in this sample. A fully compliant EFI UGA driver +# requires both the UGA Draw and the UGA I/O Protocol. Please refer to Microsoft's +# documentation on UGA for details on how to write a UGA driver that is able +# to function both in the EFI pre-boot environment and from the OS runtime. +# Copyright (c) 2006 - 2007, Intel Corporation +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CirrusLogic5430UgaDraw + FILE_GUID = 555F76EA-785F-40d7-9174-153C43636C68 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = InitializeCirrusLogic5430 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# +# DRIVER_BINDING = gCirrusLogic5430DriverBinding +# COMPONENT_NAME = gCirrusLogic5430ComponentName +# + +[Sources.common] + ComponentName.c + DriverSupportedEfiVersion.c + CirrusLogic5430UgaDraw.c + CirrusLogic5430GraphicsOutput.c + CirrusLogic5430.c + CirrusLogic5430.h + +[Packages] + MdePkg/MdePkg.dec + OptionRomPkg/OptionRomPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + UefiLib + UefiDriverEntryPoint + DebugLib + + +[Protocols] + gEfiDriverSupportedEfiVersionProtocolGuid # PROTOCOL ALWAYS_PRODUCED + gEfiUgaDrawProtocolGuid # PROTOCOL BY_START + gEfiGraphicsOutputProtocolGuid # PROTOCOL BY_START + gEfiPciIoProtocolGuid # PROTOCOL TO_START + +[FeaturePcd.common] + gOptionRomPkgTokenSpaceGuid.PcdSupportGop + gOptionRomPkgTokenSpaceGuid.PcdSupportUga + +[Pcd] + gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c new file mode 100644 index 0000000000..7fdb3e0f0a --- /dev/null +++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c @@ -0,0 +1,525 @@ +/*++ + +Copyright (c) 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + UefiCirrusLogic5430GraphicsOutput.c + +Abstract: + + This file produces the graphics abstration of Graphics Output Protocol. It is called by + CirrusLogic5430.c file which deals with the EFI 1.1 driver model. + This file just does graphics. + +--*/ + +#include "CirrusLogic5430.h" + +// +// Graphics Output Protocol Member Functions +// +EFI_STATUS +EFIAPI +CirrusLogic5430GraphicsOutputQueryMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ) +/*++ + +Routine Description: + + Graphics Output protocol interface to query video mode + + Arguments: + This - Protocol instance pointer. + ModeNumber - The mode number to return information on. + Info - Caller allocated buffer that returns information about ModeNumber. + SizeOfInfo - A pointer to the size, in bytes, of the Info buffer. + + Returns: + EFI_SUCCESS - Mode information returned. + EFI_BUFFER_TOO_SMALL - The Info buffer was too small. + EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode. + EFI_NOT_STARTED - Video display is not initialized. Call SetMode () + EFI_INVALID_PARAMETER - One of the input args was NULL. + +--*/ +{ + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private; + + Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); + + if (Private->HardwareNeedsStarting) { + return EFI_NOT_STARTED; + } + + if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) { + return EFI_INVALID_PARAMETER; + } + + *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)); + if (*Info == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + (*Info)->Version = 0; + (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution; + (*Info)->VerticalResolution = Private->ModeData[ModeNumber].VerticalResolution; + (*Info)->PixelFormat = PixelBltOnly; + (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CirrusLogic5430GraphicsOutputSetMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber + ) +/*++ + +Routine Description: + + Graphics Output protocol interface to set video mode + + Arguments: + This - Protocol instance pointer. + ModeNumber - The mode number to be set. + + Returns: + EFI_SUCCESS - Graphics mode was changed. + EFI_DEVICE_ERROR - The device had an error and could not complete the request. + EFI_UNSUPPORTED - ModeNumber is not supported by this device. + +--*/ +{ + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private; + CIRRUS_LOGIC_5430_MODE_DATA *ModeData; + + Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); + + if (ModeNumber >= This->Mode->MaxMode) { + return EFI_UNSUPPORTED; + } + + ModeData = &Private->ModeData[ModeNumber]; + + if (Private->LineBuffer) { + gBS->FreePool (Private->LineBuffer); + } + + Private->LineBuffer = NULL; + Private->LineBuffer = AllocatePool (ModeData->HorizontalResolution); + if (Private->LineBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[ModeNumber]); + + This->Mode->Mode = ModeNumber; + This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution; + This->Mode->Info->VerticalResolution = ModeData->VerticalResolution; + This->Mode->Info->PixelFormat = PixelBltOnly; + This->Mode->Info->PixelsPerScanLine = ModeData->HorizontalResolution; + This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + This->Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS)(UINTN)NULL; + This->Mode->FrameBufferSize = 0; + + Private->HardwareNeedsStarting = FALSE; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CirrusLogic5430GraphicsOutputBlt ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ) +/*++ + +Routine Description: + + Graphics Output protocol instance to block transfer for CirrusLogic device + +Arguments: + + This - Pointer to Graphics Output protocol instance + BltBuffer - The data to transfer to screen + BltOperation - The operation to perform + SourceX - The X coordinate of the source for BltOperation + SourceY - The Y coordinate of the source for BltOperation + DestinationX - The X coordinate of the destination for BltOperation + DestinationY - The Y coordinate of the destination for BltOperation + Width - The width of a rectangle in the blt rectangle in pixels + Height - The height of a rectangle in the blt rectangle in pixels + Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation. + If a Delta of 0 is used, the entire BltBuffer will be operated on. + If a subrectangle of the BltBuffer is used, then Delta represents + the number of bytes in a row of the BltBuffer. + +Returns: + + EFI_INVALID_PARAMETER - Invalid parameter passed in + EFI_SUCCESS - Blt operation success + +--*/ +{ + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private; + EFI_TPL OriginalTPL; + UINTN DstY; + UINTN SrcY; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + UINTN X; + UINT8 Pixel; + UINT32 WidePixel; + UINTN ScreenWidth; + UINTN Offset; + UINTN SourceOffset; + UINT32 CurrentMode; + + Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); + + if ((BltOperation < 0) || (BltOperation >= EfiGraphicsOutputBltOperationMax)) { + return EFI_INVALID_PARAMETER; + } + + if (Width == 0 || Height == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // If Delta is zero, then the entire BltBuffer is being used, so Delta + // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size, + // the number of bytes in each row can be computed. + // + if (Delta == 0) { + Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); + } + + // + // We need to fill the Virtual Screen buffer with the blt data. + // The virtual screen is upside down, as the first row is the bootom row of + // the image. + // + + CurrentMode = This->Mode->Mode; + // + // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters + // are valid for the operation and the current screen geometry. + // + if (BltOperation == EfiBltVideoToBltBuffer) { + // + // Video to BltBuffer: Source is Video, destination is BltBuffer + // + if (SourceY + Height > Private->ModeData[CurrentMode].VerticalResolution) { + return EFI_INVALID_PARAMETER; + } + + if (SourceX + Width > Private->ModeData[CurrentMode].HorizontalResolution) { + return EFI_INVALID_PARAMETER; + } + } else { + // + // BltBuffer to Video: Source is BltBuffer, destination is Video + // + if (DestinationY + Height > Private->ModeData[CurrentMode].VerticalResolution) { + return EFI_INVALID_PARAMETER; + } + + if (DestinationX + Width > Private->ModeData[CurrentMode].HorizontalResolution) { + return EFI_INVALID_PARAMETER; + } + } + // + // We have to raise to TPL Notify, so we make an atomic write the frame buffer. + // We would not want a timer based event (Cursor, ...) to come in while we are + // doing this operation. + // + OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY); + + switch (BltOperation) { + case EfiBltVideoToBltBuffer: + // + // Video to BltBuffer: Source is Video, destination is BltBuffer + // + for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) { + + Offset = (SrcY * Private->ModeData[CurrentMode].HorizontalResolution) + SourceX; + if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) { + Private->PciIo->Mem.Read ( + Private->PciIo, + EfiPciIoWidthUint32, + 0, + Offset, + Width >> 2, + Private->LineBuffer + ); + } else { + Private->PciIo->Mem.Read ( + Private->PciIo, + EfiPciIoWidthUint8, + 0, + Offset, + Width, + Private->LineBuffer + ); + } + + for (X = 0; X < Width; X++) { + Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + + Blt->Red = (UINT8) (Private->LineBuffer[X] & 0xe0); + Blt->Green = (UINT8) ((Private->LineBuffer[X] & 0x1c) << 3); + Blt->Blue = (UINT8) ((Private->LineBuffer[X] & 0x03) << 6); + } + } + break; + + case EfiBltVideoToVideo: + // + // Perform hardware acceleration for Video to Video operations + // + ScreenWidth = Private->ModeData[CurrentMode].HorizontalResolution; + SourceOffset = (SourceY * Private->ModeData[CurrentMode].HorizontalResolution) + (SourceX); + Offset = (DestinationY * Private->ModeData[CurrentMode].HorizontalResolution) + (DestinationX); + + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014); + + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015); + + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) & 0xff00) | 0x20)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) | 0x21)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) & 0xff00) | 0x22)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) | 0x23)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x24)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x25)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x26)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x27)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) & 0xff00) | 0x28)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) & 0xff00) | 0x29)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) & 0xff00) | 0x2a)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) << 8) & 0xff00) | 0x2c)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 0) & 0xff00) | 0x2d)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 8) & 0xff00) | 0x2e)); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035); + + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231); + + outb (Private, GRAPH_ADDRESS_REGISTER, 0x31); + while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01) + ; + break; + + case EfiBltVideoFill: + Blt = BltBuffer; + Pixel = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03)); + WidePixel = (Pixel << 8) | Pixel; + WidePixel = (WidePixel << 16) | WidePixel; + + if (DestinationX == 0 && Width == Private->ModeData[CurrentMode].HorizontalResolution) { + Offset = DestinationY * Private->ModeData[CurrentMode].HorizontalResolution; + if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthFillUint32, + 0, + Offset, + (Width * Height) >> 2, + &WidePixel + ); + } else { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthFillUint8, + 0, + Offset, + Width * Height, + &Pixel + ); + } + } else { + for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { + Offset = (DstY * Private->ModeData[CurrentMode].HorizontalResolution) + DestinationX; + if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthFillUint32, + 0, + Offset, + Width >> 2, + &WidePixel + ); + } else { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthFillUint8, + 0, + Offset, + Width, + &Pixel + ); + } + } + } + break; + + case EfiBltBufferToVideo: + for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { + + for (X = 0; X < Width; X++) { + Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Delta) + (SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + Private->LineBuffer[X] = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03)); + } + + Offset = (DstY * Private->ModeData[CurrentMode].HorizontalResolution) + DestinationX; + + if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthUint32, + 0, + Offset, + Width >> 2, + Private->LineBuffer + ); + } else { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthUint8, + 0, + Offset, + Width, + Private->LineBuffer + ); + } + } + break; + default: + ASSERT (FALSE); + } + + gBS->RestoreTPL (OriginalTPL); + + return EFI_SUCCESS; +} + +EFI_STATUS +CirrusLogic5430GraphicsOutputConstructor ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + UINTN Index; + + + GraphicsOutput = &Private->GraphicsOutput; + GraphicsOutput->QueryMode = CirrusLogic5430GraphicsOutputQueryMode; + GraphicsOutput->SetMode = CirrusLogic5430GraphicsOutputSetMode; + GraphicsOutput->Blt = CirrusLogic5430GraphicsOutputBlt; + + // + // Initialize the private data + // + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE), + (VOID **) &Private->GraphicsOutput.Mode + ); + if (EFI_ERROR (Status)) { + return Status; + } + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), + (VOID **) &Private->GraphicsOutput.Mode->Info + ); + if (EFI_ERROR (Status)) { + return Status; + } + Private->GraphicsOutput.Mode->MaxMode = CIRRUS_LOGIC_5430_MODE_COUNT; + Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER; + for (Index = 0; Index < Private->GraphicsOutput.Mode->MaxMode; Index++) { + Private->ModeData[Index].HorizontalResolution = CirrusLogic5430VideoModes[Index].Width; + Private->ModeData[Index].VerticalResolution = CirrusLogic5430VideoModes[Index].Height; + Private->ModeData[Index].ColorDepth = 32; + Private->ModeData[Index].RefreshRate = CirrusLogic5430VideoModes[Index].RefreshRate; + } + + Private->HardwareNeedsStarting = TRUE; + Private->LineBuffer = NULL; + + // + // Initialize the hardware + // + GraphicsOutput->SetMode (GraphicsOutput, 0); + DrawLogo ( + Private, + Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution, + Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution + ); + + return EFI_SUCCESS; +} + +EFI_STATUS +CirrusLogic5430GraphicsOutputDestructor ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + + None + +--*/ +{ + if (Private->GraphicsOutput.Mode != NULL) { + if (Private->GraphicsOutput.Mode->Info != NULL) { + gBS->FreePool (Private->GraphicsOutput.Mode->Info); + } + gBS->FreePool (Private->GraphicsOutput.Mode); + } + + return EFI_SUCCESS; +} + + diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c new file mode 100644 index 0000000000..75b1d24c8a --- /dev/null +++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c @@ -0,0 +1,427 @@ +/** @file + This file produces the graphics abstration of UGA Draw. It is called by + CirrusLogic5430.c file which deals with the EFI 1.1 driver model. + This file just does graphics. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "CirrusLogic5430.h" + +// +// UGA Draw Protocol Member Functions +// +EFI_STATUS +EFIAPI +CirrusLogic5430UgaDrawGetMode ( + IN EFI_UGA_DRAW_PROTOCOL *This, + OUT UINT32 *HorizontalResolution, + OUT UINT32 *VerticalResolution, + OUT UINT32 *ColorDepth, + OUT UINT32 *RefreshRate + ) +{ + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private; + + Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This); + + if (Private->HardwareNeedsStarting) { + return EFI_NOT_STARTED; + } + + if ((HorizontalResolution == NULL) || + (VerticalResolution == NULL) || + (ColorDepth == NULL) || + (RefreshRate == NULL)) { + return EFI_INVALID_PARAMETER; + } + + *HorizontalResolution = Private->ModeData[Private->CurrentMode].HorizontalResolution; + *VerticalResolution = Private->ModeData[Private->CurrentMode].VerticalResolution; + *ColorDepth = Private->ModeData[Private->CurrentMode].ColorDepth; + *RefreshRate = Private->ModeData[Private->CurrentMode].RefreshRate; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CirrusLogic5430UgaDrawSetMode ( + IN EFI_UGA_DRAW_PROTOCOL *This, + IN UINT32 HorizontalResolution, + IN UINT32 VerticalResolution, + IN UINT32 ColorDepth, + IN UINT32 RefreshRate + ) +{ + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private; + UINTN Index; + + Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This); + + for (Index = 0; Index < Private->MaxMode; Index++) { + + if (HorizontalResolution != Private->ModeData[Index].HorizontalResolution) { + continue; + } + + if (VerticalResolution != Private->ModeData[Index].VerticalResolution) { + continue; + } + + if (ColorDepth != Private->ModeData[Index].ColorDepth) { + continue; + } + + if (RefreshRate != Private->ModeData[Index].RefreshRate) { + continue; + } + + if (Private->LineBuffer) { + gBS->FreePool (Private->LineBuffer); + } + + Private->LineBuffer = NULL; + Private->LineBuffer = AllocatePool (HorizontalResolution); + if (Private->LineBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[Index]); + + Private->CurrentMode = Index; + + Private->HardwareNeedsStarting = FALSE; + + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +EFIAPI +CirrusLogic5430UgaDrawBlt ( + IN EFI_UGA_DRAW_PROTOCOL *This, + IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL + IN EFI_UGA_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ) +{ + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private; + EFI_TPL OriginalTPL; + UINTN DstY; + UINTN SrcY; + EFI_UGA_PIXEL *Blt; + UINTN X; + UINT8 Pixel; + UINT32 WidePixel; + UINTN ScreenWidth; + UINTN Offset; + UINTN SourceOffset; + + Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This); + + if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) { + return EFI_INVALID_PARAMETER; + } + + if (Width == 0 || Height == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // If Delta is zero, then the entire BltBuffer is being used, so Delta + // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size, + // the number of bytes in each row can be computed. + // + if (Delta == 0) { + Delta = Width * sizeof (EFI_UGA_PIXEL); + } + + // + // We need to fill the Virtual Screen buffer with the blt data. + // The virtual screen is upside down, as the first row is the bootom row of + // the image. + // + + // + // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters + // are valid for the operation and the current screen geometry. + // + if (BltOperation == EfiUgaVideoToBltBuffer) { + // + // Video to BltBuffer: Source is Video, destination is BltBuffer + // + if (SourceY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) { + return EFI_INVALID_PARAMETER; + } + + if (SourceX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) { + return EFI_INVALID_PARAMETER; + } + } else { + // + // BltBuffer to Video: Source is BltBuffer, destination is Video + // + if (DestinationY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) { + return EFI_INVALID_PARAMETER; + } + + if (DestinationX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) { + return EFI_INVALID_PARAMETER; + } + } + // + // We have to raise to TPL Notify, so we make an atomic write the frame buffer. + // We would not want a timer based event (Cursor, ...) to come in while we are + // doing this operation. + // + OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY); + + switch (BltOperation) { + case EfiUgaVideoToBltBuffer: + // + // Video to BltBuffer: Source is Video, destination is BltBuffer + // + for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) { + + Offset = (SrcY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + SourceX; + if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) { + Private->PciIo->Mem.Read ( + Private->PciIo, + EfiPciIoWidthUint32, + 0, + Offset, + Width >> 2, + Private->LineBuffer + ); + } else { + Private->PciIo->Mem.Read ( + Private->PciIo, + EfiPciIoWidthUint8, + 0, + Offset, + Width, + Private->LineBuffer + ); + } + + for (X = 0; X < Width; X++) { + Blt = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_UGA_PIXEL)); + + Blt->Red = (UINT8) (Private->LineBuffer[X] & 0xe0); + Blt->Green = (UINT8) ((Private->LineBuffer[X] & 0x1c) << 3); + Blt->Blue = (UINT8) ((Private->LineBuffer[X] & 0x03) << 6); + } + } + break; + + case EfiUgaVideoToVideo: + // + // Perform hardware acceleration for Video to Video operations + // + ScreenWidth = Private->ModeData[Private->CurrentMode].HorizontalResolution; + SourceOffset = (SourceY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (SourceX); + Offset = (DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (DestinationX); + + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014); + + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015); + + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) & 0xff00) | 0x20)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) | 0x21)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) & 0xff00) | 0x22)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) | 0x23)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x24)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x25)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x26)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x27)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) & 0xff00) | 0x28)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) & 0xff00) | 0x29)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) & 0xff00) | 0x2a)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) << 8) & 0xff00) | 0x2c)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 0) & 0xff00) | 0x2d)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 8) & 0xff00) | 0x2e)); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034); + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035); + + outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231); + + outb (Private, GRAPH_ADDRESS_REGISTER, 0x31); + while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01) + ; + break; + + case EfiUgaVideoFill: + Blt = BltBuffer; + Pixel = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03)); + WidePixel = (Pixel << 8) | Pixel; + WidePixel = (WidePixel << 16) | WidePixel; + + if (DestinationX == 0 && Width == Private->ModeData[Private->CurrentMode].HorizontalResolution) { + Offset = DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution; + if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthFillUint32, + 0, + Offset, + (Width * Height) >> 2, + &WidePixel + ); + } else { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthFillUint8, + 0, + Offset, + Width * Height, + &Pixel + ); + } + } else { + for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { + Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX; + if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthFillUint32, + 0, + Offset, + Width >> 2, + &WidePixel + ); + } else { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthFillUint8, + 0, + Offset, + Width, + &Pixel + ); + } + } + } + break; + + case EfiUgaBltBufferToVideo: + for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { + + for (X = 0; X < Width; X++) { + Blt = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Delta) + (SourceX + X) * sizeof (EFI_UGA_PIXEL)); + Private->LineBuffer[X] = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03)); + } + + Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX; + + if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthUint32, + 0, + Offset, + Width >> 2, + Private->LineBuffer + ); + } else { + Private->PciIo->Mem.Write ( + Private->PciIo, + EfiPciIoWidthUint8, + 0, + Offset, + Width, + Private->LineBuffer + ); + } + } + break; + + default: + break; + } + + gBS->RestoreTPL (OriginalTPL); + + return EFI_SUCCESS; +} + +// +// Construction and Destruction functions +// +EFI_STATUS +CirrusLogic5430UgaDrawConstructor ( + CIRRUS_LOGIC_5430_PRIVATE_DATA *Private + ) +{ + EFI_UGA_DRAW_PROTOCOL *UgaDraw; + UINTN Index; + + // + // Fill in Private->UgaDraw protocol + // + UgaDraw = &Private->UgaDraw; + + UgaDraw->GetMode = CirrusLogic5430UgaDrawGetMode; + UgaDraw->SetMode = CirrusLogic5430UgaDrawSetMode; + UgaDraw->Blt = CirrusLogic5430UgaDrawBlt; + + // + // Initialize the private data + // + Private->MaxMode = CIRRUS_LOGIC_5430_MODE_COUNT; + Private->CurrentMode = 0; + for (Index = 0; Index < Private->MaxMode; Index++) { + Private->ModeData[Index].HorizontalResolution = CirrusLogic5430VideoModes[Index].Width; + Private->ModeData[Index].VerticalResolution = CirrusLogic5430VideoModes[Index].Height; + Private->ModeData[Index].ColorDepth = 32; + Private->ModeData[Index].RefreshRate = CirrusLogic5430VideoModes[Index].RefreshRate; + } + + Private->HardwareNeedsStarting = TRUE; + Private->LineBuffer = NULL; + + // + // Initialize the hardware + // + UgaDraw->SetMode ( + UgaDraw, + Private->ModeData[Private->CurrentMode].HorizontalResolution, + Private->ModeData[Private->CurrentMode].VerticalResolution, + Private->ModeData[Private->CurrentMode].ColorDepth, + Private->ModeData[Private->CurrentMode].RefreshRate + ); + DrawLogo ( + Private, + Private->ModeData[Private->CurrentMode].HorizontalResolution, + Private->ModeData[Private->CurrentMode].VerticalResolution + ); + + return EFI_SUCCESS; +} + diff --git a/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c b/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c new file mode 100644 index 0000000000..8fddfc5f76 --- /dev/null +++ b/OptionRomPkg/CirrusLogic5430Dxe/ComponentName.c @@ -0,0 +1,240 @@ +/** @file + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "CirrusLogic5430.h" + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gCirrusLogic5430ComponentName = { + CirrusLogic5430ComponentNameGetDriverName, + CirrusLogic5430ComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gCirrusLogic5430ComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) CirrusLogic5430ComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) CirrusLogic5430ComponentNameGetControllerName, + "en" +}; + + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mCirrusLogic5430DriverNameTable[] = { + { "eng;en", L"Cirrus Logic 5430 Driver" }, + { NULL , NULL } +}; + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mCirrusLogic5430ControllerNameTable[] = { + { "eng;en", L"Cirrus Logic 5430 PCI Adapter" }, + { NULL , NULL } +}; + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 3066 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +CirrusLogic5430ComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mCirrusLogic5430DriverNameTable, + DriverName, + (BOOLEAN)(This == &gCirrusLogic5430ComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 3066 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +CirrusLogic5430ComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_UGA_DRAW_PROTOCOL *UgaDraw; + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIoProtocol; + + // + // This is a device driver, so ChildHandle must be NULL. + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Check Controller's handle + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIoProtocol, + gCirrusLogic5430DriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (!EFI_ERROR (Status)) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + gCirrusLogic5430DriverBinding.DriverBindingHandle, + ControllerHandle + ); + + return EFI_UNSUPPORTED; + } + + if (Status != EFI_ALREADY_STARTED) { + return EFI_UNSUPPORTED; + } + + // + // Get the UGA Draw Protocol on Controller + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiUgaDrawProtocolGuid, + (VOID **) &UgaDraw, + gCirrusLogic5430DriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get the Cirrus Logic 5430's Device structure + // + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mCirrusLogic5430ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gCirrusLogic5430ComponentName) + ); +} diff --git a/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c b/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c new file mode 100644 index 0000000000..77ed0079fe --- /dev/null +++ b/OptionRomPkg/CirrusLogic5430Dxe/DriverSupportedEfiVersion.c @@ -0,0 +1,20 @@ +/** @file + Copyright (c) 2007, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: DriverSupportEfiVersion.c + +**/ +#include "CirrusLogic5430.h" + +EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gCirrusLogic5430DriverSupportedEfiVersion = { + sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of Protocol structure. + 0 // Version number to be filled at start up. +}; + diff --git a/OptionRomPkg/OptionRomPkg.dec b/OptionRomPkg/OptionRomPkg.dec index b6993d7d36..d626d18b27 100644 --- a/OptionRomPkg/OptionRomPkg.dec +++ b/OptionRomPkg/OptionRomPkg.dec @@ -27,6 +27,8 @@ [PcdsFeatureFlag.common] gOptionRomPkgTokenSpaceGuid.PcdSupportScsiPassThru|TRUE|BOOLEAN|0x00010001 gOptionRomPkgTokenSpaceGuid.PcdSupportExtScsiPassThru|TRUE|BOOLEAN|0x00010002 + gOptionRomPkgTokenSpaceGuid.PcdSupportGop|TRUE|BOOLEAN|0x00010004 + gOptionRomPkgTokenSpaceGuid.PcdSupportUga|TRUE|BOOLEAN|0x00010005 [PcdsFixedAtBuild.common] gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion|0x0002000a|UINT32|0x00010003 diff --git a/OptionRomPkg/OptionRomPkg.dsc b/OptionRomPkg/OptionRomPkg.dsc index a65e5ce91b..9a19b79b0c 100644 --- a/OptionRomPkg/OptionRomPkg.dsc +++ b/OptionRomPkg/OptionRomPkg.dsc @@ -90,4 +90,5 @@ [Components.common] OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf + OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf diff --git a/OptionRomPkg/ReadMe.txt b/OptionRomPkg/ReadMe.txt index a6c160a6b6..dc51fbcb0b 100644 --- a/OptionRomPkg/ReadMe.txt +++ b/OptionRomPkg/ReadMe.txt @@ -1,14 +1,16 @@ -For now, AtapiPassThru driver in this package is to test Scsi Bus support: -ScsiBus driver should support both/either ScsiPassThru and ExtScsiPassThru -installed on a controller handle. - -AtapiPassThru driver in this package can selectively produce ScsiPassThru -and/or ExtScsiPassThru protocol based on feature flags of PcdSupportScsiPassThru -and PcdExtScsiPassThru. +AtapiPassThru: + For now, AtapiPassThru driver in this package is to test Scsi Bus support: + ScsiBus driver should support both/either ScsiPassThru and ExtScsiPassThru + installed on a controller handle. + + AtapiPassThru driver in this package can selectively produce ScsiPassThru + and/or ExtScsiPassThru protocol based on feature flags of PcdSupportScsiPassThru + and PcdExtScsiPassThru. -Please note that AtapiPassThru driver has not been tuned to size optimal. -Neither is it feature complete: several driver model protocols required -by option ROM driver, e.g. EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL Protocol. +CirrusLogic5430: + Sample implementation of UGA Draw or Graphics Output Protocol for the Cirrus + Logic 5430 family of PCI video card. It provides reference code for the GOP/UGA, + Component Name (2), EFI driver supported Verison protocol. Build Validation: MYTOOLS(VS2005) IA32 X64 IPF EBC -- 2.39.2