summaryrefslogtreecommitdiff
path: root/Core/CORE_DXE/ConSplitter
diff options
context:
space:
mode:
Diffstat (limited to 'Core/CORE_DXE/ConSplitter')
-rw-r--r--Core/CORE_DXE/ConSplitter/ConSplit.c2387
-rw-r--r--Core/CORE_DXE/ConSplitter/ConSplit.h553
-rw-r--r--Core/CORE_DXE/ConSplitter/ConSplitter.cif12
-rw-r--r--Core/CORE_DXE/ConSplitter/ConSplitter.sdl26
-rw-r--r--Core/CORE_DXE/ConSplitter/In.c1159
-rw-r--r--Core/CORE_DXE/ConSplitter/Out.c1323
6 files changed, 5460 insertions, 0 deletions
diff --git a/Core/CORE_DXE/ConSplitter/ConSplit.c b/Core/CORE_DXE/ConSplitter/ConSplit.c
new file mode 100644
index 0000000..6963438
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/ConSplit.c
@@ -0,0 +1,2387 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/ConSplit.c 7 8/28/13 10:44p Thomaschen $
+//
+// $Revision: 7 $
+//
+// $Date: 8/28/13 10:44p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/ConSplit.c $
+//
+// 7 8/28/13 10:44p Thomaschen
+// Fixed for EIP133747.
+//
+// 6 8/01/13 2:32a Thomaschen
+// Add for EIP109384.
+// [Files] ConSplit.c, ConSplit.h, In.c, CsmSimpleIn.c.
+//
+// 5 6/26/13 3:09a Thomaschen
+// Remove EIP109384.
+//
+// 3 6/04/13 1:55a Thomaschen
+// Fixed for EIP118202.
+//
+// 2 11/15/12 9:53p Wesleychen
+// Update to rev.55 for EIP103887.
+//
+// 55 10/29/12 3:44p Artems
+// [TAG] EIP103887
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Upgrade Serial Redirection to 4.6.3_Terminal_51 with Core
+// 4654, system will hang 0x06.
+// [RootCause] Uninitialized variable was used
+// [Solution] Initialize DeviceModeNumber variable before using
+// [Files] ConSplit.c
+//
+// 54 10/25/12 2:31a Deepthins
+// [TAG] EIP99475
+// [Category] Improvement
+// [Description] Multi language module Support in the console splitter
+// [Files] ConSplit.c, ConSplit.h , In.c and AmiKeycode.h
+//
+// 53 10/08/12 4:28p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] system boots in wrong text mode
+// [RootCause] Incorrect restore of graphics mode after legacy OPROM
+// execution
+// [Solution] Added code for correct restoration of system state after
+// execution of Consplit.stop function
+// [Files] Consplit.c
+//
+// 52 8/13/12 3:39p Artems
+// [TAG] EIP95607
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Execute nsh script and redirect output to file, then exit
+// from shell, setup screen will crash
+// [RootCause] Console splitter maintains global pool of supportedmodes.
+// It's getting adjusted every time new SimpleTextOut (STO) is installed
+// If new STO doesn't support particular mode it is getting marked as
+// unsupported in global pool
+// However once this STO is uninstalled global pool isn't updated, so mode
+// is still marked as unsupported,
+// though system can support it
+// [Solution] Do not connect simpleTextOut driver if it doesn'tsupport
+// mode splitter is in
+// [Files] Consplit.c
+//
+// 51 8/02/12 12:13p Artems
+// [TAG] EIP95607
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Execute nsh script and redirect output to file, then exit
+// from shell, setup screen will crash
+// [RootCause] Console splitter maintains global pool of supported
+// modes.
+// It's getting adjusted every time new SimpleTextOut (STO) is installed
+// If new STO doesn't support particular mode it is getting marked as
+// unsupported in global pool
+// However once this STO is uninstalled global pool isn't updated, so mode
+// is still marked as unsupported,
+// though system can support it
+// [Solution] Added reinitilization of global pool of supported modes on
+// STO uninstall event
+// [Files] Consplit.h Consplit.c
+//
+// 50 7/06/12 11:28a Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Support for monitor native resolution
+// [Files] GC.c, Consplit.c, Out.c, Core_Dxe.sdl
+//
+// 49 12/15/11 12:15p Felixp
+// [TAG] EIP73410
+// [Category] Improvement
+// [Description] InstallSimplePointerDevice function is updated to
+// initialize
+// LeftButton and RightButton fields of the
+// EFI_SIMPLE_POINTER_MODE structure exposed by
+// the splitter based on capabilities of the available mouse devices.
+//
+// 48 8/12/11 12:19p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 47 7/11/11 10:10a Felixp
+// Improvement (EIP 64049):
+// REPORT_NO_CON_OUT_ERROR and REPORT_NO_CON_IN_ERROR SDL tokens are added
+// to enable/disable reporting of the console errors.
+//
+// 46 5/13/11 3:37p Felixp
+// Minor improvement in CSStop: the screen is now saved after closing the
+// protocol
+//
+// 45 5/05/11 3:52p Artems
+// Added multi-language keyboard support
+//
+// 44 2/25/11 12:33p Artems
+// EIP 53767 - disable reporting keyboard absence on fast boot path
+//
+// 43 11/15/10 4:59p Felixp
+//
+// 41 9/24/10 3:38p Felixp
+// Enhancement(EIP 43535):
+// The pST->ConOut pointer used to be initialized once all ConOut
+// device are connected. The Console Splitter driver is updated
+// to initialize ConOut-related fields of the systems table
+// early (in the entry point) to workaround bugs in some of the
+// UEFI OpROM drivers that are using pST->ConOut without NULL checking.
+//
+// 40 9/24/10 7:39a Felixp
+// Additional checks for DXE_NO_CON_OUT and DXE_NO_CON_IN errors are
+// added.
+// The errors are now reported when no console devices with device path
+// available.
+//
+// 39 8/10/10 2:31p Vyacheslava
+// Simple Pointer Protocol bug fixes. (EIP#41832)
+//
+// 38 6/23/10 3:02p Felixp
+// SimplePointer splitter support is added.
+//
+// 37 2/19/10 9:58a Artems
+// Merged previous changes
+//
+// 36 2/12/10 6:13p Artems
+// EIP 34632 Added modification of MasterMode.MaxMode value if one of
+// children does not support Mode 2 or higher
+//
+// 34 8/28/09 9:07a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 33 7/08/09 4:42p Artems
+// Added missing functions headers
+//
+// 32 7/07/09 3:35p Artems
+// Added functions headers according to code standard
+//
+// 31 6/16/09 5:50p Artems
+// EIP 21415 Fixed error with CursorVisible variable
+//
+// 30 1/16/09 5:27p Felixp
+// Bug fix.
+// Headless systems hanging(EIP 18165).
+// Symptoms: Systems with no console output devices were hanging towards
+// the end of the boot process (prior to OS handoff).
+// Details: Some of the global variables used by console splitter
+// implementation
+// of TxtOut were only initialized once first physical console output
+// device is detected,
+// which was never happenning of a headless system.
+// The conosle splitter is updated to properly initialize the globals
+// when no actual console output devices are available.
+// UpdateSystemTableConOut function is updated.
+//
+// 29 1/05/09 3:11p Felixp
+// Minor update of UpdateSystemTableConOut.
+// Callback event is closed at the end of the function
+// (system table needs to be populated only once).
+//
+// 28 10/09/08 2:50p Felixp
+// StdErr and StandardErrorHandle initialization added
+//
+// 27 1/31/08 12:00p Olegi
+// Numlock bootup state made setup driven.
+//
+// 26 10/23/07 4:07p Olegi
+// Added a call to syncronize LEDs of ConIn devices during Start.
+//
+// 25 10/23/07 10:12a Felixp
+// Bug fix: after boot to Shell big part of the small AMI logo stayed on
+// the screen.
+// It was only happenning when two conditions were met: serial redirection
+// was turned off and plug in card with the option ROM was connected to
+// the system.
+//
+// 24 9/17/07 4:04p Olegi
+// Added support for AMI_EFIKEYCODE_PROTOCOL and
+// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+//
+// 23 9/05/07 5:43p Felixp
+// Report errors when no ConIn and ConOut devices are not available.
+//
+// 22 9/05/07 11:13a Felixp
+// SimpleTextInEx support removed. It causes problems. Support will add
+// again after Core labeling.
+//
+// 20 1/05/07 5:32p Artems
+//
+// 19 12/29/06 3:01p Felixp
+// 1. Support for GraphicsOutput protocol added
+// 2. Support for more then one text mode added
+//
+// 18 9/27/06 7:42p Felixp
+// SetMode funciton of the ConsoleControl protocol is updated to restore
+// default UGA mode when switching from grphics to text.
+//
+// 17 9/13/06 6:16p Felixp
+// pST->ConOut initialization logic changed: it is now initialized
+// immediately after the first ConOut device has been connected
+//
+// 16 3/13/06 2:37a Felixp
+//
+// 15 12/12/05 8:36p Felixp
+// RestoreTheScreen update: Restore Cursor Status
+//
+// 14 12/12/05 9:32a Felixp
+// Support for synchronization of console devices
+// (now screen is restored after legacy OpROM execution).
+//
+// 13 11/07/05 10:37a Felixp
+// LockStdIn function of ConsoleControl protocol implemented
+//
+// 12 7/15/05 7:17p Felixp
+// CONSOLE_DEVICES_STARTED_PROTOCOL_GUID added.
+// BDS uses it to notify Splitter that Console Devices have been started.
+// Once Splitter receives notification, it will install ConIn and ConOut
+// in System Table
+//
+// 11 5/27/05 12:16p Felixp
+//
+// 10 5/27/05 12:47a Felixp
+// Support for ConsoleControl protocol added
+//
+// 9 4/08/05 7:40a Felixp
+// fix: from now on when new device added, others not cleared
+//
+// 8 3/04/05 9:17a Mandal
+//
+// 7 2/24/05 5:30p Felixp
+// 1. Coded added to Start/Stop functions to open processed handles in
+// BY_CHILD_CONTROLLER mode
+// 2. GetControllerName implemented
+//
+// 6 2/11/05 6:11p Felixp
+// Logic to update ConDev variables
+//
+// 5 2/02/05 4:20p Felixp
+//
+// 3 2/02/05 2:32p Felixp
+// Splitter opens TxtIn and TxtOut in BY_DRIVER mode (used to be
+// GET_PROTOCOL)
+//
+// 2 2/01/05 1:17a Felixp
+//
+// 1 1/28/05 1:16p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/07/05 11:57a Felixp
+//
+// 3 1/04/05 5:15p Robert
+// Changed component name to be more consistent with the other drivers
+// that have been developed
+//
+// 2 1/03/05 5:47p Robert
+// Working beta version of the consplitter
+//
+// 1 12/30/04 9:47a Robert
+// Initial check in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ConSplit.c
+//
+// Description: Console Splitter driver that creates a cetralized input and
+// output console so that the correct data is going to and coming
+// from the correct devices
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------------
+
+#include "ConSplit.h"
+#include <Protocol/DevicePath.h>
+#include <Protocol/ConsoleControl.h>
+#include <Protocol/HiiDataBase.h>
+#include <Setup.h>
+#include <Dxe.h>
+#include <Hob.h>
+#include <Token.h>
+
+//----------------------------------------------------------------------------
+
+EFI_HANDLE ConSplitHandle = NULL;
+
+DLIST ConInList;
+DLIST ConOutList;
+DLIST ConPointerList;
+DLIST ConInKeyNotifyList;
+
+EFI_KEY_TOGGLE_STATE mCSToggleState = TOGGLE_STATE_VALID;
+BOOLEAN NumLockSet = FALSE;
+static BOOLEAN InitModesTableCalled = FALSE;
+
+static EFI_GUID gSimpleTextOutGuid = EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
+static EFI_GUID gSimpleInGuid = EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID;
+static EFI_GUID gSimpleInExGuid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
+static EFI_GUID gAmiEfiKeycodeGuid = AMI_EFIKEYCODE_PROTOCOL_GUID;
+static EFI_GUID gSimplePointerGuid = EFI_SIMPLE_POINTER_PROTOCOL_GUID;
+static EFI_GUID gEfiDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+static EFI_GUID gAmiMultiLangSupportGuid = AMI_MULTI_LANG_SUPPORT_PROTOCOL_GUID;
+
+extern SIMPLE_TEXT_OUTPUT_MODE MasterMode;
+
+
+EFI_STATUS InstallConOutDevice(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut,
+ IN EFI_HANDLE Handle
+ );
+
+EFI_STATUS InstallConInDevice(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn,
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx,
+ IN AMI_EFIKEYCODE_PROTOCOL *KeycodeIn,
+ IN EFI_HANDLE Handle
+ );
+
+EFI_STATUS InstallSimplePointerDevice(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer,
+ IN EFI_HANDLE Handle
+ );
+
+EFI_STATUS ConOutHandleCheck(
+ IN EFI_HANDLE Handle
+ );
+
+EFI_STATUS ConInHandleCheck(
+ IN EFI_HANDLE Handle
+ );
+
+VOID CSSetKbLayoutNotifyFn(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+EFI_HII_DATABASE_PROTOCOL *HiiDatabase = NULL;
+EFI_HII_KEYBOARD_LAYOUT *gKeyDescriptorList = NULL;
+UINT16 KeyDescriptorListSize = 0;
+static EFI_GUID SetKeyboardLayoutEventGuid = EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID;
+
+EFI_STATUS ConSimplePointerHandleCheck( IN EFI_HANDLE Handle );
+
+EFI_DRIVER_BINDING_PROTOCOL gConSplitterDriverBindingProtocol = {
+ CSSupported,
+ CSStart,
+ CSStop,
+ 0x10,
+ NULL,
+ NULL
+ };
+AMI_MULTI_LANG_SUPPORT_PROTOCOL gMultiLangSupportProtocol = {
+ KeyboardLayoutMap
+};
+
+#ifdef EFI_DEBUG
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+static EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#endif
+static CHAR16 *gDriverName=L"AMI Console Splitter Driver";
+static CHAR16 *gControllerName=L"AMI Console Splitter";
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: ComponentNameGetControllerName
+//
+// Description:
+// EFI_COMPONENT_NAME_PROTOCOL GetControllerName function
+//
+// Input:
+// IN EFI_COMPONENT_NAME_PROTOCOL* This - pointer to protocol instance
+// IN EFI_HANDLE Controller - controller handle
+// IN EFI_HANDLE ChildHandle - child handle
+// IN CHAR8* Language - pointer to language description
+// OUT CHAR16** ControllerName - pointer to store pointer to controller name
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - controller name returned
+// EFI_INVALID_PARAMETER - language undefined
+// EFI_UNSUPPORTED - given language not supported
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS ComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+)
+{
+ //Supports only English
+ if(!Language || !ControllerName)
+ return EFI_INVALID_PARAMETER;
+
+ if ( ChildHandle!=ConSplitHandle
+ || !LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH)
+ ) return EFI_UNSUPPORTED;
+
+ *ControllerName=gControllerName;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: ComponentNameGetDriverName
+//
+// Description:
+// EFI_COMPONENT_NAME_PROTOCOL GetDriverName function
+//
+// Input:
+// IN EFI_COMPONENT_NAME_PROTOCOL* This - pointer to protocol instance
+// IN CHAR8* Language - pointer to language description
+// OUT CHAR16** DriverName - pointer to store pointer to driver name
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver name returned
+// EFI_INVALID_PARAMETER - language undefined
+// EFI_UNSUPPORTED - given language not supported
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS ComponentNameGetDriverName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+)
+{
+ //Supports only English
+ if(!Language || !DriverName)
+ return EFI_INVALID_PARAMETER;
+
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+ else
+ *DriverName=gDriverName;
+
+ return EFI_SUCCESS;
+}
+
+//Component Name Protocol
+static EFI_COMPONENT_NAME2_PROTOCOL gComponentName = {
+ ComponentNameGetDriverName,
+ ComponentNameGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+#endif
+
+EFI_CONSOLE_CONTROL_SCREEN_MODE ScreenMode = EfiConsoleControlScreenText;
+BOOLEAN CursorVisible = TRUE;
+BOOLEAN StdInLocked = FALSE;
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetMode
+//
+// Description:
+// This function returns current console mode
+//
+// Input:
+// IN EFI_CONSOLE_CONTROL_PROTOCOL *This - pointer to console protocol
+// OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode - placeholder for mode to return
+// OUT OPTIONAL BOOLEAN *UgaExists - if not NULL on return will have current UGA present state
+// OUT OPTIONAL BOOLEAN *StdInLocked - if not NULL on return will have value of STD_IN_LOCKED state
+//
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function returns correct values
+//
+// Modified:
+//
+// Referrals:
+// ScreenMode
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS GetMode(
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
+ OUT BOOLEAN *UgaExists OPTIONAL,
+ OUT BOOLEAN *StdInLocked OPTIONAL
+)
+{
+ if (Mode) *Mode = ScreenMode;
+ if (UgaExists) *UgaExists = TRUE;
+ if (StdInLocked) *StdInLocked = FALSE;
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetMode
+//
+// Description:
+// This function sets current console mode
+//
+// Input:
+// IN EFI_CONSOLE_CONTROL_PROTOCOL *This - pointer to console protocol
+// IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode - mode to set
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - mode set successfully
+// EFI_INVALID_PARAMETER - incorrect mode given
+//
+// Modified:
+// ScreenMode
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS SetMode(
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
+)
+{
+ if (ScreenMode != Mode)
+ {
+ ScreenMode = Mode;
+ if (ScreenMode == EfiConsoleControlScreenText)
+ {
+ //Restore UGA mode when switching from graphics to text
+ DLINK *ListPtr = ConOutList.pHead;
+ CON_SPLIT_OUT *SimpleOut;
+ while ( ListPtr != NULL)
+ {
+ SimpleOut = OUTTER(ListPtr, Link, CON_SPLIT_OUT);
+ RestoreUgaMode(SimpleOut->Handle);
+ ListPtr = ListPtr->pNext;
+ }
+
+ if (CursorVisible)
+ mCSOutProtocol.EnableCursor(&mCSOutProtocol,TRUE);
+ }
+ else if (ScreenMode == EfiConsoleControlScreenGraphics)
+ {
+ DLINK *ListPtr = ConOutList.pHead;
+ CON_SPLIT_OUT *SimpleOut;
+ CursorVisible = MasterMode.CursorVisible;
+ if (CursorVisible)
+ mCSOutProtocol.EnableCursor(&mCSOutProtocol,FALSE);
+ //Save UGA mode when switching from text to graphics
+ while ( ListPtr != NULL)
+ {
+ SimpleOut = OUTTER(ListPtr, Link, CON_SPLIT_OUT);
+ SaveUgaMode(SimpleOut->Handle);
+ ListPtr = ListPtr->pNext;
+ }
+
+ }
+ else return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: LockStdIn
+//
+// Description:
+// This function toggles STD_IN_LOCKED state
+//
+// Input:
+// IN EFI_CONSOLE_CONTROL_PROTOCOL *This - pointer to console protocol
+// IN CHAR16 *Password - pointer to password string
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+//
+// Modified:
+// StdInLocked
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS LockStdIn(
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ IN CHAR16 *Password
+)
+{
+ //TODO: add support for the password
+ StdInLocked = !StdInLocked;
+ return EFI_SUCCESS;
+};
+
+EFI_GUID gConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+
+EFI_CONSOLE_CONTROL_PROTOCOL gConsoleControlProtocol = {
+ GetMode,
+ SetMode,
+ LockStdIn
+};
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateSystemTableConOut
+//
+// Description:
+// This function updates system table ConOut pointer
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID UpdateSystemTableConOut()
+{
+ UINT32 CRC32 = 0;
+
+ if( ConOutList.Size==0 ){
+ //Initialize all the global variables used by
+ //splitter implementation of TxtOut.
+ //When physical ConOut devices are available, the initialization is performed
+ //within InitModesTable routine.
+ VERIFY_EFI_ERROR(ResizeSplitterBuffer(0));
+ VERIFY_EFI_ERROR(pBS->AllocatePool(EfiBootServicesData, sizeof(SUPPORT_RES), &SupportedModes));
+ SupportedModes[0].Rows = 25;
+ SupportedModes[0].Columns = 80;
+ SupportedModes[0].AllDevices = TRUE;
+ }
+
+ pST->ConOut = &mCSOutProtocol;
+ pST->ConsoleOutHandle = ConSplitHandle;
+ // We want to initialize ConOut-related fields of the systems table early
+ // to workaround bugs in some of the UEFI OpROM drivers
+ // that are using pST->ConOut without NULL checking.
+ // We are not installing the instance of SimpleTextOut on ConSplitHandle though,
+ // because it confuses the logic of TSE notification callbacks.
+ // The protocol is installed once all ConOut devices are connected
+ // in ReportNoConOutError.
+ if (pST->StdErr==NULL){
+ pST->StdErr = pST->ConOut;
+ pST->StandardErrorHandle = pST->ConsoleOutHandle;
+ }
+
+ // Now calculate the CRC32 value
+ pST->Hdr.CRC32 = 0;
+ pST->BootServices->CalculateCrc32(pST, sizeof(EFI_SYSTEM_TABLE), &CRC32);
+ pST->Hdr.CRC32 = CRC32;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ReportNoConOutError
+//
+// Description:
+// This function checks if physical ConOut devices are available.
+// If not, DXE_NO_CON_OUT error is reported.
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID ReportNoConOutError(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+#if REPORT_NO_CON_OUT_ERROR
+ DLINK *Link;
+ EFI_STATUS Status;
+
+ //Report error if no ConOut devices available or
+ // all console devices are fake devices (without device path).
+ for(Link = ConOutList.pHead; Link!=NULL; Link=Link->pNext){
+ CON_SPLIT_OUT *SimpleOut = OUTTER(Link, Link, CON_SPLIT_OUT);
+ VOID *Dp;
+
+ Status = pBS->HandleProtocol(
+ SimpleOut->Handle, &gEfiDevicePathProtocolGuid, &Dp
+ );
+ if (!EFI_ERROR(Status)) break; // Got one device path
+ }
+ //Report error if no ConOut devices with device path exists
+ if( ConOutList.Size==0 || EFI_ERROR(Status) )
+ ERROR_CODE(DXE_NO_CON_OUT, EFI_ERROR_MAJOR);
+#endif
+ pBS->InstallMultipleProtocolInterfaces (
+ &ConSplitHandle, &gSimpleTextOutGuid, &mCSOutProtocol,
+ &gConsoleControlProtocolGuid, &gConsoleControlProtocol,
+ NULL
+ );
+ pBS->CloseEvent(Event);
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateSystemTableConIn
+//
+// Description:
+// This function updates system table ConIn pointer
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID UpdateSystemTableConIn(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ UINT32 CRC32 = 0;
+
+#if REPORT_NO_CON_IN_ERROR
+ DLINK *Link;
+ EFI_STATUS Status;
+
+ EFI_HOB_HANDOFF_INFO_TABLE *pHit;
+ static EFI_GUID guidHob = HOB_LIST_GUID;
+
+ //Report error if no ConIn devices available or
+ // all console devices are fake devices (without device path).
+ for(Link = ConInList.pHead; Link!=NULL; Link=Link->pNext){
+ CON_SPLIT_IN *SimpleIn = OUTTER(Link, Link, CON_SPLIT_IN);
+ VOID *Dp;
+
+ Status = pBS->HandleProtocol(
+ SimpleIn->Handle, &gEfiDevicePathProtocolGuid, &Dp
+ );
+ if (!EFI_ERROR(Status)) break; // Got one device path
+ }
+
+ pHit = GetEfiConfigurationTable(pST, &guidHob);
+ //Report error if no ConIn devices with device path exists
+ if( (ConInList.Size == 0 || EFI_ERROR(Status)) && (pHit->BootMode == BOOT_WITH_FULL_CONFIGURATION))
+ ERROR_CODE(DXE_NO_CON_IN, EFI_ERROR_MAJOR);
+#endif
+ pST->ConIn = &mCSSimpleInProtocol;
+
+ pBS->InstallMultipleProtocolInterfaces (
+ &ConSplitHandle,
+ &gSimpleInGuid, &mCSSimpleInProtocol,
+ &gSimpleInExGuid, &mCSSimpleInExProtocol,
+ &gAmiEfiKeycodeGuid, &mCSKeycodeInProtocol,
+ &gEfiSimplePointerProtocolGuid, &mCSSimplePointerProtocol,
+ NULL
+ );
+
+ pST->ConsoleInHandle = ConSplitHandle;
+
+ // Now calculate the CRC32 value
+ pST->Hdr.CRC32 = 0;
+ pST->BootServices->CalculateCrc32(pST, sizeof(EFI_SYSTEM_TABLE), &CRC32);
+ pST->Hdr.CRC32 = CRC32;
+
+ pBS->CloseEvent(Event);
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSEntryPoint
+//
+// Description:
+// This function is Console splitter driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - image handle of Console splitter driver
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver installed successfully
+// EFI_ERROR - error occured during execution
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ static EFI_GUID guidConInStarted = CONSOLE_IN_DEVICES_STARTED_PROTOCOL_GUID;
+ static EFI_GUID guidConOutStarted = CONSOLE_OUT_DEVICES_STARTED_PROTOCOL_GUID;
+ // {8FF925F1-8624-4d38-9ED2-F8F5AA94F84A}
+ static EFI_GUID gDummyProtocolGuid =
+ { 0x8ff925f1, 0x8624, 0x4d38, { 0x9e, 0xd2, 0xf8, 0xf5, 0xaa, 0x94, 0xf8, 0x4a } };
+
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+ VOID *pRegistration;
+ SETUP_DATA *SetupData = NULL;
+ UINTN VariableSize = 0;
+ EFI_GUID SetupGuid = SETUP_GUID;
+
+ // initialize AMI library
+ InitAmiLib(ImageHandle, SystemTable);
+
+ // initiaize the ImageHandle and DriverBindingHandle
+ gConSplitterDriverBindingProtocol.DriverBindingHandle = NULL;
+ gConSplitterDriverBindingProtocol.ImageHandle = ImageHandle;
+
+ // Install driver binding protocol here
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &gConSplitterDriverBindingProtocol.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, &gConSplitterDriverBindingProtocol,
+#ifdef EFI_DEBUG
+ &gEfiComponentName2ProtocolGuid, &gComponentName,
+#endif
+ &gAmiMultiLangSupportGuid, &gMultiLangSupportProtocol,
+ NULL);
+
+ // Create and event for the Simple In Interface
+ Status = pBS->CreateEvent (EFI_EVENT_NOTIFY_WAIT, TPL_NOTIFY,
+ CSWaitForKey, &mCSSimpleInProtocol,
+ &mCSSimpleInProtocol.WaitForKey
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Create and event for the SimpleInEx Interface
+ Status = pBS->CreateEvent (EFI_EVENT_NOTIFY_WAIT, TPL_NOTIFY,
+ CSWaitForKey, &mCSSimpleInExProtocol,
+ &mCSSimpleInExProtocol.WaitForKeyEx
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ // Create and event for the KeycodeIn Interface
+ Status = pBS->CreateEvent (EFI_EVENT_NOTIFY_WAIT, TPL_NOTIFY,
+ CSWaitForKey, &mCSKeycodeInProtocol,
+ &mCSKeycodeInProtocol.WaitForKeyEx
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Create an event for the SimplePointer Interface
+ Status = pBS->CreateEvent(
+ EFI_EVENT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ ConSplitterSimplePointerWaitForInput,
+ &mCSSimplePointerProtocol,
+ &mCSSimplePointerProtocol.WaitForInput
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ // Initialize the global lists here
+ DListInit(&ConInList);
+ DListInit(&ConOutList);
+ DListInit(&ConPointerList);
+ DListInit(&ConInKeyNotifyList);
+
+ // Register Protocol Notification to expose
+ // Console Splitter interface only after all consoles initialized
+ RegisterProtocolCallback(
+ &guidConOutStarted, ReportNoConOutError,
+ NULL, &Event,&pRegistration
+ );
+ RegisterProtocolCallback(
+ &guidConInStarted, UpdateSystemTableConIn,
+ NULL, &Event,&pRegistration
+ );
+
+ //We need a valid handle
+ //The only way to create it is to install a protocol
+ //Let's install a dummy protocol
+ pBS->InstallMultipleProtocolInterfaces (
+ &ConSplitHandle,
+ &gDummyProtocolGuid, NULL,
+ NULL
+ );
+
+ //install pST->ConOut
+ UpdateSystemTableConOut();
+
+//multi keyboard layout support
+ Status = pBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ CSSetKbLayoutNotifyFn,
+ NULL,
+ &SetKeyboardLayoutEventGuid,
+ &Event);
+ CSSetKbLayoutNotifyFn(NULL, NULL);
+
+ // Lighten up the keyboard(s) lights
+ if(NumLockSet == FALSE) {
+ Status = GetEfiVariable(L"Setup", &SetupGuid, NULL, &VariableSize, &SetupData);
+ if (!EFI_ERROR(Status)) {
+ if (SetupData->Numlock) {
+ mCSToggleState |= NUM_LOCK_ACTIVE;
+ }
+ pBS->FreePool(SetupData);
+ }
+ NumLockSet=TRUE;
+ }
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSSupported
+//
+// Description:
+// This function is Console splitter driver Supported function for driver
+// binding protocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to driver binding protocol
+// IN EFI_HANDLE ControllerHandle - controller handle to install driver on
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - pointer to device path
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver supports given controller
+// EFI_UNSUPPORTED - driver doesn't support given controller
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn = NULL;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx = NULL;
+ AMI_EFIKEYCODE_PROTOCOL *KeycodeIn = NULL;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut = NULL;
+ EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer = NULL;
+ EFI_STATUS SimplePointerStatus;
+ EFI_STATUS OutStatus;
+ EFI_STATUS InStatus;
+ EFI_STATUS InExStatus;
+ EFI_STATUS KeycodeInStatus;
+ INT32 Dummy;
+
+ if (ControllerHandle == ConSplitHandle)
+ return EFI_UNSUPPORTED;
+
+ // check to see if this device has a simple text out protocol installed on it
+ OutStatus = pBS->OpenProtocol ( ControllerHandle, &gSimpleTextOutGuid,
+ &SimpleOut, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if(!EFI_ERROR(OutStatus)) {
+ OutStatus = IsModeSupported(SimpleOut, MasterMode.Mode, &Dummy);
+ if(EFI_ERROR(OutStatus)) {
+ pBS->CloseProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ This->DriverBindingHandle, ControllerHandle);
+ }
+ }
+
+
+ // check to see if this device has a simple input protocol installed on it
+ InStatus = pBS->OpenProtocol ( ControllerHandle, &gSimpleInGuid,
+ &SimpleIn, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ InExStatus = pBS->OpenProtocol ( ControllerHandle, &gSimpleInExGuid,
+ &SimpleInEx, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ KeycodeInStatus = pBS->OpenProtocol ( ControllerHandle, &gAmiEfiKeycodeGuid,
+ &KeycodeIn, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ // check if device has simple pointer protocol installed on it
+ SimplePointerStatus = pBS->OpenProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ &SimplePointer,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (!EFI_ERROR(SimplePointerStatus))
+ pBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ if (!EFI_ERROR(OutStatus))
+ pBS->CloseProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ if (!EFI_ERROR(InStatus))
+ pBS->CloseProtocol(ControllerHandle, &gSimpleInGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ if (!EFI_ERROR(InExStatus))
+ pBS->CloseProtocol(ControllerHandle, &gAmiEfiKeycodeGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ if (!EFI_ERROR(KeycodeInStatus))
+ pBS->CloseProtocol(ControllerHandle, &gSimpleInExGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ if ( EFI_ERROR(SimplePointerStatus) &&
+ EFI_ERROR(OutStatus) &&
+ EFI_ERROR(InStatus) &&
+ EFI_ERROR(InExStatus) &&
+ EFI_ERROR(KeycodeInStatus) )
+ return EFI_UNSUPPORTED;
+
+ return EFI_SUCCESS;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSStart
+//
+// Description:
+// This function is Console splitter driver Start function for driver
+// binding protocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to driver binding protocol
+// IN EFI_HANDLE ControllerHandle - controller handle to install driver on
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - pointer to device path
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver started successfully
+// EFI_UNSUPPORTED - driver didn't start
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSStart(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn = NULL;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx = NULL;
+ AMI_EFIKEYCODE_PROTOCOL *KeycodeIn = NULL;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut = NULL;
+ EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer = NULL;
+ EFI_STATUS Status;
+ EFI_STATUS OutStatus;
+ EFI_STATUS InStatus;
+ EFI_STATUS InExStatus;
+ EFI_STATUS KeycodeInStatus;
+
+ // grab the pointers for the ConIn, ConOut, and StdErr from the System Table
+ // install the current handles for these devices.
+
+ // if Simple In, add the Con In device to the list and
+ InStatus = pBS->OpenProtocol(ControllerHandle, &gSimpleInGuid,
+ &SimpleIn, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ InExStatus = pBS->OpenProtocol(ControllerHandle, &gSimpleInExGuid,
+ &SimpleInEx, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ KeycodeInStatus = pBS->OpenProtocol(ControllerHandle, &gAmiEfiKeycodeGuid,
+ &KeycodeIn, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (!EFI_ERROR(InStatus) || !EFI_ERROR(InExStatus) || !EFI_ERROR(KeycodeInStatus))
+ {
+ InStatus = InstallConInDevice(SimpleIn, SimpleInEx, KeycodeIn, ControllerHandle);
+ if (InStatus == EFI_OUT_OF_RESOURCES)
+ return InStatus;
+
+ if (!EFI_ERROR(InStatus))
+ pBS->OpenProtocol(ControllerHandle, &gSimpleInGuid,
+ &SimpleIn, This->DriverBindingHandle,
+ ConSplitHandle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+ }
+
+ Status = pBS->OpenProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ &SimplePointer,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (!EFI_ERROR(Status)) {
+ Status = InstallSimplePointerDevice( SimplePointer, ControllerHandle );
+ if (!EFI_ERROR(Status)) {
+ Status = pBS->OpenProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ &SimplePointer,
+ This->DriverBindingHandle,
+ ConSplitHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ } else if (Status == EFI_OUT_OF_RESOURCES)
+ return Status;
+ }
+
+ // if it has a simple text out add the Con Out device to the list and
+ OutStatus = pBS->OpenProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ &SimpleOut, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if (!EFI_ERROR(OutStatus) )
+ {
+ OutStatus = InstallConOutDevice(SimpleOut, ControllerHandle);
+ if (OutStatus == EFI_OUT_OF_RESOURCES)
+ return OutStatus;
+
+ if (!EFI_ERROR(OutStatus))
+ {
+ RestoreTheScreen(ControllerHandle,SimpleOut);
+ pBS->OpenProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ &SimpleOut, This->DriverBindingHandle,
+ ConSplitHandle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+ }
+ }
+
+ // If no devices were installed, then Houston we have a problem
+ if ( EFI_ERROR(OutStatus) && EFI_ERROR(InStatus) && EFI_ERROR(Status) )
+ return EFI_UNSUPPORTED;
+
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSStop
+//
+// Description:
+// This function is Console splitter driver Stop function for driver
+// binding protocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to driver binding protocol
+// IN EFI_HANDLE ControllerHandle - controller handle to install driver on
+// IN UINTN NumberOfChildren - number of childs on this handle
+// IN OPTIONAL EFI_HANDLE *ChildHandleBuffer - pointer to child handles array
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver stopped successfully
+// EFI_INVALID_PARAMETER - invalid values passed for NumberOfChildren or
+// ChildHandleBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
+)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ DLINK *ListPtr;
+ CON_SPLIT_IN *SimpleIn;
+ CON_SPLIT_OUT *SimpleOut;
+ CON_SPLIT_SIMPLE_POINTER *SimplePointer = NULL;
+ BOOLEAN Stopped = FALSE;
+ DLINK *HandleLink = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY_HANDLE *CsInNotifyHandle = NULL;
+
+ if (NumberOfChildren == 0)
+ return EFI_SUCCESS;
+
+ if ( NumberOfChildren != 1 ||
+ ChildHandleBuffer == NULL ||
+ *ChildHandleBuffer!= ConSplitHandle )
+ return EFI_INVALID_PARAMETER;
+
+ // remove simple text out, simple in, simple pointer
+ ListPtr = ConOutList.pHead;
+ while ( ListPtr != NULL)
+ {
+ SimpleOut = OUTTER(ListPtr, Link, CON_SPLIT_OUT);
+ if ( SimpleOut->Handle == ControllerHandle)
+ {
+ pBS->CloseProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ pBS->CloseProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ This->DriverBindingHandle, ConSplitHandle);
+ DListDelete(&ConOutList, ListPtr);
+ Stopped = TRUE;
+ SaveTheScreen(ControllerHandle, SimpleOut->SimpleOut);
+ Status = pBS->FreePool(SimpleOut);
+ break;
+ }
+
+ ListPtr = ListPtr->pNext;
+ }
+
+ //If we already populated pST->ConOut preserve
+ //screen buffer and list of supported modes
+ //to keep using it when ConOut devices are connected
+ if(ConOutList.Size == 0 && !pST->ConOut) //all devices stops
+ {
+ if(SupportedModes != NULL)
+ {
+ pBS->FreePool(SupportedModes);
+ SupportedModes = NULL;
+ }
+
+ if(ScreenBuffer != NULL)
+ {
+ pBS->FreePool(ScreenBuffer);
+ ScreenBuffer = NULL;
+ }
+
+ if(AttributeBuffer != NULL)
+ {
+ pBS->FreePool(AttributeBuffer);
+ AttributeBuffer = NULL;
+ }
+
+ MasterMode.Mode=0;
+ } else {
+ if(Stopped && ConOutList.Size > 0) //re-initialize supported modes buffer if at least one child was stopped
+ AdjustSupportedModes();
+ }
+
+ ListPtr = ConInList.pHead;
+ while ( ListPtr != NULL)
+ {
+ SimpleIn = OUTTER(ListPtr, Link, CON_SPLIT_IN);
+ if ( SimpleIn->Handle == ControllerHandle)
+ {
+ DListDelete(&ConInList, ListPtr);
+
+ pBS->CloseProtocol(ControllerHandle, &gSimpleInGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ pBS->CloseProtocol(ControllerHandle, &gSimpleInExGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ pBS->CloseProtocol(ControllerHandle, &gAmiEfiKeycodeGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ pBS->CloseProtocol(ControllerHandle, &gSimpleInGuid,
+ This->DriverBindingHandle, ConSplitHandle);
+ break;
+ }
+
+ ListPtr = ListPtr->pNext;
+ }
+
+ if (ListPtr != NULL && SimpleIn->SimpleInEx != NULL) {
+ for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY);
+
+ for (HandleLink = CsInKeyNotify->NotifyHandleList.pHead; HandleLink != NULL;
+ HandleLink = HandleLink->pNext) {
+ CsInNotifyHandle = OUTTER(HandleLink, Link, CON_SPLIT_IN_KEY_NOTIFY_HANDLE);
+
+ if (SimpleIn->SimpleInEx != CsInNotifyHandle->SimpleInEx) {
+ continue;
+ }
+
+ Status = SimpleIn->SimpleInEx->UnregisterKeyNotify(
+ SimpleIn->SimpleInEx, CsInNotifyHandle->NotifyHandle);
+
+ DListDelete(&(CsInKeyNotify->NotifyHandleList), HandleLink);
+ Status = pBS->FreePool(CsInNotifyHandle);
+ }
+ }
+ Status = pBS->FreePool(SimpleIn);
+ }
+
+ ListPtr = ConPointerList.pHead;
+ while (ListPtr != NULL) {
+ SimplePointer = OUTTER(ListPtr, Link, CON_SPLIT_SIMPLE_POINTER);
+ if ( SimplePointer->Handle == ControllerHandle ) {
+ DListDelete(&ConPointerList, ListPtr);
+
+ pBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ pBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ This->DriverBindingHandle,
+ ConSplitHandle
+ );
+ Status = pBS->FreePool(SimplePointer);
+ break;
+ }
+ ListPtr = ListPtr->pNext;
+ }
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateConVar
+//
+// Description:
+// This function stores device path of given controller in EFI variable with
+// name sVarName
+//
+// Input:
+// IN EFI_HANDLE Controller - controller, which device path to store
+// IN CHAR16 *sVarName - name of EFI variable to store device path under
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID UpdateConVar(
+ IN EFI_HANDLE Controller,
+ IN CHAR16 *sVarName
+)
+{
+ static EFI_GUID guidDevicePath = EFI_DEVICE_PATH_PROTOCOL_GUID;
+ static EFI_GUID guidEfiVar = EFI_GLOBAL_VARIABLE;
+ EFI_DEVICE_PATH_PROTOCOL *pDevicePath, *pConDev = NULL;
+ EFI_STATUS Status;
+ UINTN DataSize=0;
+ UINT32 Attributes;
+
+ Status = pBS->HandleProtocol(Controller,&guidDevicePath, &pDevicePath);
+ if (EFI_ERROR(Status))
+ return;
+
+ Status = GetEfiVariable(sVarName, &guidEfiVar, &Attributes, &DataSize, &pConDev);
+ if (EFI_ERROR(Status))
+ {
+ if (Status!=EFI_NOT_FOUND)
+ return;
+
+ DataSize = DPLength(pDevicePath);
+ pRS->SetVariable(sVarName, &guidEfiVar,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize, pDevicePath);
+ return;
+ }
+
+ if (!DPIsOneOf(pConDev, pDevicePath, FALSE))
+ {
+ EFI_DEVICE_PATH_PROTOCOL *pNewConDev = DPAddInstance(pConDev, pDevicePath);
+ DataSize = DPLength(pNewConDev);
+ pRS->SetVariable(sVarName, &guidEfiVar, Attributes, DataSize, pNewConDev);
+ pBS->FreePool(pNewConDev);
+ }
+
+ pBS->FreePool(pConDev);
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InstallSimplePointerDevice
+//
+// Description:
+// This function adds another ConIn device to splitter
+//
+// Input:
+// *SimpleIn - pointer to new protocol
+// *SimpleInEx - pointer to new extended protocol
+// *KeycodeIn - pointer to AMI key code protocol
+// Handle - handle of new device
+//
+// Output:
+// EFI_SUCCESS - device added successfully
+// EFI_UNSUPPORTED - device not supported
+// EFI_OUT_OF_RESOURCES - not enough resources to perform operation
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS InstallSimplePointerDevice(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer,
+ IN EFI_HANDLE Handle )
+{
+ EFI_STATUS Status;
+ CON_SPLIT_SIMPLE_POINTER *ConSimplePointer = NULL;
+
+ if (EFI_ERROR(ConSimplePointerHandleCheck(Handle)))
+ return EFI_UNSUPPORTED;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CON_SPLIT_SIMPLE_POINTER),
+ &ConSimplePointer
+ );
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ ConSimplePointer->SimplePointer = SimplePointer;
+ ConSimplePointer->Handle = Handle;
+ mCSSimplePointerProtocol.Mode->LeftButton |= SimplePointer->Mode->LeftButton;
+ mCSSimplePointerProtocol.Mode->RightButton |= SimplePointer->Mode->RightButton;
+ DListAdd(&ConPointerList, &ConSimplePointer->Link);
+ return EFI_SUCCESS;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InstallConOutDevice
+//
+// Description:
+// This function adds another ConOut device to splitter
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut - pointer to new protocol
+// IN EFI_HANDLE Handle - handle of new device
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device added successfully
+// EFI_UNSUPPORTED - device not supported
+// EFI_OUT_OF_RESOURCES - not enough resources to perform operation
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS InstallConOutDevice(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut,
+ IN EFI_HANDLE Handle
+)
+{
+ EFI_STATUS Status;
+ CON_SPLIT_OUT *ConOut;
+ INT32 DeviceModeNumber = 0;
+ BOOLEAN FirstChild = FALSE;
+
+ if (EFI_ERROR(ConOutHandleCheck(Handle)))
+ return EFI_UNSUPPORTED;
+
+ if(MasterMode.Mode != 0) //already in extended mode
+ if (EFI_ERROR(IsModeSupported(SimpleOut, MasterMode.Mode, &DeviceModeNumber)))
+ return EFI_UNSUPPORTED; //device doesn't support current mode - do not include into list
+
+
+ if (ConOutList.Size==0 && !InitModesTableCalled) //this is first call
+ {
+ FirstChild = TRUE;
+ Status = InitModesTable(SimpleOut, Handle);
+ if(EFI_ERROR(Status)) //first device becomes master
+ return Status;
+ }
+ else
+ UpdateModesTable(SimpleOut, Handle); //all next devices
+
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(CON_SPLIT_OUT), &ConOut);
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ ConOut->SimpleOut = SimpleOut;
+
+ ConOut->Handle = Handle;
+
+ DListAdd(&ConOutList, &(ConOut->Link));
+
+ if(!FirstChild) {
+ // set child display to a current master mode
+ SimpleOut->SetMode(SimpleOut, DeviceModeNumber);
+ SimpleOut->EnableCursor(SimpleOut, MasterMode.CursorVisible);
+ }
+ UpdateConVar(Handle, L"ConOutDev");
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InstallConInDevice
+//
+// Description:
+// This function adds another ConIn device to splitter
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn - pointer to new protocol
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx - pointer to new extended
+// protocol
+// IN AMI_EFIKEYCODE_PROTOCOL *KeycodeIn - pointer to AMI key code protocol
+// IN EFI_HANDLE Handle - handle of new device
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device added successfully
+// EFI_UNSUPPORTED - device not supported
+// EFI_OUT_OF_RESOURCES - not enough resources to perform operation
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS InstallConInDevice(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn,
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx,
+ IN AMI_EFIKEYCODE_PROTOCOL *KeycodeIn,
+ IN EFI_HANDLE Handle
+)
+{
+ EFI_STATUS Status;
+ CON_SPLIT_IN *ConIn;
+ DLINK *ListPtr;
+ CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY_HANDLE *CsInNotifyHandle = NULL;
+
+ if (EFI_ERROR(ConInHandleCheck(Handle)))
+ return EFI_UNSUPPORTED;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(CON_SPLIT_IN), &ConIn);
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ ConIn->SimpleIn = SimpleIn;
+ ConIn->SimpleInEx = SimpleInEx;
+ ConIn->KeycodeInEx = KeycodeIn;
+
+ ConIn->Handle = Handle;
+
+ DListAdd(&ConInList, &(ConIn->Link));
+
+ UpdateConVar(Handle, L"ConInDev");
+
+ if (SimpleInEx == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ SimpleInEx->SetState(SimpleInEx, &mCSToggleState);
+
+ for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY);
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(CON_SPLIT_IN_KEY_NOTIFY_HANDLE), &CsInNotifyHandle);
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CsInNotifyHandle->SimpleInEx = SimpleInEx;
+
+ Status = SimpleInEx->RegisterKeyNotify(SimpleInEx, &CsInKeyNotify->KeyData,
+ CsInKeyNotify->KeyNotificationFunction, &(CsInNotifyHandle->NotifyHandle));
+ if (EFI_ERROR(Status)) {
+ Status = pBS->FreePool(CsInNotifyHandle);
+ continue;
+ }
+
+ DListAdd(&(CsInKeyNotify->NotifyHandleList), &(CsInNotifyHandle->Link));
+ }
+
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConOutHandleCheck
+//
+// Description:
+// This function checks if ConOut device already present in Splitter
+//
+// Input:
+// IN EFI_HANDLE Handle - handle of device to check
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device not present
+// EFI_UNSUPPORTED - device already present
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ConOutHandleCheck(
+ IN EFI_HANDLE Handle
+)
+{
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ // if the list is empty return the status that was passed in
+ if (SimpleOut == NULL)
+ return EFI_SUCCESS;
+
+ // check for a handle that was already identified
+ while ( SimpleOut != NULL)
+ {
+ // check the handle
+ if (SimpleOut->Handle == Handle)
+ return EFI_UNSUPPORTED;
+ // go to the next element in the list
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+ }
+
+ // if it is a new handle return the status pass in
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConInHandleCheck
+//
+// Description:
+// This function checks if ConIn device already present in Splitter
+//
+// Input:
+// IN EFI_HANDLE Handle - handle of device to check
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device not present
+// EFI_UNSUPPORTED - device already present
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ConInHandleCheck(
+ IN EFI_HANDLE Handle
+)
+{
+ CON_SPLIT_IN *SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN);
+
+ // if the list is empty return the status that was passed in
+ if (SimpleIn == NULL)
+ return EFI_SUCCESS;
+
+ // check for a handle that was already identified
+ while ( SimpleIn != NULL)
+ {
+ // check the handle
+ if (SimpleIn->Handle == Handle)
+ return EFI_UNSUPPORTED;
+ // go to the next element in the list
+ SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN);
+ }
+
+ // if it is a new handle return the status pass in
+ return EFI_SUCCESS;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConSimplePointerHandleCheck
+//
+// Description:
+// This function checks if ConIn device already present in Splitter.
+//
+// Input: Handle - handle of device to check
+//
+// Output:
+// EFI_SUCCESS - device not present
+// EFI_UNSUPPORTED - device already present
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ConSimplePointerHandleCheck( IN EFI_HANDLE Handle )
+{
+ CON_SPLIT_SIMPLE_POINTER *SimplePointer;
+
+ SimplePointer = OUTTER(ConPointerList.pHead, Link, CON_SPLIT_SIMPLE_POINTER);
+
+ // if the list is empty return the status that was passed in
+ if (SimplePointer == NULL)
+ return EFI_SUCCESS;
+
+ // check for a handle that was already identified
+ while ( SimplePointer != NULL) {
+
+ // check the handle
+ if (SimplePointer->Handle == Handle)
+ return EFI_UNSUPPORTED;
+
+ // go to the next element in the list
+ SimplePointer = OUTTER(SimplePointer->Link.pNext, Link, CON_SPLIT_SIMPLE_POINTER);
+ }
+
+ // if it is a new handle return the status pass in
+ return EFI_SUCCESS;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InitModesTable
+//
+// Description:
+// This function fills the SupportedModes table with modes supported by first
+// simple text out device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol
+// IN EFI_HANDLE Handle - handle of first ConOut device
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - table filled successfully
+// EFI_OUT_OF_RESOURCES - not enough resources to perform operation
+//
+// Modified: SupportedModes, MasterMode
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS InitModesTable(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN EFI_HANDLE Handle
+)
+{
+ INT32 MaxMode;
+ INT32 CurrentMode;
+ UINTN Rows, Columns;
+ INT32 i;
+ EFI_STATUS Status;
+
+ if(Handle == ConSplitHandle)
+ return EFI_SUCCESS;
+
+ InitModesTableCalled = TRUE;
+
+ MaxMode = This->Mode->MaxMode;
+ CurrentMode = This->Mode->Mode;
+
+ //The SupportedModes structure
+ //may have already been initialized in UpdateSystemTableConOut.
+ //If this is the case, free the memory before reinitialization.
+ if (SupportedModes!=NULL){
+ //If SupportedModes is not NULL,
+ //ResizeSplitterBuffer(0) has already been called
+ pBS->FreePool(SupportedModes);
+ SupportedModes = NULL;
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(SUPPORT_RES)* MaxMode,
+ &SupportedModes);
+ if(EFI_ERROR(Status))
+ {
+ MasterMode.MaxMode = 1;
+ return EFI_SUCCESS;
+ }
+
+ MasterMode.MaxMode = MaxMode; //modify default value
+
+ for(i = 0; i < MaxMode; i++)
+ {
+ Status = This->QueryMode(This, i, &Columns, &Rows);
+ SupportedModes[i].Rows = (INT32)Rows;
+ SupportedModes[i].Columns = (INT32)Columns;
+ SupportedModes[i].AllDevices = EFI_ERROR(Status) ? FALSE : TRUE;
+ }
+
+//Make sure MasterMode.Mode <> CurrentMode, otherwise ResizeSplitterBuffer won't do anything
+ MasterMode.Mode = CurrentMode + 1;
+ Status = ResizeSplitterBuffer(CurrentMode);
+ MasterMode.Mode = CurrentMode;
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: IsModeSupported
+//
+// Description:
+// This function determines if mode, specified by ModeNum supported by
+// simple text out device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol to check
+// IN UINTN ModeNum - mode to check
+// OUT INT32 *DeviceModeNumber - device mode number correspondent to ModeNum
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - mode supported by device
+// EFI_UNSUPPORTED - mode not supported by device
+//
+// Modified:
+//
+// Referrals: SupportedModes
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS IsModeSupported(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum,
+ OUT INT32 *DeviceModeNumber)
+{
+ INT32 MaxMode;
+ UINTN Rows, Columns;
+ INT32 i;
+ EFI_STATUS Status;
+
+ MaxMode = This->Mode->MaxMode;
+ for(i = 0; i < MaxMode; i++)
+ {
+ Status = This->QueryMode(This, i , &Columns, &Rows);
+ if (!EFI_ERROR(Status) && \
+ SupportedModes[ModeNum].Rows == (INT32)Rows && \
+ SupportedModes[ModeNum].Columns == (INT32)Columns)
+ {
+ *DeviceModeNumber = i;
+ return EFI_SUCCESS;
+ }
+
+ }
+ return EFI_UNSUPPORTED;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateModesTable
+//
+// Description:
+// This function updates supported modes table when new devices started don't
+// support some of this modes
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol to check
+// IN EFI_HANDLE Handle - handle of device
+//
+// Output:
+// VOID
+//
+// Modified: SupportedModes
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID UpdateModesTable(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN EFI_HANDLE Handle
+)
+{
+ INT32 i, ModeNumber;
+ EFI_STATUS Status;
+
+ if(Handle == ConSplitHandle)
+ return;
+
+
+ for(i = 0; i < MasterMode.MaxMode; i++) {
+ if(SupportedModes[i].AllDevices == FALSE) continue;
+ Status = IsModeSupported(This, i, &ModeNumber);
+ SupportedModes[i].AllDevices = EFI_ERROR(Status) ? FALSE : TRUE;
+ }
+
+//update MasterMode.MaxMode value based on modes supported by different devices
+//lookup for the first mode above 1 not supported by all devices - this will be
+//new MaxMode value
+ for(i = 2; i < MasterMode.MaxMode; i++) {
+ if(SupportedModes[i].AllDevices == FALSE) {
+ MasterMode.MaxMode = i;
+ break;
+ }
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ResizeSplitterBuffer
+//
+// Description:
+// This function allocates new buffers when mode changed
+//
+// Input:
+// IN INT32 ModeNum - new mode
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - new buffers allocated
+// EFI_OUT_OF_RESOURCES - not enough resources to perform operation
+//
+// Modified: ScreenBuffer, EndOfTheScreen,AttributeBuffer
+//
+// Referrals: SupportedModes, MasterMode
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ResizeSplitterBuffer(
+ IN INT32 ModeNum
+)
+{
+ INT32 Row, Col;
+ CHAR16 *NewCharBuffer;
+ INT32 *NewAttributeBuffer;
+ EFI_STATUS Status;
+
+ if(ModeNum != MasterMode.Mode || SupportedModes == NULL) //check if it is first init
+ {
+
+ if(SupportedModes == NULL)
+ {
+ Row = 25;
+ Col = 80;
+ }
+ else
+ {
+ Row = SupportedModes[ModeNum].Rows;
+ Col = SupportedModes[ModeNum].Columns;
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(CHAR16) * Row * Col,
+ &NewCharBuffer);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(INT32) * Row * Col,
+ &NewAttributeBuffer);
+ if(EFI_ERROR(Status))
+ {
+ pBS->FreePool(NewCharBuffer);
+ return Status;
+ }
+
+ if(ScreenBuffer != NULL)
+ pBS->FreePool(ScreenBuffer);
+ ScreenBuffer = NewCharBuffer;
+ EndOfTheScreen = ScreenBuffer + (Row * Col);
+
+ if(AttributeBuffer != NULL)
+ pBS->FreePool(AttributeBuffer);
+ AttributeBuffer = NewAttributeBuffer;
+ Columns = Col;
+ }
+ MemClearScreen();
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSSetKbLayoutNotifyFn
+//
+// Description:
+// This function stores a pointer to the current keyboard layout
+//
+// Input:
+// IN EFI_EVENT Event - event that caused this function to be called
+// IN VOID *Context - context of the event
+//
+// Output:
+// VOID
+//
+// Modified:
+// gKeyDescriptorList - changed to point to the current EFI_HII_KEYBOARD_LAYOUT
+// or, NULL if no layout currently set
+// LayoutLength - set to the size of the current keyboard layout
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID CSSetKbLayoutNotifyFn(
+ IN EFI_EVENT Event,
+ IN VOID *Context)
+{
+ EFI_STATUS Status;
+
+ if(HiiDatabase == NULL) {
+ Status = pBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, &HiiDatabase);
+ if(EFI_ERROR(Status))
+ return;
+ }
+
+ Status = HiiDatabase->GetKeyboardLayout(HiiDatabase, NULL, &KeyDescriptorListSize, gKeyDescriptorList);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ if(gKeyDescriptorList != NULL)
+ pBS->FreePool(gKeyDescriptorList);
+
+ Status = pBS->AllocatePool(EfiBootServicesData, KeyDescriptorListSize, &gKeyDescriptorList);
+ if(EFI_ERROR(Status)) {
+ KeyDescriptorListSize = 0;
+ gKeyDescriptorList = NULL;
+ } else {
+ HiiDatabase->GetKeyboardLayout(HiiDatabase, NULL, &KeyDescriptorListSize, gKeyDescriptorList);
+ }
+ } else if(Status == EFI_NOT_FOUND) {
+ if(gKeyDescriptorList != NULL) {
+ pBS->FreePool(gKeyDescriptorList);
+ KeyDescriptorListSize = 0;
+ gKeyDescriptorList = NULL;
+ }
+ }
+}
+
+VOID AdjustSupportedModes(
+ VOID
+)
+{
+ DLINK *ListPtr;
+ CON_SPLIT_OUT *SimpleOut;
+ EFI_STATUS Status;
+ INT32 i;
+ UINTN Columns;
+ UINTN Rows;
+
+ ListPtr = ConOutList.pHead;
+ SimpleOut = OUTTER(ListPtr, Link, CON_SPLIT_OUT);
+
+//re-initialize supported modes buffer
+ if(MasterMode.MaxMode < SimpleOut->SimpleOut->Mode->MaxMode) {
+ if (SupportedModes != NULL)
+ pBS->FreePool(SupportedModes);
+ Status = pBS->AllocatePool(EfiBootServicesData, SimpleOut->SimpleOut->Mode->MaxMode * sizeof(SUPPORT_RES), &SupportedModes);
+ if(EFI_ERROR(Status))
+ return;
+ }
+ MasterMode.MaxMode = SimpleOut->SimpleOut->Mode->MaxMode;
+ for(i = 0; i < MasterMode.MaxMode; i++) {
+ Status = SimpleOut->SimpleOut->QueryMode(SimpleOut->SimpleOut, i, &Columns, &Rows);
+ SupportedModes[i].Rows = (INT32)Rows;
+ SupportedModes[i].Columns = (INT32)Columns;
+ SupportedModes[i].AllDevices = EFI_ERROR(Status) ? FALSE : TRUE;
+ }
+
+//update supported modes buffer
+ ListPtr = ListPtr->pNext;
+ while(ListPtr != NULL) {
+ SimpleOut = OUTTER(ListPtr, Link, CON_SPLIT_OUT);
+ UpdateModesTable(SimpleOut->SimpleOut, SimpleOut->Handle);
+ ListPtr = ListPtr->pNext;
+ }
+}
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: KeyboardLayoutMap
+//
+// Description:
+// This function maps an EFI_KEY to a Unicode character, based on the current
+// keyboard layout
+//
+// Input:
+// IN AMI_EFI_KEY_DATA *KeyData - pointer to the key data returned by a device
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - key was mapped successfully
+// EFI_NOT_FOUND - the key was not found in the keyboard layout
+// EFI_INVALID_PARAMETER - KeyData is NULL
+//
+// Modified:
+// AMI_EFI_KEY_DATA *KeyData - KeyData->Key.UnicodeChar is changed to match
+// the character found in the keyboard layout
+//
+// Referrals:
+// EFI_HII_KEYBOARD_LAYOUT* gKeyDescriptorList - Pointer to the current
+// keyboard layout
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS KeyboardLayoutMap(
+ IN AMI_MULTI_LANG_SUPPORT_PROTOCOL *This,
+ IN OUT AMI_EFI_KEY_DATA *KeyData)
+{
+ EFI_STATUS Status;
+ EFI_KEY_DESCRIPTOR *KeyDescriptor;
+
+ BOOLEAN AltState = FALSE;
+ BOOLEAN ShiftKeyState = FALSE;
+ BOOLEAN ShiftState = ShiftKeyState;
+
+ static UINT16 ModifierIndex = 0xFFFF;
+ static CHAR16 ModifierUnicodeChar = 0x0000;
+
+ UINT16 i = 0;
+
+ if(gKeyDescriptorList== NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ KeyDescriptor = (EFI_KEY_DESCRIPTOR*)&(gKeyDescriptorList->Descriptors);
+
+ // check alt status (left alt or right alt)
+ if( ((KeyData->KeyState.KeyShiftState)&(RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED)) != 0 )
+ AltState = TRUE;
+
+ if( ((KeyData->KeyState.KeyShiftState)&(RIGHT_SHIFT_PRESSED|LEFT_SHIFT_PRESSED)) != 0 )
+ ShiftKeyState = TRUE;
+
+ Status = EFI_NOT_FOUND;
+ if ( (ModifierIndex != 0xFFFF) && (KeyDescriptor[ModifierIndex].Modifier == EFI_NS_KEY_MODIFIER) ) {
+ // Previous key had a modifier, we need to find out what to do
+ // for now, only handle EFI_NS_KEY_MODIFIER
+ for (i = ModifierIndex+1; KeyDescriptor[i].Modifier == EFI_NS_KEY_DEPENDENCY_MODIFIER && i < gKeyDescriptorList->DescriptorCount; i++) {
+ if(KeyDescriptor[i].Key == KeyData->EfiKey) {
+ if ((KeyDescriptor[i].AffectedAttribute&EFI_AFFECTED_BY_STANDARD_SHIFT) != 0)
+ ShiftState = ShiftKeyState;
+ else
+ ShiftState = FALSE;
+ // account for cAPS lOCK, only applicable if the affected attribute is set
+ if (!AltState && ((KeyDescriptor[i].AffectedAttribute&EFI_AFFECTED_BY_CAPS_LOCK) != 0) && ((KeyData->KeyState.KeyToggleState&CAPS_LOCK_ACTIVE) != 0))
+ ShiftState = !ShiftState;
+
+ if (AltState && ShiftState && (KeyDescriptor[i].ShiftedAltGrUnicode != 0x0000)) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].ShiftedAltGrUnicode;
+ Status = EFI_SUCCESS;
+ }
+ else if (AltState && !ShiftState && (KeyDescriptor[i].AltGrUnicode != 0x0000)) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].AltGrUnicode;
+ Status = EFI_SUCCESS;
+ }
+ else if (!AltState && ShiftState && (KeyDescriptor[i].ShiftedUnicode != 0x0000)) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].ShiftedUnicode;
+ Status = EFI_SUCCESS;
+ }
+ else if (!AltState && !ShiftState && (KeyDescriptor[i].Unicode != 0x0000)) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].Unicode;
+ Status = EFI_SUCCESS;
+ }
+ break;
+ }
+ }
+
+ if (EFI_ERROR(Status))
+ // No match found, just return the deadkey's character
+ KeyData->Key.UnicodeChar = ModifierUnicodeChar;
+ ModifierIndex = 0xFFFF;
+ ModifierUnicodeChar = 0x0000;
+ return EFI_SUCCESS;
+ }
+
+ // Search the KeyDescriptorList for a matching key
+ for(i = 0; i < gKeyDescriptorList->DescriptorCount; i++)
+ {
+ if(KeyDescriptor[i].Key == KeyData->EfiKey || (KeyDescriptor[i].Key == 0xA5A5 && KeyData->PS2ScanCode == 0x73)) {
+ if ((KeyDescriptor[i].AffectedAttribute&EFI_AFFECTED_BY_STANDARD_SHIFT) != 0)
+ ShiftState = ShiftKeyState;
+ else
+ ShiftState = FALSE;
+ // account for cAPS lOCK, only applicable if the affected attribute is set
+ if (!AltState && ((KeyDescriptor[i].AffectedAttribute&EFI_AFFECTED_BY_CAPS_LOCK) != 0) && ((KeyData->KeyState.KeyToggleState&CAPS_LOCK_ACTIVE) != 0))
+ ShiftState = !ShiftState;
+
+ switch (KeyDescriptor[i].Modifier) {
+ case EFI_NULL_MODIFIER:
+ Status = EFI_SUCCESS;
+ if (AltState && ShiftState) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].ShiftedAltGrUnicode;
+ }
+ else if (AltState && !ShiftState) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].AltGrUnicode;
+ }
+ else if (!AltState && ShiftState) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].ShiftedUnicode;
+ }
+ else if (!AltState && !ShiftState) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].Unicode;
+ }
+ break;
+ case EFI_NS_KEY_MODIFIER:
+ Status = EFI_SUCCESS;
+ if (AltState && ShiftState && (KeyDescriptor[i].ShiftedAltGrUnicode != 0x0000)) {
+ ModifierIndex = i;
+ ModifierUnicodeChar = KeyDescriptor[i].ShiftedAltGrUnicode;
+ KeyData->Key.UnicodeChar = 0x0000; // don't return a character yet, the next keypress will determine the correct character
+ }
+ else if (AltState && !ShiftState && (KeyDescriptor[i].AltGrUnicode != 0x0000)) {
+ ModifierIndex = i;
+ ModifierUnicodeChar = KeyDescriptor[i].AltGrUnicode;
+ KeyData->Key.UnicodeChar = 0x0000; // don't return a character yet, the next keypress will determine the correct character
+ }
+ else if (!AltState && ShiftState && (KeyDescriptor[i].ShiftedUnicode != 0x0000)) {
+ ModifierIndex = i;
+ ModifierUnicodeChar = KeyDescriptor[i].ShiftedUnicode;
+ KeyData->Key.UnicodeChar = 0x0000; // don't return a character yet, the next keypress will determine the correct character
+ }
+ else if (!AltState && !ShiftState && (KeyDescriptor[i].Unicode != 0x0000)) {
+ ModifierIndex = i;
+ ModifierUnicodeChar = KeyDescriptor[i].Unicode;
+ KeyData->Key.UnicodeChar = 0x0000; // don't return a character yet, the next keypress will determine the correct character
+ }
+ default:
+ case EFI_NS_KEY_DEPENDENCY_MODIFIER:
+ // skip deadkey-dependent modifiers and unknown modifiers
+ break;
+ } // switch (KeyDescriptor[i].Modifier)
+
+ if (!EFI_ERROR(Status) && (KeyData->Key.UnicodeChar != 0x0000 || ModifierUnicodeChar != 0x0000))
+ break; // successfully mapped a key, break for(...) loop
+ }
+ }
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/ConSplitter/ConSplit.h b/Core/CORE_DXE/ConSplitter/ConSplit.h
new file mode 100644
index 0000000..f64cad5
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/ConSplit.h
@@ -0,0 +1,553 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/ConSplit.h 4 8/02/13 4:27a Thomaschen $
+//
+// $Revision: 4 $
+//
+// $Date: 8/02/13 4:27a $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/ConSplit.h $
+//
+// 4 8/02/13 4:27a Thomaschen
+// Add for EIP109384.
+// [Files] ConSplit.c, ConSplit.h, In.c, CsmSimpleIn.c.
+//
+// 3 6/26/13 3:10a Thomaschen
+// Remove EIP109384.
+//
+// 1 6/04/13 1:53a Thomaschen
+// Fixed for EIP118202.
+//
+// 16 10/25/12 2:32a Deepthins
+// [TAG] EIP99475
+// [Category] Improvement
+// [Description] Multi language module Support in the console splitter
+// [Files] ConSplit.c, ConSplit.h , In.c and AmiKeycode.h
+//
+// 15 8/02/12 12:14p Artems
+// [TAG] EIP95607
+// [Category] Bug Fix
+// [Symptom] Execute nsh script and redirect output to file, then exit
+// from shell, setup screen will crash
+// [RootCause] Console splitter maintains global pool of supported
+// modes.
+// It's getting adjusted every time new SimpleTextOut (STO) is installed
+// If new STO doesn't support particular mode it is getting marked as
+// unsupported in global pool
+// However once this STO is uninstalled global pool isn't updated, so mode
+// is still marked as unsupported,
+// though system can support it
+// [Solution] Added reinitilization of global pool of supported modes on
+// STO uninstall event
+// [Files] Consplit.h Consplit.c
+//
+// 14 8/12/11 12:17p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 13 5/05/11 3:52p Artems
+// Added multi-language keyboard support
+//
+// 12 6/23/10 3:02p Felixp
+// SimplePointer splitter support is added.
+//
+// 11 7/07/09 3:35p Artems
+// Added functions headers according to code standard
+//
+// 10 9/17/07 4:04p Olegi
+// Added support for AMI_EFIKEYCODE_PROTOCOL and
+// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+//
+// 9 9/05/07 11:13a Felixp
+// SimpleTextInEx support removed. It causes problems. Support will add
+// again after Core labeling.
+//
+// 8 9/04/07 2:55p Olegi
+// Added EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL support.
+//
+// 7 1/05/07 4:23p Artems
+//
+// 6 12/29/06 3:01p Felixp
+// 1. Support for GraphicsOutput protocol added
+// 2. Support for more then one text mode added
+//
+// 5 9/27/06 7:42p Felixp
+// SetMode funciton of the ConsoleControl protocol is updated to restore
+// default UGA mode when switching from grphics to text.
+//
+// 4 3/13/06 2:37a Felixp
+//
+// 3 12/12/05 9:32a Felixp
+// Support for synchronization of console devices
+// (now screen is restored after legacy OpROM execution).
+//
+// 2 11/07/05 10:37a Felixp
+// LockStdIn function of ConsoleControl protocol implemented
+//
+// 1 1/28/05 1:16p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/07/05 11:57a Felixp
+//
+// 3 1/04/05 5:15p Robert
+// Changed component name to be more consistent with the other drivers
+// that have been developed
+//
+// 2 1/03/05 5:47p Robert
+// Working beta version of the consplitter
+//
+// 1 12/30/04 9:47a Robert
+// Initial check in
+//
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ConSplit.h
+//
+// Description: This file contains the structure and function prototypes needed
+// for the Console Splitter driver
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+#ifndef __CONSOLE_SPLITTER_H__
+#define __CONSOLE_SPLITTER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//--------------------------------------------------------------------------------
+
+#include <EFI.h>
+#include <Protocol\SimpleTextOut.h >
+#include <Protocol\SimpleTextIn.h>
+#include <Protocol\SimpleTextInEx.h>
+#include <Protocol\amikeycode.h>
+#include <Protocol\SimplePointer.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\ComponentName2.h>
+#include <AmiDxeLib.h>
+
+//--------------------------------------------------------------------------------
+
+#pragma pack (1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT_SIMPLE_POINTER
+//
+// Description:
+// This structure represents Splitter Simple Pointer devices linked list.
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Link DLINK Linked list pointer
+// SimplePointer EFI_SIMPLE_POINTER_PROTOCOL* Protocol pointer
+// Handle EFI_HANDLE Device handle
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _CON_SPLIT_SIMPLE_POINTER {
+ DLINK Link; //MUST BE THE FIRST FIELD
+ EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;
+ EFI_HANDLE Handle;
+} CON_SPLIT_SIMPLE_POINTER;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT_OUT
+//
+// Description:
+// This structure represents Splitter ConOut devices linked list
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Link DLINK Linked list pointer
+// SimpleOut EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* Protocol pointer
+// Handle EFI_HANDLE Device handle
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _CON_SPLIT_OUT
+ {
+ DLINK Link; //MUST BE THE FIRST FIELD
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut;
+ EFI_HANDLE Handle;
+ } CON_SPLIT_OUT;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT_IN_KEY_NOTIFY
+//
+// Description:
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ DLINK Link; //MUST BE THE FIRST FIELD
+ EFI_KEY_DATA KeyData;
+ EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction;
+ DLIST NotifyHandleList;
+} CON_SPLIT_IN_KEY_NOTIFY;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT_IN_KEY_NOTIFY
+//
+// Description:
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ DLINK Link; //MUST BE THE FIRST FIELD
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx;
+ EFI_HANDLE NotifyHandle;
+} CON_SPLIT_IN_KEY_NOTIFY_HANDLE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT_IN
+//
+// Description:
+// This structure represents Splitter ConIn devices linked list
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Link DLINK Linked list pointer
+// SimpleIn EFI_SIMPLE_TEXT_INPUT_PROTOCOL* Protocol pointer
+// SimpleInEx EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL* Protocol pointer
+// KeycodeInEx AMI_EFIKEYCODE_PROTOCOL* Protocol pointer
+// Handle EFI_HANDLE Device handle
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _CON_SPLIT_IN
+ {
+ DLINK Link; //MUST BE THE FIRST FIELD
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx;
+ AMI_EFIKEYCODE_PROTOCOL *KeycodeInEx;
+ EFI_HANDLE Handle;
+ } CON_SPLIT_IN;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT
+//
+// Description:
+// This structure represents Splitter devices structure
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Input CON_SPLIT_IN Input devices linked list
+// Output CON_SPLIT_OUT Output devices linked list
+// StdErr CON_SPLIT_OUT Error output devices linked list
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _CON_SPLIT
+ {
+ CON_SPLIT_IN Input;
+ CON_SPLIT_OUT Output;
+ CON_SPLIT_OUT StdErr;
+ } CON_SPLIT;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SUPPORT_RES
+//
+// Description:
+// This structure represents Splitter supported resolutions database
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Columns INT32 Max number of text columns
+// Rows INT32 Max number of text rows
+// AllDevices BOOLEAN Flag if all devices support given resolution
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct __SUPPORT_RES
+ {
+ INT32 Columns;
+ INT32 Rows;
+ BOOLEAN AllDevices;
+ } SUPPORT_RES;
+
+#pragma pack()
+
+//-----------------------------------------------------------------------------------
+
+SUPPORT_RES *SupportedModes;
+
+//virtual splitter output buffer
+CHAR16 *ScreenBuffer;
+CHAR16 *EndOfTheScreen;
+INT32 *AttributeBuffer;
+INT32 Columns;
+
+extern SIMPLE_TEXT_OUTPUT_MODE MasterMode;
+extern EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL mCSOutProtocol;
+extern EFI_SIMPLE_TEXT_INPUT_PROTOCOL mCSSimpleInProtocol;
+extern EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL mCSSimpleInExProtocol;
+extern AMI_EFIKEYCODE_PROTOCOL mCSKeycodeInProtocol;
+extern DLIST ConInList;
+extern DLIST ConOutList;
+extern DLIST ConPointerList;
+extern DLIST ConInKeyNotifyList;
+extern BOOLEAN StdInLocked;
+extern EFI_SIMPLE_POINTER_PROTOCOL mCSSimplePointerProtocol;
+
+//-----------------------------------------------------------------------------------
+
+EFI_STATUS ConSplitterSimplePointerReset(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification );
+
+EFI_STATUS ConSplitterSimplePointerGetState(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN OUT EFI_SIMPLE_POINTER_STATE *State );
+
+VOID ConSplitterSimplePointerWaitForInput(
+ IN EFI_EVENT Event,
+ IN VOID *Context );
+
+EFI_STATUS CSSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
+
+EFI_STATUS CSStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS CSStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+EFI_STATUS CSReset(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+EFI_STATUS CSOutputString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+ );
+
+EFI_STATUS CSTestString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+ );
+
+EFI_STATUS CSQueryMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum,
+ OUT UINTN *Col,
+ OUT UINTN *Row
+ );
+
+EFI_STATUS CSSetMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum
+ );
+
+EFI_STATUS CSSetAttribute(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Attribute
+ );
+
+EFI_STATUS CSClearScreen(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
+ );
+
+EFI_STATUS CSSetCursorPosition(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+ );
+
+EFI_STATUS CSEnableCursor(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN Visible
+ );
+
+EFI_STATUS CSInReset(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN EV
+ );
+
+EFI_STATUS CSReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ );
+
+VOID CSWaitForKey(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+EFI_STATUS CSInResetEx(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN EV
+ );
+
+EFI_STATUS CSReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+ );
+
+EFI_STATUS
+CSReadEfiKey (
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+ );
+
+EFI_STATUS CSInSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+);
+
+EFI_STATUS CSInRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+);
+
+EFI_STATUS CSInUnRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+);
+
+VOID RestoreTheScreen(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut
+ );
+
+VOID SaveTheScreen(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut
+ );
+
+EFI_STATUS MemClearScreen(
+ VOID
+ );
+
+VOID SaveUgaMode(
+ IN EFI_HANDLE ControllerHandle
+ );
+
+VOID RestoreUgaMode(
+ IN EFI_HANDLE ControllerHandle
+ );
+
+EFI_STATUS InitModesTable(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN EFI_HANDLE Handle
+ );
+
+VOID UpdateModesTable(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN EFI_HANDLE Handle
+ );
+
+EFI_STATUS IsModeSupported(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum,
+ OUT INT32 *DeviceModeNumber
+ );
+
+EFI_STATUS ResizeSplitterBuffer(
+ IN INT32 ModeNum
+ );
+
+VOID UpdateMasterMode(
+ IN SIMPLE_TEXT_OUTPUT_MODE *Mode
+ );
+
+EFI_STATUS CSInKeyboardLayoutMap(
+ IN OUT AMI_EFI_KEY_DATA *KeyData
+ );
+
+VOID AdjustSupportedModes(
+ VOID
+ );
+
+EFI_STATUS KeyboardLayoutMap(
+ IN AMI_MULTI_LANG_SUPPORT_PROTOCOL *This,
+ IN OUT AMI_EFI_KEY_DATA *KeyData
+ );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_DXE/ConSplitter/ConSplitter.cif b/Core/CORE_DXE/ConSplitter/ConSplitter.cif
new file mode 100644
index 0000000..ff3fc94
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/ConSplitter.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "ConSplitter"
+ category = ModulePart
+ LocalRoot = "Core\CORE_DXE\ConSplitter\"
+ RefName = "ConSplitter"
+[files]
+"\ConSplitter.sdl"
+"\ConSplit.c"
+"\ConSplit.h"
+"\Out.c"
+"\In.c"
+<endComponent>
diff --git a/Core/CORE_DXE/ConSplitter/ConSplitter.sdl b/Core/CORE_DXE/ConSplitter/ConSplitter.sdl
new file mode 100644
index 0000000..730b34e
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/ConSplitter.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "PAUSEKEY_SUPPORT"
+ Value = "0"
+ Help = "Pause key support. ON - Pause key causes pause during POST. OFF - Pause key ignored."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REPORT_NO_CON_OUT_ERROR"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REPORT_NO_CON_IN_ERROR"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "CONSOLE_SPLITTER_DIR"
+End
+
diff --git a/Core/CORE_DXE/ConSplitter/In.c b/Core/CORE_DXE/ConSplitter/In.c
new file mode 100644
index 0000000..9d8d561
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/In.c
@@ -0,0 +1,1159 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/In.c 5 7/08/15 4:32a Chienhsieh $
+//
+// $Revision: 5 $
+//
+// $Date: 7/08/15 4:32a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/In.c $
+//
+// 5 7/08/15 4:32a Chienhsieh
+// Update for eip217417.
+//
+// 4 8/02/13 4:26a Thomaschen
+// Add for EIP109384.
+// [Files] ConSplit.c, ConSplit.h, In.c, CsmSimpleIn.c.
+//
+// 3 6/26/13 3:11a Thomaschen
+// Remove EIP109384.
+//
+// 1 6/04/13 1:52a Thomaschen
+// Fixed for EIP118202.
+//
+// 32 10/25/12 2:33a Deepthins
+// [TAG] EIP99475
+// [Category] Improvement
+// [Description] Multi language module Support in the console splitter
+//
+// [Files] ConSplit.c, ConSplit.h , In.c and AmiKeycode.h
+//
+// 31 7/20/12 10:38a Artems
+// [TAG] EIP93929
+// [Description] Implement support to initialize the Keyboard in first
+// call of readkeystoke in fast boot case
+// [Files] In.c
+//
+// 30 4/11/12 5:35p Artems
+// [TAG] EIPN/A
+// [Category] Bug Fix
+// [Symptom] Function SetState was not broadcasted to third party
+// drivers
+// [RootCause] Splitter uses AMI proprietary protocol to broadcast
+// SetState function
+// which is not installed by third party drivers
+// [Solution] Modified splitter to broadcast SetState function via
+// SimpleTextInEx protocol
+// [Files] in.c
+//
+// 29 3/21/12 12:53p Artems
+// EIP 83358: Fixed bug in SimplePointerGetState function, where
+// EFI_SUCCESS was lost if ohter device returns DEVICE_ERROR
+//
+// 28 9/22/11 6:29a Rameshr
+// [TAG] EIP63054
+// [Category] New Feature
+// [Description] 0000790: Add warning to ReadKeyStrokeEx for partial key
+// press
+// [Files] KeyboardCommonDefinitions.h, In.c, Kbc.h, Ps2Kbd.c,
+// Efiusbkb.c, efiusbkb.h
+//
+// 27 7/21/11 3:41p Aaronp
+// // [TAG] EIP65187
+// // [Category] Bug Fix
+// // [Severity] Minor
+// // [Symptom] unicode character was not returned when english selected
+// // and alt key pressed
+// // [RootCause] The EFI_HII_KEYBOARD_LAYOUT table provides the
+// AltGraphic
+// // and Shifted AltGraphic unicode definitions for key combinations, and
+// // there are NULL values for undefined key combinations.
+// // [Solution] Changed how the EFI_HII_KEYBOARD_LAYOUT table is
+// consumed
+// // so that the current unicode character in the AMI_EFI_KEY_DATA
+// structure
+// // will not be overwritten when the EFI_HII_KEYBOARD_LAYOUT has a NULL
+// // value in the matching table entry.
+// // [Files] In.c
+//
+// 25 5/05/11 4:53p Artems
+// Removed unnecessary checks
+//
+// 24 5/05/11 3:54p Artems
+// Added multi-language keyboard support
+//
+// 23 8/10/10 2:29p Vyacheslava
+// Initialized default value of Status in the
+// ConSplitterSimplePointerReset function.
+//
+// 22 6/23/10 3:02p Felixp
+// SimplePointer splitter support is added.
+//
+// 21 1/18/10 3:40a Rameshr
+// NumLock,Capslock,Scroll Lock LED's synced properly between Keyboard
+// connect and disconnect.
+// EIP 27917
+//
+// 20 10/09/09 12:15p Felixp
+// SetState function is updated to process all the physical devices
+// despite the errors returned by some of them.
+//
+// 19 8/13/09 3:04p Rameshr
+// When item "num-lock status" set off, Num-lock will keep open until in
+// DOS.
+// EIP:21757
+//
+// 18 7/07/09 3:35p Artems
+// Added functions headers according to code standard
+//
+// 17 4/30/09 5:45p Felixp
+// Minor improvements on the pause key implementation.
+//
+// 16 3/30/09 10:24a Pats
+// Issue: EIP 19547 - Pause key support needed in Aptio
+// Solution: Function CsReadEfiKey modified to enter pause loop when pause
+// key detected. Requires mod in Ps2Kbd.c and efiusbkb.c.
+//
+// 15 1/23/09 9:55a Rameshr
+// Symptom:SCT failure in ReadKeystrokeEx function.
+// Solution: Validated the Input parameters Keydata for the
+// ReadKeystrokeEx Function.
+// Eip: 19039
+//
+// 14 11/17/08 10:22a Rameshraju
+// Problem:SCT failure on RegisterKeyNotify, SetState and
+// UnregisterKeyNotify.
+// Fix : Validated the input parameters for RegisterKeyNotify, SetState
+// and UnregisterKeyNotify.
+// EIP:17578
+//
+// 13 10/08/08 4:27p Olegi
+// Implemented the Register/Unregister key notofocation function in
+// SimpletextinEx protocol.
+//
+// 12 3/17/08 4:49p Rameshraju
+// ReadEfiKey doesnt not return correct key value randomly.
+//
+// 11 1/31/08 12:00p Olegi
+// Numlock bootup state made setup driven.
+//
+// 10 11/16/07 4:05p Olegi
+// Modifications in CSReadKeyStroke function.
+//
+// 9 10/23/07 4:14p Olegi
+// Modifications in CSInSetState that allow the sync between the Input
+// Devices' LEDs.
+//
+// 8 10/16/07 10:47a Olegi
+// Modification in CSReadEfiKey().
+//
+// 7 9/17/07 4:04p Olegi
+// Added support for AMI_EFIKEYCODE_PROTOCOL and
+// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+//
+// 6 9/05/07 11:13a Felixp
+// SimpleTextInEx support removed. It causes problems. Support will add
+// again after Core labeling.
+//
+// 3 3/13/06 2:37a Felixp
+//
+// 2 11/07/05 10:37a Felixp
+// LockStdIn function of ConsoleControl protocol implemented
+//
+// 1 1/28/05 1:16p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/07/05 11:57a Felixp
+//
+// 2 1/03/05 5:47p Robert
+// Working beta version of the consplitter
+//
+// 1 12/30/04 9:47a Robert
+// Initial check in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Out.c
+//
+// Description: File contains the Simple Text Output functionality for the
+// Console Splitter Driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------------
+
+#include "ConSplit.h"
+#include "token.h"
+#include <Protocol/SimplePointer.h>
+
+//----------------------------------------------------------------------------
+extern EFI_HII_KEYBOARD_LAYOUT *gKeyDescriptorList;
+extern EFI_KEY_TOGGLE_STATE mCSToggleState;
+EFI_SIMPLE_POINTER_MODE gSimplePointerMode = {
+ 0x10000,
+ 0x10000,
+ 0x10000,
+ FALSE,
+ FALSE
+};
+
+VOID ConnectInputDevices(
+ VOID
+);
+
+//----------------------------------------------------------------------------
+
+EFI_SIMPLE_TEXT_INPUT_PROTOCOL mCSSimpleInProtocol = {
+ CSInReset,
+ CSReadKeyStroke,
+ NULL
+ } ;
+
+EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL mCSSimpleInExProtocol = {
+ CSInResetEx,
+ CSReadKeyStrokeEx,
+ NULL,
+ CSInSetState,
+ CSInRegisterKeyNotify,
+ CSInUnRegisterKeyNotify
+ } ;
+
+AMI_EFIKEYCODE_PROTOCOL mCSKeycodeInProtocol = {
+ CSInResetEx,
+ CSReadEfiKey,
+ NULL,
+ CSInSetState,
+ CSInRegisterKeyNotify,
+ CSInUnRegisterKeyNotify
+ } ;
+
+EFI_SIMPLE_POINTER_PROTOCOL mCSSimplePointerProtocol = {
+ ConSplitterSimplePointerReset,
+ ConSplitterSimplePointerGetState,
+ ConSplitterSimplePointerWaitForInput,
+ &gSimplePointerMode
+};
+
+//----------------------------------------------------------------------------
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConSplitterSimplePointerReset
+//
+// Description: Resets the pointer device hardware.
+//
+// Input:
+// *This - pointer to protocol instance.
+// ExtendedVerification - Driver may perform diagnostics on reset.
+//
+// Output:
+// EFI_SUCCESS - device was reset successfully
+// EFI_ERROR - some of devices returned error
+//
+//----------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ConSplitterSimplePointerReset (
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_STATUS TestStatus;
+ CON_SPLIT_SIMPLE_POINTER *ConSimplePointer = NULL;
+
+ if (StdInLocked)
+ return EFI_ACCESS_DENIED;
+
+ if (ConPointerList.pHead == NULL)
+ return EFI_DEVICE_ERROR;
+
+ ConSimplePointer = OUTTER(ConPointerList.pHead, Link, CON_SPLIT_SIMPLE_POINTER);
+
+ // we need to loop through all the registered simple pointer devices
+ // and call each of their Reset function
+ while (ConSimplePointer != NULL) {
+ TestStatus = ConSimplePointer->SimplePointer->Reset(ConSimplePointer->SimplePointer, ExtendedVerification);
+ ConSimplePointer = OUTTER( ConSimplePointer->Link.pNext, Link, CON_SPLIT_SIMPLE_POINTER );
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ return Status;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConSplitterSimplePointerGetState
+//
+// Description: Retrieves the current state of a pointer device.
+// Reads the next keystroke from the input device. The WaitForKey Event can
+// be used to test for existance of a keystroke via WaitForEvent () call.
+// If the ConIn is password locked make it look like no keystroke is availible
+//
+// Input:
+// This - Protocol instance pointer.
+// State - A pointer to the state information on the pointer device.
+//
+// Output:
+// EFI_SUCCESS - The keystroke information was returned.
+// EFI_NOT_READY - There was no keystroke data availiable.
+// EFI_DEVICE_ERROR - The keydtroke information was not returned due to
+// hardware errors.
+//
+//----------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ConSplitterSimplePointerGetState(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN OUT EFI_SIMPLE_POINTER_STATE *State )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_POINTER_STATE CurrentState;
+ CON_SPLIT_SIMPLE_POINTER *ConSimplePointer = NULL;
+ BOOLEAN EfiSuccessDetected = FALSE;
+ BOOLEAN EfiDeviceErrorDetected = FALSE;
+ BOOLEAN EfiNotReadyDetected = FALSE;
+
+ if (StdInLocked)
+ return EFI_ACCESS_DENIED;
+
+ if (ConPointerList.pHead == NULL)
+ return EFI_DEVICE_ERROR;
+
+ ConSimplePointer = OUTTER( ConPointerList.pHead, Link, CON_SPLIT_SIMPLE_POINTER );
+
+ State->RelativeMovementX = 0;
+ State->RelativeMovementY = 0;
+ State->RelativeMovementZ = 0;
+ State->LeftButton = FALSE;
+ State->RightButton = FALSE;
+
+ // we need to loop through all the registered simple pointer devices
+ while (ConSimplePointer != NULL) {
+
+ Status = ConSimplePointer->SimplePointer->GetState(ConSimplePointer->SimplePointer, &CurrentState);
+
+ if (!EFI_ERROR(Status)) {
+
+ EfiSuccessDetected = TRUE;
+
+ if (CurrentState.LeftButton)
+ State->LeftButton = TRUE;
+
+ if (CurrentState.RightButton)
+ State->RightButton = TRUE;
+
+ if ( CurrentState.RelativeMovementX != 0 && ConSimplePointer->SimplePointer->Mode->ResolutionX != 0 )
+ State->RelativeMovementX +=
+ (CurrentState.RelativeMovementX * (INT32)gSimplePointerMode.ResolutionX) /
+ (INT32)ConSimplePointer->SimplePointer->Mode->ResolutionX;
+
+ if ( CurrentState.RelativeMovementY != 0 && ConSimplePointer->SimplePointer->Mode->ResolutionY != 0 )
+ State->RelativeMovementY +=
+ (CurrentState.RelativeMovementY * (INT32)gSimplePointerMode.ResolutionY) /
+ (INT32)ConSimplePointer->SimplePointer->Mode->ResolutionY;
+
+ if ( CurrentState.RelativeMovementZ != 0 && ConSimplePointer->SimplePointer->Mode->ResolutionZ != 0 )
+ State->RelativeMovementZ +=
+ (CurrentState.RelativeMovementZ * (INT32)gSimplePointerMode.ResolutionZ) /
+ (INT32)ConSimplePointer->SimplePointer->Mode->ResolutionZ;
+
+ } else if (Status == EFI_DEVICE_ERROR) {
+ EfiDeviceErrorDetected = TRUE;
+ } else {
+ EfiNotReadyDetected = TRUE;
+ }
+
+ ConSimplePointer = OUTTER( ConSimplePointer->Link.pNext, Link, CON_SPLIT_SIMPLE_POINTER );
+ }
+
+ return (EfiSuccessDetected) ? EFI_SUCCESS : (EfiDeviceErrorDetected) ? EFI_DEVICE_ERROR : EFI_NOT_READY;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConSplitterSimplePointerWaitForInput
+//
+// Description: This is callback function for WaitForInputEvent to use with
+// WaitForEvent() to wait for input from the pointer device.
+//
+// Input:
+// Event - The Event assoicated with callback.
+// Context - Context registered when Event was created.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID ConSplitterSimplePointerWaitForInput(
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_STATUS TestStatus;
+ CON_SPLIT_SIMPLE_POINTER *ConSimplePointer = NULL;
+
+ if (StdInLocked)
+ return;
+
+ if (ConPointerList.pHead == NULL)
+ return;
+
+ ConSimplePointer = OUTTER( ConPointerList.pHead, Link, CON_SPLIT_SIMPLE_POINTER );
+
+ // loop through simple pointer events and check their events
+ // if one event has been signaled, signal my event and exit.
+ // we need to loop through all the registered simple pointer devices
+ while (ConSimplePointer != NULL) {
+ TestStatus = pBS->CheckEvent(ConSimplePointer->SimplePointer->WaitForInput);
+ ConSimplePointer = OUTTER( ConSimplePointer->Link.pNext, Link, CON_SPLIT_SIMPLE_POINTER );
+
+ if (!EFI_ERROR(TestStatus))
+ pBS->SignalEvent(Event);
+ }
+
+ return;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInReset
+//
+// Description:
+// This function resets the input device hardware. This routine is a part
+// of SimpleTextIn protocol implementation.
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This - pointer to protocol instance
+// IN BOOLEAN EV - flag if Extended verification has to be performed
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device was reset successfully
+// EFI_ERROR - some of devices returned error
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSInReset(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN EV
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_IN *SimpleIn;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ if (ConInList.pHead == NULL)
+ return EFI_SUCCESS;
+
+ SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN);
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their Reset function
+ while ( SimpleIn != NULL)
+ {
+ TestStatus = SimpleIn->SimpleIn->Reset(SimpleIn->SimpleIn, EV);
+ SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ return Status;
+
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSReadKeyStroke
+//
+// Description:
+// This function reads the next keystroke from the input device. This
+// routine is a part of SimpleTextIn protocol implementation
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This - pointer to protocol instance
+// OUT EFI_INPUT_KEY *Key - key pressed information
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Keystroke data successfully retrieved
+// EFI_NOT_READY - There was no keystroke data available
+// EFI_DEVICE_ERROR - The keystroke information was not returned
+// due to hardware error
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSReadKeyStroke(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+)
+{
+ EFI_STATUS Status;
+ AMI_EFI_KEY_DATA EfiKeyData;
+
+ Status = CSReadEfiKey ( (AMI_EFIKEYCODE_PROTOCOL*) This, &EfiKeyData );
+ if (Status == EFI_SUCCESS) {
+ //
+ // Check for the Partial Key. If found, SimpleTextIn ReadKeyStroke
+ // Should not return that Key has bee found.
+ //
+ if(EfiKeyData.Key.ScanCode == 00 && EfiKeyData.Key.UnicodeChar == 0 &&
+ (EfiKeyData.KeyState.KeyToggleState & KEY_STATE_EXPOSED )) {
+ return EFI_NOT_READY;
+ }
+ *Key = EfiKeyData.Key;
+ return EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSWaitForKey
+//
+// Description:
+// This function is a callback for the EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event
+// Checks whether the new key is available and if so - signals the event
+//
+// Input:
+// IN EFI_EVENT Event - event to signal
+// IN VOID *Context - pointer to event specific context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID CSWaitForKey(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_IN *SimpleIn;
+
+ if (StdInLocked) return ;
+ if (ConInList.pHead == NULL) return;
+
+// loop through simple in events and check their events
+// if one event has been signaled, signal my event and exit
+
+ SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN);
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their Reset function
+ while ( SimpleIn != NULL)
+ {
+ TestStatus = pBS->CheckEvent(SimpleIn->SimpleIn->WaitForKey);
+ SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN);
+
+ if (!EFI_ERROR(TestStatus))
+ pBS->SignalEvent (Event);
+ }
+
+ return;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInResetEx
+//
+// Description:
+// This function resets the input device hardware. This routine is a part
+// of SimpleTextInEx protocol implementation
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance
+// IN BOOLEAN ExtendedVerification - flag if Extended verification has to be performed
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device was reset successfully
+// EFI_ERROR - some of devices returned error
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSInResetEx(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification )
+{
+ return CSInReset(0, ExtendedVerification);
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSReadKeyStrokeEx
+//
+// Description:
+// This function reads the next keystroke from the input device. This
+// routine is a part of SimpleTextInEx protocol implementation
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance
+// OUT EFI_KEY_DATA *KeyData - key pressed information
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Keystroke data successfully retrieved
+// EFI_NOT_READY - There was no keystroke data available
+// EFI_DEVICE_ERROR - The keystroke information was not returned
+// due to hardware error
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+ AMI_EFI_KEY_DATA EfiKeyData;
+
+ if(KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = CSReadEfiKey ( (AMI_EFIKEYCODE_PROTOCOL*) This, &EfiKeyData );
+ if (Status == EFI_SUCCESS) {
+ KeyData->Key = EfiKeyData.Key;
+ KeyData->KeyState = EfiKeyData.KeyState;
+ return EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSReadEfiKey
+//
+// Description:
+// This function reads the next keystroke from the input device. This
+// routine is a part of AmiKeyCode protocol implementation
+//
+// Input:
+// IN AMI_EFIKEYCODE_PROTOCOL *This - pointer to protocol instance
+// OUT AMI_EFI_KEY_DATA *KeyData - key pressed information
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Keystroke data successfully retrieved
+// EFI_NOT_READY - There was no keystroke data available
+// EFI_DEVICE_ERROR - The keystroke information was not returned
+// due to hardware error
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSReadEfiKey (
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+)
+{
+ AMI_EFI_KEY_DATA TempKey;
+ EFI_STATUS Status = EFI_NOT_READY;
+ CON_SPLIT_IN *SimpleIn;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ ConnectInputDevices();
+
+ if (ConInList.pHead == NULL) return EFI_NOT_READY;
+
+ SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN);
+
+ pBS->SetMem(KeyData, sizeof(AMI_EFI_KEY_DATA), 0);
+
+ // we need to loop through all the registered EfiKey, SimpleInEx and
+ // SimpleIn devices and call each of their ReadKeyStroke function
+ while (SimpleIn != NULL)
+ {
+ if (SimpleIn->KeycodeInEx) {
+ Status = SimpleIn->KeycodeInEx->ReadEfikey(SimpleIn->KeycodeInEx, &TempKey);
+ } else if(SimpleIn->SimpleInEx != NULL) {
+ Status = SimpleIn->SimpleInEx->ReadKeyStrokeEx(
+ SimpleIn->SimpleInEx, (EFI_KEY_DATA*)&TempKey);
+ } else if(SimpleIn->SimpleIn != NULL) {
+ Status = SimpleIn->SimpleIn->ReadKeyStroke(
+ SimpleIn->SimpleIn, (EFI_INPUT_KEY*)&TempKey);
+ }
+
+ // Check for the Toggle State change
+ if (!EFI_ERROR(Status) && (TempKey.KeyState.KeyToggleState & TOGGLE_STATE_VALID)) {
+ if ((TempKey.KeyState.KeyToggleState & ~KEY_STATE_EXPOSED ) != mCSToggleState) {
+ mCSToggleState = (TempKey.KeyState.KeyToggleState & ~KEY_STATE_EXPOSED);
+ CSInSetState ( (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL*) This,
+ &mCSToggleState );
+ }
+ }
+
+ if (!EFI_ERROR(Status)) {
+ *KeyData = TempKey;
+ break;
+ }
+
+ SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN);
+ }
+#if PAUSEKEY_SUPPORT
+ if (!EFI_ERROR(Status) && TempKey.EfiKey == EfiKeyPause) {
+ while(TRUE) {
+ Status = CSReadEfiKey ( This, &TempKey );
+ if ((!EFI_ERROR(Status)) && (TempKey.EfiKey != EfiKeyPause) && (TempKey.EfiKey != 0x55)) {
+ break;
+ }
+ }
+ *KeyData = TempKey;
+ }
+#endif
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInSetState
+//
+// Description:
+// This function sets certain state for input device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance
+// IN EFI_KEY_TOGGLE_STATE *KeyToggleState - pointer to state to set
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Keystroke data successfully retrieved
+// EFI_UNSUPPORTED - Given state not supported
+// EFI_INVALID_PARAMETER - KeyToggleState is NULL
+// EFI_DEVICE_ERROR - input device not found
+// EFI_ACCESS_DENIED - input device is busy
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSInSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ CON_SPLIT_IN *SimpleIn;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ if (ConInList.pHead == NULL)
+ return EFI_UNSUPPORTED;
+
+ if(KeyToggleState == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!(*KeyToggleState & TOGGLE_STATE_VALID) ||
+ ((*KeyToggleState & (~(TOGGLE_STATE_VALID | KEY_STATE_EXPOSED |
+ SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE)))) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ mCSToggleState = *KeyToggleState; // Update global toggle state
+
+ SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN);
+
+ // we need to loop through all the registered KeycodeInEx devices
+ // and call each of their SetState function
+ while ( SimpleIn != NULL )
+ {
+ if (SimpleIn->SimpleInEx) {
+ SimpleIn->SimpleInEx->SetState(SimpleIn->SimpleInEx, KeyToggleState);
+ }
+ SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN);
+ }
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInKeyNotificationFunction
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS
+CSInKeyNotificationFunction(
+ IN EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ DLINK *ListPtr;
+ UINTN Index = 0;
+ UINTN Count = 0;
+ EFI_KEY_NOTIFY_FUNCTION *NotifyFunctionList = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ if (ConInKeyNotifyList.pHead == NULL) return EFI_DEVICE_ERROR;
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ ConInKeyNotifyList.Size * sizeof(EFI_KEY_NOTIFY_FUNCTION),
+ (VOID**)&NotifyFunctionList);
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY);
+
+ if (!MemCmp(&(CsInKeyNotify->KeyData), KeyData, sizeof(CsInKeyNotify->KeyData))) {
+ NotifyFunctionList[Count++] = CsInKeyNotify->KeyNotificationFunction;
+ }
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ NotifyFunctionList[Index](&(CsInKeyNotify->KeyData));
+ }
+
+ pBS->FreePool(NotifyFunctionList);
+
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInRegisterKeyNotify
+//
+// Description:
+// This function registers a notification function for a particular
+// keystroke of the input device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance
+// IN EFI_KEY_DATA *KeyData - key value
+// IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction - notification function
+// OUT EFI_HANDLE *NotifyHandle - returned registered handle
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - notification function registered successfully
+// EFI_INVALID_PARAMETER - KeyData/KeyNotificationFunction/NotifyHandle is NULL
+// EFI_DEVICE_ERROR - input device not found
+// EFI_ACCESS_DENIED - input device is busy
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSInRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ DLINK *ListPtr = NULL;
+ CON_SPLIT_IN *ConIn = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY_HANDLE *CsInNotifyHandle = NULL;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ if(KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY);
+
+ if ((!MemCmp(&CsInKeyNotify->KeyData, KeyData, sizeof(CsInKeyNotify->KeyData))) &&
+ (CsInKeyNotify->KeyNotificationFunction == KeyNotificationFunction)) {
+ *NotifyHandle = (EFI_HANDLE)&(CsInKeyNotify->Link);
+ return EFI_SUCCESS;
+ }
+
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(CON_SPLIT_IN_KEY_NOTIFY), &CsInKeyNotify);
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ MemCpy(&(CsInKeyNotify->KeyData), KeyData, sizeof(CsInKeyNotify->KeyData));
+ CsInKeyNotify->KeyNotificationFunction = KeyNotificationFunction;
+ DListAdd(&ConInKeyNotifyList, &(CsInKeyNotify->Link));
+ DListInit(&(CsInKeyNotify->NotifyHandleList));
+ // we need to loop through all the registered SimpleInEx
+ // and call each of their ReadKeyStroke function
+ for (ListPtr = ConInList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ ConIn = OUTTER(ListPtr, Link, CON_SPLIT_IN);
+
+ if (ConIn->SimpleInEx == NULL) {
+ continue;
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(CON_SPLIT_IN_KEY_NOTIFY_HANDLE), &CsInNotifyHandle);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+
+ CsInNotifyHandle->SimpleInEx = ConIn->SimpleInEx;
+ DListAdd(&(CsInKeyNotify->NotifyHandleList), &(CsInNotifyHandle->Link));
+
+ Status = ConIn->SimpleInEx->RegisterKeyNotify(ConIn->SimpleInEx,
+ KeyData, CSInKeyNotificationFunction, &(CsInNotifyHandle->NotifyHandle));
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ }
+
+ if (EFI_ERROR(Status)) {
+ for (ListPtr = CsInKeyNotify->NotifyHandleList.pHead;
+ ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInNotifyHandle = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY_HANDLE);
+
+ CsInNotifyHandle->SimpleInEx->UnregisterKeyNotify(
+ CsInNotifyHandle->SimpleInEx, CsInNotifyHandle->NotifyHandle);
+
+ DListDelete(&(CsInKeyNotify->NotifyHandleList), ListPtr);
+ pBS->FreePool(CsInNotifyHandle);
+ }
+
+ pBS->FreePool(CsInKeyNotify);
+
+ return Status;
+ }
+
+ *NotifyHandle = (EFI_HANDLE)&(CsInKeyNotify->Link);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInUnRegisterKeyNotify
+//
+// Description:
+// This function unregisters a notification function with given handle
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance
+// IN EFI_HANDLE NotificationHandle - handle to unregister
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - notification function unregistered successfully
+// EFI_INVALID_PARAMETER - NotificationHandle is NULL
+// EFI_DEVICE_ERROR - input device not found
+// EFI_ACCESS_DENIED - input device is busy
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSInUnRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ DLINK *ListPtr = NULL;
+ DLINK *HandleLink = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY_HANDLE *CsInNotifyHandle = NULL;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ if (NotificationHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY);
+
+ if (NotificationHandle == (EFI_HANDLE)&(CsInKeyNotify->Link)) {
+ DListDelete(&ConInKeyNotifyList, ListPtr);
+ break;
+ }
+ }
+
+ if (ListPtr == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // we need to loop through all the registered SimpleInEx
+ // and call each of their ReadKeyStroke function
+
+ for (HandleLink = CsInKeyNotify->NotifyHandleList.pHead; HandleLink != NULL;
+ HandleLink = HandleLink->pNext) {
+ CsInNotifyHandle = OUTTER(HandleLink, Link, CON_SPLIT_IN_KEY_NOTIFY_HANDLE);
+
+ Status = CsInNotifyHandle->SimpleInEx->UnregisterKeyNotify(
+ CsInNotifyHandle->SimpleInEx, CsInNotifyHandle->NotifyHandle);
+
+ DListDelete(&(CsInKeyNotify->NotifyHandleList), HandleLink);
+ Status = pBS->FreePool(CsInNotifyHandle);
+ }
+
+ Status = pBS->FreePool(CsInKeyNotify);
+
+ return Status;
+}
+
+
+#if FAST_BOOT_SUPPORT
+#include <Protocol/FastBootProtocol.h>
+static AMI_FAST_BOOT_PROTOCOL *AmiFbProtocol = NULL;
+
+VOID ConnectInputDevices(
+ VOID
+)
+{
+ EFI_STATUS Status;
+ static Executed = FALSE;
+
+ if(Executed)
+ return;
+
+ if(AmiFbProtocol == NULL) {
+ Status = pBS->LocateProtocol(&AmiFastBootProtocolGuid, NULL, &AmiFbProtocol);
+ if(EFI_ERROR(Status)) {
+ AmiFbProtocol = NULL;
+ return;
+ }
+ }
+
+ if(AmiFbProtocol->IsRuntime()) {
+ AmiFbProtocol->ConnectInputDevices();
+ Executed = TRUE;
+ }
+}
+
+#else //#if FAST_BOOT_SUPPORT
+VOID ConnectInputDevices(
+ VOID
+){return;}
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/ConSplitter/Out.c b/Core/CORE_DXE/ConSplitter/Out.c
new file mode 100644
index 0000000..d11ebc8
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/Out.c
@@ -0,0 +1,1323 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/ConSplitter/Out.c 19 7/06/12 11:31a Artems $
+//
+// $Revision: 19 $
+//
+// $Date: 7/06/12 11:31a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/ConSplitter/Out.c $
+//
+// 19 7/06/12 11:31a Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Support for monitor native resolution
+// [Files] Gc.c, Consplit.c, Out.c, Core_Dxe.sdl
+//
+// 18 10/27/11 12:50p Felixp
+// [TAG] EIP65867
+// [Category] Improvement
+// [Description] Screen content that was printed in a timer callback was
+// not getting restored after OpROM
+// execution.
+// The previous check-in didn't address all the issue.
+// This is a more sophisticated solution.
+//
+// 17 8/03/11 3:27p Felixp
+// [TAG] EIP65867
+// [Category] Improvement
+// [Description] Screen content that was printed in a timer callback was
+// not getting restored after OpROM execution.
+// RestoreTheScreen function is updated.
+//
+// 16 10/09/09 6:15p Felixp
+// UGA constant replaced with GOP constant (UEFI 2.1 compatibility)
+//
+// 15 7/07/09 3:35p Artems
+// Added functions headers according to code standard
+//
+// 14 6/16/09 5:49p Artems
+// EIP 21415 Fixed error with CursorVisible variable
+//
+// 11 10/23/07 10:13a Felixp
+// Bug fix: System was hanging in SCT during Simple Text Output protocol
+// testing
+// when "Enable Screen Ouput" SCT option was enabled.
+//
+// 10 7/20/07 12:16p Felixp
+// Clear the screen when switching from graphics screen to text screen
+// without mode switching
+//
+// 9 1/05/07 6:01p Artems
+//
+// 8 12/29/06 3:01p Felixp
+// 1. Support for GraphicsOutput protocol added
+// 2. Support for more then one text mode added
+//
+// 7 9/27/06 7:42p Felixp
+// SetMode funciton of the ConsoleControl protocol is updated to restore
+// default UGA mode when switching from grphics to text.
+//
+// 6 3/13/06 2:37a Felixp
+//
+// 5 12/12/05 8:36p Felixp
+// RestoreTheScreen update: Restore Cursor Status
+//
+// 4 12/12/05 9:32a Felixp
+// Support for synchronization of console devices
+// (now screen is restored after legacy OpROM execution).
+//
+// 3 7/21/05 5:12p Robert
+//
+// 2 1/31/05 11:31a Robert
+//
+// 1 1/28/05 1:16p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/07/05 11:57a Felixp
+//
+// 2 1/03/05 5:47p Robert
+// Working beta version of the consplitter
+//
+// 1 12/30/04 9:47a Robert
+// Initial check in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Out.c
+//
+// Description: File contains the Simple Text Output functionality for the
+// Console Splitter Driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------------
+
+#include "ConSplit.h"
+#include <Protocol/GraphicsOutput.h>
+
+//----------------------------------------------------------------------------
+
+#define DefaultAttribute 0x0F
+#define DefaultCursorVisible TRUE
+
+SUPPORT_RES *SupportedModes = NULL;
+
+SIMPLE_TEXT_OUTPUT_MODE MasterMode =
+ {
+ 1, // MaxMode
+ 0, // Current Mode
+ 0x0F, // Attribute
+ 0, // Column
+ 0, // Row
+ 1 // CursorVisible
+ };
+
+
+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL mCSOutProtocol =
+ {
+ CSReset,
+ CSOutputString,
+ CSTestString,
+ CSQueryMode,
+ CSSetMode,
+ CSSetAttribute,
+ CSClearScreen,
+ CSSetCursorPosition,
+ CSEnableCursor,
+ &MasterMode
+ };
+
+//****************************** Virtual ConOut **********************//
+CHAR16 *ScreenBuffer = NULL;
+CHAR16 *SaveScreenBuffer = NULL;
+CHAR16 *EndOfTheScreen = NULL;
+INT32 *AttributeBuffer = NULL;
+INT32 *SaveAttributeBuffer = NULL;
+INT32 Columns = 0;
+BOOLEAN BlankScreen = TRUE;
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ScrollScreen
+//
+// Description:
+// This function scrolls internal splitter buffer
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID ScrollScreen(
+ VOID
+)
+{
+ INT32 i;
+ CHAR16 *pChar = EndOfTheScreen - Columns;
+ INT32 *pAttr = AttributeBuffer + (pChar-ScreenBuffer);
+
+ pBS->CopyMem(
+ ScreenBuffer+Columns, ScreenBuffer,
+ sizeof(CHAR16)* (EndOfTheScreen - pChar)
+ );
+
+ for(i=0; i<Columns; i++)
+ {
+ *pChar++ = ' ';
+ *pAttr++ = MasterMode.Attribute;
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: MemOutputString
+//
+// Description:
+// This function puts string into internal splitter buffer
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN CHAR16 *String - pointer to string
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS MemOutputString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+)
+{
+ INT32 Col = MasterMode.CursorColumn;
+ UINTN Offset = MasterMode.CursorRow * Columns;
+ CHAR16 *pChar = ScreenBuffer + Offset + Col;
+ INT32 *pAttr = AttributeBuffer + Offset + Col;
+ BlankScreen = FALSE;
+
+ while(TRUE){
+ switch(*String){
+ case 0:
+ return EFI_SUCCESS;
+ case '\n':
+ if ((pChar + Columns) >= EndOfTheScreen)
+ ScrollScreen();
+ else
+ {
+ pChar += Columns;
+ pAttr += Columns;
+ }
+ break;
+ case '\r':
+ pChar -= Col;
+ pAttr -= Col;
+ Col = 0;
+ break;
+ case '\b':
+ if (Col)
+ {
+ pChar--;
+ pAttr--;
+ Col--;
+ }
+ break;
+ default:
+ if ((pChar + 1) == EndOfTheScreen)
+ {
+ ScrollScreen();
+ pChar -= Col;
+ pAttr -= Col;
+ Col = 0;
+ }
+ else
+ {
+ *pChar++ = *String;
+ *pAttr++ = MasterMode.Attribute;
+ Col++;
+ if (Col >= Columns)
+ Col = 0;
+ }
+ break;
+ }
+ String++;
+ }
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: RestoreTextScreen
+//
+// Description:
+// This function restores screen after switching mode
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *pScreen - pointer to protocol instance
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID RestoreTextScreen(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *pScreen
+)
+{
+ CHAR16 *pChar = ScreenBuffer, *pStr = ScreenBuffer;
+ INT32 Col = 0, *pAttr = AttributeBuffer, Attr;
+ CHAR16 c;
+
+ if (BlankScreen)
+ return;
+
+ Attr = *pAttr;
+ pScreen->SetCursorPosition(pScreen,0,0);
+ pScreen->SetAttribute(pScreen,Attr);
+
+ for(; pChar<EndOfTheScreen; pChar++, pAttr++)
+ {
+ if (Col == Columns || *pAttr != Attr)
+ {
+ c = *pChar;
+ *pChar = 0;
+ pScreen->OutputString(pScreen, pStr);
+ *pChar = c;
+ pStr = pChar;
+ if (*pAttr != Attr)
+ {
+ Attr = *pAttr;
+ pScreen->SetAttribute(pScreen, Attr);
+ }
+ else
+ {
+ Col=1;
+ continue;
+ }
+ }
+ Col++;
+ }
+ //print last row
+ c = *--pChar;
+ *pChar = 0;
+ pScreen->OutputString(pScreen, pStr);
+ *pChar = c;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: MemClearScreen
+//
+// Description:
+// This function clears internal splitter buffer
+//
+// Input:
+// VOID
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS MemClearScreen(
+ VOID
+)
+{
+ CHAR16 *pChar;
+ INT32 *pAttr;
+ for( pChar = ScreenBuffer, pAttr = AttributeBuffer
+ ; pChar < EndOfTheScreen
+ ; pChar++, pAttr++ )
+ {
+ *pChar = ' ';
+ *pAttr = MasterMode.Attribute;
+ }
+ BlankScreen = TRUE;
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: MemReset
+//
+// Description:
+// This function resets internal splitter buffer
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN BOOLEAN EV - extended verification flag
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS MemReset(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN EV
+)
+{
+ return MemClearScreen();
+}
+
+///////////////// Uga Save/Restore
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL *PixelBuffer = NULL;
+UINT32 GraphicsMode, TextMode = 0;
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: RestoreUgaScreen
+//
+// Description:
+// This function restores screen after switching from text to graphics mode
+//
+// Input:
+// IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This - pointer to protocol instance
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID RestoreUgaScreen(
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop
+)
+{
+ if (PixelBuffer){
+ EFI_STATUS Status;
+ Status = Gop->SetMode(Gop, GraphicsMode);
+ if (!EFI_ERROR(Status))
+ Gop->Blt(
+ Gop, PixelBuffer, EfiBltBufferToVideo, 0, 0, 0, 0,
+ Gop->Mode->Info->HorizontalResolution,
+ Gop->Mode->Info->VerticalResolution, 0
+ );
+ pBS->FreePool(PixelBuffer);
+ PixelBuffer = NULL;
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SaveUgaScreen
+//
+// Description:
+// This function saves graphics screen before switching to text mode
+//
+// Input:
+// IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This - pointer to protocol instance
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID SaveUgaScreen(
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop
+)
+{
+ if (PixelBuffer)
+ pBS->FreePool(PixelBuffer);
+
+ GraphicsMode=Gop->Mode->Mode;
+ PixelBuffer = Malloc(
+ Gop->Mode->Info->VerticalResolution*
+ Gop->Mode->Info->HorizontalResolution*
+ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ if (PixelBuffer)
+ {
+ EFI_STATUS Status=Gop->Blt(
+ Gop, PixelBuffer, EfiBltVideoToBltBuffer, 0, 0, 0, 0,
+ Gop->Mode->Info->HorizontalResolution,
+ Gop->Mode->Info->VerticalResolution, 0);
+
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(PixelBuffer);
+ PixelBuffer = NULL;
+ }
+ }
+}
+
+static EFI_GUID guidGop = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: RestoreTextScreenDelta
+//
+// Description:
+// This function checks to see if anything has changed on the screen since the
+// graphics output device was disabled. If something has changed, then it will
+// add that to the display.
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID RestoreTextScreenDelta(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *pScreen
+)
+{
+ UINT32 i;
+ CHAR16 StrBuffer[2] = {0, 0};
+ CONST UINT32 SizeOfScreen = (UINT32)((UINT8*)EndOfTheScreen-(UINT8*)ScreenBuffer) / sizeof(CHAR16);
+
+
+ // Check for differences from the old state, one by one
+ // If anything is different, update the screen with Simple Out protocol
+ for(i = 0; i < SizeOfScreen; i++)
+ {
+ if( (*(SaveScreenBuffer+i) != *(ScreenBuffer + i)) ||
+ (*(SaveAttributeBuffer+i) != *(AttributeBuffer + i)) )
+ {
+ StrBuffer[0] = *(ScreenBuffer + i);
+ pScreen->SetCursorPosition(pScreen, i % Columns, i / Columns);
+ pScreen->SetAttribute(pScreen, (UINT8)*(AttributeBuffer + i) );
+ pScreen->OutputString(pScreen, StrBuffer );
+ }
+ }
+
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: RestoreTheScreen
+//
+// Description:
+// This function restores screen of the output device after switching modes
+//
+// Input:
+// IN EFI_HANDLE ControllerHandle - handle of output device to restore
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut - pointer to protocol instance
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID RestoreTheScreen(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut
+)
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+
+ if (EFI_ERROR(pBS->HandleProtocol(ControllerHandle, &guidGop, &Gop)))
+ RestoreTextScreen(SimpleOut);
+ else
+ {
+ RestoreUgaScreen(Gop);
+ if(SaveScreenBuffer != NULL)
+ {
+ RestoreTextScreenDelta(SimpleOut);
+ pBS->FreePool(SaveScreenBuffer);
+ pBS->FreePool(SaveAttributeBuffer);
+ }
+ }
+ SimpleOut->SetAttribute(SimpleOut,MasterMode.Attribute);
+ SimpleOut->EnableCursor(SimpleOut,MasterMode.CursorVisible);
+ SimpleOut->SetCursorPosition(SimpleOut,MasterMode.CursorColumn,MasterMode.CursorRow);
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SaveTheScreen
+//
+// Description:
+// This function saves the screen of the output device before switching modes
+//
+// Input:
+// IN EFI_HANDLE ControllerHandle - handle of output device to save
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut - pointer to protocol instance
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID SaveTheScreen(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut)
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+ UINT32 SizeOfScreen, SizeOfAttribute;
+ EFI_TPL OldTpl;
+
+ if (!EFI_ERROR(pBS->HandleProtocol(ControllerHandle, &guidGop, &Gop)))
+ {
+
+ SizeOfScreen = (UINT32)((UINT8*)EndOfTheScreen-(UINT8*)ScreenBuffer);
+ SizeOfAttribute = (UINT32)SizeOfScreen*(sizeof(INT32)/sizeof(CHAR16));
+
+ // Allocate memory for saving the screen state, error out if not enough memory
+ SaveScreenBuffer=Malloc(SizeOfScreen);
+ if(SaveScreenBuffer==NULL) return;
+ SaveAttributeBuffer=Malloc(SizeOfAttribute);
+ if(SaveAttributeBuffer==NULL){
+ pBS->FreePool(SaveScreenBuffer);
+ return;
+ }
+ // Make this high priority so that the saved text screen is exactly
+ // the same as graphics screen
+ OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+
+ // Perform using MemCpy (instead of pBS->MemCopy) to prevent TPL assert
+ MemCpy(SaveScreenBuffer, ScreenBuffer, SizeOfScreen);
+ MemCpy(SaveAttributeBuffer, AttributeBuffer, SizeOfAttribute);
+
+ pBS->RestoreTPL(OldTpl);
+ SaveUgaScreen(Gop);
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SaveUgaMode
+//
+// Description:
+// This function saves the graphics mode of the output device before switching modes
+//
+// Input:
+// IN EFI_HANDLE ControllerHandle - handle of output device to save
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID SaveUgaMode(
+ IN EFI_HANDLE ControllerHandle
+)
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+
+ if (EFI_ERROR(pBS->HandleProtocol(ControllerHandle, &guidGop, &Gop)))
+ return;
+
+ TextMode=Gop->Mode->Mode;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: RestoreUgaMode
+//
+// Description:
+// This function restores the graphics mode of the output device after switching modes
+//
+// Input:
+// IN EFI_HANDLE ControllerHandle - handle of output device to restore
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID RestoreUgaMode(
+ IN EFI_HANDLE ControllerHandle
+)
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+
+ if (EFI_ERROR(pBS->HandleProtocol(ControllerHandle, &guidGop, &Gop)))
+ return;
+
+ if (TextMode!=Gop->Mode->Mode)
+ {
+ Gop->SetMode(Gop,TextMode);
+ }
+ else
+ {//Just clear the screen
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Buffer = {0,0,0,0};
+ Gop->Blt( Gop, &Buffer, EfiBltVideoFill,0,0,0,0,
+ Gop->Mode->Info->HorizontalResolution,
+ Gop->Mode->Info->VerticalResolution,
+ 0
+ );
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSReset
+//
+// Description:
+// This function resets the text output device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN BOOLEAN EV - extended verification flag
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - all devices, handled by splitter were reset successfully
+// EFI_DEVICE_ERROR - error occured during resetting the device
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSReset(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN EV
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their Reset function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->Reset(SimpleOut->SimpleOut, EV);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ MemReset(This,EV);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSOutputString
+//
+// Description:
+// This function writes a string to the output device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN CHAR16 *String - pointer to string to write
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_DEVICE_ERROR - error occured during output string
+// EFI_WARN_UNKNOWN_GLYPH - some of characters were skipped during output
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSOutputString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ MemOutputString(This,String);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their OutputString function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->OutputString(SimpleOut->SimpleOut, String);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSTestString
+//
+// Description:
+// This function tests whether all characters in String can be drawn on device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN CHAR16 *String - pointer to string to test
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - all characters can be drawn
+// EFI_UNSUPPORTED - there are characters that cannot be drawn
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSTestString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their TestString function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->TestString(SimpleOut->SimpleOut, String);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSQueryMode
+//
+// Description:
+// This function returns information about text mode referred by ModeNum
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN UINTN ModeNum - mode number to obtain information about
+// OUT UINTN *Col - max number of columns supported in this mode
+// OUT UINTN *Row - max number of rows supported in this mode
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_UNSUPPORTED - given mode unsupported
+// EFI_DEVICE_ERROR - error occured during execution
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSQueryMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum,
+ OUT UINTN *Col,
+ OUT UINTN *Row
+)
+{
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if((ModeNum >= (UINTN)MasterMode.MaxMode) || (!SupportedModes[ModeNum].AllDevices))
+ return EFI_UNSUPPORTED;
+
+ if (SimpleOut == NULL)
+ {
+ // since we use a default text mode, return that value
+ *Col = 80;
+ *Row = 25;
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ *Col = SupportedModes[ModeNum].Columns;
+ *Row = SupportedModes[ModeNum].Rows;
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSSetMode
+//
+// Description:
+// This function sets text mode referred by ModeNumber
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN UINTN ModeNum - mode number to set
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_UNSUPPORTED - given mode unsupported
+// EFI_DEVICE_ERROR - error occured during execution
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSSetMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ INT32 DeviceMode;
+
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if((ModeNum >= (UINTN)MasterMode.MaxMode) || (!SupportedModes[ModeNum].AllDevices))
+ return EFI_UNSUPPORTED;
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ TestStatus = ResizeSplitterBuffer((INT32)ModeNum);
+ if (EFI_ERROR(TestStatus))
+ return TestStatus;
+
+ MasterMode.Mode = (INT32)ModeNum;
+ // we need to loop through all the registered simple text out devices
+ // and call each of their SetMode function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = IsModeSupported(SimpleOut->SimpleOut, ModeNum, &DeviceMode);
+
+ TestStatus = SimpleOut->SimpleOut->SetMode(SimpleOut->SimpleOut, DeviceMode);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ return EFI_ERROR(Status);
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSSetAttribute
+//
+// Description:
+// This function sets the foreground color and background color for the screen
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN UINTN Attribute - attribute to set
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - attribute was changed successfully
+// EFI_DEVICE_ERROR - device had an error
+// EFI_UNSUPPORTED - attribute is not supported
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSSetAttribute(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Attribute
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their SetAttribute function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->SetAttribute(SimpleOut->SimpleOut, Attribute);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSClearScreen
+//
+// Description:
+// This function clears screen of output device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_DEVICE_ERROR - error occured during execution
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSClearScreen(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their ClearScreen function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->ClearScreen(SimpleOut->SimpleOut);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ MemClearScreen();
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSSetCursorPosition
+//
+// Description:
+// This function sets cursor position of output device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN UINTN Column - column position
+// IN UINTN Row - row position
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_DEVICE_ERROR - error occured during execution
+// EFI_UNSUPPORTED - given position cannot be set
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSSetCursorPosition(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their SetCursorPosition function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->SetCursorPosition(SimpleOut->SimpleOut, Column, Row);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSEnableCursor
+//
+// Description:
+// This function enables / disables cursor on the screen
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN BOOLEAN Visible - if TRUE cursor will be visible, FALSE - not visible
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_DEVICE_ERROR - error occured during execution
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSEnableCursor(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN Visible )
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their SetCursorPosition function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->EnableCursor(SimpleOut->SimpleOut, Visible);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ MasterMode.CursorVisible = Visible;
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateMasterMode
+//
+// Description:
+// This function updates splitter mode to values referred by Mode
+//
+// Input:
+// IN SIMPLE_TEXT_OUTPUT_MODE *Mode - pointer to values to be set
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID UpdateMasterMode(
+ SIMPLE_TEXT_OUTPUT_MODE *Mode)
+{
+ MasterMode.Attribute = Mode->Attribute;
+ MasterMode.CursorColumn = Mode->CursorColumn;
+ MasterMode.CursorRow = Mode->CursorRow;
+ while(MasterMode.CursorColumn>=SupportedModes[MasterMode.Mode].Columns){
+ MasterMode.CursorColumn-=SupportedModes[MasterMode.Mode].Columns;
+ MasterMode.CursorRow++;
+ };
+ if (MasterMode.CursorRow>=SupportedModes[MasterMode.Mode].Rows)
+ MasterMode.CursorRow=SupportedModes[MasterMode.Mode].Rows-1;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************