diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/CSM/thunk/CsmVideo | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Core/EM/CSM/thunk/CsmVideo')
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/AmiMapping.c | 162 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/AmiMapping.h | 153 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/ComponentName.c | 324 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/CsmVideo.cif | 20 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/CsmVideo.dxs | 46 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/CsmVideo.mak | 66 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/CsmVideo.sdl | 58 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.c | 3886 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.h | 597 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/VesaBiosExtensions.h | 463 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/VgaClass.c | 1349 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/VgaClass.h | 418 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/VgaMiniPort.h | 78 | ||||
-rw-r--r-- | Core/EM/CSM/thunk/CsmVideo/pci22.h | 621 |
14 files changed, 8241 insertions, 0 deletions
diff --git a/Core/EM/CSM/thunk/CsmVideo/AmiMapping.c b/Core/EM/CSM/thunk/CsmVideo/AmiMapping.c new file mode 100644 index 0000000..88c165b --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/AmiMapping.c @@ -0,0 +1,162 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2006, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/AmiMapping.c 2 3/04/11 2:28p Olegi $ +// +// $Revision: 2 $ +// +// $Date: 3/04/11 2:28p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/AmiMapping.c $ +// +// 2 3/04/11 2:28p Olegi +// [TAG] EIP55098 +// [Category] Spec Update +// [Severity] Important +// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI +// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode. +// [Files] UefiBiosVideo.h +// UefiBiosVideo.c +// ComponentName.c +// AmiMapping.h +// AmiMapping.c +// +// 1 12/29/06 3:33p Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: AmiMapping.c +// +// Description: Mapping from EDK to AMI definitions +// +//<AMI_FHDR_END> +//********************************************************************** +#include "AmiMapping.h" +#include "VgaMiniPort.h" + +EFI_GUID gEfiVgaMiniPortProtocolGuid = EFI_VGA_MINI_PORT_PROTOCOL_GUID; + +EFI_STATUS EfiLibInstallAllDriverProtocols ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, + IN EFI_HANDLE DriverBindingHandle, +#if EFI_SPECIFICATION_VERSION <= 0x20000 + IN EFI_COMPONENT_NAME_PROTOCOL *ComponentName, OPTIONAL +#else + IN EFI_COMPONENT_NAME2_PROTOCOL *ComponentName, OPTIONAL +#endif + IN VOID/*EFI_DRIVER_CONFIGURATION_PROTOCOL*/ *DriverConfiguration, OPTIONAL + IN VOID/*EFI_DRIVER_DIAGNOSTICS_PROTOCOL*/ *DriverDiagnostics OPTIONAL +) +{ + EFI_STATUS Status; + InitAmiLib (ImageHandle, SystemTable); + DriverBinding->ImageHandle = ImageHandle; + DriverBinding->DriverBindingHandle = DriverBindingHandle; + Status = gBS->InstallMultipleProtocolInterfaces ( + &DriverBinding->DriverBindingHandle, + &gEfiDriverBindingProtocolGuid, DriverBinding, + NULL + ); + if (EFI_ERROR(Status)) return Status; + if (ComponentName) + Status = gBS->InstallMultipleProtocolInterfaces ( + &DriverBinding->DriverBindingHandle, +#if EFI_SPECIFICATION_VERSION <= 0x20000 + &gEfiComponentNameProtocolGuid, ComponentName, +#else + &gEfiComponentName2ProtocolGuid,ComponentName, +#endif + NULL + ); + return Status; +} + +BOOLEAN +EfiLibCompareLanguage ( + CHAR8 *Language1, + CHAR8 *Language2 + ) + +{ + return *(UINT16*)Language1==*(UINT16*)Language2 + && Language1[2]==Language2[2]; +} + +EFI_STATUS EfiLibLookupUnicodeString ( + CHAR8 *Language, + CHAR8 *SupportedLanguages, + EFI_UNICODE_STRING_TABLE *UnicodeStringTable, + CHAR16 **UnicodeString + ) +{ + // + // Make sure the parameters are valid + // + if (Language == NULL || UnicodeString == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // If there are no supported languages, or the Unicode String Table is empty, then the + // Unicode String specified by Language is not supported by this Unicode String Table + // + if (SupportedLanguages == NULL || UnicodeStringTable == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure Language is in the set of Supported Languages + // + while (*SupportedLanguages != 0) { + if (EfiLibCompareLanguage (Language, SupportedLanguages)) { + + // + // Search the Unicode String Table for the matching Language specifier + // + while (UnicodeStringTable->Language != NULL) { + if (EfiLibCompareLanguage (Language, UnicodeStringTable->Language)) { + + // + // A matching string was found, so return it + // + *UnicodeString = UnicodeStringTable->UnicodeString; + return EFI_SUCCESS; + } + UnicodeStringTable++; + } + return EFI_UNSUPPORTED; + } + SupportedLanguages += 3; + } + return EFI_UNSUPPORTED; +} +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2006, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/CSM/thunk/CsmVideo/AmiMapping.h b/Core/EM/CSM/thunk/CsmVideo/AmiMapping.h new file mode 100644 index 0000000..9c92d54 --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/AmiMapping.h @@ -0,0 +1,153 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2006, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/AmiMapping.h 3 12/23/13 10:21a Olegi $ +// +// $Revision: 3 $ +// +// $Date: 12/23/13 10:21a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/AmiMapping.h $ +// +// 3 12/23/13 10:21a Olegi +// [TAG] EIP148123 +// [Description] CSM includes file which name has been changed +// +// 2 3/04/11 2:28p Olegi +// [TAG] EIP55098 +// [Category] Spec Update +// [Severity] Important +// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI +// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode. +// [Files] UefiBiosVideo.h +// UefiBiosVideo.c +// ComponentName.c +// AmiMapping.h +// AmiMapping.c +// +// 1 12/29/06 3:33p Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: AmiMapping.h +// +// Description: Mapping from EDK to AMI definitions +// +//<AMI_FHDR_END> +//********************************************************************** +#ifndef __AMI_MAPPING__H__ +#define __AMI_MAPPING__H__ +#ifdef __cplusplus +extern "C" { +#endif +#include <Protocol/DriverBinding.h> +#include <Protocol/ComponentName.h> +#include <AmiDxeLib.h> +#include <Token.h> + +#define STATIC static +#define EFI_GUID_DEFINITION(a) +#define EFI_PROTOCOL_DEFINITION(a) CONVERT_TO_STRING(Protocol/a.h) +#define EFI_DRIVER_ENTRY_POINT(a) +#define EFI_TPL_NOTIFY TPL_NOTIFY +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) + +#define EfiZeroMem(Address, Length) gBS->SetMem ((Address), (Length), 0) +#define gBS pBS +#define ReportStatusCodeWithDevicePath(a,b,c,d,e) + +#define ACPI_ADR_DISPLAY_TYPE_VGA 1 +#define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \ + ((UINT32) ( (((_DeviceIdScheme) & 0x1) << 31) | \ + (((_HeadId) & 0x7) << 18) | \ + (((_NonVgaOutput) & 0x1) << 17) | \ + (((_BiosCanDetect) & 0x1) << 16) | \ + (((_VendorInfo) & 0xf) << 12) | \ + (((_Type) & 0xf) << 8) | \ + (((_Port) & 0xf) << 4) | \ + ((_Index) & 0xf) )) +#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION < 0x4028F) +#define SetDevicePathNodeLength SET_NODE_LENGTH +#endif + +#define EfiAppendDevicePathNode DPAddNode +#define CR(pField, OutterType, Field, Signature) OUTTER(pField, Field, OutterType) +#define EFI_SEGMENT(_Adr) (UINT16) ((UINT16) (((UINTN) (_Adr)) >> 4) & 0xf000) +#define EFI_OFFSET(_Adr) (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff) +#define EFI_SIMPLE_TEXT_OUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL +#define EFI_SIMPLE_TEXT_OUTPUT_MODE SIMPLE_TEXT_OUTPUT_MODE +#define CHAR_NULL 0x0000 +#define CHAR_BACKSPACE 0x0008 +#define CHAR_TAB 0x0009 +#define CHAR_LINEFEED 0x000A +#define CHAR_CARRIAGE_RETURN 0x000D + +typedef struct { + CHAR8 *Language; + CHAR16 *UnicodeString; +} EFI_UNICODE_STRING_TABLE; + +#define INSTALL_ALL_DRIVER_PROTOCOLS EfiLibInstallAllDriverProtocols +EFI_STATUS +EfiLibInstallAllDriverProtocols ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, + IN EFI_HANDLE DriverBindingHandle, +#if EFI_SPECIFICATION_VERSION <= 0x20000 + IN EFI_COMPONENT_NAME_PROTOCOL *ComponentName, OPTIONAL +#else + IN EFI_COMPONENT_NAME2_PROTOCOL *ComponentName, OPTIONAL +#endif + IN VOID/*EFI_DRIVER_CONFIGURATION_PROTOCOL*/ *DriverConfiguration, OPTIONAL + IN VOID/*EFI_DRIVER_DIAGNOSTICS_PROTOCOL*/ *DriverDiagnostics OPTIONAL + ); + +EFI_STATUS +EfiLibLookupUnicodeString ( + CHAR8 *Language, + CHAR8 *SupportedLanguages, + EFI_UNICODE_STRING_TABLE *UnicodeStringTable, + CHAR16 **UnicodeString + ); + +EFI_STATUS +EFIAPI +VgaClassDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2006, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/CSM/thunk/CsmVideo/ComponentName.c b/Core/EM/CSM/thunk/CsmVideo/ComponentName.c new file mode 100644 index 0000000..786cec4 --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/ComponentName.c @@ -0,0 +1,324 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +/*++ + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +--*/ +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + ComponentName.c + +Abstract: + +--*/ +//*** AMI PORTING BEGIN ***// +//This file is not part of the component. +//#include "BiosVideo.h" +#include "UefiBiosVideo.h" +//*** AMI PORTING END *****// + +// +// EFI Component Name Functions +// +EFI_STATUS +EFIAPI +BiosVideoComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +BiosVideoComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +EFI_STATUS + +EFIAPI +BiosVideoComponentName2GetDriverName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + + +EFI_STATUS +EFIAPI +BiosVideoComponentName2GetControllerName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + + +// +// EFI Component Name Protocol +// +EFI_COMPONENT_NAME2_PROTOCOL gBiosVideoComponentName2 = { + BiosVideoComponentName2GetDriverName, + BiosVideoComponentName2GetControllerName, + LANGUAGE_CODE_ENGLISH +}; + +EFI_COMPONENT_NAME_PROTOCOL gBiosVideoComponentName = { + BiosVideoComponentNameGetDriverName, + BiosVideoComponentNameGetControllerName, + "eng" +}; + +static EFI_UNICODE_STRING_TABLE mBiosVideoDriverNameTable[] = { + { + "eng", + L"BIOS[INT10] Video Driver" + }, + { + NULL, + NULL + } +}; + +static EFI_UNICODE_STRING_TABLE mBiosVideoDriverNameTable2[] = { + { + LANGUAGE_CODE_ENGLISH, + L"BIOS[INT10] Video Driver" + }, + { + NULL, + NULL + } +}; + +EFI_STATUS +EFIAPI +BiosVideoComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + Language - A pointer to a three character ISO 639-2 language identifier. + This is the language of the driver name that 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. + DriverName - 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. + + Returns: + EFI_SUCCESS - The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - DriverName is NULL. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + + return EfiLibLookupUnicodeString ( + Language, + gBiosVideoComponentName.SupportedLanguages, + mBiosVideoDriverNameTable, + DriverName + ); +} + +EFI_STATUS +EFIAPI +BiosVideoComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + ControllerHandle - The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + ChildHandle - 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. + Language - A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that 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. + ControllerName - 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. + + Returns: + 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. + EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - ControllerName is NULL. + EFI_UNSUPPORTED - The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + return EFI_UNSUPPORTED; +} + + +EFI_STATUS +EFIAPI +BiosVideoComponentName2GetDriverName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + Language - A pointer to a three character ISO 639-2 language identifier. + This is the language of the driver name that 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. + DriverName - 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. + + Returns: + EFI_SUCCESS - The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - DriverName is NULL. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + + return EfiLibLookupUnicodeString ( + Language, + gBiosVideoComponentName2.SupportedLanguages, + mBiosVideoDriverNameTable2, + DriverName + ); +} + + +EFI_STATUS +EFIAPI +BiosVideoComponentName2GetControllerName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +/*++ + + Routine Description: + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + Arguments: + This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + ControllerHandle - The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + ChildHandle - 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. + Language - A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that 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. + ControllerName - 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. + + Returns: + 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. + EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE. + EFI_INVALID_PARAMETER - Language is NULL. + EFI_INVALID_PARAMETER - ControllerName is NULL. + EFI_UNSUPPORTED - The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + EFI_UNSUPPORTED - The driver specified by This does not support the + language specified by Language. + +--*/ +{ + return EFI_UNSUPPORTED; +} diff --git a/Core/EM/CSM/thunk/CsmVideo/CsmVideo.cif b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.cif new file mode 100644 index 0000000..e357445 --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.cif @@ -0,0 +1,20 @@ +<component> + name = "CsmVideo" + category = ModulePart + LocalRoot = "Core\EM\CSM\Thunk\CsmVideo\" + RefName = "CsmVideo" +[files] +"CsmVideo.sdl" +"CsmVideo.mak" +"UefiBiosVideo.h" +"UefiBiosVideo.c" +"ComponentName.c" +"VesaBiosExtensions.h" +"pci22.h" +"AmiMapping.h" +"AmiMapping.c" +"VgaMiniPort.h" +"VgaClass.h" +"VgaClass.c" +"CsmVideo.dxs" +<endComponent> diff --git a/Core/EM/CSM/thunk/CsmVideo/CsmVideo.dxs b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.dxs new file mode 100644 index 0000000..2f961f5 --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.dxs @@ -0,0 +1,46 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/CsmVideo.dxs 1 11/10/11 6:34p Olegi $ +// +// $Revision: 1 $ +// +// $Date: 11/10/11 6:34p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/CsmVideo.dxs $ +// +// 1 11/10/11 6:34p Olegi +// +//********************************************************************** + +#include <Protocol\LegacyBios.h> + +DEPENDENCY_START + EFI_LEGACY_BIOS_PROTOCOL_GUID +DEPENDENCY_END + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/CSM/thunk/CsmVideo/CsmVideo.mak b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.mak new file mode 100644 index 0000000..4d59620 --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.mak @@ -0,0 +1,66 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2006, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** + +#********************************************************************** +# $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/CsmVideo.mak 2 4/27/07 5:18p Olegi $ +# +# $Revision: 2 $ +# +# $Date: 4/27/07 5:18p $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/CsmVideo.mak $ +# +# 2 4/27/07 5:18p Olegi +# +# 1 12/29/06 3:33p Felixp +# +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: CsmVideo.mak +# +# Description: CSM Video make file +# +#<AMI_FHDR_END> +#********************************************************************** +all : CsmVideo + +CsmVideo : $(BUILD_DIR)\CsmVideo.mak CsmVideoBin + +$(BUILD_DIR)\CsmVideo.mak : $(CsmVideo_DIR)\$(@B).cif $(CsmVideo_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(CsmVideo_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +CsmVideoBin : $(AMIDXELIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\CsmVideo.mak all\ + GUID=29CF55F8-B675-4f5d-8F2F-B87A3ECFD063\ + ENTRY_POINT=BiosVideoDriverEntryPoint\ + EXT_HEADERS=$(BUILD_DIR)\Token.h\ + TYPE=BS_DRIVER \ + COMPRESS=1 +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2006, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#**********************************************************************
\ No newline at end of file diff --git a/Core/EM/CSM/thunk/CsmVideo/CsmVideo.sdl b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.sdl new file mode 100644 index 0000000..19768e8 --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.sdl @@ -0,0 +1,58 @@ +TOKEN + Name = "CsmVideo_SUPPORT" + Value = "1" + Help = "Main switch to enable CsmVideo support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "INT10_VESA_GO_SUPPORT" + Value = "1" + Help = "Enables/Disables support of the Graphics Output protocol using VESA INT10 extensions" + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "INT10_VGA_GO_SUPPORT" + Value = "0" + Help = "Enables/Disables support of the Graphics Output protocol using standard VGA INT10 calls in 640x480 16 color mode.\If both VGA_GO_SUPPORT and VESA_GO_SUPPORT enabled, VGA calls will only be used if VESA extensions are not supported by the video card." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "INT10_SIMPLE_TEXT_SUPPORT" + Value = "1" + Help = "Enables/Disables support of the Simple Text Output protocol using text mode.\If VGA_GO_SUPPORT or VESA_GO_SUPPORT or both enabled, text mode will will only be used if neither VESA nor standard VGA graphical modes are supported" + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "INT10_TRUST_EDID_INFORMATION" + Value = "1" + Help = "Some SSUs(Server Switch Units) return invalid EDID information, for these turn this switch off." + TokenType = Boolean + TargetH = Yes +End + + +PATH + Name = "CsmVideo_DIR" +End + +MODULE + Help = "Includes CsmVideo.mak to Project" + File = "CsmVideo.mak" +End + +ELINK + Name = "$(BUILD_DIR)\CsmVideo.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End + diff --git a/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.c b/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.c new file mode 100644 index 0000000..ddbe46c --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.c @@ -0,0 +1,3886 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +/*++ + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +--*/ +/*++ + +Copyright (c) 2006 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + BiosVideo.c + +Abstract: + + ConsoleOut Routines that speak VGA. + +Revision History + +--*/ + +//*** AMI PORTING BEGIN ***// +#include "AcpiRes.h" +//*** AMI PORTING END *****// +#include "UefiBiosVideo.h" + +#define TRACE_BIOS_VIDEO TRACE_ALWAYS +//#define TRACE_BIOS_VIDEO TRACE_NEVER + +// +// EFI Driver Binding Protocol Instance +// +EFI_DRIVER_BINDING_PROTOCOL gBiosVideoDriverBinding = { + BiosVideoDriverBindingSupported, + BiosVideoDriverBindingStart, + BiosVideoDriverBindingStop, + 0x00000024, + NULL, + NULL +}; + +typedef struct _TEXT_MODE { + INT32 ModeNum; + INT32 Col; + INT32 Row; + UINT32 VideoCol; // horizontal pixels + UINT32 VideoRow; // vertical pixels +} TEXT_MODE; + +#if CORE_COMBINED_VERSION < 0x4028e +const TEXT_MODE TextModeArray[] = {GC_MODE_LIST}; +const INT32 MaxTextMode=(sizeof(TextModeArray)/sizeof(TEXT_MODE)); +#else +extern TEXT_MODE TextModeArray[]; +extern INT32 MaxTextMode; +#endif + +// remove the following line when Protocol/EdidOverride.h becomes available +EFI_GUID gEfiEdidOverrideProtocolGuid = EFI_EDID_OVERRIDE_PROTOCOL_GUID; + +//*** AMI PORTING BEGIN ***// +#if INT10_VGA_GO_SUPPORT==1 +//*** AMI PORTING END *****// +// +// Global lookup tables for VGA graphics modes +// +UINT8 mVgaLeftMaskTable[] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; + +UINT8 mVgaRightMaskTable[] = { 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; + +UINT8 mVgaBitMaskTable[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; + +EFI_GRAPHICS_OUTPUT_BLT_PIXEL mVgaColorToGraphicsOutputColor[] = { + { 0x00, 0x00, 0x00, 0x00 }, + { 0x98, 0x00, 0x00, 0x00 }, + { 0x00, 0x98, 0x00, 0x00 }, + { 0x98, 0x98, 0x00, 0x00 }, + { 0x00, 0x00, 0x98, 0x00 }, + { 0x98, 0x00, 0x98, 0x00 }, + { 0x00, 0x98, 0x98, 0x00 }, + { 0x98, 0x98, 0x98, 0x00 }, + { 0x10, 0x10, 0x10, 0x00 }, + { 0xff, 0x10, 0x10, 0x00 }, + { 0x10, 0xff, 0x10, 0x00 }, + { 0xff, 0xff, 0x10, 0x00 }, + { 0x10, 0x10, 0xff, 0x00 }, + { 0xf0, 0x10, 0xff, 0x00 }, + { 0x10, 0xff, 0xff, 0x00 }, + { 0xff, 0xff, 0xff, 0x00 } +}; + +//*** AMI PORTING BEGIN ***// +#endif //if INT10_VGA_GO_SUPPORT==1 +#if INT10_VESA_GO_SUPPORT==1 +//*** AMI PORTING END *****// + +// +// Standard timing defined by VESA EDID +// +VESA_BIOS_EXTENSIONS_EDID_TIMING mEstablishedEdidTiming[] = { + // + // Established Timing I + // + {800, 600, 60}, + {800, 600, 56}, + {640, 480, 75}, + {640, 480, 72}, + {640, 480, 67}, + {640, 480, 60}, + {720, 400, 88}, + {720, 400, 70}, + // + // Established Timing II + // + {1280, 1024, 75}, + {1024, 768, 75}, + {1024, 768, 70}, + {1024, 768, 60}, + {1024, 768, 87}, + {832, 624, 75}, + {800, 600, 75}, + {800, 600, 72}, + // + // Established Timing III + // + {1152, 870, 75} +}; +//*** AMI PORTING BEGIN ***// +#endif //if INT10_VESA_GO_SUPPORT==1 +//*** AMI PORTING END *****// + +UINT32 SupportedResolutions[29] = { 0 }; + +EFI_STATUS +BiosVideoChildHandleInstall ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ParentHandle, + IN EFI_PCI_IO_PROTOCOL *ParentPciIo, + IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios, + IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +EFI_STATUS +BiosVideoChildHandleUninstall ( + EFI_DRIVER_BINDING_PROTOCOL *This, + EFI_HANDLE Controller, + EFI_HANDLE Handle + ) +; + +VOID +BiosVideoDeviceReleaseResource ( + BIOS_VIDEO_DEV *BiosVideoPrivate + ) +; + +//*** AMI PORTING BEGIN ***// +//CsmVideo Policy Protocol support +//The protocol can be used to set the driver policy. +// The two supported policies are: +// SimpleTextOut over the text mode 3 (TextMode=TRUE) +// GOP over graphical mode (TextMode=FALSE) +EFI_HANDLE VgaControllerHandle = NULL; +BOOLEAN TextModePolicy = FALSE; + +EFI_STATUS CsmVideoPolicySetMode( + IN CSM_VIDEO_POLICY_PROTOCOL *This, + IN BOOLEAN TextMode, IN BOOLEAN ForceModeChange +){ +#if INT10_SIMPLE_TEXT_SUPPORT==0 + return (TextMode) ? EFI_UNSUPPORTED : EFI_SUCCESS; +#else + EFI_STATUS Status; + BOOLEAN OriginalPolicy=TextModePolicy; + EFI_HANDLE Handle; + + TextModePolicy = TextMode; + if ( VgaControllerHandle == NULL + || OriginalPolicy==TextModePolicy && !ForceModeChange + ) return EFI_SUCCESS; + + // save the VGA handle + // the global variable VgaControllerHandle will be nullified + // by the Stop function during Disconnect. + Handle = VgaControllerHandle; + Status = pBS->DisconnectController( Handle, NULL, NULL ); + if (!EFI_ERROR(Status)) + Status = pBS->ConnectController( Handle, NULL, NULL, TRUE ); + else + TextModePolicy = OriginalPolicy; + if (EFI_ERROR(Status)) return Status; + return (TextModePolicy==TextMode) ? EFI_SUCCESS : EFI_UNSUPPORTED; +#endif +} + +EFI_STATUS CsmVideoPolicyGetMode( + IN CSM_VIDEO_POLICY_PROTOCOL *This,IN BOOLEAN *IsTextMode +){ + if (IsTextMode!=NULL) *IsTextMode = TextModePolicy; + return (VgaControllerHandle == NULL) ? EFI_NOT_STARTED : EFI_SUCCESS; +} + +CSM_VIDEO_POLICY_PROTOCOL CsmVideoPolicyProtocol = { + CsmVideoPolicyGetMode, CsmVideoPolicySetMode +}; +//*** AMI PORTING END *****// + +EFI_STATUS GetBadEdid ( + IN EFI_EDID_OVERRIDE_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle, + OUT UINT32 *Attributes, + IN OUT UINTN *EdidSize, + IN OUT UINT8 **Edid + ) +{ + static UINT8 EdidData[0x80] = {0}; + EdidData[0x7f] = 1; // invalid checksum + + *Edid = EdidData; + *EdidSize = 0x80; + *Attributes = 0; + + return EFI_SUCCESS; +} + + +// +// Driver Entry Point +// +EFI_DRIVER_ENTRY_POINT (BiosVideoDriverEntryPoint) + +EFI_STATUS +EFIAPI +BiosVideoDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + + Routine Description: + + Driver Entry Point. + + Arguments: + + ImageHandle - Handle of driver image. + SystemTable - Pointer to system table. + + Returns: + + EFI_STATUS + +--*/ +{ + EFI_STATUS Status; + static EFI_GUID gCsmThunkDriverGuid = + { 0x2362ea9c, 0x84e5, 0x4dff, 0x83, 0xbc, 0xb5, 0xac, 0xec, 0xb5, 0x7c, 0xbb }; + + Status = EfiLibInstallAllDriverProtocols ( + ImageHandle, + SystemTable, + &gBiosVideoDriverBinding, + ImageHandle, +#if EFI_SPECIFICATION_VERSION <= 0x20000 + &gBiosVideoComponentName, +#else + &gBiosVideoComponentName2, +#endif + NULL, + NULL + ); +//*** AMI PORTING BEGIN ***// +#if INT10_SIMPLE_TEXT_SUPPORT==1 +{ +//create new handle + EFI_HANDLE Handle = NULL; + VgaClassDriverEntryPoint(Handle,SystemTable); +} +#endif + +#if INT10_TRUST_EDID_INFORMATION == 0 +{ + // Install EdidOverride with the dummy EDID information; this is needed to ignore + // bad EDID information + EFI_STATUS Status; + static EFI_EDID_OVERRIDE_PROTOCOL EdidOverride = { GetBadEdid }; + + Status = gBS->InstallMultipleProtocolInterfaces( + &ImageHandle, + &gEfiEdidOverrideProtocolGuid, &EdidOverride, + NULL + ); +} +#endif + +// Install CsmVideoPolicy protocol + gBS->InstallMultipleProtocolInterfaces( + &ImageHandle, + &gCsmVideoPolicyProtocolGuid, &CsmVideoPolicyProtocol, + &gCsmThunkDriverGuid, NULL, + NULL + ); + +//AMI CSM Core does not need Legacy BIOS GUID +//Just return the status + return Status; +/* + if (EFI_ERROR (Status)) { + return Status; + } + // + // Install Legacy BIOS GUID to mark this driver as a BIOS Thunk Driver + // + return gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gEfiLegacyBiosGuid, + NULL, + NULL + ); +*/ +//*** AMI PORTING END *****// +} +//*** AMI PORTING BEGIN ***// +//Exit Boot Services callback is not needed. +/* +VOID +BiosVideoExitBootServices ( + EFI_EVENT Event, + VOID *Context + ) +*/ +/*++ + +Routine Description: + + Callback function for exit boot service event + +Arguments: + + Event - EFI_EVENT structure + Context - Event context + +Returns: + + None + +--*/ +/*{ + BIOS_VIDEO_DEV *BiosVideoPrivate; + EFI_IA32_REGISTER_SET Regs; + + // + // Get our context + // + BiosVideoPrivate = (BIOS_VIDEO_DEV *) Context; + + // + // Set the 80x25 Text VGA Mode + // + Regs.H.AH = 0x00; + Regs.H.AL = 0x83; + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + + Regs.H.AH = 0x11; + Regs.H.AL = 0x14; + Regs.H.BL = 0; + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); +} +*/ +//*** AMI PORTING END *****// + +EFI_STATUS +EFIAPI +BiosVideoDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + + Routine Description: + + Supported. + + Arguments: + + This - Pointer to driver binding protocol + Controller - Controller handle to connect + RemainingDevicePath - A pointer to the remaining portion of a device path + + + Returns: + + EFI_STATUS - EFI_SUCCESS:This controller can be managed by this driver, + Otherwise, this controller cannot be managed by this driver + +--*/ +{ + EFI_STATUS Status; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 Pci; + + // + // See if the Legacy BIOS Protocol is available + // + Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // See if this is a PCI Graphics Controller by looking at the Command register and + // Class Code Register + // + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + if (EFI_ERROR (Status)) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + Status = EFI_UNSUPPORTED; + if (Pci.Hdr.ClassCode[2] == 0x03 || (Pci.Hdr.ClassCode[2] == 0x00 && Pci.Hdr.ClassCode[1] == 0x01)) { + Status = EFI_SUCCESS; + } + +Done: + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return Status; +} + +EFI_STATUS +EFIAPI +BiosVideoDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + + Routine Description: + + Install Graphics Output Protocol onto VGA device handles + + Arguments: + + This - Pointer to driver binding protocol + Controller - Controller handle to connect + RemainingDevicePath - A pointer to the remaining portion of a device path + + Returns: + + EFI_STATUS + +--*/ +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + UINTN Flags; +//*** AMI PORTING BEGIN ***// +// See comments below regarding the Capabilities usage + UINT64 Capabilities = 0; +//*** AMI PORTING END *****// + + PciIo = NULL; + // + // Prepare for status code + // + Status = gBS->HandleProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // Open the IO Abstraction(s) needed + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // See if the Legacy BIOS Protocol is available + // + Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); + if (EFI_ERROR (Status)) { + goto Done; + } + + ReportStatusCodeWithDevicePath ( + EFI_PROGRESS_CODE, + EFI_P_PC_ENABLE, + 0, + &gEfiCallerIdGuid, + ParentDevicePath + ); + // + // Enable the device and make sure VGA cycles are being forwarded to this VGA device + // +//*** AMI PORTING BEGIN ***// +// We need to check what is supported by the hardware before enabling attributes + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSupported, + 0, + &Capabilities + ); + + if ( EFI_ERROR(Status) ) { + goto Done; + } + + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationEnable, + Capabilities & EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO, + NULL + ); +/* + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationEnable, + EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO, + NULL + ); +*/ +//*** AMI PORTING END *****// + if (EFI_ERROR (Status)) { + ReportStatusCodeWithDevicePath ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_RESOURCE_CONFLICT, + 0, + &gEfiCallerIdGuid, + ParentDevicePath + ); + goto Done; + } + // + // Check to see if there is a legacy option ROM image associated with this PCI device + // + Status = LegacyBios->CheckPciRom ( + LegacyBios, + Controller, + NULL, + NULL, + &Flags + ); + if (EFI_ERROR (Status)) { + goto Done; + } + // + // Post the legacy option ROM if it is available. + // + ReportStatusCodeWithDevicePath ( + EFI_PROGRESS_CODE, + EFI_P_PC_RESET, + 0, + &gEfiCallerIdGuid, + ParentDevicePath + ); + Status = LegacyBios->InstallPciRom ( + LegacyBios, + Controller, + NULL, + &Flags, + NULL, + NULL, + NULL, + NULL + ); + if (EFI_ERROR (Status)) { + ReportStatusCodeWithDevicePath ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR, + 0, + &gEfiCallerIdGuid, + ParentDevicePath + ); + goto Done; + } + + // + // Create child handle and install GraphicsOutputProtocol on it + // + Status = BiosVideoChildHandleInstall ( + This, + Controller, + PciIo, + LegacyBios, + ParentDevicePath, + RemainingDevicePath + ); + +Done: + if (EFI_ERROR (Status)) { + if (PciIo != NULL) { + ReportStatusCodeWithDevicePath ( + EFI_PROGRESS_CODE, + EFI_P_PC_DISABLE, + 0, + &gEfiCallerIdGuid, + ParentDevicePath + ); + // + // Turn off the PCI device and disable forwarding of VGA cycles to this device + // + if (Capabilities != 0) + { + PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationDisable, +//*** AMI PORTING BEGIN ***// + Capabilities & EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO, +// EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO, +//*** AMI PORTING END *****// + NULL + ); + } + // + // Release PCI I/O Protocols on the controller handle. + // + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + } + } + + return Status; +} + +EFI_STATUS +EFIAPI +BiosVideoDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +/*++ + + Routine Description: + + Stop. + + Arguments: + + This - Pointer to driver binding protocol + Controller - Controller handle to connect + NumberOfChilren - Number of children handle created by this driver + ChildHandleBuffer - Buffer containing child handle created + + Returns: + + EFI_SUCCESS - Driver disconnected successfully from controller + EFI_UNSUPPORTED - Cannot find BIOS_VIDEO_DEV structure + +--*/ +{ + EFI_STATUS Status; + BIOS_VIDEO_DEV *BiosVideoPrivate; + BOOLEAN AllChildrenStopped; + UINTN Index; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT64 Capabilities; + + BiosVideoPrivate = NULL; + + if (NumberOfChildren == 0) { +//*** AMI PORTING BEGIN ***// +//In text mode, the child handle is not created +//and the mini port protocol is installed on the PciIo handle. +//Original implementation does not stop controller in this case +//Here is the fix: +#if INT10_SIMPLE_TEXT_SUPPORT==1 + Status = gBS->OpenProtocol ( + Controller, + &gEfiVgaMiniPortProtocolGuid, + NULL, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (!EFI_ERROR(Status)){ + return BiosVideoChildHandleUninstall (This, Controller, Controller); + } +#endif + + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + ASSERT_EFI_ERROR(Status); + + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSupported, + 0, + &Capabilities + ); + ASSERT_EFI_ERROR(Status); + + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationDisable, + Capabilities & EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO, + NULL + ); + + ASSERT_EFI_ERROR(Status); + if(EFI_ERROR(Status)) return EFI_DEVICE_ERROR; +//*** AMI PORTING END *****// + // + // Close PCI I/O protocol on the controller handle + // + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return EFI_SUCCESS; + } + + AllChildrenStopped = TRUE; + for (Index = 0; Index < NumberOfChildren; Index++) { + Status = BiosVideoChildHandleUninstall (This, Controller, ChildHandleBuffer[Index]); + + if (EFI_ERROR (Status)) { + AllChildrenStopped = FALSE; + } + } + + if (!AllChildrenStopped) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +BiosVideoChildHandleInstall ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ParentHandle, + IN EFI_PCI_IO_PROTOCOL *ParentPciIo, + IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios, + IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + +Routine Description: + Install child handles if the Handle supports MBR format. + +Arguments: + This - Calling context. + Handle - Parent Handle + PciIo - Parent PciIo interface + LegacyBios - Parent LegacyBios interface + DevicePath - Parent Device Path + +Returns: + EFI_SUCCESS - If a child handle was added + other - A child handle was not added + +--*/ +{ + EFI_STATUS Status; + BIOS_VIDEO_DEV *BiosVideoPrivate; + PCI_TYPE00 Pci; + ACPI_ADR_DEVICE_PATH AcpiDeviceNode; + + // + // Allocate the private device structure for video device + // + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (BIOS_VIDEO_DEV), + &BiosVideoPrivate + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + EfiZeroMem (BiosVideoPrivate, sizeof (BIOS_VIDEO_DEV)); + + // + // See if this is a VGA compatible controller or not + // + Status = ParentPciIo->Pci.Read ( + ParentPciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + if (EFI_ERROR (Status)) { + ReportStatusCodeWithDevicePath ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR, + 0, + &gEfiCallerIdGuid, + ParentDevicePath + ); + goto Done; + } + BiosVideoPrivate->VgaCompatible = FALSE; + if (Pci.Hdr.ClassCode[2] == 0x00 && Pci.Hdr.ClassCode[1] == 0x01) { + BiosVideoPrivate->VgaCompatible = TRUE; + } + + if (Pci.Hdr.ClassCode[2] == 0x03 && Pci.Hdr.ClassCode[1] == 0x00 && Pci.Hdr.ClassCode[0] == 0x00) { + BiosVideoPrivate->VgaCompatible = TRUE; + } + + // + // Initialize the child private structure + // + BiosVideoPrivate->Signature = BIOS_VIDEO_DEV_SIGNATURE; + BiosVideoPrivate->Handle = NULL; + +//*** AMI PORTING BEGIN ***// +//Exit Boot Services callback is not needed. +/* + Status = gBS->CreateEvent ( + EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES, + EFI_TPL_NOTIFY, + BiosVideoExitBootServices, + BiosVideoPrivate, + &BiosVideoPrivate->ExitBootServicesEvent + ); + if (EFI_ERROR (Status)) { + goto Done; + } +*/ +//*** AMI PORTING END *****// + + // + // Fill in Graphics Output specific mode structures + // + BiosVideoPrivate->HardwareNeedsStarting = TRUE; + BiosVideoPrivate->ModeData = NULL; + BiosVideoPrivate->LineBuffer = NULL; + BiosVideoPrivate->VgaFrameBuffer = NULL; + BiosVideoPrivate->VbeFrameBuffer = NULL; + +//*** AMI PORTING BEGIN ***// +//Let's do it only if VgaMiniPort is going to be installed +/* + // + // Fill in the VGA Mini Port Protocol fields + // + BiosVideoPrivate->VgaMiniPort.SetMode = BiosVideoVgaMiniPortSetMode; + BiosVideoPrivate->VgaMiniPort.VgaMemoryOffset = 0xb8000; + BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterOffset = 0x3d4; + BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterOffset = 0x3d5; + BiosVideoPrivate->VgaMiniPort.VgaMemoryBar = EFI_PCI_IO_PASS_THROUGH_BAR; + BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR; + BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR; +*/ + // + // Assume that Graphics Output Protocol will be produced until proven otherwise + // + BiosVideoPrivate->ProduceGraphicsOutput = TRUE; + + // + // Set Gop Device Path, here RemainingDevicePath will not be one End of Device Path Node. + // + if ((RemainingDevicePath == NULL) || (!IsDevicePathEnd (RemainingDevicePath))) { + if (RemainingDevicePath == NULL) { + EfiZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH)); + AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH; + AcpiDeviceNode.Header.SubType = ACPI_ADR_DP; + AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0); + SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH)); + + BiosVideoPrivate->DevicePath = EfiAppendDevicePathNode ( + ParentDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode + ); + } else { + BiosVideoPrivate->DevicePath = EfiAppendDevicePathNode (ParentDevicePath, RemainingDevicePath); + } + + // + // Create child handle associated with device path + // The newely created handle can be used for calling EDID_OVERRIDE_PROTOCOL + // + BiosVideoPrivate->Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &BiosVideoPrivate->Handle, + &gEfiDevicePathProtocolGuid, + BiosVideoPrivate->DevicePath, + NULL + ); + if (EFI_ERROR (Status)) { + goto Done; + } + } + + // + // Child handle need to consume the Legacy Bios protocol + // + BiosVideoPrivate->LegacyBios = ParentLegacyBios; + + // + // When check for VBE, PCI I/O protocol is needed, so use parent's protocol interface temporally + // + BiosVideoPrivate->PciIo = ParentPciIo; + + // + // Check for VESA BIOS Extensions for modes that are compatible with Graphics Output + // +//*** AMI PORTING BEGIN ***// +// Status = BiosVideoCheckForVbe (BiosVideoPrivate); +#if INT10_VESA_GO_SUPPORT==1 + if ( TextModePolicy ) + Status = EFI_UNSUPPORTED; + else + Status = BiosVideoCheckForVbe (BiosVideoPrivate, &Pci); +#else + Status = EFI_UNSUPPORTED; +#endif +//*** AMI PORTING END *****// + if (EFI_ERROR (Status)) { + // + // The VESA BIOS Extensions are not compatible with Graphics Output, so check for support + // for the standard 640x480 16 color VGA mode + // +//*** AMI PORTING BEGIN ***// +// if (BiosVideoPrivate->VgaCompatible) { +// Status = BiosVideoCheckForVga (BiosVideoPrivate); +// } +#if INT10_VGA_GO_SUPPORT==1 + if (!TextModePolicy && BiosVideoPrivate->VgaCompatible) { + Status = BiosVideoCheckForVga (BiosVideoPrivate); + } +#endif +//*** AMI PORTING END *****// + + if (EFI_ERROR (Status)) { + // + // Neither VBE nor the standard 640x480 16 color VGA mode are supported, so do + // not produce the Graphics Output protocol. Instead, produce the VGA MiniPort Protocol. + // + BiosVideoPrivate->ProduceGraphicsOutput = FALSE; + + // + // INT services are available, so on the 80x25 and 80x50 text mode are supported + // + BiosVideoPrivate->VgaMiniPort.MaxMode = 2; + } + } + + if (BiosVideoPrivate->ProduceGraphicsOutput) { + // + // Create child handle and install Graphics Output Protocol,EDID Discovered/Active Protocol + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &BiosVideoPrivate->Handle, + &gEfiGraphicsOutputProtocolGuid, + &BiosVideoPrivate->GraphicsOutput, + &gEfiEdidDiscoveredProtocolGuid, + &BiosVideoPrivate->EdidDiscovered, + &gEfiEdidActiveProtocolGuid, + &BiosVideoPrivate->EdidActive, + NULL + ); + + if (!EFI_ERROR (Status)) { + // + // Open the Parent Handle for the child + // + Status = gBS->OpenProtocol ( + ParentHandle, + &gEfiPciIoProtocolGuid, + (VOID **) &BiosVideoPrivate->PciIo, + This->DriverBindingHandle, + BiosVideoPrivate->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + } + } else { +//*** AMI PORTING BEGIN ***// +#if INT10_SIMPLE_TEXT_SUPPORT==1 +//The code if moved here from BiosVideoChildHandleInstall + // + // Fill in the VGA Mini Port Protocol fields + // + BiosVideoPrivate->VgaMiniPort.SetMode = BiosVideoVgaMiniPortSetMode; + BiosVideoPrivate->VgaMiniPort.VgaMemoryOffset = 0xb8000; + BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterOffset = 0x3d4; + BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterOffset = 0x3d5; + BiosVideoPrivate->VgaMiniPort.VgaMemoryBar = EFI_PCI_IO_PASS_THROUGH_BAR; + BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR; + BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR; +//*** AMI PORTING END *****// +//*** AMI PORTING BEGIN ***// + //This is needed! Otherwise VgaClass driver rejects VgaMiniPort + //device due to the lack of PciIo protocol + BiosVideoPrivate->Handle=ParentHandle; +//*** AMI PORTING END *****// + // + // Install VGA Mini Port Protocol + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &BiosVideoPrivate->Handle, + &gEfiVgaMiniPortProtocolGuid, + &BiosVideoPrivate->VgaMiniPort, + NULL + ); +//*** AMI PORTING BEGIN ***// +#else +#endif //INT10_SIMPLE_TEXT_SUPPORT==1 +//*** AMI PORTING END *****// + } + +Done: + if (EFI_ERROR (Status)) { + // + // Free private data structure + // + BiosVideoDeviceReleaseResource (BiosVideoPrivate); + } +//*** AMI PORTING BEGIN ***// +// The protocols are installed. +// Update global variables used by the CsmVideoPolicy protocol implementation. + TextModePolicy = !BiosVideoPrivate->ProduceGraphicsOutput; + VgaControllerHandle = ParentHandle; +//*** AMI PORTING END *****// + return Status; +} + +EFI_STATUS +BiosVideoChildHandleUninstall ( + EFI_DRIVER_BINDING_PROTOCOL *This, + EFI_HANDLE Controller, + EFI_HANDLE Handle + ) +/*++ + +Routine Description: + + Deregister an video child handle and free resources + +Arguments: + + This - Protocol instance pointer. + Controller - Video controller handle + Handle - Video child handle + +Returns: + + EFI_STATUS + +--*/ +{ + EFI_STATUS Status; + EFI_IA32_REGISTER_SET Regs; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort; + BIOS_VIDEO_DEV *BiosVideoPrivate; + EFI_PCI_IO_PROTOCOL *PciIo; + + BiosVideoPrivate = NULL; + + Status = gBS->OpenProtocol ( + Handle, + &gEfiGraphicsOutputProtocolGuid, + (VOID **) &GraphicsOutput, + This->DriverBindingHandle, + Handle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput); + } + + Status = gBS->OpenProtocol ( + Handle, + &gEfiVgaMiniPortProtocolGuid, + (VOID **) &VgaMiniPort, + This->DriverBindingHandle, + Handle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS (VgaMiniPort); + } + + if (BiosVideoPrivate == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Close PCI I/O protocol that opened by child handle + // + Status = gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Handle + ); + + // + // Uninstall protocols on child handle + // + if (BiosVideoPrivate->ProduceGraphicsOutput) { + Status = gBS->UninstallMultipleProtocolInterfaces ( + BiosVideoPrivate->Handle, + &gEfiDevicePathProtocolGuid, + BiosVideoPrivate->DevicePath, + &gEfiGraphicsOutputProtocolGuid, + &BiosVideoPrivate->GraphicsOutput, + &gEfiEdidDiscoveredProtocolGuid, + &BiosVideoPrivate->EdidDiscovered, + &gEfiEdidActiveProtocolGuid, + &BiosVideoPrivate->EdidActive, + NULL + ); + } else { + Status = gBS->UninstallMultipleProtocolInterfaces ( + BiosVideoPrivate->Handle, + &gEfiVgaMiniPortProtocolGuid, + &BiosVideoPrivate->VgaMiniPort, + NULL + ); + } + if (EFI_ERROR (Status)) { + gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + return Status; + } + + // + // Set the 80x25 Text VGA Mode + // + Regs.H.AH = 0x00; + Regs.H.AL = 0x03; + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + + Regs.H.AH = 0x11; + Regs.H.AL = 0x14; + Regs.H.BL = 0; + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + + // + // Do not disable IO/memory decode since that would prevent legacy ROM from working + // + + // + // Release all allocated resources + // + BiosVideoDeviceReleaseResource (BiosVideoPrivate); +//*** AMI PORTING BEGIN ***// +// The protocols are uninstalled. +// Update global variables used by the CsmVideoPolicy protocol implementation. + VgaControllerHandle = NULL; +//*** AMI PORTING END *****// + return EFI_SUCCESS; +} + +VOID +BiosVideoDeviceReleaseResource ( + BIOS_VIDEO_DEV *BiosVideoPrivate + ) +/*++ +Routing Description: + + Release resources of an video child device before stopping it. + +Arguments: + + BiosVideoPrivate - Video child device private data structure + +Returns: + + NONE + +---*/ +{ + if (BiosVideoPrivate == NULL) { + return ; + } + + // + // Release all the resourses occupied by the BIOS_VIDEO_DEV + // + + // + // Free VGA Frame Buffer + // + if (BiosVideoPrivate->VgaFrameBuffer != NULL) { + gBS->FreePool (BiosVideoPrivate->VgaFrameBuffer); + BiosVideoPrivate->VgaFrameBuffer = NULL; + } + // + // Free VBE Frame Buffer + // + if (BiosVideoPrivate->VbeFrameBuffer != NULL) { + gBS->FreePool (BiosVideoPrivate->VbeFrameBuffer); + BiosVideoPrivate->VbeFrameBuffer = NULL; + } + // + // Free line buffer + // + if (BiosVideoPrivate->LineBuffer != NULL) { + gBS->FreePool (BiosVideoPrivate->LineBuffer); + BiosVideoPrivate->LineBuffer = NULL; + } + // + // Free mode data + // + if (BiosVideoPrivate->ModeData != NULL) { + gBS->FreePool (BiosVideoPrivate->ModeData); + BiosVideoPrivate->ModeData = NULL; + } + // + // Free memory allocated below 1MB + // + if (BiosVideoPrivate->PagesBelow1MB != 0) { + gBS->FreePages (BiosVideoPrivate->PagesBelow1MB, BiosVideoPrivate->NumberOfPagesBelow1MB); + } + + if (BiosVideoPrivate->VbeSaveRestorePages != 0) { + gBS->FreePages (BiosVideoPrivate->VbeSaveRestoreBuffer, BiosVideoPrivate->VbeSaveRestorePages); + } + // + // Free graphics output protocol occupied resource + // + if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) { + if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) { + gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info); + BiosVideoPrivate->GraphicsOutput.Mode->Info = NULL; + } + gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode); + BiosVideoPrivate->GraphicsOutput.Mode = NULL; + } + // + // Free EDID discovered protocol occupied resource + // + if (BiosVideoPrivate->EdidDiscovered.Edid != NULL) { + gBS->FreePool (BiosVideoPrivate->EdidDiscovered.Edid); + BiosVideoPrivate->EdidDiscovered.Edid = NULL; + } + // + // Free EDID active protocol occupied resource + // + if (BiosVideoPrivate->EdidActive.Edid != NULL) { + gBS->FreePool (BiosVideoPrivate->EdidActive.Edid); + BiosVideoPrivate->EdidActive.Edid = NULL; + } + + if (BiosVideoPrivate->DevicePath!= NULL) { + gBS->FreePool (BiosVideoPrivate->DevicePath); + BiosVideoPrivate->DevicePath = NULL; + } + + // + // Close the ExitBootServices event + // +//*** AMI PORTING BEGIN ***// +//ExitBootServicesEvent is not used +/* + if (BiosVideoPrivate->ExitBootServicesEvent != NULL) { + gBS->CloseEvent (BiosVideoPrivate->ExitBootServicesEvent); + } +*/ +//*** AMI PORTING END *****// + + gBS->FreePool (BiosVideoPrivate); + + return ; +} + +//*** AMI PORTING BEGIN ***// +#if INT10_VESA_GO_SUPPORT==1 +//*** AMI PORTING END *****// +STATIC +UINT32 +CalculateEdidKey ( + VESA_BIOS_EXTENSIONS_EDID_TIMING *EdidTiming + ) +/*++ + + Routine Description: + + Generate a search key for a specified timing data. + + Arguments: + + EdidTiming - Pointer to EDID timing + + Returns: + The 32 bit unique key for search. + +--*/ +{ + UINT32 Key; + + // + // Be sure no conflicts for all standard timing defined by VESA. + // + Key = (EdidTiming->HorizontalResolution * 2) + EdidTiming->VerticalResolution + EdidTiming->RefreshRate; + return Key; +} + +STATIC +BOOLEAN +ParseEdidData ( + UINT8 *EdidBuffer + ) +/*++ + + Routine Description: + + Parse the Established Timing and Standard Timing in EDID data block. + + Arguments: + + EdidBuffer - Pointer to EDID data block + ValidEdidTiming - Valid EDID timing information + + Returns: + TRUE - The EDID data is valid. + FALSE - The EDID data is invalid. + +--*/ +{ + UINT8 CheckSum; + UINT32 Index; + UINT32 ValidNumber; + UINT32 TimingBits; + UINT8 *BufferIndex; + UINT16 HorizontalResolution; + UINT16 VerticalResolution; + UINT8 AspectRatio; + VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *EdidDataBlock; + + EdidDataBlock = (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *) EdidBuffer; + + // + // Check the checksum of EDID data + // + CheckSum = 0; + for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE; Index ++) { + CheckSum = CheckSum + EdidBuffer[Index]; + } + if (CheckSum != 0) { + TRACE((TRACE_BIOS_VIDEO, "EDID checksum is invalid, EDID will be ignored.\n")); + return FALSE; + } + + ValidNumber = 0; + // + // Established timing data + // + TimingBits = EdidDataBlock->EstablishedTimings[0] | + (EdidDataBlock->EstablishedTimings[1] << 8) | + ((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ; + for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) { + if (TimingBits & 0x1) { + SupportedResolutions[Index] = mEstablishedEdidTiming[Index].VerticalResolution | + (mEstablishedEdidTiming[Index].HorizontalResolution << 16); + ValidNumber ++; + } + TimingBits = TimingBits >> 1; + } + + // + // If no Established timing data, read the standard timing data + // + BufferIndex = &EdidDataBlock->StandardTimingIdentification[0]; + for (Index = 0; Index < 8; Index ++) { + if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){ + // + // A valid Standard Timing + // + HorizontalResolution = BufferIndex[0] * 8 + 248; + AspectRatio = BufferIndex[1] >> 6; + switch (AspectRatio) { + case 0: + VerticalResolution = HorizontalResolution / 16 * 10; + break; + case 1: + VerticalResolution = HorizontalResolution / 4 * 3; + break; + case 2: + VerticalResolution = HorizontalResolution / 5 * 4; + break; + case 3: + VerticalResolution = HorizontalResolution / 16 * 9; + break; + default: + VerticalResolution = HorizontalResolution / 4 * 3; + break; + } + + SupportedResolutions[Index + 17] = VerticalResolution |(HorizontalResolution << 16); + ValidNumber ++; + } + BufferIndex += 2; + } + + if ( (EdidDataBlock->FeatureSupport & 2) == 2) { + // Preferred timing mode is indicated in the first detailed timing block + for (Index = 0; Index < 4; Index ++) { + if ((EdidDataBlock->DetailedTimingDescriptions[Index*18 + 0] | + EdidDataBlock->DetailedTimingDescriptions[Index*18 + 1]) && + (EdidDataBlock->DetailedTimingDescriptions[Index*18 + 2] | + (EdidDataBlock->DetailedTimingDescriptions[Index*18 + 4] & 0xf0))) { + + SupportedResolutions[Index + 25] = + (EdidDataBlock->DetailedTimingDescriptions[Index*18 + 5] | ((UINT16)(EdidDataBlock->DetailedTimingDescriptions[Index*18 + 7] & 0xF0) << 4)) + | ((UINT32)(EdidDataBlock->DetailedTimingDescriptions[Index*18 + 2] | ((UINT16)(EdidDataBlock->DetailedTimingDescriptions[Index*18 + 4] & 0xF0) << 4)) << 16); + +TRACE((TRACE_BIOS_VIDEO, "EDID Detailed timing[%d]: inserted resolution 0x%x (%dx%d)\n", Index, SupportedResolutions[Index + 25], + EdidDataBlock->DetailedTimingDescriptions[Index*18 + 2] | ((EdidDataBlock->DetailedTimingDescriptions[Index*18 + 4] & 0xF0) << 4), + EdidDataBlock->DetailedTimingDescriptions[Index*18 + 5] | ((EdidDataBlock->DetailedTimingDescriptions[Index*18 + 7] & 0xF0) << 4) +)); + + ValidNumber ++; + } + } + } + +//*** AMI PORTING BEGIN ***// +// Bug fix. The function was returning TRUE even when no valid timings found. +// return TRUE; + return (ValidNumber != 0); +//*** AMI PORTING END ***// +} + +STATIC +BOOLEAN +SearchEdidTiming ( + UINT32 ResolutionKey + ) +/*++ + + Routine Description: + + Search a specified Timing in all the valid EDID timings. + + Arguments: + + ValidEdidTiming - All valid EDID timing information. + EdidTiming - The Timing to search for. + + Returns: + + TRUE - Found. + FALSE - Not found. + +--*/ +{ + UINT32 Index; + for (Index = 0; Index < 29; Index ++) { + if (ResolutionKey == SupportedResolutions[Index]) { + return TRUE; + } + } + + return FALSE; +} + +//*** AMI PORTING BEGIN ***// +#if CSM_VGA_64BITBAR_WORKAROUND +BOOLEAN CheckAbove4g(PCI_TYPE00 *PciConfSpace){ + UINTN i; +//--------------------- + for(i=0; i<PCI_MAX_BAR-1;i++){ + //check all six bars if + if((PciConfSpace->Device.Bar[i] & 0x04) && ( PciConfSpace->Device.Bar[i+1]!=0) ) return TRUE; + } + return FALSE; +} + + +EFI_STATUS Update64BitLinearBufferAddr(EFI_PCI_IO_PROTOCOL *PciIo, UINT64 *LowerAddrPart, PCI_TYPE00 *PciConfSpace){ + UINTN i,j; + EFI_STATUS Status; + ASLR_QWORD_ASD *BarRes=NULL; + UINT64 start, end, bar, test; + UINT32 *pUp32; +//----------------------------- + + //pBS->SetMem(&BarRes[0], sizeof(BarRes), 0); + //Get PciIo Bar ACPI QW Resource Descriptor and Count... + + for(i=0; i<PCI_MAX_BAR; i++){ + //Free Memory allocated for us by PciBus Driver... + //if we got here by continue statement... + if(BarRes!=NULL){ + pBS->FreePool(BarRes); + BarRes=NULL; + } + + Status = PciIo->GetBarAttributes(PciIo,(UINT8)i, NULL, &BarRes); + if(EFI_ERROR(Status)) return Status; + + //care only about 64 bit resources end filter out Unused BARs and NOT64bit BARs + if(BarRes->Hdr.Name==ASLV_SR_EndTag) continue; + if(BarRes->_GRA < 64) continue; + + start=BarRes->_MIN; + end=BarRes->_MAX; + test=*LowerAddrPart; + + //Free Memory allocated for us by PciBus Driver... + if(BarRes!=NULL){ + pBS->FreePool(BarRes); + BarRes=NULL; + } + + //now try to match what we read from PCI Config to Res Descriptor returned by the call to PciIo... + for(j=0, bar=0; j<PCI_MAX_BAR-1;j++){ + if(PciConfSpace->Device.Bar[j] & 0x04){ + //here we got 64 bit BAR.... + bar=PciConfSpace->Device.Bar[j] & (~0xF); //Mask read only Bar Type bits... + //fill Upper Part of BAR address + j++; + pUp32=((UINT32*)&bar)+1; + *pUp32=PciConfSpace->Device.Bar[j]; + pUp32=((UINT32*)&test)+1; + *pUp32=PciConfSpace->Device.Bar[j]; + + //Check if we found match? + if(start==bar){ + if((start <= test) && (test < end)) { + *LowerAddrPart=test; + return EFI_SUCCESS; + } else break; + } + } + } + } + return EFI_SUCCESS; +} +#endif +//*** AMI PORTING END *****// + +EFI_STATUS CheckForDuplicateMode (BIOS_VIDEO_DEV *VideoDev, UINTN ModeNumber) +{ + UINT16 Xres = VideoDev->VbeModeInformationBlock->XResolution; + UINT16 Yres = VideoDev->VbeModeInformationBlock->YResolution; + UINTN i; + BIOS_VIDEO_MODE_DATA *ModeData = VideoDev->ModeData; + + // walk through the list of published modes, see if there is a match + for (i = 0; i < ModeNumber; i++) + { + if (ModeData->HorizontalResolution == Xres + && ModeData->VerticalResolution == Yres) + { + return EFI_SUCCESS; + } + ModeData++; + } + return EFI_NOT_FOUND; +} + +EFI_STATUS +EFIAPI +BiosVideoCheckForVbe ( + IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate, +//*** AMI PORTING BEGIN ***// + PCI_TYPE00 *PciConfSpace +//*** AMI PORTING END *****// + ) +/*++ + + Routine Description: + + Check for VBE device + + Arguments: + + BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure + + Returns: + + EFI_SUCCESS - VBE device found + +--*/ +{ + EFI_STATUS Status; + EFI_IA32_REGISTER_SET Regs; + UINT16 *ModeNumberPtr; + BOOLEAN ModeFound; + BOOLEAN EdidFound; + BOOLEAN EdidMatch; + BIOS_VIDEO_MODE_DATA *ModeBuffer; + BIOS_VIDEO_MODE_DATA *CurrentModeData; + UINTN PreferMode; + UINTN ModeNumber; + UINT32 ResolutionKey; + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *GraphicsOutputMode; + INT32 i; + EFI_EDID_OVERRIDE_PROTOCOL *EdidOverride; + UINT32 EdidAttributes; + BOOLEAN EdidOverrideFound; + UINTN EdidOverrideDataSize; + UINT8 *EdidOverrideDataBlock; + UINTN EdidActiveDataSize; + UINT8 *EdidActiveDataBlock; +//*** AMI PORTING BEGIN ***// +#if CSM_VGA_64BITBAR_WORKAROUND + BOOLEAN Above4g; +#endif +//*** AMI PORTING END *****// + + EdidOverrideFound = FALSE; + EdidOverrideDataBlock = NULL; + EdidActiveDataSize = 0; + EdidActiveDataBlock = NULL; + +//*** AMI PORTING BEGIN ***// +#if CSM_VGA_64BITBAR_WORKAROUND + Above4g=CheckAbove4g(PciConfSpace); +#endif +//*** AMI PORTING END *****// + + // + // Allocate buffer under 1MB for VBE data structures + // + BiosVideoPrivate->NumberOfPagesBelow1MB = EFI_SIZE_TO_PAGES ( + sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK) + + sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK) + + sizeof (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK) + + sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK) + ); + + BiosVideoPrivate->PagesBelow1MB = 0x00100000 - 1; + + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiBootServicesData, + BiosVideoPrivate->NumberOfPagesBelow1MB, + &BiosVideoPrivate->PagesBelow1MB + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Fill in the Graphics Output Protocol + // + BiosVideoPrivate->GraphicsOutput.QueryMode = BiosVideoGraphicsOutputQueryMode; + BiosVideoPrivate->GraphicsOutput.SetMode = BiosVideoGraphicsOutputSetMode; + BiosVideoPrivate->GraphicsOutput.Blt = BiosVideoGraphicsOutputVbeBlt; + BiosVideoPrivate->GraphicsOutput.Mode = NULL; + + // + // Fill in the VBE related data structures + // + BiosVideoPrivate->VbeInformationBlock = (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK *) (UINTN) (BiosVideoPrivate->PagesBelow1MB); + BiosVideoPrivate->VbeModeInformationBlock = (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeInformationBlock + 1); + BiosVideoPrivate->VbeEdidDataBlock = (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *) (BiosVideoPrivate->VbeModeInformationBlock + 1); + BiosVideoPrivate->VbeCrtcInformationBlock = (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeModeInformationBlock + 1); + BiosVideoPrivate->VbeSaveRestorePages = 0; + BiosVideoPrivate->VbeSaveRestoreBuffer = 0; + + // + // Test to see if the Video Adapter is compliant with VBE 3.0 + // + gBS->SetMem (&Regs, sizeof (Regs), 0); + Regs.X.AX = VESA_BIOS_EXTENSIONS_RETURN_CONTROLLER_INFORMATION; + gBS->SetMem (BiosVideoPrivate->VbeInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK), 0); + BiosVideoPrivate->VbeInformationBlock->VESASignature = VESA_BIOS_EXTENSIONS_VBE2_SIGNATURE; + Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeInformationBlock); + Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeInformationBlock); + + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + + Status = EFI_DEVICE_ERROR; + + // + // See if the VESA call succeeded + // + if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) { + return Status; + } + // + // Check for 'VESA' signature + // + if (BiosVideoPrivate->VbeInformationBlock->VESASignature != VESA_BIOS_EXTENSIONS_VESA_SIGNATURE) { + return Status; + } + // + // Check to see if this is VBE 2.0 or higher + // + if (BiosVideoPrivate->VbeInformationBlock->VESAVersion < VESA_BIOS_EXTENSIONS_VERSION_2_0) { + return Status; + } + + EdidFound = FALSE; + EdidAttributes = 0xff; + EdidOverrideDataSize = 0; + + // + // Check if EDID Override protocol is installed by platform. + // + Status = gBS->LocateProtocol ( + &gEfiEdidOverrideProtocolGuid, + NULL, + (VOID **) &EdidOverride + ); + + if (!EFI_ERROR (Status)) { + // + // Allocate double size of VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE to avoid overflow + // + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof ((VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE * 2)), + &EdidOverrideDataBlock + ); + + if (EFI_ERROR(Status)) { + goto Done; + } + + Status = EdidOverride->GetEdid ( + EdidOverride, + BiosVideoPrivate->Handle, + &EdidAttributes, + &EdidOverrideDataSize, + (UINT8 **) &EdidOverrideDataBlock + ); + if (!EFI_ERROR (Status) && +//*** AMI PORTING BEGIN ***// +// EdidAttributes == 0 && +//*** AMI PORTING END ***// + EdidOverrideDataSize != 0) { + // + // Succeeded to get EDID Override Data + // + TRACE((TRACE_BIOS_VIDEO, "EDID override protocol found: data size %x, attribute %x\n", EdidOverrideDataSize, EdidAttributes)); + EdidOverrideFound = TRUE; + } + } + + + // "EdidFound" is forcibly FALSE, + // because some SSUs(Server Switch Unit) return invalid response. + if (!EdidOverrideFound || EdidAttributes == EFI_EDID_OVERRIDE_DONT_OVERRIDE) { + // + // If EDID Override data doesn't exist or EFI_EDID_OVERRIDE_DONT_OVERRIDE returned, + // read EDID information through INT10 call and fill in EdidDiscovered structure + // + gBS->SetMem (&Regs, sizeof (Regs), 0); + Regs.X.AX = VESA_BIOS_EXTENSIONS_EDID; + Regs.X.BX = 1; + Regs.X.CX = 0; + Regs.X.DX = 0; + Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeEdidDataBlock); + Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeEdidDataBlock); + + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + if (Regs.X.AX == VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) { + + BiosVideoPrivate->EdidDiscovered.SizeOfEdid = VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE; + Status = gBS->AllocatePool ( + EfiBootServicesData, + VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE, + &BiosVideoPrivate->EdidDiscovered.Edid + ); + if (EFI_ERROR (Status)) { + goto Done; + } + gBS->CopyMem ( + BiosVideoPrivate->EdidDiscovered.Edid, + BiosVideoPrivate->VbeEdidDataBlock, + VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE + ); + + EdidFound = TRUE; + } + } + + // + // Set up ActiveEdid data pointer and size + // + if (EdidFound) { + EdidActiveDataSize = VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE; + EdidActiveDataBlock = BiosVideoPrivate->EdidDiscovered.Edid; + } else if (EdidOverrideFound) { + EdidActiveDataSize = EdidOverrideDataSize; + EdidActiveDataBlock = EdidOverrideDataBlock; + EdidFound = TRUE; + } + + if (EdidFound) { + // + // Parse EDID data structure to retrieve modes supported by monitor + // + if (ParseEdidData ((UINT8 *) EdidActiveDataBlock) == TRUE) { + // + // Copy EDID Override Data to EDID Active Data + // + BiosVideoPrivate->EdidActive.SizeOfEdid = (UINT32)EdidActiveDataSize; + Status = gBS->AllocatePool ( + EfiBootServicesData, + EdidActiveDataSize, + &BiosVideoPrivate->EdidActive.Edid + ); + if (EFI_ERROR (Status)) { + goto Done; + } + gBS->CopyMem ( + BiosVideoPrivate->EdidActive.Edid, + EdidActiveDataBlock, + EdidActiveDataSize + ); + } + } else { + BiosVideoPrivate->EdidActive.SizeOfEdid = 0; + BiosVideoPrivate->EdidActive.Edid = NULL; + EdidFound = FALSE; + } + + // + // Walk through the mode list to see if there is at least one mode the is compatible with the EDID mode + // + ModeNumberPtr = (UINT16 *) + ( + (((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0xffff0000) >> 12) | + ((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0x0000ffff) + ); + + PreferMode = 0; + ModeNumber = 0; + + TRACE((TRACE_BIOS_VIDEO, "VESA: fetching the list of VESA modes supported by the controller from %x\n", ModeNumberPtr)); + + for (; *ModeNumberPtr != VESA_BIOS_EXTENSIONS_END_OF_MODE_LIST; ModeNumberPtr++) { + // + // Make sure this is a mode number defined by the VESA VBE specification. If it isn'tm then skip this mode number. + // + TRACE((TRACE_BIOS_VIDEO,"VESA mode %x ", *ModeNumberPtr)); + + if ((*ModeNumberPtr & VESA_BIOS_EXTENSIONS_MODE_NUMBER_VESA) == 0) { + TRACE((TRACE_BIOS_VIDEO,".. skipping as it is not a proper VESA mode number\n")); + continue; + } + + // + // Get the information about the mode + // + gBS->SetMem (&Regs, sizeof (Regs), 0); + Regs.X.AX = VESA_BIOS_EXTENSIONS_RETURN_MODE_INFORMATION; + Regs.X.CX = *ModeNumberPtr; + gBS->SetMem (BiosVideoPrivate->VbeModeInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK), 0); + Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeModeInformationBlock); + Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeModeInformationBlock); + + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + + // + // See if the call succeeded. If it didn't, then try the next mode. + // + if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) { + TRACE((TRACE_BIOS_VIDEO,".. skipping as we can not retrieve mode details\n")); + continue; + } + + TRACE((TRACE_BIOS_VIDEO, "(%dx%d) ", BiosVideoPrivate->VbeModeInformationBlock->XResolution, BiosVideoPrivate->VbeModeInformationBlock->YResolution)); + + // + // See if the mode supported in hardware. If it doesn't then try the next mode. + // + if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_HARDWARE) == 0) { + TRACE((TRACE_BIOS_VIDEO,"skipping as the mode is not supported in hardware...\n")); + continue; + } + + // + // See if the mode supports color. If it doesn't then try the next mode. + // + if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_COLOR) == 0) { + TRACE((TRACE_BIOS_VIDEO,"is invalid, skipping...\n")); + continue; + } + // + // See if the mode supports graphics. If it doesn't then try the next mode. + // + if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_GRAPHICS) == 0) { + TRACE((TRACE_BIOS_VIDEO,"skipping as the mode is not graphical...\n")); + continue; + } + // + // See if the mode supports a linear frame buffer. If it doesn't then try the next mode. + // + if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER) == 0) { + TRACE((TRACE_BIOS_VIDEO,"skipping as the mode has not linear frame buffer...\n")); + continue; + } + // + // See if the mode supports 32 bit color. If it doesn't then try the next mode. + // 32 bit mode can be implemented by 24 Bits Per Pixel. Also make sure the + // number of bits per pixel is a multiple of 8 or more than 32 bits per pixel + // + if (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel < 24) { + TRACE((TRACE_BIOS_VIDEO,"skipping as BPP (%d) is less than 24...\n", BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel)); + continue; + } + + if (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel > 32) { + TRACE((TRACE_BIOS_VIDEO,"skipping as BPP (%d) is more than 32...\n", BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel)); + continue; + } + + if ((BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel % 8) != 0) { + TRACE((TRACE_BIOS_VIDEO,"skipping as BPP (%d) modulo 8 is non-zero...\n", BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel)); + continue; + } + // + // See if the physical base pointer for the linear mode is valid. If it isn't then try the next mode. + // + if (BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr == 0) { + TRACE((TRACE_BIOS_VIDEO,"skipping as PhysBasePtr is zero...\n")); + continue; + } + EdidMatch = FALSE; + if (EdidFound) { + // + // EDID exist, check whether this mode match with any mode in EDID + // + ResolutionKey = BiosVideoPrivate->VbeModeInformationBlock->YResolution | + (BiosVideoPrivate->VbeModeInformationBlock->XResolution << 16); + + if (SearchEdidTiming (ResolutionKey) == TRUE) { + EdidMatch = TRUE; + TRACE((TRACE_BIOS_VIDEO, "EDID match found.\n")); + } + } + + // + // Select a reasonable mode to be set for current display mode + // + ModeFound = FALSE; + + for(i = 0; i < MaxTextMode; i++) + { + if(TextModeArray[i].VideoCol == BiosVideoPrivate->VbeModeInformationBlock->XResolution && + TextModeArray[i].VideoRow == BiosVideoPrivate->VbeModeInformationBlock->YResolution) + { + ModeFound = TRUE; + TRACE((TRACE_BIOS_VIDEO, "MODE match found (%d).\n", i)); + } + } + if ((!EdidMatch) && (!ModeFound)) { + // + // When EDID exist and if the timing matches with VESA add it. + // And also add three possible resolutions, i.e. 1024x768, 800x600, 640x480 + // + TRACE((TRACE_BIOS_VIDEO, "neither EDID nor MODE match is found.\n", i)); + continue; + } + + if (CheckForDuplicateMode(BiosVideoPrivate, ModeNumber) == EFI_SUCCESS) + { + TRACE((TRACE_BIOS_VIDEO, "skipping as the same resolution (%dx%d) is already available\n", + BiosVideoPrivate->VbeModeInformationBlock->XResolution, + BiosVideoPrivate->VbeModeInformationBlock->YResolution)); + continue; + } + + // + // Add mode to the list of available modes + // + ModeNumber ++; + Status = gBS->AllocatePool ( + EfiBootServicesData, + ModeNumber * sizeof (BIOS_VIDEO_MODE_DATA), + (VOID **) &ModeBuffer + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + if (ModeNumber > 1) { + gBS->CopyMem ( + ModeBuffer, + BiosVideoPrivate->ModeData, + (ModeNumber - 1) * sizeof (BIOS_VIDEO_MODE_DATA) + ); + } + + if (BiosVideoPrivate->ModeData != NULL) { + gBS->FreePool (BiosVideoPrivate->ModeData); + BiosVideoPrivate->ModeData = NULL; + } + + CurrentModeData = &ModeBuffer[ModeNumber - 1]; + CurrentModeData->VbeModeNumber = *ModeNumberPtr; + if (BiosVideoPrivate->VbeInformationBlock->VESAVersion >= VESA_BIOS_EXTENSIONS_VERSION_3_0) { + CurrentModeData->BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->LinBytesPerScanLine; + CurrentModeData->Red.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRedFieldPosition; + CurrentModeData->Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRedMaskSize) - 1); + CurrentModeData->Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->LinBlueFieldPosition; + CurrentModeData->Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinBlueMaskSize) - 1); + CurrentModeData->Green.Position = BiosVideoPrivate->VbeModeInformationBlock->LinGreenFieldPosition; + CurrentModeData->Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinGreenMaskSize) - 1); + CurrentModeData->Reserved.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRsvdFieldPosition; + CurrentModeData->Reserved.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRsvdMaskSize) - 1); + } else { + CurrentModeData->BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->BytesPerScanLine; + CurrentModeData->Red.Position = BiosVideoPrivate->VbeModeInformationBlock->RedFieldPosition; + CurrentModeData->Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RedMaskSize) - 1); + CurrentModeData->Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->BlueFieldPosition; + CurrentModeData->Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->BlueMaskSize) - 1); + CurrentModeData->Green.Position = BiosVideoPrivate->VbeModeInformationBlock->GreenFieldPosition; + CurrentModeData->Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->GreenMaskSize) - 1); + CurrentModeData->Reserved.Position = BiosVideoPrivate->VbeModeInformationBlock->RsvdFieldPosition; + CurrentModeData->Reserved.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RsvdMaskSize) - 1); + } +//*** AMI PORTING BEGIN ***// +//Bug fix: The original logic did not work for a modes with 24-bit pixels. +// For a 24-bit pixels, the PixelFormat must be set to PixelBitMask, which +// was not happening with the original "if" statement +// if ((CurrentModeData->Red.Mask == 0xff) && (CurrentModeData->Green.Mask == 0xff) && (CurrentModeData->Blue.Mask == 0xff)) { + if ( (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel == 32) + && (CurrentModeData->Red.Mask == 0xff) && (CurrentModeData->Green.Mask == 0xff) && (CurrentModeData->Blue.Mask == 0xff) + ) { +//*** AMI PORTING END *****// + if ((CurrentModeData->Red.Position == 0) && (CurrentModeData->Green.Position == 8)) { + CurrentModeData->PixelFormat = PixelRedGreenBlueReserved8BitPerColor; + } else if ((CurrentModeData->Blue.Position == 0) && (CurrentModeData->Green.Position == 8)) { + CurrentModeData->PixelFormat = PixelBlueGreenRedReserved8BitPerColor; + } + } else { + CurrentModeData->PixelFormat = PixelBitMask; + } + CurrentModeData->PixelBitMask.RedMask = ((UINT32) CurrentModeData->Red.Mask) << CurrentModeData->Red.Position; + CurrentModeData->PixelBitMask.GreenMask = ((UINT32) CurrentModeData->Green.Mask) << CurrentModeData->Green.Position; + CurrentModeData->PixelBitMask.BlueMask = ((UINT32) CurrentModeData->Blue.Mask) << CurrentModeData->Blue.Position; + CurrentModeData->PixelBitMask.ReservedMask = ((UINT32) CurrentModeData->Reserved.Mask) << CurrentModeData->Reserved.Position; + +//*** AMI PORTING BEGIN ***// +#if CSM_VGA_64BITBAR_WORKAROUND + if(Above4g){ + UINT64 PhysBasePtr4g=BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr; + //------------------------------------ + Status=Update64BitLinearBufferAddr(BiosVideoPrivate->PciIo, &PhysBasePtr4g, PciConfSpace); + if (EFI_ERROR (Status)) { + goto Done; + } + + CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN)PhysBasePtr4g; + }else +#endif + { + CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN)BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr; + } + //CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN)BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr; + +//*** AMI PORTING END *****// + CurrentModeData->HorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution; + CurrentModeData->VerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution; + + CurrentModeData->BitsPerPixel = BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel; + +//*** AMI PORTING BEGIN ***// +// UEFI SCT 2.3.1 Summer Summit version reports that framebuffersize mismatch in query mode of SCT test +// Calculated the framebuffersize based for each mode configuration + if(CurrentModeData->PixelFormat == PixelRedGreenBlueReserved8BitPerColor || + CurrentModeData->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) { + CurrentModeData->FrameBufferSize=((CurrentModeData->BytesPerScanLine * 8) / CurrentModeData->BitsPerPixel) * + CurrentModeData->VerticalResolution * + sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); + } else { + CurrentModeData->FrameBufferSize = BiosVideoPrivate->VbeInformationBlock->TotalMemory * 64 * 1024; + } +//*** AMI PORTING END *****// + + CurrentModeData->RefreshRate = 60; + + BiosVideoPrivate->ModeData = ModeBuffer; + } + // + // Check to see if we found any modes that are compatible with GRAPHICS OUTPUT + // + if (ModeNumber == 0) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + // + // Allocate buffer for Graphics Output Protocol mode information + // + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE), + (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode + ); + if (EFI_ERROR (Status)) { + goto Done; + } + GraphicsOutputMode = BiosVideoPrivate->GraphicsOutput.Mode; + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), + (VOID **) &GraphicsOutputMode->Info + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + GraphicsOutputMode->MaxMode = (UINT32) ModeNumber; + // + // Current mode is still unknown, set it to an invalid mode. + // + GraphicsOutputMode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER; + TRACE((TRACE_BIOS_VIDEO, "Total number of GOP modes: %d\n", ModeNumber)); + // + // Find the best mode to initialize + // + Status = BiosVideoGraphicsOutputSetMode (&BiosVideoPrivate->GraphicsOutput, (UINT32) PreferMode); + if (EFI_ERROR (Status)) { + for (PreferMode = 0; PreferMode < ModeNumber; PreferMode ++) { + Status = BiosVideoGraphicsOutputSetMode ( + &BiosVideoPrivate->GraphicsOutput, + (UINT32) PreferMode + ); + if (!EFI_ERROR (Status)) { + break; + } + } + if (PreferMode == ModeNumber) { + // + // None mode is set successfully. + // + goto Done; + } + } + +Done: + // + // If there was an error, then free the mode structure + // + if (EFI_ERROR (Status)) { + if (BiosVideoPrivate->ModeData != NULL) { + gBS->FreePool (BiosVideoPrivate->ModeData); + BiosVideoPrivate->ModeData = NULL; + } + if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) { + if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) { + gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info); + BiosVideoPrivate->GraphicsOutput.Mode->Info = NULL; + } + gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode); + BiosVideoPrivate->GraphicsOutput.Mode = NULL; + } + } + + return Status; +} + +//*** AMI PORTING BEGIN ***// +#endif//if INT10_VESA_GO_SUPPORT==1 +//*** AMI PORTING END *****// +//*** AMI PORTING BEGIN ***// +#if INT10_VGA_GO_SUPPORT==1 +//*** AMI PORTING END *****// +EFI_STATUS +EFIAPI +BiosVideoCheckForVga ( + IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate + ) +/*++ + + Routine Description: + + Check for VGA device + + Arguments: + + BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure + + Returns: + + EFI_SUCCESS - Standard VGA device found + +--*/ +{ + EFI_STATUS Status; + BIOS_VIDEO_MODE_DATA *ModeBuffer; + + // + // Fill in the Graphics Output Protocol + // + BiosVideoPrivate->GraphicsOutput.QueryMode = BiosVideoGraphicsOutputQueryMode; + BiosVideoPrivate->GraphicsOutput.SetMode = BiosVideoGraphicsOutputSetMode; + BiosVideoPrivate->GraphicsOutput.Blt = BiosVideoGraphicsOutputVgaBlt; + + // + // Allocate buffer for Graphics Output Protocol mode information + // + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE), + (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode + ); + if (EFI_ERROR (Status)) { + goto Done; + } + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), + (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode->Info + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // Add mode to the list of available modes + // + BiosVideoPrivate->GraphicsOutput.Mode->MaxMode = 1; + + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (BIOS_VIDEO_MODE_DATA), + (VOID **) &ModeBuffer + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + ModeBuffer->VbeModeNumber = 0x0012; + ModeBuffer->BytesPerScanLine = 640; + ModeBuffer->LinearFrameBuffer = (VOID *) (UINTN) (0xa0000); + ModeBuffer->FrameBufferSize = 0; + ModeBuffer->HorizontalResolution = 640; + ModeBuffer->VerticalResolution = 480; + ModeBuffer->RefreshRate = 60; + ModeBuffer->PixelFormat = PixelBltOnly; +//*** AMI PORTING BEGIN ***// +//Bug fix: initialize BitsPerPixel + ModeBuffer->BitsPerPixel = 4; +//*** AMI PORTING END *****// + + BiosVideoPrivate->ModeData = ModeBuffer; + + // + // Test to see if the Video Adapter support the 640x480 16 color mode + // + BiosVideoPrivate->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER; + Status = BiosVideoGraphicsOutputSetMode (&BiosVideoPrivate->GraphicsOutput, 0); + +Done: + // + // If there was an error, then free the mode structure + // + if (EFI_ERROR (Status)) { + if (BiosVideoPrivate->ModeData != NULL) { + gBS->FreePool (BiosVideoPrivate->ModeData); + BiosVideoPrivate->ModeData = NULL; + } + if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) { + if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) { + gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info); + BiosVideoPrivate->GraphicsOutput.Mode->Info = NULL; + } + gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode); + BiosVideoPrivate->GraphicsOutput.Mode = NULL; + } + } + return Status; +} +//*** AMI PORTING BEGIN ***// +#endif//if INT10_VGA_GO_SUPPORT==1 +//*** AMI PORTING END *****// + +// +// Graphics Output Protocol Member Functions for VESA BIOS Extensions +// +EFI_STATUS +EFIAPI +BiosVideoGraphicsOutputQueryMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ) +/*++ + +Routine Description: + + Graphics Output protocol interface to get video mode + + Arguments: + 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_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode. + EFI_NOT_STARTED - Video display is not initialized. Call SetMode () + EFI_INVALID_PARAMETER - One of the input args was NULL. + +--*/ +{ + BIOS_VIDEO_DEV *BiosVideoPrivate; + EFI_STATUS Status; + BIOS_VIDEO_MODE_DATA *ModeData; + + BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This); + + if (BiosVideoPrivate->HardwareNeedsStarting) { + ReportStatusCodeWithDevicePath ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_OUTPUT_ERROR, + 0, + &gEfiCallerIdGuid, + BiosVideoPrivate->DevicePath + ); + return EFI_NOT_STARTED; + } + + if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) { + return EFI_INVALID_PARAMETER; + } + + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), + Info + ); + if (EFI_ERROR (Status)) { + return Status; + } + + *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + ModeData = &BiosVideoPrivate->ModeData[ModeNumber]; + (*Info)->Version = 0; + (*Info)->HorizontalResolution = ModeData->HorizontalResolution; + (*Info)->VerticalResolution = ModeData->VerticalResolution; + (*Info)->PixelFormat = ModeData->PixelFormat; + (*Info)->PixelInformation = ModeData->PixelBitMask; + + (*Info)->PixelsPerScanLine = (ModeData->BytesPerScanLine * 8) / ModeData->BitsPerPixel; + + return EFI_SUCCESS; +} + +//*** AMI PORTING BEGIN ***// +// The AllocateTheBuffers function below and certain modifications of +// the BiosVideoGraphicsOutputVbeBlt nd BiosVideoVgaMiniPortSetMode functions +// are made to address the issues reaised in EIP 35682. +// +// The BLT function (BiosVideoGraphicsOutputVbeBlt) uses several memory buffers. +// Default implementation allocates the buffers in the SetMode(BiosVideoVgaMiniPortSetMode) +// function. We are changing implementation to allocate the buffers right in the BLT function +// before the first use. The code that releases the buffers is still in the SetMode function. +// +// This is a workaround for the "UEFI Windows 7 Startup Repair" bug. +// When Startup Repair option is selected, it crashes with the 0xc0000225 error prior +// to the call to ExitBootServices. +// The problem is caused by the Windows inability to handle memory map changes. +// The memory map changes when Windows calls Gop->SetMode and our implementation of the +// SetMode(BiosVideoGraphicsOutputVbeBlt) allocates the buffers. +// This workaround moves buffer allocation to the BLT function (BiosVideoGraphicsOutputVbeBlt), +// which Windows never calls and therefore memory map never changes. +EFI_STATUS AllocateTheBuffers(BIOS_VIDEO_DEV *BiosVideoPrivate){ + EFI_STATUS Status; + BIOS_VIDEO_MODE_DATA *ModeData; + UINT16 MaxBytesPerScanLine = 0; + UINT32 MaxVerticalResolution = 0; + UINT32 CurrentMode = (BiosVideoPrivate->GraphicsOutput).Mode->Mode; + UINT32 MaxMode = (BiosVideoPrivate->GraphicsOutput).Mode->MaxMode; + UINT32 Index; + + TRACE((TRACE_BIOS_VIDEO, "UefiBiosVideo AllocateTheBuffers()\n")); + for(Index = 0; Index < MaxMode; Index++) { + ModeData = &BiosVideoPrivate->ModeData[Index]; + + if (MaxBytesPerScanLine < ModeData->BytesPerScanLine) { + MaxBytesPerScanLine = ModeData->BytesPerScanLine; + } + if (MaxVerticalResolution < ModeData->VerticalResolution) { + MaxVerticalResolution = ModeData->VerticalResolution; + } + + TRACE((TRACE_BIOS_VIDEO, "VbeModeNumber: 0x%x\n", ModeData->VbeModeNumber)); + TRACE((TRACE_BIOS_VIDEO, "BytesPerScanLine: 0x%x\n", \ + ModeData->BytesPerScanLine)); + TRACE((TRACE_BIOS_VIDEO, "HorizontalResolution: 0x%x\n", \ + ModeData->HorizontalResolution)); + TRACE((TRACE_BIOS_VIDEO, "VerticalResolution: 0x%x\n", \ + ModeData->VerticalResolution)); + } + + TRACE((TRACE_BIOS_VIDEO, "MaxBytesPerScanLine: 0x%x\n", MaxBytesPerScanLine)); + TRACE((TRACE_BIOS_VIDEO, "MaxVerticalResolution: 0x%x\n", \ + MaxVerticalResolution)); + + ModeData = &BiosVideoPrivate->ModeData[CurrentMode]; + + Status = gBS->AllocatePool ( + EfiBootServicesData, + MaxBytesPerScanLine, + &BiosVideoPrivate->LineBuffer + ); + if (EFI_ERROR (Status)) { + BiosVideoPrivate->LineBuffer=NULL; + return Status; + } + MemSet(BiosVideoPrivate->LineBuffer, MaxBytesPerScanLine, 0); + + // + // Allocate a working buffer for BLT operations to the VGA frame buffer + // + Status = gBS->AllocatePool ( + EfiBootServicesData, + 4 * 480 * 80, + &BiosVideoPrivate->VgaFrameBuffer + ); + if (EFI_ERROR (Status)) { + gBS->FreePool (BiosVideoPrivate->LineBuffer); + BiosVideoPrivate->LineBuffer=NULL; + return Status; + } + MemSet(BiosVideoPrivate->VgaFrameBuffer, 4 * 480 * 80, 0); + + // + // Allocate a working buffer for BLT operations to the VBE frame buffer + // + Status = gBS->AllocatePool ( + EfiBootServicesData, + MaxBytesPerScanLine * MaxVerticalResolution, + &BiosVideoPrivate->VbeFrameBuffer + ); + if (EFI_ERROR (Status)) { + gBS->FreePool (BiosVideoPrivate->LineBuffer); + BiosVideoPrivate->LineBuffer=NULL; + return Status; + } + MemSet( + BiosVideoPrivate->VbeFrameBuffer, + MaxBytesPerScanLine * MaxVerticalResolution, + 0 + ); + + // + // Initialize the state of the VbeFrameBuffer + // + if (ModeData->VbeModeNumber >= 0x100) { + gBS->CopyMem ( + BiosVideoPrivate->VbeFrameBuffer, + ModeData->LinearFrameBuffer, + (ModeData->BytesPerScanLine * ModeData->VerticalResolution)); + + } + return Status; +} + +//*** AMI PORTING END *****// + +EFI_STATUS +EFIAPI +BiosVideoGraphicsOutputSetMode ( + 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. + +--*/ +{ +//*** AMI PORTING BEGIN ***// +//Workaround for EIP 35682. See comments above +//AllocateTheBuffers function for additional details. +// EFI_STATUS Status; +//*** AMI PORTING END *****// + BIOS_VIDEO_DEV *BiosVideoPrivate; + EFI_IA32_REGISTER_SET Regs; + BIOS_VIDEO_MODE_DATA *ModeData; + + BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This); + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (ModeNumber >= This->Mode->MaxMode) { + return EFI_UNSUPPORTED; + } +/* + if (ModeNumber == This->Mode->Mode) { + return EFI_SUCCESS; + } +*/ + ModeData = &BiosVideoPrivate->ModeData[ModeNumber]; + + if (BiosVideoPrivate->LineBuffer) { + gBS->FreePool (BiosVideoPrivate->LineBuffer); + BiosVideoPrivate->LineBuffer = NULL; + } + + if (BiosVideoPrivate->VgaFrameBuffer) { + gBS->FreePool (BiosVideoPrivate->VgaFrameBuffer); + BiosVideoPrivate->VgaFrameBuffer = NULL; + } + + if (BiosVideoPrivate->VbeFrameBuffer) { + gBS->FreePool (BiosVideoPrivate->VbeFrameBuffer); + BiosVideoPrivate->VbeFrameBuffer = NULL; + } + + BiosVideoPrivate->LineBuffer = NULL; +//*** AMI PORTING BEGIN ***// +// Workaround for EIP 35682. +// Buffer allocation code is moved to AllocateTheBuffers function, +// which is called from the BiosVideoGraphicsOutputVbeBlt. +// See comments above AllocateTheBuffers function for additional details. +/* + Status = gBS->AllocatePool ( + EfiBootServicesData, + ModeData->BytesPerScanLine, + &BiosVideoPrivate->LineBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } +*/ +//*** AMI PORTING END *****// + // + // Clear all registers + // + gBS->SetMem (&Regs, sizeof (Regs), 0); + + if (ModeData->VbeModeNumber < 0x100) { + // + // Allocate a working buffer for BLT operations to the VGA frame buffer + // + BiosVideoPrivate->VgaFrameBuffer = NULL; +//*** AMI PORTING BEGIN ***// +//*** AMI PORTING BEGIN ***// +// Workaround for EIP 35682. +// Buffer allocation code is moved to AllocateTheBuffers function, +// which is called from the BiosVideoGraphicsOutputVbeBlt. +// See comments above AllocateTheBuffers function for additional details. +/* + Status = gBS->AllocatePool ( + EfiBootServicesData, + 4 * 480 * 80, + &BiosVideoPrivate->VgaFrameBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } +*/ +//*** AMI PORTING END *****// + // + // Set VGA Mode + // + Regs.X.AX = ModeData->VbeModeNumber; + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + + } else { + // + // Allocate a working buffer for BLT operations to the VBE frame buffer + // + BiosVideoPrivate->VbeFrameBuffer = NULL; +//*** AMI PORTING BEGIN ***// +//*** AMI PORTING BEGIN ***// +// Workaround for EIP 35682. +// Buffer allocation code is moved to AllocateTheBuffers function, +// which is called from the BiosVideoGraphicsOutputVbeBlt. +// See comments above AllocateTheBuffers function for additional details. +/* + Status = gBS->AllocatePool ( + EfiBootServicesData, + ModeData->BytesPerScanLine * ModeData->VerticalResolution, + &BiosVideoPrivate->VbeFrameBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } +*/ +//*** AMI PORTING END *****// + // + // Set VBE mode + // + Regs.X.AX = VESA_BIOS_EXTENSIONS_SET_MODE; + Regs.X.BX = (UINT16) (ModeData->VbeModeNumber | VESA_BIOS_EXTENSIONS_MODE_NUMBER_LINEAR_FRAME_BUFFER); + gBS->SetMem (BiosVideoPrivate->VbeCrtcInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK), 0); + Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeCrtcInformationBlock); + Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeCrtcInformationBlock); + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + + // + // Check to see if the call succeeded + // + if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) { + ReportStatusCodeWithDevicePath ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_OUTPUT_ERROR, + 0, + &gEfiCallerIdGuid, + BiosVideoPrivate->DevicePath + ); + return EFI_DEVICE_ERROR; + } +//*** AMI PORTING BEGIN ***// + // + // Initialize the state of the VbeFrameBuffer + // + +/* + Status = BiosVideoPrivate->PciIo->Mem.Read ( + BiosVideoPrivate->PciIo, + EfiPciIoWidthUint32, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) (UINTN) ModeData->LinearFrameBuffer, + (ModeData->BytesPerScanLine * ModeData->VerticalResolution) >> 2, + BiosVideoPrivate->VbeFrameBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } +*/ +// Workaround for EIP 35682. +// Buffer allocation and initialization code is moved to AllocateTheBuffers function, +// which is called from the BiosVideoGraphicsOutputVbeBlt. +// See comments above AllocateTheBuffers function for additional details. +/* + gBS->CopyMem ( + BiosVideoPrivate->VbeFrameBuffer, + ModeData->LinearFrameBuffer, + (ModeData->BytesPerScanLine * ModeData->VerticalResolution)); +*/ + } +//*** AMI PORTING END ***// + + This->Mode->Mode = ModeNumber; + This->Mode->Info->Version = 0; + This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution; + This->Mode->Info->VerticalResolution = ModeData->VerticalResolution; + This->Mode->Info->PixelFormat = ModeData->PixelFormat; + This->Mode->Info->PixelInformation = ModeData->PixelBitMask; + This->Mode->Info->PixelsPerScanLine = (ModeData->BytesPerScanLine * 8) / ModeData->BitsPerPixel; + This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + // + // Frame BufferSize remain unchanged + // + This->Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) ModeData->LinearFrameBuffer; + This->Mode->FrameBufferSize = ModeData->FrameBufferSize; + + BiosVideoPrivate->HardwareNeedsStarting = FALSE; + + return EFI_SUCCESS; +} + +//*** AMI PORTING BEGIN ***// +#if INT10_VESA_GO_SUPPORT==1 +//*** AMI PORTING END *****// +// +// BUGBUG : Add Blt for 16 bit color, 15 bit color, and 8 bit color modes +// +EFI_STATUS +EFIAPI +BiosVideoGraphicsOutputVbeBlt ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ) +/*++ + +Routine Description: + + Graphics Output protocol instance to block transfer for VBE 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 + +--*/ +{ + BIOS_VIDEO_DEV *BiosVideoPrivate; + BIOS_VIDEO_MODE_DATA *Mode; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_TPL OriginalTPL; + UINTN DstY; + UINTN SrcY; + UINTN DstX; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + VOID *MemAddress; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer; + UINTN BytesPerScanLine; + UINTN Index; + UINT8 *VbeBuffer; + UINT8 *VbeBuffer1; + UINT8 *BltUint8; + UINT32 VbePixelWidth; + UINT32 Pixel; + +//*** AMI PORTING BEGIN ***// +//Bug fix: This is accessed before it's checked on NULL + if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) { + return EFI_INVALID_PARAMETER; + } +//*** AMI PORTING END *****// + BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This); +//*** AMI PORTING BEGIN ***// +// Workaround for EIP 35682. +// Allocate memory buffers during the first call of the funciton. +// See comments above AllocateTheBuffers function for additional details. + if (BiosVideoPrivate->LineBuffer==NULL){ + EFI_STATUS Status = AllocateTheBuffers(BiosVideoPrivate); + if (EFI_ERROR(Status)) return Status; + } +//*** AMI PORTING END *****// + Mode = &BiosVideoPrivate->ModeData[This->Mode->Mode]; + PciIo = BiosVideoPrivate->PciIo; + + VbeFrameBuffer = BiosVideoPrivate->VbeFrameBuffer; + MemAddress = Mode->LinearFrameBuffer; + BytesPerScanLine = Mode->BytesPerScanLine; + VbePixelWidth = Mode->BitsPerPixel / 8; + BltUint8 = (UINT8 *) BltBuffer; + +//*** AMI PORTING BEGIN ***// +//These parameter checks are moved to the beginning of the function +/* + if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) { + return EFI_INVALID_PARAMETER; + } +*/ +//*** AMI PORTING END *****// + + if (Width == 0 || Height == 0) { + return EFI_INVALID_PARAMETER; + } + // + // 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. + // + if (BltOperation == EfiBltVideoToBltBuffer) { + // + // Video to BltBuffer: Source is Video, destination is BltBuffer + // + if (SourceY + Height > Mode->VerticalResolution) { + return EFI_INVALID_PARAMETER; + } + + if (SourceX + Width > Mode->HorizontalResolution) { + return EFI_INVALID_PARAMETER; + } + } else { + // + // BltBuffer to Video: Source is BltBuffer, destination is Video + // + if (DestinationY + Height > Mode->VerticalResolution) { + return EFI_INVALID_PARAMETER; + } + + if (DestinationX + Width > Mode->HorizontalResolution) { + 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 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 (EFI_TPL_NOTIFY); + + switch (BltOperation) { + case EfiBltVideoToBltBuffer: + for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) { + Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + DstY * Delta + DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + // + // Shuffle the packed bytes in the hardware buffer to match EFI_GRAPHICS_OUTPUT_BLT_PIXEL + // + VbeBuffer = ((UINT8 *) VbeFrameBuffer + (SrcY * BytesPerScanLine + SourceX * VbePixelWidth)); + for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) { + Pixel = *(UINT32 *) (VbeBuffer); + Blt->Red = (UINT8) ((Pixel >> Mode->Red.Position) & Mode->Red.Mask); + Blt->Blue = (UINT8) ((Pixel >> Mode->Blue.Position) & Mode->Blue.Mask); + Blt->Green = (UINT8) ((Pixel >> Mode->Green.Position) & Mode->Green.Mask); + Blt->Reserved = 0; + Blt++; + VbeBuffer += VbePixelWidth; + } + + } + break; + + case EfiBltVideoToVideo: + for (Index = 0; Index < Height; Index++) { + if (DestinationY <= SourceY) { + SrcY = SourceY + Index; + DstY = DestinationY + Index; + } else { + SrcY = SourceY + Height - Index - 1; + DstY = DestinationY + Height - Index - 1; + } + + VbeBuffer = ((UINT8 *) VbeFrameBuffer + DstY * BytesPerScanLine + DestinationX * VbePixelWidth); + VbeBuffer1 = ((UINT8 *) VbeFrameBuffer + SrcY * BytesPerScanLine + SourceX * VbePixelWidth); + + gBS->CopyMem ( + VbeBuffer, + VbeBuffer1, + Width * VbePixelWidth + ); + + if (VbePixelWidth == 4) { +//*** AMI PORTING BEGIN ***// +// Replace PciIo.Mem with CopyMem to optimize performance +/* + PciIo->Mem.Write ( + PciIo, + EfiPciIoWidthUint32, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) ((UINTN) MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth), + Width, + VbeBuffer + ); +*/ + gBS->CopyMem ((UINT8*)MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth, + (UINT8*)VbeBuffer, + Width * VbePixelWidth); +//*** AMI PORTING END *****// + } else { +//*** AMI PORTING BEGIN ***// +// Replace PciIo.Mem with CopyMem to optimize performance +/* + PciIo->Mem.Write ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) ((UINTN) MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth), + Width * VbePixelWidth, + VbeBuffer + ); +*/ + gBS->CopyMem ((UINT8*)MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth, + (UINT8*)VbeBuffer, + Width * VbePixelWidth); + } +//*** AMI PORTING END *****// + } + break; + + case EfiBltVideoFill: + VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth); + Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltUint8; + // + // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer + // + Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) | + ( + (Blt->Green & Mode->Green.Mask) << + Mode->Green.Position + ) | + ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position); + + for (Index = 0; Index < Width; Index++) { + gBS->CopyMem ( + VbeBuffer, + &Pixel, + VbePixelWidth + ); + VbeBuffer += VbePixelWidth; + } + + VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth); + for (DstY = DestinationY + 1; DstY < (Height + DestinationY); DstY++) { + gBS->CopyMem ( + (VOID *) ((UINTN) VbeFrameBuffer + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth), + VbeBuffer, + Width * VbePixelWidth + ); + } + + for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) { +//*** AMI PORTING BEGIN ***// +// Replace PciIo.Mem with CopyMem to optimize performance +/* + PciIo->Mem.Write ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) ((UINTN) MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth), + Width * VbePixelWidth, + VbeBuffer + ); +*/ + gBS->CopyMem ((UINT8*)MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth, + (UINT8*)VbeBuffer, + Width * VbePixelWidth); +//*** AMI PORTING END *****// + } + break; + + case EfiBltBufferToVideo: +//*** AMI PORTING BEGIN ***// +//The original BLT loop is replaced to optimize performance by: +// replacing PciIo->Mem.Write with CopyMem and +// replacing multiplication with addition +/* + for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { + Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + (SrcY * Delta) + (SourceX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + VbeBuffer = ((UINT8 *) VbeFrameBuffer + (DstY * BytesPerScanLine + DestinationX * VbePixelWidth)); + for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) { + // + // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer + // + Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) | + ((Blt->Green & Mode->Green.Mask) << Mode->Green.Position) | + ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position); + gBS->CopyMem ( + VbeBuffer, + &Pixel, + VbePixelWidth + ); + Blt++; + VbeBuffer += VbePixelWidth; + } + + VbeBuffer = ((UINT8 *) VbeFrameBuffer + (DstY * BytesPerScanLine + DestinationX * VbePixelWidth)); + PciIo->Mem.Write ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) ((UINTN) MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth), + Width * VbePixelWidth, + VbeBuffer + ); + } +*/ +{ + UINTN VbeBufferOffset = DestinationY * BytesPerScanLine + DestinationX * VbePixelWidth; + UINT8* BltBufferAddress = BltUint8 + SourceY * Delta + SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); + UINTN VbeLineWidth = VbePixelWidth*Width; + UINTN BufferOffset = VbeBufferOffset; + + for (SrcY = SourceY; SrcY < (Height + SourceY); SrcY++) { + + VbeBuffer = (UINT8 *) VbeFrameBuffer + BufferOffset; + + if (Mode->PixelFormat != PixelBlueGreenRedReserved8BitPerColor){ + Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)BltBufferAddress; + for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) { + // + // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer + // + Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) | + ((Blt->Green & Mode->Green.Mask) << Mode->Green.Position) | + ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position); + gBS->CopyMem ( + VbeBuffer, + &Pixel, + VbePixelWidth + ); + Blt++; + VbeBuffer += VbePixelWidth; + } + VbeBuffer = (UINT8 *) VbeFrameBuffer + BufferOffset; + }else{ + gBS->CopyMem (VbeBuffer, BltBufferAddress, VbeLineWidth); + } + BufferOffset += BytesPerScanLine; + BltBufferAddress += Delta; + } + BufferOffset = VbeBufferOffset; + for (SrcY = SourceY; SrcY < (Height + SourceY); SrcY++) { + gBS->CopyMem ((UINT8*)MemAddress + BufferOffset, + (UINT8 *)VbeFrameBuffer + BufferOffset, + VbeLineWidth); + BufferOffset += BytesPerScanLine; + } +} +//*** AMI PORTING END *****// + break; + } + + gBS->RestoreTPL (OriginalTPL); + + return EFI_SUCCESS; +} +//*** AMI PORTING BEGIN ***// +#endif //if INT10_VESA_GO_SUPPORT==1 +//*** AMI PORTING END *****// +//*** AMI PORTING BEGIN ***// +#if INT10_VGA_GO_SUPPORT==1 +//*** AMI PORTING END *****// +STATIC +VOID +WriteGraphicsController ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINTN Address, + IN UINTN Data + ) +/*++ + +Routine Description: + + Write graphics controller registers + +Arguments: + + PciIo - Pointer to PciIo protocol instance of the controller + Address - Register address + Data - Data to be written to register + +Returns: + + None + +--*/ +{ + Address = Address | (Data << 8); + PciIo->Io.Write ( + PciIo, + EfiPciIoWidthUint16, + EFI_PCI_IO_PASS_THROUGH_BAR, + VGA_GRAPHICS_CONTROLLER_ADDRESS_REGISTER, + 1, + &Address + ); +} + +VOID +VgaReadBitPlanes ( + EFI_PCI_IO_PROTOCOL *PciIo, + UINT8 *HardwareBuffer, + UINT8 *MemoryBuffer, + UINTN WidthInBytes, + UINTN Height + ) +/*++ + +Routine Description: + + Read the four bit plane of VGA frame buffer + +Arguments: + + PciIo - Pointer to PciIo protocol instance of the controller + HardwareBuffer - Hardware VGA frame buffer address + MemoryBuffer - Memory buffer address + WidthInBytes - Number of bytes in a line to read + Height - Height of the area to read + +Returns: + + None + +--*/ +{ + UINTN BitPlane; + UINTN Rows; + UINTN FrameBufferOffset; + UINT8 *Source; + UINT8 *Destination; + + // + // Program the Mode Register Write mode 0, Read mode 0 + // + WriteGraphicsController ( + PciIo, + VGA_GRAPHICS_CONTROLLER_MODE_REGISTER, + VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_0 + ); + + for (BitPlane = 0, FrameBufferOffset = 0; + BitPlane < VGA_NUMBER_OF_BIT_PLANES; + BitPlane++, FrameBufferOffset += VGA_BYTES_PER_BIT_PLANE + ) { + // + // Program the Read Map Select Register to select the correct bit plane + // + WriteGraphicsController ( + PciIo, + VGA_GRAPHICS_CONTROLLER_READ_MAP_SELECT_REGISTER, + BitPlane + ); + + Source = HardwareBuffer; + Destination = MemoryBuffer + FrameBufferOffset; + + for (Rows = 0; Rows < Height; Rows++, Source += VGA_BYTES_PER_SCAN_LINE, Destination += VGA_BYTES_PER_SCAN_LINE) { +//*** AMI PORTING BEGIN ***// +// Replace PciIo.Mem with CopyMem to optimize performance +/* + PciIo->Mem.Read ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Source, + WidthInBytes, + (VOID *) Destination + ); +*/ + gBS->CopyMem ((UINT8*)Source, + (UINT8*)Destination, + WidthInBytes); +//*** AMI PORTING END *****// + } + } +} + +VOID +VgaConvertToGraphicsOutputColor ( + UINT8 *MemoryBuffer, + UINTN X, + UINTN Y, + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer + ) +/*++ + +Routine Description: + + Internal routine to convert VGA color to Grahpics Output color + +Arguments: + + MemoryBuffer - Buffer containing VGA color + X - The X coordinate of pixel on screen + Y - The Y coordinate of pixel on screen + BltBuffer - Buffer to contain converted Grahpics Output color + +Returns: + + None + +--*/ +{ + UINTN Mask; + UINTN Bit; + UINTN Color; + + MemoryBuffer += ((Y << 6) + (Y << 4) + (X >> 3)); + Mask = mVgaBitMaskTable[X & 0x07]; + for (Bit = 0x01, Color = 0; Bit < 0x10; Bit <<= 1, MemoryBuffer += VGA_BYTES_PER_BIT_PLANE) { + if (*MemoryBuffer & Mask) { + Color |= Bit; + } + } + + *BltBuffer = mVgaColorToGraphicsOutputColor[Color]; +} + +UINT8 +VgaConvertColor ( + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer + ) +/*++ + +Routine Description: + + Internal routine to convert Grahpics Output color to VGA color + +Arguments: + + BltBuffer - buffer containing Grahpics Output color + +Returns: + + Converted VGA color + +--*/ +{ + UINT8 Color; + + Color = (UINT8) ((BltBuffer->Blue >> 7) | ((BltBuffer->Green >> 6) & 0x02) | ((BltBuffer->Red >> 5) & 0x04)); +//*** AMI PORTING BEGIN ***// +// if ((BltBuffer->Red + BltBuffer->Green + BltBuffer->Blue) > 0x180) { + if ((BltBuffer->Red >= 0xC0) || (BltBuffer->Blue >= 0xC0) || (BltBuffer->Green >= 0xC0)) { + Color |= 0x08; + } + // Prevent "washing out" of single color + if (((BltBuffer->Red >= 0xC0) && (BltBuffer->Blue == 0) && (BltBuffer->Green == 0)) || \ + ((BltBuffer->Blue >= 0xC0) && (BltBuffer->Red == 0) && (BltBuffer->Green == 0)) || \ + ((BltBuffer->Green >= 0xC0) && (BltBuffer->Blue == 0) && (BltBuffer->Red == 0))) { + Color &= 0x07; + } +//*** AMI PORTING END ***// + + return Color; +} + +EFI_STATUS +EFIAPI +BiosVideoGraphicsOutputVgaBlt ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ) +/*++ + +Routine Description: + + Grahpics Output protocol instance to block transfer for VGA device + +Arguments: + + This - Pointer to Grahpics Output protocol instance + BltBuffer - The data to transfer to screen + BltOperation - The operation to perform + SourceX - The X coordinate of the source for BltOperation + 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 + +--*/ +{ + BIOS_VIDEO_DEV *BiosVideoPrivate; + EFI_TPL OriginalTPL; + UINT8 *MemAddress; + UINTN BytesPerScanLine; + UINTN BytesPerBitPlane; + UINTN Bit; + UINTN Index; + UINTN Index1; + UINTN StartAddress; + UINTN Bytes; + UINTN Offset; + UINT8 LeftMask; + UINT8 RightMask; + UINTN Address; + UINTN AddressFix; + UINT8 *Address1; + UINT8 *SourceAddress; + UINT8 *DestinationAddress; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT8 Data; + UINT8 PixelColor; + UINT8 *VgaFrameBuffer; + UINTN SourceOffset; + UINTN SourceWidth; + UINTN Rows; + UINTN Columns; + UINTN X; + UINTN Y; + UINTN CurrentMode; + + BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This); + +//*** AMI PORTING BEGIN ***// +// Workaround for EIP 35682. +// Allocate memory buffers during the first call of the funciton. +// See comments above AllocateTheBuffers function for additional details. + if (BiosVideoPrivate->LineBuffer==NULL){ + EFI_STATUS Status = AllocateTheBuffers(BiosVideoPrivate); + if (EFI_ERROR(Status)) return Status; + } +//*** AMI PORTING END *****// + + CurrentMode = This->Mode->Mode; + PciIo = BiosVideoPrivate->PciIo; + MemAddress = BiosVideoPrivate->ModeData[CurrentMode].LinearFrameBuffer; + BytesPerScanLine = BiosVideoPrivate->ModeData[CurrentMode].BytesPerScanLine >> 3; + BytesPerBitPlane = BytesPerScanLine * BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution; + VgaFrameBuffer = BiosVideoPrivate->VgaFrameBuffer; + + if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) { + return EFI_INVALID_PARAMETER; + } + + if (Width == 0 || Height == 0) { + return EFI_INVALID_PARAMETER; + } + // + // 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. + // + if (BltOperation == EfiBltVideoToBltBuffer) { + // + // Video to BltBuffer: Source is Video, destination is BltBuffer + // + if (SourceY + Height > BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution) { + return EFI_INVALID_PARAMETER; + } + + if (SourceX + Width > BiosVideoPrivate->ModeData[CurrentMode].HorizontalResolution) { + return EFI_INVALID_PARAMETER; + } + } else { + // + // BltBuffer to Video: Source is BltBuffer, destination is Video + // + if (DestinationY + Height > BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution) { + return EFI_INVALID_PARAMETER; + } + + if (DestinationX + Width > BiosVideoPrivate->ModeData[CurrentMode].HorizontalResolution) { + 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 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 (EFI_TPL_NOTIFY); + + // + // Compute some values we need for VGA + // + switch (BltOperation) { + case EfiBltVideoToBltBuffer: + + SourceOffset = (SourceY << 6) + (SourceY << 4) + (SourceX >> 3); + SourceWidth = ((SourceX + Width - 1) >> 3) - (SourceX >> 3) + 1; + + // + // Read all the pixels in the 4 bit planes into a memory buffer that looks like the VGA buffer + // + VgaReadBitPlanes ( + PciIo, + MemAddress + SourceOffset, + VgaFrameBuffer + SourceOffset, + SourceWidth, + Height + ); + + // + // Convert VGA Bit Planes to a Graphics Output 32-bit color value + // + BltBuffer += (DestinationY * (Delta >> 2) + DestinationX); + for (Rows = 0, Y = SourceY; Rows < Height; Rows++, Y++, BltBuffer += (Delta >> 2)) { + for (Columns = 0, X = SourceX; Columns < Width; Columns++, X++, BltBuffer++) { + VgaConvertToGraphicsOutputColor (VgaFrameBuffer, X, Y, BltBuffer); + } + + BltBuffer -= Width; + } + + break; + + case EfiBltVideoToVideo: + // + // Check for an aligned Video to Video operation + // + if ((SourceX & 0x07) == 0x00 && (DestinationX & 0x07) == 0x00 && (Width & 0x07) == 0x00) { + // + // Program the Mode Register Write mode 1, Read mode 0 + // + WriteGraphicsController ( + PciIo, + VGA_GRAPHICS_CONTROLLER_MODE_REGISTER, + VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_1 + ); + + SourceAddress = (UINT8 *) (MemAddress + (SourceY << 6) + (SourceY << 4) + (SourceX >> 3)); + DestinationAddress = (UINT8 *) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3)); + Bytes = Width >> 3; + for (Index = 0, Offset = 0; Index < Height; Index++, Offset += BytesPerScanLine) { + PciIo->CopyMem ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) (DestinationAddress + Offset), + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) (SourceAddress + Offset), + Bytes + ); + } + } else { + SourceOffset = (SourceY << 6) + (SourceY << 4) + (SourceX >> 3); + SourceWidth = ((SourceX + Width - 1) >> 3) - (SourceX >> 3) + 1; + + // + // Read all the pixels in the 4 bit planes into a memory buffer that looks like the VGA buffer + // + VgaReadBitPlanes ( + PciIo, + MemAddress + SourceOffset, + VgaFrameBuffer + SourceOffset, + SourceWidth, + Height + ); + } + + break; + + case EfiBltVideoFill: + StartAddress = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3)); + Bytes = ((DestinationX + Width - 1) >> 3) - (DestinationX >> 3); + LeftMask = mVgaLeftMaskTable[DestinationX & 0x07]; + RightMask = mVgaRightMaskTable[(DestinationX + Width - 1) & 0x07]; + if (Bytes == 0) { + LeftMask &= RightMask; + RightMask = 0; + } + + if (LeftMask == 0xff) { + StartAddress--; + Bytes++; + LeftMask = 0; + } + + if (RightMask == 0xff) { + Bytes++; + RightMask = 0; + } + + PixelColor = VgaConvertColor (BltBuffer); + + // + // Program the Mode Register Write mode 2, Read mode 0 + // + WriteGraphicsController ( + PciIo, + VGA_GRAPHICS_CONTROLLER_MODE_REGISTER, + VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2 + ); + + // + // Program the Data Rotate/Function Select Register to replace + // + WriteGraphicsController ( + PciIo, + VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER, + VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE + ); + + if (LeftMask != 0) { + // + // Program the BitMask register with the Left column mask + // + WriteGraphicsController ( + PciIo, + VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER, + LeftMask + ); + + for (Index = 0, Address = StartAddress; Index < Height; Index++, Address += BytesPerScanLine) { + // + // Read data from the bit planes into the latches + // +//*** AMI PORTING BEGIN ***// +// Replace PciIo.Mem with direct memory access to optimize performance +/* + PciIo->Mem.Read ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Address, + 1, + &Data + ); +*/ + Data = *(volatile UINT8*)(UINTN)Address; +//*** AMI PORTING END *****// + // + // Write the lower 4 bits of PixelColor to the bit planes in the pixels enabled by BitMask + // +//*** AMI PORTING BEGIN ***// +// Replace PciIo.Mem with direct memory access to optimize performance +/* + PciIo->Mem.Write ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Address, + 1, + &PixelColor + ); +*/ + *(volatile UINT8*)(UINTN)Address = PixelColor; +//*** AMI PORTING END *****// + } + } + + if (Bytes > 1) { + // + // Program the BitMask register with the middle column mask of 0xff + // + WriteGraphicsController ( + PciIo, + VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER, + 0xff + ); + + for (Index = 0, Address = StartAddress + 1; Index < Height; Index++, Address += BytesPerScanLine) { +//*** AMI PORTING BEGIN ***// +// Replace PciIo.Mem with SetMem to optimize performance +/* + PciIo->Mem.Write ( + PciIo, + EfiPciIoWidthFillUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Address, + Bytes - 1, + &PixelColor + ); +*/ + gBS->SetMem((VOID*)Address, Bytes - 1, PixelColor); +//*** AMI PORTING END ***// + } + } + + if (RightMask != 0) { + // + // Program the BitMask register with the Right column mask + // + WriteGraphicsController ( + PciIo, + VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER, + RightMask + ); + + for (Index = 0, Address = StartAddress + Bytes; Index < Height; Index++, Address += BytesPerScanLine) { + // + // Read data from the bit planes into the latches + // +//*** AMI PORTING BEGIN ***// +// Replace PciIo.Mem with direct memory access to optimize performance +/* + PciIo->Mem.Read ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Address, + 1, + &Data + ); +*/ + Data = *(volatile UINT8*)(UINTN)Address; +//*** AMI PORTING END *****// + // + // Write the lower 4 bits of PixelColor to the bit planes in the pixels enabled by BitMask + // +//*** AMI PORTING BEGIN ***// +// Replace PciIo.Mem with direct memory access to optimize performance +/* + PciIo->Mem.Write ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Address, + 1, + &PixelColor + ); +*/ + *(volatile UINT8*)(UINTN)Address = PixelColor; +//*** AMI PORTING END *****// + } + } + break; + + case EfiBltBufferToVideo: + StartAddress = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3)); + LeftMask = mVgaBitMaskTable[DestinationX & 0x07]; + + // + // Program the Mode Register Write mode 2, Read mode 0 + // + WriteGraphicsController ( + PciIo, + VGA_GRAPHICS_CONTROLLER_MODE_REGISTER, + VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2 + ); + + // + // Program the Data Rotate/Function Select Register to replace + // + WriteGraphicsController ( + PciIo, + VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER, + VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE + ); + + for (Index = 0, Address = StartAddress; Index < Height; Index++, Address += BytesPerScanLine) { + for (Index1 = 0; Index1 < Width; Index1++) { + BiosVideoPrivate->LineBuffer[Index1] = VgaConvertColor (&BltBuffer[(SourceY + Index) * (Delta >> 2) + SourceX + Index1]); + } + AddressFix = Address; + + for (Bit = 0; Bit < 8; Bit++) { + // + // Program the BitMask register with the Left column mask + // + WriteGraphicsController ( + PciIo, + VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER, + LeftMask + ); + + for (Index1 = Bit, Address1 = (UINT8 *) AddressFix; Index1 < Width; Index1 += 8, Address1++) { + // + // Read data from the bit planes into the latches + // +//*** AMI PORTING BEGIN ***// +// Replace PciIo.Mem with direct memory access to optimize performance +/* + PciIo->Mem.Read ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Address1, + 1, + &Data + ); +*/ + Data = *(volatile UINT8*)(UINTN)Address1; + +/* + PciIo->Mem.Write ( + PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + (UINT64) Address1, + 1, + &BiosVideoPrivate->LineBuffer[Index1] + ); +*/ + *(volatile UINT8*)(UINTN)Address1 = BiosVideoPrivate->LineBuffer[Index1]; +//*** AMI PORTING END *****// + } + + LeftMask = (UINT8) (LeftMask >> 1); + if (LeftMask == 0) { + LeftMask = 0x80; + AddressFix++; + } + } + } + + break; + } + + gBS->RestoreTPL (OriginalTPL); + + return EFI_SUCCESS; +} +//*** AMI PORTING BEGIN ***// +#endif //if INT10_VGA_GO_SUPPORT==1 +//*** AMI PORTING END *****// +//*** AMI PORTING BEGIN ***// +#if INT10_SIMPLE_TEXT_SUPPORT==1 +//*** AMI PORTING END *****// +// +// VGA Mini Port Protocol Functions +// +EFI_STATUS +EFIAPI +BiosVideoVgaMiniPortSetMode ( + IN EFI_VGA_MINI_PORT_PROTOCOL *This, + IN UINTN ModeNumber + ) +/*++ + +Routine Description: + + VgaMiniPort protocol interface to set mode + +Arguments: + + This - Pointer to VgaMiniPort protocol instance + ModeNumber - The index of the mode + +Returns: + + EFI_UNSUPPORTED - The requested mode is not supported + EFI_SUCCESS - The requested mode is set successfully + +--*/ +{ + BIOS_VIDEO_DEV *BiosVideoPrivate; + EFI_IA32_REGISTER_SET Regs; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Make sure the ModeNumber is a valid value + // + if (ModeNumber >= This->MaxMode) { + return EFI_UNSUPPORTED; + } + // + // Get the device structure for this device + // + BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS (This); + + switch (ModeNumber) { + case 0: + // + // Set the 80x25 Text VGA Mode + // + Regs.H.AH = 0x00; + Regs.H.AL = 0x83; + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + + Regs.H.AH = 0x11; + Regs.H.AL = 0x14; + Regs.H.BL = 0; + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + break; + + case 1: + // + // Set the 80x50 Text VGA Mode + // + Regs.H.AH = 0x00; + Regs.H.AL = 0x83; + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + Regs.H.AH = 0x11; + Regs.H.AL = 0x12; + Regs.H.BL = 0; + BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); + break; + + default: + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} +//*** AMI PORTING BEGIN ***// +#endif //if INT10_SIMPLE_TEXT_SUPPORT==1 +//*** AMI PORTING END *****// +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.h b/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.h new file mode 100644 index 0000000..9421b5e --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.h @@ -0,0 +1,597 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +// +// This file contains a 'Sample Driver' and is licensed as such +// under the terms of your license agreement with Intel or your +// vendor. This file may be modified by the user, subject to +// the additional terms of the license agreement +// +/*++ + +Copyright (c) 2006 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + UefiBiosVideo.h + +Abstract: + +Revision History +--*/ + +#ifndef _BIOS_GRAPHICS_OUTPUT_H +#define _BIOS_GRAPHICS_OUTPUT_H + +//*** AMI PORTING BEGIN ***// +#include "AmiMapping.h" +#include "EdkIICommon.h" +//#include "Tiano.h" +//#include "EfiDriverLib.h" +#include <Protocol/CsmVideoPolicy.h> +//*** AMI PORTING END *****// +#include "VesaBiosExtensions.h" +#include "Pci22.h" + +// +// Driver Consumed Protocol Prototypes +// +#include EFI_PROTOCOL_DEFINITION (DevicePath) +#include EFI_PROTOCOL_DEFINITION (PciIo) +#include EFI_PROTOCOL_DEFINITION (LegacyBios) +//*** AMI PORTING BEGIN ***// +//AMI CSM Core does not need this GUID +//#include EFI_GUID_DEFINITION (LegacyBios) +//*** AMI PORTING END *****// +//*** AMI PORTING BEGIN ***// +//#include EFI_GUID_DEFINITION (StatusCodeCallerId) +//#include EFI_GUID_DEFINITION (StatusCodeDataTypeId) +//*** AMI PORTING END *****// + +// +// Driver Produced Protocol Prototypes +// +#include EFI_PROTOCOL_DEFINITION (DriverBinding) +#include EFI_PROTOCOL_DEFINITION (ComponentName) +#include EFI_PROTOCOL_DEFINITION (GraphicsOutput) +#include EFI_PROTOCOL_DEFINITION (EdidDiscovered) +#include EFI_PROTOCOL_DEFINITION (EdidActive) + +//*** AMI PORTING BEGIN ***// +//#include EFI_PROTOCOL_DEFINITION (VgaMiniPort) +#include "VgaMiniPort.h" + +// uncomment the following lind and remove the following block when Protocol/EdidOverride.h is available +//#include EFI_PROTOCOL_DEFINITION (EdidOverride) +#define EFI_EDID_OVERRIDE_PROTOCOL_GUID \ + { 0x48ecb431, 0xfb72, 0x45c0, 0xa9, 0x22, 0xf4, 0x58, 0xfe, 0x4, 0xb, 0xd5 } + +#define EFI_EDID_OVERRIDE_DONT_OVERRIDE 0x01 +#define EFI_EDID_OVERRIDE_ENABLE_HOT_PLUG 0x02 + +typedef struct _EFI_EDID_OVERRIDE_PROTOCOL EFI_EDID_OVERRIDE_PROTOCOL; + +typedef EFI_STATUS (EFIAPI *EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID) ( + IN EFI_EDID_OVERRIDE_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle, + OUT UINT32 *Attributes, + IN OUT UINTN *EdidSize, + IN OUT UINT8 **Edid + ); + +struct _EFI_EDID_OVERRIDE_PROTOCOL { + EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID GetEdid; +}; +//*** AMI PORTING END *****// + +// +// Packed format support: The number of bits reserved for each of the colors and the actual +// position of RGB in the frame buffer is specified in the VBE Mode information +// +typedef struct { + UINT8 Position; // Position of the color + UINT8 Mask; // The number of bits expressed as a mask +} BIOS_VIDEO_COLOR_PLACEMENT; + +// +// BIOS Graphics Output Graphical Mode Data +// +typedef struct { + UINT16 VbeModeNumber; + UINT16 BytesPerScanLine; + VOID *LinearFrameBuffer; + UINTN FrameBufferSize; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + UINT32 RefreshRate; + UINT32 BitsPerPixel; + BIOS_VIDEO_COLOR_PLACEMENT Red; + BIOS_VIDEO_COLOR_PLACEMENT Green; + BIOS_VIDEO_COLOR_PLACEMENT Blue; + BIOS_VIDEO_COLOR_PLACEMENT Reserved; + EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; + EFI_PIXEL_BITMASK PixelBitMask; +} BIOS_VIDEO_MODE_DATA; + +// +// BIOS video child handle private data Structure +// +#define BIOS_VIDEO_DEV_SIGNATURE EFI_SIGNATURE_32 ('B', 'V', 'M', 'p') + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + + // + // Consumed Protocols + // + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + + // + // Produced Protocols + // + EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput; + EFI_EDID_DISCOVERED_PROTOCOL EdidDiscovered; + EFI_EDID_ACTIVE_PROTOCOL EdidActive; + EFI_VGA_MINI_PORT_PROTOCOL VgaMiniPort; + + // + // General fields + // + BOOLEAN VgaCompatible; + BOOLEAN ProduceGraphicsOutput; +//*** AMI PORTING BEGIN ***// +// ExitBootServicesEvent is not used +// EFI_EVENT ExitBootServicesEvent; +//*** AMI PORTING END *****// + + // + // Graphics Output Protocol related fields + // + BOOLEAN HardwareNeedsStarting; + BIOS_VIDEO_MODE_DATA *ModeData; + UINT8 *LineBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer; + UINT8 *VgaFrameBuffer; + + // + // VESA Bios Extensions related fields + // + UINTN NumberOfPagesBelow1MB; // Number of 4KB pages in PagesBelow1MB + EFI_PHYSICAL_ADDRESS PagesBelow1MB; // Buffer for all VBE Information Blocks + VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK *VbeInformationBlock; // 0x200 bytes. Must be allocated below 1MB + VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK *VbeModeInformationBlock; // 0x100 bytes. Must be allocated below 1MB + VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *VbeEdidDataBlock; // 0x80 bytes. Must be allocated below 1MB + VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *VbeCrtcInformationBlock; // 59 bytes. Must be allocated below 1MB + UINTN VbeSaveRestorePages; // Number of 4KB pages in VbeSaveRestoreBuffer + EFI_PHYSICAL_ADDRESS VbeSaveRestoreBuffer; // Must be allocated below 1MB + // + // Status code + // + EFI_DEVICE_PATH_PROTOCOL *DevicePath; +} BIOS_VIDEO_DEV; + +#define BIOS_VIDEO_DEV_FROM_PCI_IO_THIS(a) CR (a, BIOS_VIDEO_DEV, PciIo, BIOS_VIDEO_DEV_SIGNATURE) +#define BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS(a) CR (a, BIOS_VIDEO_DEV, GraphicsOutput, BIOS_VIDEO_DEV_SIGNATURE) +#define BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS(a) CR (a, BIOS_VIDEO_DEV, VgaMiniPort, BIOS_VIDEO_DEV_SIGNATURE) + +#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff + +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gBiosVideoDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gBiosVideoComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gBiosVideoComponentName2; + +// +// Driver Binding Protocol functions +// +EFI_STATUS +EFIAPI +BiosVideoDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Controller - GC_TODO: add argument description + RemainingDevicePath - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +BiosVideoDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Controller - GC_TODO: add argument description + RemainingDevicePath - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +BiosVideoDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Controller - GC_TODO: add argument description + NumberOfChildren - GC_TODO: add argument description + ChildHandleBuffer - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +// +// Private worker functions +// +EFI_STATUS +BiosVideoCheckForVbe ( + BIOS_VIDEO_DEV *BiosVideoPrivate, +//*** AMI PORTING BEGIN ***// + PCI_TYPE00 *PciConfSpace +//*** AMI PORTING END *****// +) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + BiosVideoPrivate - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +BiosVideoCheckForVga ( + BIOS_VIDEO_DEV *BiosVideoPrivate + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + BiosVideoPrivate - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +STATIC +EFI_STATUS +DeRegisterVideoChildHandle ( + EFI_DRIVER_BINDING_PROTOCOL *This, + EFI_HANDLE Controller, + EFI_HANDLE Handle + ) +/*++ + +Routine Description: + + Deregister an video child handle and free resources + +Arguments: + + This - Protocol instance pointer. + Controller - Video controller handle + Handle - Video child handle + +Returns: + + EFI_STATUS + +--*/ +; + +VOID +BiosVideoDeviceReleaseResource ( + BIOS_VIDEO_DEV *BiosVideoChildPrivate + ) +/*++ +Routing Description: + + Release resources of a video child device before stopping it. + +Arguments: + + BiosVideoChildPrivate - Video child device private data structure + +Returns: + + NONE + +---*/ +; + +// +// BIOS Graphics Output Protocol functions +// +EFI_STATUS +EFIAPI +BiosVideoGraphicsOutputQueryMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ) +/*++ + +Routine Description: + + Graphics Output protocol interface to get video mode + + Arguments: + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +BiosVideoGraphicsOutputSetMode ( + 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. + +--*/ +; + +EFI_STATUS +EFIAPI +BiosVideoGraphicsOutputVbeBlt ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ) +/*++ + +Routine Description: + + Graphics Output protocol instance to block transfer for VBE 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 + +--*/ +; + +EFI_STATUS +EFIAPI +BiosVideoGraphicsOutputVgaBlt ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ) +/*++ + +Routine Description: + + Grahpics Output protocol instance to block transfer for VGA device + +Arguments: + + This - Pointer to Grahpics Output protocol instance + BltBuffer - The data to transfer to screen + BltOperation - The operation to perform + SourceX - The X coordinate of the source for BltOperation + 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 + +--*/ +; + +// +// BIOS VGA Mini Port Protocol functions +// +EFI_STATUS +EFIAPI +BiosVideoVgaMiniPortSetMode ( + IN EFI_VGA_MINI_PORT_PROTOCOL *This, + IN UINTN ModeNumber + ) +/*++ + +Routine Description: + + VgaMiniPort protocol interface to set mode + +Arguments: + + This - Pointer to VgaMiniPort protocol instance + ModeNumber - The index of the mode + +Returns: + + EFI_UNSUPPORTED - The requested mode is not supported + EFI_SUCCESS - The requested mode is set successfully + +--*/ +; + +// +// Standard VGA Definitions +// +#define VGA_HORIZONTAL_RESOLUTION 640 +#define VGA_VERTICAL_RESOLUTION 480 +#define VGA_NUMBER_OF_BIT_PLANES 4 +#define VGA_PIXELS_PER_BYTE 8 +#define VGA_BYTES_PER_SCAN_LINE (VGA_HORIZONTAL_RESOLUTION / VGA_PIXELS_PER_BYTE) +#define VGA_BYTES_PER_BIT_PLANE (VGA_VERTICAL_RESOLUTION * VGA_BYTES_PER_SCAN_LINE) + +#define VGA_GRAPHICS_CONTROLLER_ADDRESS_REGISTER 0x3ce +#define VGA_GRAPHICS_CONTROLLER_DATA_REGISTER 0x3cf + +#define VGA_GRAPHICS_CONTROLLER_SET_RESET_REGISTER 0x00 + +#define VGA_GRAPHICS_CONTROLLER_ENABLE_SET_RESET_REGISTER 0x01 + +#define VGA_GRAPHICS_CONTROLLER_COLOR_COMPARE_REGISTER 0x02 + +#define VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER 0x03 +#define VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE 0x00 +#define VGA_GRAPHICS_CONTROLLER_FUNCTION_AND 0x08 +#define VGA_GRAPHICS_CONTROLLER_FUNCTION_OR 0x10 +#define VGA_GRAPHICS_CONTROLLER_FUNCTION_XOR 0x18 + +#define VGA_GRAPHICS_CONTROLLER_READ_MAP_SELECT_REGISTER 0x04 + +#define VGA_GRAPHICS_CONTROLLER_MODE_REGISTER 0x05 +#define VGA_GRAPHICS_CONTROLLER_READ_MODE_0 0x00 +#define VGA_GRAPHICS_CONTROLLER_READ_MODE_1 0x08 +#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_0 0x00 +#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_1 0x01 +#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2 0x02 +#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_3 0x03 + +#define VGA_GRAPHICS_CONTROLLER_MISCELLANEOUS_REGISTER 0x06 + +#define VGA_GRAPHICS_CONTROLLER_COLOR_DONT_CARE_REGISTER 0x07 + +#define VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER 0x08 + +#endif diff --git a/Core/EM/CSM/thunk/CsmVideo/VesaBiosExtensions.h b/Core/EM/CSM/thunk/CsmVideo/VesaBiosExtensions.h new file mode 100644 index 0000000..5adcdfb --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/VesaBiosExtensions.h @@ -0,0 +1,463 @@ +// +// This file contains a 'Sample Driver' and is licensed as such +// under the terms of your license agreement with Intel or your +// vendor. This file may be modified by the user, subject to +// the additional terms of the license agreement +// +/*++ + +Copyright (c) 1999 - 2006 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + VesaBiosExtensions.h + +Abstract: + +Revision History + +--*/ + +#ifndef _VESA_BIOS_EXTENSIONS_H +#define _VESA_BIOS_EXTENSIONS_H + +// +// Turn on byte packing of data structures +// +#pragma pack(1) +// +// VESA BIOS Extensions status codes +// +#define VESA_BIOS_EXTENSIONS_STATUS_SUCCESS 0x004f + +// +// VESA BIOS Extensions Services +// +#define VESA_BIOS_EXTENSIONS_RETURN_CONTROLLER_INFORMATION 0x4f00 + +/*++ + + Routine Description: + Function 00 : Return Controller Information + + Arguments: + Inputs: + AX = 0x4f00 + ES:DI = Pointer to buffer to place VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK structure + Outputs: + AX = Return Status + +--*/ +#define VESA_BIOS_EXTENSIONS_RETURN_MODE_INFORMATION 0x4f01 + +/*++ + + Routine Description: + Function 01 : Return Mode Information + + Arguments: + Inputs: + AX = 0x4f01 + CX = Mode Number + ES:DI = Pointer to buffer to place VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK structure + Outputs: + AX = Return Status + +--*/ +#define VESA_BIOS_EXTENSIONS_SET_MODE 0x4f02 + +/*++ + + Routine Description: + Function 02 : Set Mode + + Arguments: + Inputs: + AX = 0x4f02 + BX = Desired mode to set + D0-D8 = Mode Number + D9-D10 = Reserved (must be 0) + D11 = 0 - Use current default refresh rate + = 1 - Use user specfieid CRTC values for refresh rate + D12-D13 = Reserved (must be 0) + D14 = 0 - Use windowed frame buffer model + = 1 - Use linear/flat frame buffer model + D15 = 0 - Clear display memory + = 1 - Don't clear display memory + ES:DI = Pointer to buffer to the VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK structure + Outputs: + AX = Return Status + +--*/ +#define VESA_BIOS_EXTENSIONS_RETURN_CURRENT_MODE 0x4f03 + +/*++ + + Routine Description: + Function 03 : Return Current Mode + + Arguments: + Inputs: + AX = 0x4f03 + Outputs: + AX = Return Status + BX = Current mode + D0-D13 = Mode Number + D14 = 0 - Windowed frame buffer model + = 1 - Linear/flat frame buffer model + D15 = 0 - Memory cleared at last mode set + = 1 - Memory not cleared at last mode set + +--*/ +#define VESA_BIOS_EXTENSIONS_SAVE_RESTORE_STATE 0x4f04 + +/*++ + + Routine Description: + Function 04 : Save/Restore State + + Arguments: + Inputs: + AX = 0x4f03 + DL = 0x00 - Return Save/Restore State buffer size + = 0x01 - Save State + = 0x02 - Restore State + CX = Requested Status + D0 = Save/Restore controller hardware state + D1 = Save/Restore BIOS data state + D2 = Save/Restore DAC state + D3 = Save/Restore Regsiter state + ES:BX = Pointer to buffer if DL=1 or DL=2 + Outputs: + AX = Return Status + BX = Number of 64 byte blocks to hold the state buffer if DL=0 + +--*/ +#define VESA_BIOS_EXTENSIONS_EDID 0x4f15 + +/*++ + + Routine Description: + Function 15 : implement VBE/DDC service + + Arguments: + Inputs: + AX = 0x4f15 + BL = 0x00 - Report VBE/DDC Capabilities + CX = 0x00 - Controller unit number (00 = primary controller) + ES:DI = Null pointer, must be 0:0 in version 1.0 + Outputs: + AX = Return Status + BH = Approx. time in seconds, rounded up, to transfer one EDID block(128 bytes) + BL = DDC level supported + D0 = 0 DDC1 not supported + = 1 DDC1 supported + D1 = 0 DDC2 not supported + = 1 DDC2 supported + D2 = 0 Screen not blanked during data transfer + = 1 Screen blanked during data transfer + + Inputs: + AX = 0x4f15 + BL = 0x01 - Read EDID + CX = 0x00 - Controller unit number (00 = primary controller) + DX = 0x00 - EDID block number + ES:DI = Pointer to buffer in which the EDID block is returned + Outputs: + AX = Return Status +--*/ + +// +// Timing data from EDID data block +// +#define VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE 128 +#define VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER 17 + +typedef struct { + UINT16 HorizontalResolution; + UINT16 VerticalResolution; + UINT16 RefreshRate; +} VESA_BIOS_EXTENSIONS_EDID_TIMING; + +typedef struct { + UINT32 ValidNumber; + UINT32 Key[VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER]; +} VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING; + +typedef struct { + UINT8 Header[8]; //EDID header "00 FF FF FF FF FF FF 00" + UINT16 ManufactureName; //EISA 3-character ID + UINT16 ProductCode; //Vendor assigned code + UINT32 SerialNumber; //32-bit serial number + UINT8 WeekOfManufacture; //Week number + UINT8 YearOfManufacture; //Year + UINT8 EdidVersion; //EDID Structure Version + UINT8 EdidRevision; //EDID Structure Revision + UINT8 VideoInputDefinition; + UINT8 MaxHorizontalImageSize; //cm + UINT8 MaxVerticalImageSize; //cm + UINT8 DisplayTransferCharacteristic; + UINT8 FeatureSupport; + UINT8 RedGreenLowBits; //Rx1 Rx0 Ry1 Ry0 Gx1 Gx0 Gy1Gy0 + UINT8 BlueWhiteLowBits; //Bx1 Bx0 By1 By0 Wx1 Wx0 Wy1 Wy0 + UINT8 RedX; //Red-x Bits 9 - 2 + UINT8 RedY; //Red-y Bits 9 - 2 + UINT8 GreenX; //Green-x Bits 9 - 2 + UINT8 GreenY; //Green-y Bits 9 - 2 + UINT8 BlueX; //Blue-x Bits 9 - 2 + UINT8 BlueY; //Blue-y Bits 9 - 2 + UINT8 WhiteX; //White-x Bits 9 - 2 + UINT8 WhiteY; //White-x Bits 9 - 2 + UINT8 EstablishedTimings[3]; + UINT8 StandardTimingIdentification[16]; + UINT8 DetailedTimingDescriptions[72]; + UINT8 ExtensionFlag; //Number of (optional) 128-byte EDID extension blocks to follow + UINT8 Checksum; +} VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK; + +// +// Super VGA Information Block +// +typedef struct { + UINT32 VESASignature; // 'VESA' 4 byte signature + UINT16 VESAVersion; // VBE version number + UINT32 OEMStringPtr; // Pointer to OEM string + UINT32 Capabilities; // Capabilities of video card + UINT32 VideoModePtr; // Pointer to an array of 16-bit supported modes values terminated by 0xFFFF + UINT16 TotalMemory; // Number of 64kb memory blocks + UINT16 OemSoftwareRev; // VBE implementation Software revision + UINT32 OemVendorNamePtr; // VbeFarPtr to Vendor Name String + UINT32 OemProductNamePtr; // VbeFarPtr to Product Name String + UINT32 OemProductRevPtr; // VbeFarPtr to Product Revision String + UINT8 Reserved[222]; // Reserved for VBE implementation scratch area + UINT8 OemData[256]; // Data area for OEM strings. Pad to 512 byte block size +} VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK; + +// +// Super VGA Information Block VESASignature values +// +#define VESA_BIOS_EXTENSIONS_VESA_SIGNATURE EFI_SIGNATURE_32 ('V', 'E', 'S', 'A') +#define VESA_BIOS_EXTENSIONS_VBE2_SIGNATURE EFI_SIGNATURE_32 ('V', 'B', 'E', '2') + +// +// Super VGA Information Block VESAVersion values +// +#define VESA_BIOS_EXTENSIONS_VERSION_1_2 0x0102 +#define VESA_BIOS_EXTENSIONS_VERSION_2_0 0x0200 +#define VESA_BIOS_EXTENSIONS_VERSION_3_0 0x0300 + +// +// Super VGA Information Block Capabilities field bit defintions +// +#define VESA_BIOS_EXTENSIONS_CAPABILITY_8_BIT_DAC 0x01 // 0: DAC width is fixed at 6 bits/color +// 1: DAC width switchable to 8 bits/color +// +#define VESA_BIOS_EXTENSIONS_CAPABILITY_NOT_VGA 0x02 // 0: Controller is VGA compatible +// 1: Controller is not VGA compatible +// +#define VESA_BIOS_EXTENSIONS_CAPABILITY_NOT_NORMAL_RAMDAC 0x04 // 0: Normal RAMDAC operation +// 1: Use blank bit in function 9 to program RAMDAC +// +#define VESA_BIOS_EXTENSIONS_CAPABILITY_STEREOSCOPIC 0x08 // 0: No hardware stereoscopic signal support +// 1: Hardware stereoscopic signal support +// +#define VESA_BIOS_EXTENSIONS_CAPABILITY_VESA_EVC 0x10 // 0: Stero signaling supported via external VESA stereo connector +// 1: Stero signaling supported via VESA EVC connector +// +// Super VGA mode number bite field definitions +// +#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_VESA 0x0100 // 0: Not a VESA defined VBE mode +// 1: A VESA defined VBE mode +// +#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_REFRESH_CONTROL_USER 0x0800 // 0: Use current BIOS default referesh rate +// 1: Use the user specified CRTC values for refresh rate +// +#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_LINEAR_FRAME_BUFFER 0x4000 // 0: Use a banked/windowed frame buffer +// 1: Use a linear/flat frame buffer +// +#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_PRESERVE_MEMORY 0x8000 // 0: Clear display memory +// 1: Preseve display memory +// +// Super VGA Information Block mode list terminator value +// +#define VESA_BIOS_EXTENSIONS_END_OF_MODE_LIST 0xffff + +// +// Window Function +// +typedef +VOID +(*VESA_BIOS_EXTENSIONS_WINDOW_FUNCTION) ( + VOID + ); + +// +// Super VGA Mode Information Block +// +typedef struct { + // + // Manadory fields for all VESA Bios Extensions revisions + // + UINT16 ModeAttributes; // Mode attributes + UINT8 WinAAttributes; // Window A attributes + UINT8 WinBAttributes; // Window B attributes + UINT16 WinGranularity; // Window granularity in k + UINT16 WinSize; // Window size in k + UINT16 WinASegment; // Window A segment + UINT16 WinBSegment; // Window B segment + UINT32 WindowFunction; // Pointer to window function + UINT16 BytesPerScanLine; // Bytes per scanline + // + // Manadory fields for VESA Bios Extensions 1.2 and above + // + UINT16 XResolution; // Horizontal resolution + UINT16 YResolution; // Vertical resolution + UINT8 XCharSize; // Character cell width + UINT8 YCharSize; // Character cell height + UINT8 NumberOfPlanes; // Number of memory planes + UINT8 BitsPerPixel; // Bits per pixel + UINT8 NumberOfBanks; // Number of CGA style banks + UINT8 MemoryModel; // Memory model type + UINT8 BankSize; // Size of CGA style banks + UINT8 NumberOfImagePages; // Number of images pages + UINT8 Reserved1; // Reserved + UINT8 RedMaskSize; // Size of direct color red mask + UINT8 RedFieldPosition; // Bit posn of lsb of red mask + UINT8 GreenMaskSize; // Size of direct color green mask + UINT8 GreenFieldPosition; // Bit posn of lsb of green mask + UINT8 BlueMaskSize; // Size of direct color blue mask + UINT8 BlueFieldPosition; // Bit posn of lsb of blue mask + UINT8 RsvdMaskSize; // Size of direct color res mask + UINT8 RsvdFieldPosition; // Bit posn of lsb of res mask + UINT8 DirectColorModeInfo; // Direct color mode attributes + // + // Manadory fields for VESA Bios Extensions 2.0 and above + // + UINT32 PhysBasePtr; // Physical Address for flat memory frame buffer + UINT32 Reserved2; // Reserved + UINT16 Reserved3; // Reserved + // + // Manadory fields for VESA Bios Extensions 3.0 and above + // + UINT16 LinBytesPerScanLine; // Bytes/scan line for linear modes + UINT8 BnkNumberOfImagePages; // Number of images for banked modes + UINT8 LinNumberOfImagePages; // Number of images for linear modes + UINT8 LinRedMaskSize; // Size of direct color red mask (linear mode) + UINT8 LinRedFieldPosition; // Bit posiiton of lsb of red mask (linear modes) + UINT8 LinGreenMaskSize; // Size of direct color green mask (linear mode) + UINT8 LinGreenFieldPosition; // Bit posiiton of lsb of green mask (linear modes) + UINT8 LinBlueMaskSize; // Size of direct color blue mask (linear mode) + UINT8 LinBlueFieldPosition; // Bit posiiton of lsb of blue mask (linear modes) + UINT8 LinRsvdMaskSize; // Size of direct color reserved mask (linear mode) + UINT8 LinRsvdFieldPosition; // Bit posiiton of lsb of reserved mask (linear modes) + UINT32 MaxPixelClock; // Maximum pixel clock (in Hz) for graphics mode + UINT8 Pad[190]; // Pad to 256 byte block size +} VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK; + +// +// Super VGA Mode Information Block ModeAttributes field bit defintions +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_HARDWARE 0x0001 // 0: Mode not supported in handware +// 1: Mode supported in handware +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_TTY 0x0004 // 0: TTY Output functions not supported by BIOS +// 1: TTY Output functions supported by BIOS +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_COLOR 0x0008 // 0: Monochrome mode +// 1: Color mode +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_GRAPHICS 0x0010 // 0: Text mode +// 1: Graphics mode +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NOT_VGA 0x0020 // 0: VGA compatible mode +// 1: Not a VGA compatible mode +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NOT_WINDOWED 0x0040 // 0: VGA compatible windowed memory mode +// 1: Not a VGA compatible windowed memory mode +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER 0x0080 // 0: No linear fram buffer mode available +// 1: Linear frame buffer mode available +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_DOUBLE_SCAN 0x0100 // 0: No double scan mode available +// 1: Double scan mode available +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_INTERLACED 0x0200 // 0: No interlaced mode is available +// 1: Interlaced mode is available +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NO_TRIPPLE_BUFFER 0x0400 // 0: No hardware triple buffer mode support available +// 1: Hardware triple buffer mode support available +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_STEREOSCOPIC 0x0800 // 0: No hardware steroscopic display support +// 1: Hardware steroscopic display support +// +#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_DUAL_DISPLAY 0x1000 // 0: No dual display start address support +// 1: Dual display start address support +// +// Super VGA Mode Information Block WinAAttribite/WinBAttributes field bit defintions +// +#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_RELOCATABLE 0x01 // 0: Single non-relocatable window only +// 1: Relocatable window(s) are supported +// +#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_READABLE 0x02 // 0: Window is not readable +// 1: Window is readable +// +#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_WRITABLE 0x04 // 0: Window is not writable +// 1: Window is writable +// +// Super VGA Mode Information Block DirectColorMode field bit defintions +// +#define VESA_BIOS_EXTENSIONS_DIRECT_COLOR_MODE_PROG_COLOR_RAMP 0x01 // 0: Color ram is fixed +// 1: Color ramp is programmable +// +#define VESA_BIOS_EXTENSIONS_DIRECT_COLOR_MODE_RSVD_USABLE 0x02 // 0: Bits in Rsvd field are reserved +// 1: Bits in Rsdv field are usable +// +// Super VGA Memory Models +// +typedef enum { + memPL = 3, // Planar memory model + memPK = 4, // Packed pixel memory model + memRGB= 6, // Direct color RGB memory model + memYUV= 7, // Direct color YUV memory model +} VESA_BIOS_EXTENSIONS_MEMORY_MODELS; + +// +// Super VGA CRTC Information Block +// +typedef struct { + UINT16 HorizontalTotal; // Horizontal total in pixels + UINT16 HorizontalSyncStart; // Horizontal sync start in pixels + UINT16 HorizontalSyncEnd; // Horizontal sync end in pixels + UINT16 VericalTotal; // Vertical total in pixels + UINT16 VericalSyncStart; // Vertical sync start in pixels + UINT16 VericalSyncEnd; // Vertical sync end in pixels + UINT8 Flags; // Flags (Interlaced/DoubleScan/etc). + UINT32 PixelClock; // Pixel clock in units of Hz + UINT16 RefreshRate; // Refresh rate in units of 0.01 Hz + UINT8 Reserved[40]; // Pad +} VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK; + +#define VESA_BIOS_EXTENSIONS_CRTC_FLAGS_DOUBLE_SCAN 0x01 // 0: Graphics mode is not souble scanned +// 1: Graphics mode is double scanned +// +#define VESA_BIOS_EXTENSIONS_CRTC_FLAGSINTERLACED 0x02 // 0: Graphics mode is not interlaced +// 1: Graphics mode is interlaced +// +#define VESA_BIOS_EXTENSIONS_CRTC_HORIZONTAL_SYNC_NEGATIVE 0x04 // 0: Horizontal sync polarity is positive(+) +// 0: Horizontal sync polarity is negative(-) +// +#define VESA_BIOS_EXTENSIONS_CRTC_VERITICAL_SYNC_NEGATIVE 0x08 // 0: Verical sync polarity is positive(+) +// 0: Verical sync polarity is negative(-) +// +// Turn off byte packing of data structures +// +#pragma pack() + +#endif diff --git a/Core/EM/CSM/thunk/CsmVideo/VgaClass.c b/Core/EM/CSM/thunk/CsmVideo/VgaClass.c new file mode 100644 index 0000000..1315bf5 --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/VgaClass.c @@ -0,0 +1,1349 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +/*++ + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +--*/ +/*++ + +Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + + +Module Name: + + VgaClass.c + +Abstract: + This driver produces a VGA console. + +--*/ +#include "VgaClass.h" +//*** AMI PORTING BEGIN ***// +#if INT10_SIMPLE_TEXT_SUPPORT==1 +//*** AMI PORTING END *****// + +// +// EFI Driver Binding Protocol for the VGA Class Driver +// +EFI_DRIVER_BINDING_PROTOCOL gVgaClassDriverBinding = { + VgaClassDriverBindingSupported, + VgaClassDriverBindingStart, + VgaClassDriverBindingStop, + 0x10, + NULL, + NULL +}; + +// +// Local variables +// +static CHAR16 CrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL }; + +typedef struct { + CHAR16 Unicode; + CHAR8 PcAnsi; + CHAR8 Ascii; +} UNICODE_TO_CHAR; + +// +// This list is used to define the valid extend chars. +// It also provides a mapping from Unicode to PCANSI or +// ASCII. The ASCII mapping we just made up. +// +// +STATIC UNICODE_TO_CHAR UnicodeToPcAnsiOrAscii[] = { + BOXDRAW_HORIZONTAL, + 0xc4, + L'-', + BOXDRAW_VERTICAL, + 0xb3, + L'|', + BOXDRAW_DOWN_RIGHT, + 0xda, + L'/', + BOXDRAW_DOWN_LEFT, + 0xbf, + L'\\', + BOXDRAW_UP_RIGHT, + 0xc0, + L'\\', + BOXDRAW_UP_LEFT, + 0xd9, + L'/', + BOXDRAW_VERTICAL_RIGHT, + 0xc3, + L'|', + BOXDRAW_VERTICAL_LEFT, + 0xb4, + L'|', + BOXDRAW_DOWN_HORIZONTAL, + 0xc2, + L'+', + BOXDRAW_UP_HORIZONTAL, + 0xc1, + L'+', + BOXDRAW_VERTICAL_HORIZONTAL, + 0xc5, + L'+', + BOXDRAW_DOUBLE_HORIZONTAL, + 0xcd, + L'-', + BOXDRAW_DOUBLE_VERTICAL, + 0xba, + L'|', + BOXDRAW_DOWN_RIGHT_DOUBLE, + 0xd5, + L'/', + BOXDRAW_DOWN_DOUBLE_RIGHT, + 0xd6, + L'/', + BOXDRAW_DOUBLE_DOWN_RIGHT, + 0xc9, + L'/', + BOXDRAW_DOWN_LEFT_DOUBLE, + 0xb8, + L'\\', + BOXDRAW_DOWN_DOUBLE_LEFT, + 0xb7, + L'\\', + BOXDRAW_DOUBLE_DOWN_LEFT, + 0xbb, + L'\\', + BOXDRAW_UP_RIGHT_DOUBLE, + 0xd4, + L'\\', + BOXDRAW_UP_DOUBLE_RIGHT, + 0xd3, + L'\\', + BOXDRAW_DOUBLE_UP_RIGHT, + 0xc8, + L'\\', + BOXDRAW_UP_LEFT_DOUBLE, + 0xbe, + L'/', + BOXDRAW_UP_DOUBLE_LEFT, + 0xbd, + L'/', + BOXDRAW_DOUBLE_UP_LEFT, + 0xbc, + L'/', + BOXDRAW_VERTICAL_RIGHT_DOUBLE, + 0xc6, + L'|', + BOXDRAW_VERTICAL_DOUBLE_RIGHT, + 0xc7, + L'|', + BOXDRAW_DOUBLE_VERTICAL_RIGHT, + 0xcc, + L'|', + BOXDRAW_VERTICAL_LEFT_DOUBLE, + 0xb5, + L'|', + BOXDRAW_VERTICAL_DOUBLE_LEFT, + 0xb6, + L'|', + BOXDRAW_DOUBLE_VERTICAL_LEFT, + 0xb9, + L'|', + BOXDRAW_DOWN_HORIZONTAL_DOUBLE, + 0xd1, + L'+', + BOXDRAW_DOWN_DOUBLE_HORIZONTAL, + 0xd2, + L'+', + BOXDRAW_DOUBLE_DOWN_HORIZONTAL, + 0xcb, + L'+', + BOXDRAW_UP_HORIZONTAL_DOUBLE, + 0xcf, + L'+', + BOXDRAW_UP_DOUBLE_HORIZONTAL, + 0xd0, + L'+', + BOXDRAW_DOUBLE_UP_HORIZONTAL, + 0xca, + L'+', + BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, + 0xd8, + L'+', + BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, + 0xd7, + L'+', + BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, + 0xce, + L'+', + + BLOCKELEMENT_FULL_BLOCK, + 0xdb, + L'*', + BLOCKELEMENT_LIGHT_SHADE, + 0xb0, + L'+', + + GEOMETRICSHAPE_UP_TRIANGLE, + 0x1e, + L'^', + GEOMETRICSHAPE_RIGHT_TRIANGLE, + 0x10, + L'>', + GEOMETRICSHAPE_DOWN_TRIANGLE, + 0x1f, + L'v', + GEOMETRICSHAPE_LEFT_TRIANGLE, + 0x11, + L'<', + + ARROW_LEFT, + 0x3c, + L'<', + + ARROW_UP, + 0x18, + L'^', + + ARROW_RIGHT, + 0x3e, + L'>', + + ARROW_DOWN, + 0x19, + L'v', + + 0x0000, + 0x00 +}; + +// +// Private worker functions +// +STATIC +VOID +SetVideoCursorPosition ( + IN VGA_CLASS_DEV *VgaClassDev, + IN UINTN Column, + IN UINTN Row, + IN UINTN MaxColumn + ); + +STATIC +VOID +WriteCrtc ( + IN VGA_CLASS_DEV *VgaClassDev, + IN UINT16 Address, + IN UINT8 Data + ); + +STATIC +BOOLEAN +LibIsValidTextGraphics ( + IN CHAR16 Graphic, + OUT CHAR8 *PcAnsi, OPTIONAL + OUT CHAR8 *Ascii OPTIONAL + ); + +STATIC +BOOLEAN +IsValidAscii ( + IN CHAR16 Ascii + ); + +STATIC +BOOLEAN +IsValidEfiCntlChar ( + IN CHAR16 c + ); + +// +// Driver Entry Point +// +EFI_DRIVER_ENTRY_POINT (VgaClassDriverEntryPoint) + +EFI_STATUS +EFIAPI +VgaClassDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + + Routine Description: + + Driver Entry Point. + + Arguments: + + (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT) + + Returns: + EFI_STATUS +--*/ +// GC_TODO: ImageHandle - add argument and description to function comment +// GC_TODO: SystemTable - add argument and description to function comment +{ + return INSTALL_ALL_DRIVER_PROTOCOLS ( + ImageHandle, + SystemTable, + &gVgaClassDriverBinding, + ImageHandle, +//*** AMI PORTING BEGIN ***// + NULL, +// &gVgaClassComponentName, +//*** AMI PORTING END *****// + NULL, + NULL + ); +} + +EFI_STATUS +EFIAPI +VgaClassDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + + Routine Description: + + Supported. + + Arguments: + + (Standard DriverBinding Protocol Supported() function) + + Returns: + + EFI_STATUS + +--*/ +// GC_TODO: This - add argument and description to function comment +// GC_TODO: Controller - add argument and description to function comment +// GC_TODO: RemainingDevicePath - add argument and description to function comment +{ + EFI_STATUS Status; + EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort; + + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiVgaMiniPortProtocolGuid, + (VOID **) &VgaMiniPort, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + NULL, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return Status; +} + +EFI_STATUS +EFIAPI +VgaClassDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + + Routine Description: + + Layers the Simple Text Output Protocol on top of the + VGA Mini Port Protocol + + Arguments: + + (Standard DriverBinding Protocol Start() function) + + Returns: + + EFI_STATUS + +--*/ +// GC_TODO: This - add argument and description to function comment +// GC_TODO: Controller - add argument and description to function comment +// GC_TODO: RemainingDevicePath - add argument and description to function comment +// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +{ + EFI_STATUS Status; + EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort; + EFI_PCI_IO_PROTOCOL *PciIo; + VGA_CLASS_DEV *VgaClassPrivate; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + Status = gBS->HandleProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + &DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Report that VGA Class driver is being enabled + // + ReportStatusCodeWithDevicePath ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_ENABLE, + 0, + &gEfiCallerIdGuid, + DevicePath + ); + + // + // Open the IO Abstraction(s) needed + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->OpenProtocol ( + Controller, + &gEfiVgaMiniPortProtocolGuid, + (VOID **) &VgaMiniPort, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Allocate the private device structure + // + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (VGA_CLASS_DEV), + &VgaClassPrivate + ); + if (EFI_ERROR (Status)) { + gBS->CloseProtocol ( + Controller, + &gEfiVgaMiniPortProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return EFI_OUT_OF_RESOURCES; + } + + EfiZeroMem (VgaClassPrivate, sizeof (VGA_CLASS_DEV)); + + // + // Initialize the private device structure + // + VgaClassPrivate->Signature = VGA_CLASS_DEV_SIGNATURE; + VgaClassPrivate->Handle = Controller; + VgaClassPrivate->VgaMiniPort = VgaMiniPort; + VgaClassPrivate->PciIo = PciIo; + + VgaClassPrivate->SimpleTextOut.Reset = VgaClassReset; + VgaClassPrivate->SimpleTextOut.OutputString = VgaClassOutputString; + VgaClassPrivate->SimpleTextOut.TestString = VgaClassTestString; + VgaClassPrivate->SimpleTextOut.ClearScreen = VgaClassClearScreen; + VgaClassPrivate->SimpleTextOut.SetAttribute = VgaClassSetAttribute; + VgaClassPrivate->SimpleTextOut.SetCursorPosition = VgaClassSetCursorPosition; + VgaClassPrivate->SimpleTextOut.EnableCursor = VgaClassEnableCursor; + VgaClassPrivate->SimpleTextOut.QueryMode = VgaClassQueryMode; + VgaClassPrivate->SimpleTextOut.SetMode = VgaClassSetMode; + + VgaClassPrivate->SimpleTextOut.Mode = &VgaClassPrivate->SimpleTextOutputMode; + VgaClassPrivate->SimpleTextOutputMode.MaxMode = VgaMiniPort->MaxMode; + VgaClassPrivate->DevicePath = DevicePath; + + Status = VgaClassPrivate->SimpleTextOut.SetAttribute ( + &VgaClassPrivate->SimpleTextOut, + EFI_TEXT_ATTR (EFI_WHITE, + EFI_BLACK) + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + Status = VgaClassPrivate->SimpleTextOut.Reset ( + &VgaClassPrivate->SimpleTextOut, + FALSE + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + Status = VgaClassPrivate->SimpleTextOut.EnableCursor ( + &VgaClassPrivate->SimpleTextOut, + TRUE + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + Status = gBS->InstallMultipleProtocolInterfaces ( + &Controller, + &gEfiSimpleTextOutProtocolGuid, + &VgaClassPrivate->SimpleTextOut, + NULL + ); + + return Status; + +ErrorExit: + ReportStatusCodeWithDevicePath ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR, + 0, + &gEfiCallerIdGuid, + DevicePath + ); + + return Status; + +} + +EFI_STATUS +EFIAPI +VgaClassDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +/*++ + + Routine Description: + + Stop. + + Arguments: + + (Standard DriverBinding Protocol Stop() function) + + Returns: + + EFI_STATUS + +--*/ +// GC_TODO: This - add argument and description to function comment +// GC_TODO: Controller - add argument and description to function comment +// GC_TODO: NumberOfChildren - add argument and description to function comment +// GC_TODO: ChildHandleBuffer - add argument and description to function comment +// GC_TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_STATUS Status; + EFI_SIMPLE_TEXT_OUT_PROTOCOL *SimpleTextOut; + VGA_CLASS_DEV *VgaClassPrivate; + + Status = gBS->OpenProtocol ( + Controller, + &gEfiSimpleTextOutProtocolGuid, + (VOID **) &SimpleTextOut, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + VgaClassPrivate = VGA_CLASS_DEV_FROM_THIS (SimpleTextOut); + + // + // Report that VGA Class driver is being disabled + // + ReportStatusCodeWithDevicePath ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_DISABLE, + 0, + &gEfiCallerIdGuid, + VgaClassPrivate->DevicePath + ); + + Status = gBS->UninstallProtocolInterface ( + Controller, + &gEfiSimpleTextOutProtocolGuid, + &VgaClassPrivate->SimpleTextOut + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Release PCI I/O and VGA Mini Port Protocols on the controller handle. + // + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + gBS->CloseProtocol ( + Controller, + &gEfiVgaMiniPortProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + gBS->FreePool (VgaClassPrivate); + + return EFI_SUCCESS; +} +// +// Simple Text Output Protocol Functions +// +EFI_STATUS +EFIAPI +VgaClassReset ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + ExtendedVerification - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + EFI_STATUS Status; + VGA_CLASS_DEV *VgaClassPrivate; + + VgaClassPrivate = VGA_CLASS_DEV_FROM_THIS (This); + + ReportStatusCodeWithDevicePath ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_RESET, + 0, + &gEfiCallerIdGuid, + VgaClassPrivate->DevicePath + ); + + This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK)); + + Status = This->SetMode (This, 0); + if (EFI_ERROR (Status)) { + return Status; + } + + return This->ClearScreen (This); +} + +EFI_STATUS +EFIAPI +VgaClassOutputString ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN CHAR16 *WString + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + WString - GC_TODO: add argument description + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + EFI_STATUS Status; + VGA_CLASS_DEV *VgaClassDev; + EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode; + UINTN MaxColumn; + UINTN MaxRow; + CHAR16 *SavedWString; + UINT32 VideoChar; + CHAR8 GraphicChar; + + VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This); + + Mode = This->Mode; + + Status = This->QueryMode ( + This, + Mode->Mode, + &MaxColumn, + &MaxRow + ); + if (EFI_ERROR (Status)) { + return Status; + } + + SavedWString = WString; + for (; *WString != CHAR_NULL; WString++) { + + switch (*WString) { + case CHAR_BACKSPACE: + if (Mode->CursorColumn > 0) { + Mode->CursorColumn--; + } + break; + + case CHAR_LINEFEED: + if (Mode->CursorRow == (INT32) (MaxRow - 1)) { + // + // Scroll the screen by copying the contents + // of the VGA display up one line + // + VgaClassDev->PciIo->CopyMem ( + VgaClassDev->PciIo, + EfiPciIoWidthUint32, + VgaClassDev->VgaMiniPort->VgaMemoryBar, + VgaClassDev->VgaMiniPort->VgaMemoryOffset, + VgaClassDev->VgaMiniPort->VgaMemoryBar, + VgaClassDev->VgaMiniPort->VgaMemoryOffset + MaxColumn * 2, + ((MaxRow - 1) * MaxColumn) >> 1 + ); + + // + // Print Blank Line of spaces with the current color attributes + // + VideoChar = (Mode->Attribute << 8) | ' '; + VideoChar = (VideoChar << 16) | VideoChar; + VgaClassDev->PciIo->Mem.Write ( + VgaClassDev->PciIo, + EfiPciIoWidthFillUint32, + VgaClassDev->VgaMiniPort->VgaMemoryBar, + VgaClassDev->VgaMiniPort->VgaMemoryOffset + (MaxRow - 1) * MaxColumn * 2, + MaxColumn >> 1, + &VideoChar + ); + } + + if (Mode->CursorRow < (INT32) (MaxRow - 1)) { + Mode->CursorRow++; + } + break; + + case CHAR_CARRIAGE_RETURN: + Mode->CursorColumn = 0; + break; + + default: + if (!LibIsValidTextGraphics (*WString, &GraphicChar, NULL)) { + // + // Just convert to ASCII + // + GraphicChar = (CHAR8) *WString; + if (!IsValidAscii (GraphicChar)) { + // + // Keep the API from supporting PCANSI Graphics chars + // + GraphicChar = '?'; + } + } + + VideoChar = (Mode->Attribute << 8) | GraphicChar; + VgaClassDev->PciIo->Mem.Write ( + VgaClassDev->PciIo, + EfiPciIoWidthUint16, + VgaClassDev->VgaMiniPort->VgaMemoryBar, + VgaClassDev->VgaMiniPort->VgaMemoryOffset + ((Mode->CursorRow * MaxColumn + Mode->CursorColumn) * 2), + 1, + &VideoChar + ); + + if (Mode->CursorColumn >= (INT32) (MaxColumn - 1)) { + This->OutputString (This, CrLfString); + } else { + Mode->CursorColumn++; + } + break; + } + } + + SetVideoCursorPosition ( + VgaClassDev, + (UINTN) Mode->CursorColumn, + (UINTN) Mode->CursorRow, + MaxColumn + ); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +VgaClassTestString ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN CHAR16 *WString + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + WString - GC_TODO: add argument description + +Returns: + + EFI_UNSUPPORTED - GC_TODO: Add description for return value + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + while (*WString != 0x0000) { + if (!(IsValidAscii (*WString) || IsValidEfiCntlChar (*WString) || LibIsValidTextGraphics (*WString, NULL, NULL))) { + return EFI_UNSUPPORTED; + } + + WString++; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +VgaClassClearScreen ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + EFI_STATUS Status; + VGA_CLASS_DEV *VgaClassDev; + UINTN MaxRow; + UINTN MaxColumn; + UINT32 VideoChar; + + VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This); + + Status = This->QueryMode ( + This, + This->Mode->Mode, + &MaxColumn, + &MaxRow + ); + if (EFI_ERROR (Status)) { + return Status; + } + + VideoChar = (This->Mode->Attribute << 8) | ' '; + VideoChar = (VideoChar << 16) | VideoChar; + VgaClassDev->PciIo->Mem.Write ( + VgaClassDev->PciIo, + EfiPciIoWidthFillUint32, + VgaClassDev->VgaMiniPort->VgaMemoryBar, + VgaClassDev->VgaMiniPort->VgaMemoryOffset, + (MaxRow * MaxColumn) >> 1, + &VideoChar + ); + + This->SetCursorPosition (This, 0, 0); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +VgaClassSetAttribute ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN UINTN Attribute + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Attribute - GC_TODO: add argument description + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + EFI_UNSUPPORTED - GC_TODO: Add description for return value + +--*/ +{ +//*** AMI PORTING BEGIN ***// +// Comparison of unsigned value with zero +// if (Attribute >= 0 && Attribute <= EFI_MAX_ATTRIBUTE) { + if (Attribute <= EFI_MAX_ATTRIBUTE) { +//*** AMI PORTING END *****// + This->Mode->Attribute = (INT32) Attribute; + return EFI_SUCCESS; + } + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +VgaClassSetCursorPosition ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN UINTN Column, + IN UINTN Row + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Column - GC_TODO: add argument description + Row - GC_TODO: add argument description + +Returns: + + EFI_UNSUPPORTED - GC_TODO: Add description for return value + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + EFI_STATUS Status; + VGA_CLASS_DEV *VgaClassDev; + UINTN MaxColumn; + UINTN MaxRow; + + VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This); + + Status = This->QueryMode ( + This, + This->Mode->Mode, + &MaxColumn, + &MaxRow + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Column >= MaxColumn || Row >= MaxRow) { + return EFI_UNSUPPORTED; + } + + SetVideoCursorPosition (VgaClassDev, Column, Row, MaxColumn); + + This->Mode->CursorColumn = (INT32) Column; + This->Mode->CursorRow = (INT32) Row; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +VgaClassEnableCursor ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN BOOLEAN Visible + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Visible - GC_TODO: add argument description + +Returns: + + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + VGA_CLASS_DEV *VgaClassDev; + + VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This); + if (Visible) { + switch (This->Mode->Mode) { + case 1: + WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x06); + WriteCrtc (VgaClassDev, CRTC_CURSOR_END, 0x07); + break; + + default: + WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x0e); + WriteCrtc (VgaClassDev, CRTC_CURSOR_END, 0x0f); + break; + } + } else { + WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x20); + } + + This->Mode->CursorVisible = Visible; + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +VgaClassQueryMode ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN UINTN ModeNumber, + OUT UINTN *Columns, + OUT UINTN *Rows + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + ModeNumber - GC_TODO: add argument description + Columns - GC_TODO: add argument description + Rows - GC_TODO: add argument description + +Returns: + + EFI_UNSUPPORTED - GC_TODO: Add description for return value + EFI_UNSUPPORTED - GC_TODO: Add description for return value + EFI_SUCCESS - GC_TODO: Add description for return value + +--*/ +{ + VGA_CLASS_DEV *VgaClassDev; + + VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This); + + if ((INT32) ModeNumber >= This->Mode->MaxMode) { + *Columns = 0; + *Rows = 0; + return EFI_UNSUPPORTED; + } + + switch (ModeNumber) { + case 0: + *Columns = 80; + *Rows = 25; + break; + + case 1: + *Columns = 80; + *Rows = 50; + break; + + default: + *Columns = 0; + *Rows = 0; + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +VgaClassSetMode ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN UINTN ModeNumber + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + ModeNumber - GC_TODO: add argument description + +Returns: + + EFI_UNSUPPORTED - GC_TODO: Add description for return value + +--*/ +{ + EFI_STATUS Status; + VGA_CLASS_DEV *VgaClassDev; + + VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This); + + if ((INT32) ModeNumber >= This->Mode->MaxMode) { + return EFI_UNSUPPORTED; + } + + This->ClearScreen (This); + + This->Mode->Mode = (INT32) ModeNumber; + + Status = VgaClassDev->VgaMiniPort->SetMode (VgaClassDev->VgaMiniPort, ModeNumber); + + return Status; +} +// +// Private Worker Functions +// +STATIC +VOID +SetVideoCursorPosition ( + IN VGA_CLASS_DEV *VgaClassDev, + IN UINTN Column, + IN UINTN Row, + IN UINTN MaxColumn + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + VgaClassDev - GC_TODO: add argument description + Column - GC_TODO: add argument description + Row - GC_TODO: add argument description + MaxColumn - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + Column = Column & 0xff; + Row = Row & 0xff; + MaxColumn = MaxColumn & 0xff; + WriteCrtc ( + VgaClassDev, + CRTC_CURSOR_LOCATION_HIGH, + (UINT8) ((Row * MaxColumn + Column) >> 8) + ); + WriteCrtc ( + VgaClassDev, + CRTC_CURSOR_LOCATION_LOW, + (UINT8) ((Row * MaxColumn + Column) & 0xff) + ); +} + +STATIC +VOID +WriteCrtc ( + IN VGA_CLASS_DEV *VgaClassDev, + IN UINT16 Address, + IN UINT8 Data + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + VgaClassDev - GC_TODO: add argument description + Address - GC_TODO: add argument description + Data - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + VgaClassDev->PciIo->Io.Write ( + VgaClassDev->PciIo, + EfiPciIoWidthUint8, + VgaClassDev->VgaMiniPort->CrtcAddressRegisterBar, + VgaClassDev->VgaMiniPort->CrtcAddressRegisterOffset, + 1, + &Address + ); + + VgaClassDev->PciIo->Io.Write ( + VgaClassDev->PciIo, + EfiPciIoWidthUint8, + VgaClassDev->VgaMiniPort->CrtcDataRegisterBar, + VgaClassDev->VgaMiniPort->CrtcDataRegisterOffset, + 1, + &Data + ); +} + +STATIC +BOOLEAN +LibIsValidTextGraphics ( + IN CHAR16 Graphic, + OUT CHAR8 *PcAnsi, OPTIONAL + OUT CHAR8 *Ascii OPTIONAL + ) +/*++ + +Routine Description: + + Detects if a Unicode char is for Box Drawing text graphics. + +Arguments: + + Grphic - Unicode char to test. + + PcAnsi - Optional pointer to return PCANSI equivalent of Graphic. + + Asci - Optional pointer to return Ascii equivalent of Graphic. + +Returns: + + TRUE if Gpaphic is a supported Unicode Box Drawing character. + +--*/ +// GC_TODO: Graphic - add argument and description to function comment +{ + UNICODE_TO_CHAR *Table; + + if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) { + // + // Unicode drawing code charts are all in the 0x25xx range, + // arrows are 0x21xx + // + return FALSE; + } + + for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) { + if (Graphic == Table->Unicode) { + if (PcAnsi) { + *PcAnsi = Table->PcAnsi; + } + + if (Ascii) { + *Ascii = Table->Ascii; + } + + return TRUE; + } + } + + return FALSE; +} + +STATIC +BOOLEAN +IsValidAscii ( + IN CHAR16 Ascii + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Ascii - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + if ((Ascii >= 0x20) && (Ascii <= 0x7f)) { + return TRUE; + } + + return FALSE; +} + +STATIC +BOOLEAN +IsValidEfiCntlChar ( + IN CHAR16 c + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + c - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + if (c == CHAR_NULL || c == CHAR_BACKSPACE || c == CHAR_LINEFEED || c == CHAR_CARRIAGE_RETURN) { + return TRUE; + } + + return FALSE; +} +//*** AMI PORTING BEGIN ***// +#endif //if INT10_SIMPLE_TEXT_SUPPORT==1 +//*** AMI PORTING END *****//
\ No newline at end of file diff --git a/Core/EM/CSM/thunk/CsmVideo/VgaClass.h b/Core/EM/CSM/thunk/CsmVideo/VgaClass.h new file mode 100644 index 0000000..fd184de --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/VgaClass.h @@ -0,0 +1,418 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +// +// This file contains a 'Sample Driver' and is licensed as such +// under the terms of your license agreement with Intel or your +// vendor. This file may be modified by the user, subject to +// the additional terms of the license agreement +// +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + + +Module Name: + + VgaClass.h + +Abstract: + + +Revision History +--*/ + +#ifndef _VGA_CLASS_H +#define _VGA_CLASS_H + +//*** AMI PORTING BEGIN ***// +#include "AmiMapping.h" +//#include "Tiano.h" +//#include "EfiDriverLib.h" +//*** AMI PORTING END *****// +#include "Pci22.h" +//*** AMI PORTING BEGIN ***// +//#include "EfiStatusCode.h" +//#include "EfiCompNameSupport.h" +//#include "ComponentName.h" +//*** AMI PORTING END *****// + +// +// Driver Consumed Protocol Prototypes +// +#include EFI_PROTOCOL_DEFINITION (DevicePath) +#include EFI_PROTOCOL_DEFINITION (PciIo) +//*** AMI PORTING BEGIN ***// +//#include EFI_PROTOCOL_DEFINITION (VgaMiniPort) +#include "VgaMiniPort.h" +//*** AMI PORTING END *****// +#include EFI_PROTOCOL_DEFINITION (SimpleTextIn) +//*** AMI PORTING BEGIN ***// +//#include EFI_GUID_DEFINITION (StatusCodeCallerId) +//#include EFI_GUID_DEFINITION (StatusCodeDataTypeId) +//*** AMI PORTING END *****// + +// +// Driver Produced Protocol Prototypes +// +#include EFI_PROTOCOL_DEFINITION (DriverBinding) +#include EFI_PROTOCOL_DEFINITION (SimpleTextOut) + +// +// VGA specific registers +// +#define CRTC_CURSOR_START 0xA +#define CRTC_CURSOR_END 0xB + +#define CRTC_CURSOR_LOCATION_HIGH 0xE +#define CRTC_CURSOR_LOCATION_LOW 0xF + +#define EFI_MAX_ATTRIBUTE 0x7f + +// +// VGA Class Device Structure +// +#define VGA_CLASS_DEV_SIGNATURE EFI_SIGNATURE_32 ('V', 'G', 'A', 'C') + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + EFI_SIMPLE_TEXT_OUT_PROTOCOL SimpleTextOut; + EFI_SIMPLE_TEXT_OUTPUT_MODE SimpleTextOutputMode; + EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; +} VGA_CLASS_DEV; + +#define VGA_CLASS_DEV_FROM_THIS(a) CR (a, VGA_CLASS_DEV, SimpleTextOut, VGA_CLASS_DEV_SIGNATURE) + +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gVgaClassDriverBinding; + +// +// Driver Binding Protocol functions +// +EFI_STATUS +EFIAPI +VgaClassDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Controller - GC_TODO: add argument description + RemainingDevicePath - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +VgaClassDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Controller - GC_TODO: add argument description + RemainingDevicePath - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +VgaClassDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Controller - GC_TODO: add argument description + NumberOfChildren - GC_TODO: add argument description + ChildHandleBuffer - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +// +// Simple Text Output Protocol functions +// +EFI_STATUS +EFIAPI +VgaClassReset ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + ExtendedVerification - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +VgaClassOutputString ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN CHAR16 *WString + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + WString - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +VgaClassTestString ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN CHAR16 *WString + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + WString - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +VgaClassClearScreen ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +VgaClassSetAttribute ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN UINTN Attribute + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Attribute - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +VgaClassSetCursorPosition ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN UINTN Column, + IN UINTN Row + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Column - GC_TODO: add argument description + Row - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +VgaClassEnableCursor ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN BOOLEAN Visible + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + Visible - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +VgaClassQueryMode ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN UINTN ModeNumber, + OUT UINTN *Columns, + OUT UINTN *Rows + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + ModeNumber - GC_TODO: add argument description + Columns - GC_TODO: add argument description + Rows - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +VgaClassSetMode ( + IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, + IN UINTN ModeNumber + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + This - GC_TODO: add argument description + ModeNumber - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +#endif diff --git a/Core/EM/CSM/thunk/CsmVideo/VgaMiniPort.h b/Core/EM/CSM/thunk/CsmVideo/VgaMiniPort.h new file mode 100644 index 0000000..e21a894 --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/VgaMiniPort.h @@ -0,0 +1,78 @@ +// +// This file contains 'Framework Code' and is licensed as such +// under the terms of your license agreement with Intel or your +// vendor. This file may not be modified, except as allowed by +// additional terms of your license agreement. +// +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + + +Module Name: + + VgaMiniPort.h + +Abstract: + + Vga Mini port binding for a VGA controller + +Revision History + +--*/ + +#ifndef _VGA_MINI_PORT_H +#define _VGA_MINI_PORT_H + +#define EFI_VGA_MINI_PORT_PROTOCOL_GUID \ + { \ + 0xc7735a2f, 0x88f5, 0x4882, 0xae, 0x63, 0xfa, 0xac, 0x8c, 0x8b, 0x86, 0xb3 \ + } + +EFI_FORWARD_DECLARATION (EFI_VGA_MINI_PORT_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_VGA_MINI_PORT_SET_MODE) ( + IN EFI_VGA_MINI_PORT_PROTOCOL * This, + IN UINTN ModeNumber + ); + +/*++ + + Routine Description: + Sets the text display mode of a VGA controller + + Arguments: + This - Protocol instance pointer. + Mode - Mode number. 0 - 80x25 1-80x50 + + Returns: + EFI_SUCCESS - The mode was set + EFI_DEVICE_ERROR - The device is not functioning properly. + +--*/ +typedef struct _EFI_VGA_MINI_PORT_PROTOCOL { + EFI_VGA_MINI_PORT_SET_MODE SetMode; + + UINT64 VgaMemoryOffset; + UINT64 CrtcAddressRegisterOffset; + UINT64 CrtcDataRegisterOffset; + + UINT8 VgaMemoryBar; + UINT8 CrtcAddressRegisterBar; + UINT8 CrtcDataRegisterBar; + + UINT8 MaxMode; +} EFI_VGA_MINI_PORT_PROTOCOL; + +extern EFI_GUID gEfiVgaMiniPortProtocolGuid; + +#endif diff --git a/Core/EM/CSM/thunk/CsmVideo/pci22.h b/Core/EM/CSM/thunk/CsmVideo/pci22.h new file mode 100644 index 0000000..1c8ccd0 --- /dev/null +++ b/Core/EM/CSM/thunk/CsmVideo/pci22.h @@ -0,0 +1,621 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2013, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +/*++ + +Copyright (c) 2004 - 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. + +Module Name: + + pci22.h + +Abstract: + Support for PCI 2.2 standard. + +Revision History + +--*/ + +#ifndef _PCI22_H +#define _PCI22_H + +#define PCI_MAX_SEGMENT 0 + +#define PCI_MAX_BUS 255 + +#define PCI_MAX_DEVICE 31 +#define PCI_MAX_FUNC 7 + +// +// Command +// +#define PCI_VGA_PALETTE_SNOOP_DISABLED 0x20 + +#pragma pack(push, 1) +typedef struct { + UINT16 VendorId; + UINT16 DeviceId; + UINT16 Command; + UINT16 Status; + UINT8 RevisionID; + UINT8 ClassCode[3]; + UINT8 CacheLineSize; + UINT8 LatencyTimer; + UINT8 HeaderType; + UINT8 BIST; +} PCI_DEVICE_INDEPENDENT_REGION; + +typedef struct { + UINT32 Bar[6]; + UINT32 CISPtr; + UINT16 SubsystemVendorID; + UINT16 SubsystemID; + UINT32 ExpansionRomBar; + UINT8 CapabilityPtr; + UINT8 Reserved1[3]; + UINT32 Reserved2; + UINT8 InterruptLine; + UINT8 InterruptPin; + UINT8 MinGnt; + UINT8 MaxLat; +} PCI_DEVICE_HEADER_TYPE_REGION; + +typedef struct { + PCI_DEVICE_INDEPENDENT_REGION Hdr; + PCI_DEVICE_HEADER_TYPE_REGION Device; +} PCI_TYPE00; + +typedef struct { + UINT32 Bar[2]; + UINT8 PrimaryBus; + UINT8 SecondaryBus; + UINT8 SubordinateBus; + UINT8 SecondaryLatencyTimer; + UINT8 IoBase; + UINT8 IoLimit; + UINT16 SecondaryStatus; + UINT16 MemoryBase; + UINT16 MemoryLimit; + UINT16 PrefetchableMemoryBase; + UINT16 PrefetchableMemoryLimit; + UINT32 PrefetchableBaseUpper32; + UINT32 PrefetchableLimitUpper32; + UINT16 IoBaseUpper16; + UINT16 IoLimitUpper16; + UINT8 CapabilityPtr; + UINT8 Reserved[3]; + UINT32 ExpansionRomBAR; + UINT8 InterruptLine; + UINT8 InterruptPin; + UINT16 BridgeControl; +} PCI_BRIDGE_CONTROL_REGISTER; + +typedef struct { + PCI_DEVICE_INDEPENDENT_REGION Hdr; + PCI_BRIDGE_CONTROL_REGISTER Bridge; +} PCI_TYPE01; + +typedef union { + PCI_TYPE00 Device; + PCI_TYPE01 Bridge; +} PCI_TYPE_GENERIC; + +typedef struct { + UINT32 CardBusSocketReg; // Cardus Socket/ExCA Base + // Address Register + // + UINT16 Reserved; + UINT16 SecondaryStatus; // Secondary Status + UINT8 PciBusNumber; // PCI Bus Number + UINT8 CardBusBusNumber; // CardBus Bus Number + UINT8 SubordinateBusNumber; // Subordinate Bus Number + UINT8 CardBusLatencyTimer; // CardBus Latency Timer + UINT32 MemoryBase0; // Memory Base Register 0 + UINT32 MemoryLimit0; // Memory Limit Register 0 + UINT32 MemoryBase1; + UINT32 MemoryLimit1; + UINT32 IoBase0; + UINT32 IoLimit0; // I/O Base Register 0 + UINT32 IoBase1; // I/O Limit Register 0 + UINT32 IoLimit1; + UINT8 InterruptLine; // Interrupt Line + UINT8 InterruptPin; // Interrupt Pin + UINT16 BridgeControl; // Bridge Control +} PCI_CARDBUS_CONTROL_REGISTER; + +// +// Definitions of PCI class bytes and manipulation macros. +// +#define PCI_CLASS_OLD 0x00 +#define PCI_CLASS_OLD_OTHER 0x00 +#define PCI_CLASS_OLD_VGA 0x01 + +#define PCI_CLASS_MASS_STORAGE 0x01 +#define PCI_CLASS_MASS_STORAGE_SCSI 0x00 +#define PCI_CLASS_MASS_STORAGE_IDE 0x01 // obsolete +#define PCI_CLASS_IDE 0x01 +#define PCI_CLASS_MASS_STORAGE_FLOPPY 0x02 +#define PCI_CLASS_MASS_STORAGE_IPI 0x03 +#define PCI_CLASS_MASS_STORAGE_RAID 0x04 +#define PCI_CLASS_MASS_STORAGE_OTHER 0x80 + +#define PCI_CLASS_NETWORK 0x02 +#define PCI_CLASS_NETWORK_ETHERNET 0x00 +#define PCI_CLASS_ETHERNET 0x00 // obsolete +#define PCI_CLASS_NETWORK_TOKENRING 0x01 +#define PCI_CLASS_NETWORK_FDDI 0x02 +#define PCI_CLASS_NETWORK_ATM 0x03 +#define PCI_CLASS_NETWORK_ISDN 0x04 +#define PCI_CLASS_NETWORK_OTHER 0x80 + +#define PCI_CLASS_DISPLAY 0x03 +#define PCI_CLASS_DISPLAY_CTRL 0x03 // obsolete +#define PCI_CLASS_DISPLAY_VGA 0x00 +#define PCI_CLASS_VGA 0x00 // obsolete +#define PCI_CLASS_DISPLAY_XGA 0x01 +#define PCI_CLASS_DISPLAY_3D 0x02 +#define PCI_CLASS_DISPLAY_OTHER 0x80 +#define PCI_CLASS_DISPLAY_GFX 0x80 +#define PCI_CLASS_GFX 0x80 // obsolete +#define PCI_CLASS_BRIDGE 0x06 +#define PCI_CLASS_BRIDGE_HOST 0x00 +#define PCI_CLASS_BRIDGE_ISA 0x01 +#define PCI_CLASS_ISA 0x01 // obsolete +#define PCI_CLASS_BRIDGE_EISA 0x02 +#define PCI_CLASS_BRIDGE_MCA 0x03 +#define PCI_CLASS_BRIDGE_P2P 0x04 +#define PCI_CLASS_BRIDGE_PCMCIA 0x05 +#define PCI_CLASS_BRIDGE_NUBUS 0x06 +#define PCI_CLASS_BRIDGE_CARDBUS 0x07 +#define PCI_CLASS_BRIDGE_RACEWAY 0x08 +#define PCI_CLASS_BRIDGE_ISA_PDECODE 0x80 +#define PCI_CLASS_ISA_POSITIVE_DECODE 0x80 // obsolete + +#define PCI_CLASS_SCC 0x07 // Simple communications controllers +#define PCI_SUBCLASS_SERIAL 0x00 +#define PCI_IF_GENERIC_XT 0x00 +#define PCI_IF_16450 0x01 +#define PCI_IF_16550 0x02 +#define PCI_IF_16650 0x03 +#define PCI_IF_16750 0x04 +#define PCI_IF_16850 0x05 +#define PCI_IF_16950 0x06 +#define PCI_SUBCLASS_PARALLEL 0x01 +#define PCI_IF_PARALLEL_PORT 0x00 +#define PCI_IF_BI_DIR_PARALLEL_PORT 0x01 +#define PCI_IF_ECP_PARALLEL_PORT 0x02 +#define PCI_IF_1284_CONTROLLER 0x03 +#define PCI_IF_1284_DEVICE 0xFE +#define PCI_SUBCLASS_MULTIPORT_SERIAL 0x02 +#define PCI_SUBCLASS_MODEM 0x03 +#define PCI_IF_GENERIC_MODEM 0x00 +#define PCI_IF_16450_MODEM 0x01 +#define PCI_IF_16550_MODEM 0x02 +#define PCI_IF_16650_MODEM 0x03 +#define PCI_IF_16750_MODEM 0x04 +#define PCI_SUBCLASS_OTHER 0x80 + +#define PCI_CLASS_SYSTEM_PERIPHERAL 0x08 +#define PCI_SUBCLASS_PIC 0x00 +#define PCI_IF_8259_PIC 0x00 +#define PCI_IF_ISA_PIC 0x01 +#define PCI_IF_EISA_PIC 0x02 +#define PCI_IF_APIC_CONTROLLER 0x10 // I/O APIC interrupt controller , 32 bye none-prefectable memory. +#define PCI_IF_APIC_CONTROLLER2 0x20 +#define PCI_SUBCLASS_TIMER 0x02 +#define PCI_IF_8254_TIMER 0x00 +#define PCI_IF_ISA_TIMER 0x01 +#define PCI_EISA_TIMER 0x02 +#define PCI_SUBCLASS_RTC 0x03 +#define PCI_IF_GENERIC_RTC 0x00 +#define PCI_IF_ISA_RTC 0x00 +#define PCI_SUBCLASS_PNP_CONTROLLER 0x04 // HotPlug Controller + +#define PCI_CLASS_INPUT_DEVICE 0x09 +#define PCI_SUBCLASS_KEYBOARD 0x00 +#define PCI_SUBCLASS_PEN 0x01 +#define PCI_SUBCLASS_MOUSE_CONTROLLER 0x02 +#define PCI_SUBCLASS_SCAN_CONTROLLER 0x03 +#define PCI_SUBCLASS_GAMEPORT 0x04 + +#define PCI_CLASS_DOCKING_STATION 0x0A + +#define PCI_CLASS_PROCESSOR 0x0B +#define PCI_SUBCLASS_PROC_386 0x00 +#define PCI_SUBCLASS_PROC_486 0x01 +#define PCI_SUBCLASS_PROC_PENTIUM 0x02 +#define PCI_SUBCLASS_PROC_ALPHA 0x10 +#define PCI_SUBCLASS_PROC_POWERPC 0x20 +#define PCI_SUBCLASS_PROC_MIPS 0x30 +#define PCI_SUBCLASS_PROC_CO_PORC 0x40 // Co-Processor + +#define PCI_CLASS_SERIAL 0x0C +#define PCI_CLASS_SERIAL_FIREWIRE 0x00 +#define PCI_CLASS_SERIAL_ACCESS_BUS 0x01 +#define PCI_CLASS_SERIAL_SSA 0x02 +#define PCI_CLASS_SERIAL_USB 0x03 +#define PCI_CLASS_SERIAL_FIBRECHANNEL 0x04 +#define PCI_CLASS_SERIAL_SMB 0x05 + +#define PCI_CLASS_WIRELESS 0x0D +#define PCI_SUBCLASS_IRDA 0x00 +#define PCI_SUBCLASS_IR 0x01 +#define PCI_SUBCLASS_RF 0x02 + +#define PCI_CLASS_INTELLIGENT_IO 0x0E + +#define PCI_CLASS_SATELLITE 0x0F +#define PCI_SUBCLASS_TV 0x01 +#define PCI_SUBCLASS_AUDIO 0x02 +#define PCI_SUBCLASS_VOICE 0x03 +#define PCI_SUBCLASS_DATA 0x04 + +#define PCI_SECURITY_CONTROLLER 0x10 // Encryption and decryption controller +#define PCI_SUBCLASS_NET_COMPUT 0x00 +#define PCI_SUBCLASS_ENTERTAINMENT 0x10 + +#define PCI_CLASS_DPIO 0x11 + +#define IS_CLASS1(_p, c) ((_p)->Hdr.ClassCode[2] == (c)) +#define IS_CLASS2(_p, c, s) (IS_CLASS1 (_p, c) && ((_p)->Hdr.ClassCode[1] == (s))) +#define IS_CLASS3(_p, c, s, p) (IS_CLASS2 (_p, c, s) && ((_p)->Hdr.ClassCode[0] == (p))) + +#define IS_PCI_DISPLAY(_p) IS_CLASS1 (_p, PCI_CLASS_DISPLAY) +#define IS_PCI_VGA(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 0) +#define IS_PCI_8514(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 1) +#define IS_PCI_GFX(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_GFX, 0) +#define IS_PCI_OLD(_p) IS_CLASS1 (_p, PCI_CLASS_OLD) +#define IS_PCI_OLD_VGA(_p) IS_CLASS2 (_p, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA) +#define IS_PCI_IDE(_p) IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_IDE) +#define IS_PCI_SCSI(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SCSI, 0) +#define IS_PCI_RAID(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_RAID, 0) +#define IS_PCI_LPC(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA, 0) +#define IS_PCI_P2P(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 0) +#define IS_PCI_P2P_SUB(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 1) +#define IS_PCI_USB(_p) IS_CLASS2 (_p, PCI_CLASS_SERIAL, PCI_CLASS_SERIAL_USB) + +#define HEADER_TYPE_DEVICE 0x00 +#define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01 +#define HEADER_TYPE_CARDBUS_BRIDGE 0x02 + +#define HEADER_TYPE_MULTI_FUNCTION 0x80 +#define HEADER_LAYOUT_CODE 0x7f + +#define IS_PCI_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_PCI_TO_PCI_BRIDGE)) +#define IS_CARDBUS_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE)) +#define IS_PCI_MULTI_FUNC(_p) ((_p)->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) + +#define PCI_DEVICE_ROMBAR 0x30 +#define PCI_BRIDGE_ROMBAR 0x38 + +#define PCI_MAX_BAR 0x0006 +#define PCI_MAX_CONFIG_OFFSET 0x0100 + +#define PCI_VENDOR_ID_OFFSET 0x00 +#define PCI_DEVICE_ID_OFFSET 0x02 +#define PCI_COMMAND_OFFSET 0x04 +#define PCI_PRIMARY_STATUS_OFFSET 0x06 +#define PCI_REVISION_ID_OFFSET 0x08 +#define PCI_CLASSCODE_OFFSET 0x09 +#define PCI_CACHELINE_SIZE_OFFSET 0x0C +#define PCI_LATENCY_TIMER_OFFSET 0x0D +#define PCI_HEADER_TYPE_OFFSET 0x0E +#define PCI_BIST_OFFSET 0x0F +#define PCI_BASE_ADDRESSREG_OFFSET 0x10 +#define PCI_CARDBUS_CIS_OFFSET 0x28 +#define PCI_SVID_OFFSET 0x2C // SubSystem Vendor id +#define PCI_SUBSYSTEM_VENDOR_ID_OFFSET 0x2C +#define PCI_SID_OFFSET 0x2E // SubSystem ID +#define PCI_SUBSYSTEM_ID_OFFSET 0x2E +#define PCI_EXPANSION_ROM_BASE 0x30 +#define PCI_CAPBILITY_POINTER_OFFSET 0x34 +#define PCI_INT_LINE_OFFSET 0x3C // Interrupt Line Register +#define PCI_INT_PIN_OFFSET 0x3D // Interrupt Pin Register +#define PCI_MAXGNT_OFFSET 0x3E // Max Grant Register +#define PCI_MAXLAT_OFFSET 0x3F // Max Latency Register + +#define PCI_BRIDGE_CONTROL_REGISTER_OFFSET 0x3E +#define PCI_BRIDGE_STATUS_REGISTER_OFFSET 0x1E + +#define PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET 0x18 +#define PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET 0x19 +#define PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET 0x1a + +typedef struct { + UINT32 Reg : 8; + UINT32 Func : 3; + UINT32 Dev : 5; + UINT32 Bus : 8; + UINT32 Reserved : 7; + UINT32 Enable : 1; +} PCI_CONFIG_ACCESS_CF8; + +#pragma pack() + +#define PCI_EXPANSION_ROM_HEADER_SIGNATURE 0xaa55 +#define PCI_DATA_STRUCTURE_SIGNATURE EFI_SIGNATURE_32 ('P', 'C', 'I', 'R') +#define PCI_CODE_TYPE_PCAT_IMAGE 0x00 +#define PCI_CODE_TYPE_EFI_IMAGE 0x03 +#define EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED 0x0001 + +#define EFI_PCI_COMMAND_IO_SPACE 0x0001 +#define EFI_PCI_COMMAND_MEMORY_SPACE 0x0002 +#define EFI_PCI_COMMAND_BUS_MASTER 0x0004 +#define EFI_PCI_COMMAND_SPECIAL_CYCLE 0x0008 +#define EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE 0x0010 +#define EFI_PCI_COMMAND_VGA_PALETTE_SNOOP 0x0020 +#define EFI_PCI_COMMAND_PARITY_ERROR_RESPOND 0x0040 +#define EFI_PCI_COMMAND_STEPPING_CONTROL 0x0080 +#define EFI_PCI_COMMAND_SERR 0x0100 +#define EFI_PCI_COMMAND_FAST_BACK_TO_BACK 0x0200 + +#define EFI_PCI_BRIDGE_CONTROL_PARITY_ERROR_RESPONSE 0x0001 +#define EFI_PCI_BRIDGE_CONTROL_SERR 0x0002 +#define EFI_PCI_BRIDGE_CONTROL_ISA 0x0004 +#define EFI_PCI_BRIDGE_CONTROL_VGA 0x0008 +#define EFI_PCI_BRIDGE_CONTROL_VGA_16 0x0010 +#define EFI_PCI_BRIDGE_CONTROL_MASTER_ABORT 0x0020 +#define EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS 0x0040 +#define EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK 0x0080 +#define EFI_PCI_BRIDGE_CONTROL_PRIMARY_DISCARD_TIMER 0x0100 +#define EFI_PCI_BRIDGE_CONTROL_SECONDARY_DISCARD_TIMER 0x0200 +#define EFI_PCI_BRIDGE_CONTROL_TIMER_STATUS 0x0400 +#define EFI_PCI_BRIDGE_CONTROL_DISCARD_TIMER_SERR 0x0800 + +// +// Following are the PCI-CARDBUS bridge control bit +// +#define EFI_PCI_BRIDGE_CONTROL_IREQINT_ENABLE 0x0080 +#define EFI_PCI_BRIDGE_CONTROL_RANGE0_MEMORY_TYPE 0x0100 +#define EFI_PCI_BRIDGE_CONTROL_RANGE1_MEMORY_TYPE 0x0200 +#define EFI_PCI_BRIDGE_CONTROL_WRITE_POSTING_ENABLE 0x0400 + +// +// Following are the PCI status control bit +// +#define EFI_PCI_STATUS_CAPABILITY 0x0010 +#define EFI_PCI_STATUS_66MZ_CAPABLE 0x0020 +#define EFI_PCI_FAST_BACK_TO_BACK_CAPABLE 0x0080 +#define EFI_PCI_MASTER_DATA_PARITY_ERROR 0x0100 + +#define EFI_PCI_CAPABILITY_PTR 0x34 +#define EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR 0x14 + +#pragma pack(1) +typedef struct { + UINT16 Signature; // 0xaa55 + UINT8 Reserved[0x16]; + UINT16 PcirOffset; +} PCI_EXPANSION_ROM_HEADER; + +typedef struct { + UINT16 Signature; // 0xaa55 + UINT8 Size512; + UINT8 InitEntryPoint[3]; + UINT8 Reserved[0x12]; + UINT16 PcirOffset; +} EFI_LEGACY_EXPANSION_ROM_HEADER; + +typedef struct { + UINT32 Signature; // "PCIR" + UINT16 VendorId; + UINT16 DeviceId; + UINT16 Reserved0; + UINT16 Length; + UINT8 Revision; + UINT8 ClassCode[3]; + UINT16 ImageLength; + UINT16 CodeRevision; + UINT8 CodeType; + UINT8 Indicator; + UINT16 Reserved1; +} PCI_DATA_STRUCTURE; + +// +// PCI Capability List IDs and records +// +#define EFI_PCI_CAPABILITY_ID_PMI 0x01 +#define EFI_PCI_CAPABILITY_ID_AGP 0x02 +#define EFI_PCI_CAPABILITY_ID_VPD 0x03 +#define EFI_PCI_CAPABILITY_ID_SLOTID 0x04 +#define EFI_PCI_CAPABILITY_ID_MSI 0x05 +#define EFI_PCI_CAPABILITY_ID_HOTPLUG 0x06 +#define EFI_PCI_CAPABILITY_ID_PCIX 0x07 + +typedef struct { + UINT8 CapabilityID; + UINT8 NextItemPtr; +} EFI_PCI_CAPABILITY_HDR; + +// +// Capability EFI_PCI_CAPABILITY_ID_PMI +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 PMC; + UINT16 PMCSR; + UINT8 BridgeExtention; + UINT8 Data; +} EFI_PCI_CAPABILITY_PMI; + +// +// Capability EFI_PCI_CAPABILITY_ID_AGP +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT8 Rev; + UINT8 Reserved; + UINT32 Status; + UINT32 Command; +} EFI_PCI_CAPABILITY_AGP; + +// +// Capability EFI_PCI_CAPABILITY_ID_VPD +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 AddrReg; + UINT32 DataReg; +} EFI_PCI_CAPABILITY_VPD; + +// +// Capability EFI_PCI_CAPABILITY_ID_SLOTID +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT8 ExpnsSlotReg; + UINT8 ChassisNo; +} EFI_PCI_CAPABILITY_SLOTID; + +// +// Capability EFI_PCI_CAPABILITY_ID_MSI +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 MsgCtrlReg; + UINT32 MsgAddrReg; + UINT16 MsgDataReg; +} EFI_PCI_CAPABILITY_MSI32; + +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 MsgCtrlReg; + UINT32 MsgAddrRegLsdw; + UINT32 MsgAddrRegMsdw; + UINT16 MsgDataReg; +} EFI_PCI_CAPABILITY_MSI64; + +// +// Capability EFI_PCI_CAPABILITY_ID_HOTPLUG +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + // + // not finished - fields need to go here + // +} EFI_PCI_CAPABILITY_HOTPLUG; + +// +// Capability EFI_PCI_CAPABILITY_ID_PCIX +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 CommandReg; + UINT32 StatusReg; +} EFI_PCI_CAPABILITY_PCIX; + +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 SecStatusReg; + UINT32 StatusReg; + UINT32 SplitTransCtrlRegUp; + UINT32 SplitTransCtrlRegDn; +} EFI_PCI_CAPABILITY_PCIX_BRDG; + +#define DEVICE_ID_NOCARE 0xFFFF + +#define PCI_ACPI_UNUSED 0 +#define PCI_BAR_NOCHANGE 0 +#define PCI_BAR_OLD_ALIGN 0xFFFFFFFFFFFFFFFF +#define PCI_BAR_EVEN_ALIGN 0xFFFFFFFFFFFFFFFE +#define PCI_BAR_SQUAD_ALIGN 0xFFFFFFFFFFFFFFFD +#define PCI_BAR_DQUAD_ALIGN 0xFFFFFFFFFFFFFFFC + +#define PCI_BAR_IDX0 0x00 +#define PCI_BAR_IDX1 0x01 +#define PCI_BAR_IDX2 0x02 +#define PCI_BAR_IDX3 0x03 +#define PCI_BAR_IDX4 0x04 +#define PCI_BAR_IDX5 0x05 +#define PCI_BAR_ALL 0xFF + +#pragma pack(pop) + +// +// NOTE: The following header files are included here for +// compatibility consideration. +// +//*** AMI PORTING BEGIN ***// +//Include content +//#include "pci23.h" +#define PCI_EXP_MAX_CONFIG_OFFSET 0x1000 +#define EFI_PCI_CAPABILITY_ID_PCIEXP 0x10 + +//#include "pci30.h" +#define PCI_CLASS_MASS_STORAGE_SATADPA 0x06 + +#pragma pack(push, 1) + +typedef struct { + UINT32 Signature; // "PCIR" + UINT16 VendorId; + UINT16 DeviceId; + UINT16 DeviceListOffset; + UINT16 Length; + UINT8 Revision; + UINT8 ClassCode[3]; + UINT16 ImageLength; + UINT16 CodeRevision; + UINT8 CodeType; + UINT8 Indicator; + UINT16 MaxRuntimeImageLength; + UINT16 ConfigUtilityCodeHeaderOffset; + UINT16 DMTFCLPEntryPointOffset; +} PCI_3_0_DATA_STRUCTURE; + +#pragma pack(pop) + +//#include "EfiPci.h" +#pragma pack(push, 1) + +typedef struct { + UINT8 Register; + UINT8 Function; + UINT8 Device; + UINT8 Bus; + UINT8 Reserved[4]; +} DEFIO_PCI_ADDR; + +#define EFI_ROOT_BRIDGE_LIST 'eprb' +#define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE 0x0EF1 + +typedef struct { + UINT16 Signature; // 0xaa55 + UINT16 InitializationSize; + UINT32 EfiSignature; // 0x0EF1 + UINT16 EfiSubsystem; + UINT16 EfiMachineType; + UINT16 CompressionType; + UINT8 Reserved[8]; + UINT16 EfiImageHeaderOffset; + UINT16 PcirOffset; +} EFI_PCI_EXPANSION_ROM_HEADER; + +typedef union { + UINT8 *Raw; + PCI_EXPANSION_ROM_HEADER *Generic; + EFI_PCI_EXPANSION_ROM_HEADER *Efi; + EFI_LEGACY_EXPANSION_ROM_HEADER *PcAt; +} EFI_PCI_ROM_HEADER; + +#pragma pack(pop) +//*** AMI PORTING END *****// +#endif |