+++ /dev/null
-/**@file\r
- Console Splitter Driver. Any Handle that attatched\r
- EFI_CONSOLE_IDENTIFIER_PROTOCOL can be bound by this driver.\r
-\r
- So far it works like any other driver by opening a SimpleTextIn and/or\r
- SimpleTextOut protocol with EFI_OPEN_PROTOCOL_BY_DRIVER attributes. The big\r
- difference is this driver does not layer a protocol on the passed in\r
- handle, or construct a child handle like a standard device or bus driver.\r
- This driver produces three virtual handles as children, one for console input\r
- splitter, one for console output splitter and one for error output splitter.\r
- EFI_CONSOLE_SPLIT_PROTOCOL will be attatched onto each virtual handle to\r
- identify the splitter type.\r
-\r
- Each virtual handle, that supports both the EFI_CONSOLE_SPLIT_PROTOCOL\r
- and Console I/O protocol, will be produced in the driver entry point.\r
- The virtual handle are added on driver entry and never removed.\r
- Such design ensures sytem function well during none console device situation.\r
-\r
-Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "ConSplitter.h"\r
-\r
-//\r
-// Global Variables\r
-//\r
-STATIC TEXT_IN_SPLITTER_PRIVATE_DATA mConIn = {\r
- TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
- (EFI_HANDLE) NULL,\r
- {\r
- ConSplitterTextInReset,\r
- ConSplitterTextInReadKeyStroke,\r
- (EFI_EVENT) NULL\r
- },\r
- 0,\r
- (EFI_SIMPLE_TEXT_IN_PROTOCOL **) NULL,\r
- 0,\r
-\r
- {\r
- ConSplitterSimplePointerReset,\r
- ConSplitterSimplePointerGetState,\r
- (EFI_EVENT) NULL,\r
- (EFI_SIMPLE_POINTER_MODE *) NULL\r
- },\r
- {\r
- 0x10000,\r
- 0x10000,\r
- 0x10000,\r
- TRUE,\r
- TRUE\r
- },\r
- 0,\r
- (EFI_SIMPLE_POINTER_PROTOCOL **) NULL,\r
- 0,\r
-\r
- FALSE,\r
- {\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
- },\r
- 0,\r
- {\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
- },\r
- (EFI_EVENT) NULL,\r
-\r
- FALSE,\r
- FALSE\r
-};\r
-\r
-STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
- (EFI_HANDLE) NULL,\r
- {\r
- ConSplitterTextOutReset,\r
- ConSplitterTextOutOutputString,\r
- ConSplitterTextOutTestString,\r
- ConSplitterTextOutQueryMode,\r
- ConSplitterTextOutSetMode,\r
- ConSplitterTextOutSetAttribute,\r
- ConSplitterTextOutClearScreen,\r
- ConSplitterTextOutSetCursorPosition,\r
- ConSplitterTextOutEnableCursor,\r
- (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL\r
- },\r
- {\r
- 1,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- FALSE,\r
- },\r
- {\r
- ConSpliterGraphicsOutputQueryMode,\r
- ConSpliterGraphicsOutputSetMode,\r
- ConSpliterGraphicsOutputBlt,\r
- NULL\r
- },\r
- (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
- (TEXT_OUT_GOP_MODE *) NULL,\r
- 0,\r
- TRUE,\r
- {\r
- ConSpliterConsoleControlGetMode,\r
- ConSpliterConsoleControlSetMode,\r
- ConSpliterConsoleControlLockStdIn\r
- },\r
-\r
- 0,\r
- (TEXT_OUT_AND_GOP_DATA *) NULL,\r
- 0,\r
- (TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,\r
- 0,\r
- (INT32 *) NULL,\r
-\r
- EfiConsoleControlScreenText,\r
- 0,\r
- 0,\r
- (CHAR16 *) NULL,\r
- (INT32 *) NULL\r
-};\r
-\r
-STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
- (EFI_HANDLE) NULL,\r
- {\r
- ConSplitterTextOutReset,\r
- ConSplitterTextOutOutputString,\r
- ConSplitterTextOutTestString,\r
- ConSplitterTextOutQueryMode,\r
- ConSplitterTextOutSetMode,\r
- ConSplitterTextOutSetAttribute,\r
- ConSplitterTextOutClearScreen,\r
- ConSplitterTextOutSetCursorPosition,\r
- ConSplitterTextOutEnableCursor,\r
- (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL\r
- },\r
- {\r
- 1,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- FALSE,\r
- },\r
- {\r
- ConSpliterGraphicsOutputQueryMode,\r
- ConSpliterGraphicsOutputSetMode,\r
- ConSpliterGraphicsOutputBlt,\r
- NULL\r
- },\r
- (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
- (TEXT_OUT_GOP_MODE *) NULL,\r
- 0,\r
- TRUE,\r
- {\r
- ConSpliterConsoleControlGetMode,\r
- ConSpliterConsoleControlSetMode,\r
- ConSpliterConsoleControlLockStdIn\r
- },\r
-\r
- 0,\r
- (TEXT_OUT_AND_GOP_DATA *) NULL,\r
- 0,\r
- (TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,\r
- 0,\r
- (INT32 *) NULL,\r
-\r
- EfiConsoleControlScreenText,\r
- 0,\r
- 0,\r
- (CHAR16 *) NULL,\r
- (INT32 *) NULL\r
-};\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gConSplitterConInDriverBinding = {\r
- ConSplitterConInDriverBindingSupported,\r
- ConSplitterConInDriverBindingStart,\r
- ConSplitterConInDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding = {\r
- ConSplitterSimplePointerDriverBindingSupported,\r
- ConSplitterSimplePointerDriverBindingStart,\r
- ConSplitterSimplePointerDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding = {\r
- ConSplitterConOutDriverBindingSupported,\r
- ConSplitterConOutDriverBindingStart,\r
- ConSplitterConOutDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding = {\r
- ConSplitterStdErrDriverBindingSupported,\r
- ConSplitterStdErrDriverBindingStart,\r
- ConSplitterStdErrDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterDriverEntry (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Intialize a virtual console device to act as an agrigator of physical console\r
- devices.\r
-\r
-Arguments:\r
- ImageHandle - (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
- SystemTable - (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
-Returns:\r
- EFI_SUCCESS\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // The driver creates virtual handles for ConIn, ConOut, and StdErr.\r
- // The virtual handles will always exist even if no console exist in the\r
- // system. This is need to support hotplug devices like USB.\r
- //\r
- //\r
- // Create virtual device handle for StdErr Splitter\r
- //\r
- Status = ConSplitterTextOutConstructor (&mStdErr);\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &mStdErr.VirtualHandle,\r
- &gEfiSimpleTextOutProtocolGuid,\r
- &mStdErr.TextOut,\r
- &gEfiPrimaryStandardErrorDeviceGuid,\r
- NULL,\r
- NULL\r
- );\r
- }\r
- //\r
- // Create virtual device handle for ConIn Splitter\r
- //\r
- Status = ConSplitterTextInConstructor (&mConIn);\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &mConIn.VirtualHandle,\r
- &gEfiSimpleTextInProtocolGuid,\r
- &mConIn.TextIn,\r
- &gEfiSimplePointerProtocolGuid,\r
- &mConIn.SimplePointer,\r
- &gEfiPrimaryConsoleInDeviceGuid,\r
- NULL,\r
- NULL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Update the EFI System Table with new virtual console\r
- //\r
- gST->ConsoleInHandle = mConIn.VirtualHandle;\r
- gST->ConIn = &mConIn.TextIn;\r
- }\r
- }\r
- //\r
- // Create virtual device handle for ConOut Splitter\r
- //\r
- Status = ConSplitterTextOutConstructor (&mConOut);\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // In UEFI mode, Graphics Output Protocol is installed on virtual handle.\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &mConOut.VirtualHandle,\r
- &gEfiSimpleTextOutProtocolGuid,\r
- &mConOut.TextOut,\r
- &gEfiGraphicsOutputProtocolGuid,\r
- &mConOut.GraphicsOutput,\r
- &gEfiConsoleControlProtocolGuid,\r
- &mConOut.ConsoleControl,\r
- &gEfiPrimaryConsoleOutDeviceGuid,\r
- NULL,\r
- NULL\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Update the EFI System Table with new virtual console\r
- //\r
- gST->ConsoleOutHandle = mConOut.VirtualHandle;\r
- gST->ConOut = &mConOut.TextOut;\r
- }\r
-\r
- }\r
- //\r
- // Update the CRC32 in the EFI System Table header\r
- //\r
- gST->Hdr.CRC32 = 0;\r
- gBS->CalculateCrc32 (\r
- (UINT8 *) &gST->Hdr,\r
- gST->Hdr.HeaderSize,\r
- &gST->Hdr.CRC32\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ConSplitterTextInConstructor (\r
- TEXT_IN_SPLITTER_PRIVATE_DATA *ConInPrivate\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Construct the ConSplitter.\r
-\r
-Arguments:\r
-\r
- ConInPrivate - A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA structure.\r
-\r
-Returns:\r
- EFI_OUT_OF_RESOURCES - Out of resources.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Initilize console input splitter's private data.\r
- //\r
- Status = ConSplitterGrowBuffer (\r
- sizeof (EFI_SIMPLE_TEXT_IN_PROTOCOL *),\r
- &ConInPrivate->TextInListCount,\r
- (VOID **) &ConInPrivate->TextInList\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Create Event to support locking StdIn Device\r
- //\r
- Status = gBS->CreateEvent (\r
- EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- ConSpliterConsoleControlLockStdInEvent,\r
- NULL,\r
- &ConInPrivate->LockEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_WAIT,\r
- TPL_NOTIFY,\r
- ConSplitterTextInWaitForKey,\r
- ConInPrivate,\r
- &ConInPrivate->TextIn.WaitForKey\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- ConInPrivate->SimplePointer.Mode = &ConInPrivate->SimplePointerMode;\r
-\r
- Status = ConSplitterGrowBuffer (\r
- sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),\r
- &ConInPrivate->PointerListCount,\r
- (VOID **) &ConInPrivate->PointerList\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_WAIT,\r
- TPL_NOTIFY,\r
- ConSplitterSimplePointerWaitForInput,\r
- ConInPrivate,\r
- &ConInPrivate->SimplePointer.WaitForInput\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-ConSplitterTextOutConstructor (\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *ConOutPrivate\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Initilize console output splitter's private data.\r
- //\r
- ConOutPrivate->TextOut.Mode = &ConOutPrivate->TextOutMode;\r
-\r
- Status = ConSplitterGrowBuffer (\r
- sizeof (TEXT_OUT_AND_GOP_DATA),\r
- &ConOutPrivate->TextOutListCount,\r
- (VOID **) &ConOutPrivate->TextOutList\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Status = ConSplitterGrowBuffer (\r
- sizeof (TEXT_OUT_SPLITTER_QUERY_DATA),\r
- &ConOutPrivate->TextOutQueryDataCount,\r
- (VOID **) &ConOutPrivate->TextOutQueryData\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Setup the DevNullTextOut console to 80 x 25\r
- //\r
- ConOutPrivate->TextOutQueryData[0].Columns = 80;\r
- ConOutPrivate->TextOutQueryData[0].Rows = 25;\r
- DevNullTextOutSetMode (ConOutPrivate, 0);\r
-\r
- //\r
- // Setup resource for mode information in Graphics Output Protocol interface\r
- //\r
- if ((ConOutPrivate->GraphicsOutput.Mode = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE))) == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- if ((ConOutPrivate->GraphicsOutput.Mode->Info = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel\r
- //\r
- if ((ConOutPrivate->GraphicsOutputModeBuffer = AllocateZeroPool (sizeof (TEXT_OUT_GOP_MODE))) == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- ConOutPrivate->GraphicsOutputModeBuffer[0].HorizontalResolution = 800;\r
- ConOutPrivate->GraphicsOutputModeBuffer[0].VerticalResolution = 600;\r
-\r
- //\r
- // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()\r
- // GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat\r
- // GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize\r
- //\r
- ConOutPrivate->GraphicsOutput.Mode->Info->Version = 0;\r
- ConOutPrivate->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly;\r
- ConOutPrivate->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
- ConOutPrivate->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
- ConOutPrivate->GraphicsOutput.Mode->FrameBufferSize = 0;\r
-\r
- ConOutPrivate->GraphicsOutput.Mode->MaxMode = 1;\r
- //\r
- // Initial current mode to unknow state, and then set to mode 0\r
- //\r
- ConOutPrivate->GraphicsOutput.Mode->Mode = 0xffff;\r
- ConOutPrivate->GraphicsOutput.SetMode (&ConOutPrivate->GraphicsOutput, 0);\r
-\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-ConSplitterSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_GUID *Guid\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Generic Supported Check\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller Handle.\r
- Guid - Guid.\r
-\r
-Returns:\r
-\r
- EFI_UNSUPPORTED - unsupported.\r
- EFI_SUCCESS - operation is OK.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- VOID *Instance;\r
-\r
- //\r
- // Make sure the Console Splitter does not attempt to attach to itself\r
- //\r
- if (ControllerHandle == mConIn.VirtualHandle) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (ControllerHandle == mConOut.VirtualHandle) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (ControllerHandle == mStdErr.VirtualHandle) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- //\r
- // Check to see whether the handle has the ConsoleInDevice GUID on it\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- Guid,\r
- &Instance,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- Guid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterConInDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Console In Supported Check\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
-\r
- EFI_STATUS\r
-\r
---*/\r
-{\r
- return ConSplitterSupported (\r
- This,\r
- ControllerHandle,\r
- &gEfiConsoleInDeviceGuid\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterSimplePointerDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Standard Error Supported Check\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
-\r
- EFI_STATUS\r
-\r
---*/\r
-{\r
- return ConSplitterSupported (\r
- This,\r
- ControllerHandle,\r
- &gEfiSimplePointerProtocolGuid\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterConOutDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Console Out Supported Check\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
-\r
- EFI_STATUS\r
-\r
---*/\r
-{\r
- return ConSplitterSupported (\r
- This,\r
- ControllerHandle,\r
- &gEfiConsoleOutDeviceGuid\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterStdErrDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Standard Error Supported Check\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
-\r
- EFI_STATUS\r
-\r
---*/\r
-{\r
- return ConSplitterSupported (\r
- This,\r
- ControllerHandle,\r
- &gEfiStandardErrorDeviceGuid\r
- );\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ConSplitterVirtualHandle,\r
- IN EFI_GUID *DeviceGuid,\r
- IN EFI_GUID *InterfaceGuid,\r
- IN VOID **Interface\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Start ConSplitter on ControllerHandle, and create the virtual\r
- agrogated console device on first call Start for a SimpleTextIn handle.\r
-\r
-Arguments:\r
- (Standard DriverBinding Protocol Start() function)\r
-\r
-Returns:\r
- EFI_ERROR if a SimpleTextIn protocol is not started.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- VOID *Instance;\r
-\r
- //\r
- // Check to see whether the handle has the ConsoleInDevice GUID on it\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- DeviceGuid,\r
- &Instance,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- DeviceGuid,\r
- &Instance,\r
- This->DriverBindingHandle,\r
- ConSplitterVirtualHandle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return gBS->OpenProtocol (\r
- ControllerHandle,\r
- InterfaceGuid,\r
- Interface,\r
- This->DriverBindingHandle,\r
- ConSplitterVirtualHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterConInDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Start ConSplitter on ControllerHandle, and create the virtual\r
- agrogated console device on first call Start for a SimpleTextIn handle.\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
-\r
- EFI_STATUS\r
- EFI_ERROR if a SimpleTextIn protocol is not started.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn;\r
-\r
- //\r
- // Start ConSplitter on ControllerHandle, and create the virtual\r
- // agrogated console device on first call Start for a SimpleTextIn handle.\r
- //\r
- Status = ConSplitterStart (\r
- This,\r
- ControllerHandle,\r
- mConIn.VirtualHandle,\r
- &gEfiConsoleInDeviceGuid,\r
- &gEfiSimpleTextInProtocolGuid,\r
- (VOID **) &TextIn\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return ConSplitterTextInAddDevice (&mConIn, TextIn);\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterSimplePointerDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Start ConSplitter on ControllerHandle, and create the virtual\r
- agrogated console device on first call Start for a SimpleTextIn handle.\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
-\r
- EFI_ERROR if a SimpleTextIn protocol is not started.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;\r
-\r
- Status = ConSplitterStart (\r
- This,\r
- ControllerHandle,\r
- mConIn.VirtualHandle,\r
- &gEfiSimplePointerProtocolGuid,\r
- &gEfiSimplePointerProtocolGuid,\r
- (VOID **) &SimplePointer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return ConSplitterSimplePointerAddDevice (&mConIn, SimplePointer);\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterConOutDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Start ConSplitter on ControllerHandle, and create the virtual\r
- agrogated console device on first call Start for a SimpleTextIn handle.\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
- EFI_ERROR if a SimpleTextIn protocol is not started.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut;\r
- EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
- EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
-\r
- Status = ConSplitterStart (\r
- This,\r
- ControllerHandle,\r
- mConOut.VirtualHandle,\r
- &gEfiConsoleOutDeviceGuid,\r
- &gEfiSimpleTextOutProtocolGuid,\r
- (VOID **) &TextOut\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Try to Open Graphics Output protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiGraphicsOutputProtocolGuid,\r
- (VOID **) &GraphicsOutput,\r
- This->DriverBindingHandle,\r
- mConOut.VirtualHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- GraphicsOutput = NULL;\r
- }\r
- //\r
- // Open UGA_DRAW protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiUgaDrawProtocolGuid,\r
- (VOID **) &UgaDraw,\r
- This->DriverBindingHandle,\r
- mConOut.VirtualHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- UgaDraw = NULL;\r
- }\r
- //\r
- // If both ConOut and StdErr incorporate the same Text Out device,\r
- // their MaxMode and QueryData should be the intersection of both.\r
- //\r
- Status = ConSplitterTextOutAddDevice (&mConOut, TextOut, GraphicsOutput, UgaDraw);\r
- ConSplitterTextOutSetAttribute (&mConOut.TextOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterStdErrDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Start ConSplitter on ControllerHandle, and create the virtual\r
- agrogated console device on first call Start for a SimpleTextIn handle.\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
- EFI_ERROR if a SimpleTextIn protocol is not started.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut;\r
-\r
- Status = ConSplitterStart (\r
- This,\r
- ControllerHandle,\r
- mStdErr.VirtualHandle,\r
- &gEfiStandardErrorDeviceGuid,\r
- &gEfiSimpleTextOutProtocolGuid,\r
- (VOID **) &TextOut\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // If both ConOut and StdErr incorporate the same Text Out device,\r
- // their MaxMode and QueryData should be the intersection of both.\r
- //\r
- Status = ConSplitterTextOutAddDevice (&mStdErr, TextOut, NULL, NULL);\r
- ConSplitterTextOutSetAttribute (&mStdErr.TextOut, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (mStdErr.CurrentNumberOfConsoles == 1) {\r
- gST->StandardErrorHandle = mStdErr.VirtualHandle;\r
- gST->StdErr = &mStdErr.TextOut;\r
- //\r
- // Update the CRC32 in the EFI System Table header\r
- //\r
- gST->Hdr.CRC32 = 0;\r
- gBS->CalculateCrc32 (\r
- (UINT8 *) &gST->Hdr,\r
- gST->Hdr.HeaderSize,\r
- &gST->Hdr.CRC32\r
- );\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ConSplitterVirtualHandle,\r
- IN EFI_GUID *DeviceGuid,\r
- IN EFI_GUID *InterfaceGuid,\r
- IN VOID **Interface\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- (Standard DriverBinding Protocol Stop() function)\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- InterfaceGuid,\r
- Interface,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // close the protocol refered.\r
- //\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- DeviceGuid,\r
- This->DriverBindingHandle,\r
- ConSplitterVirtualHandle\r
- );\r
- gBS->CloseProtocol (\r
- ControllerHandle,\r
- DeviceGuid,\r
- This->DriverBindingHandle,\r
- ControllerHandle\r
- );\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterConInDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- (Standard DriverBinding Protocol Stop() function)\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn;\r
-\r
- if (NumberOfChildren == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Status = ConSplitterStop (\r
- This,\r
- ControllerHandle,\r
- mConIn.VirtualHandle,\r
- &gEfiConsoleInDeviceGuid,\r
- &gEfiSimpleTextInProtocolGuid,\r
- (VOID **) &TextIn\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Delete this console input device's data structures.\r
- //\r
- return ConSplitterTextInDeleteDevice (&mConIn, TextIn);\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterSimplePointerDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- (Standard DriverBinding Protocol Stop() function)\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;\r
-\r
- if (NumberOfChildren == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Status = ConSplitterStop (\r
- This,\r
- ControllerHandle,\r
- mConIn.VirtualHandle,\r
- &gEfiSimplePointerProtocolGuid,\r
- &gEfiSimplePointerProtocolGuid,\r
- (VOID **) &SimplePointer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Delete this console input device's data structures.\r
- //\r
- return ConSplitterSimplePointerDeleteDevice (&mConIn, SimplePointer);\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterConOutDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- (Standard DriverBinding Protocol Stop() function)\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut;\r
-\r
- if (NumberOfChildren == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Status = ConSplitterStop (\r
- This,\r
- ControllerHandle,\r
- mConOut.VirtualHandle,\r
- &gEfiConsoleOutDeviceGuid,\r
- &gEfiSimpleTextOutProtocolGuid,\r
- (VOID **) &TextOut\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Delete this console output device's data structures.\r
- //\r
- return ConSplitterTextOutDeleteDevice (&mConOut, TextOut);\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterStdErrDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- (Standard DriverBinding Protocol Stop() function)\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Complete successfully.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut;\r
-\r
- if (NumberOfChildren == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Status = ConSplitterStop (\r
- This,\r
- ControllerHandle,\r
- mStdErr.VirtualHandle,\r
- &gEfiStandardErrorDeviceGuid,\r
- &gEfiSimpleTextOutProtocolGuid,\r
- (VOID **) &TextOut\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Delete this console error out device's data structures.\r
- //\r
- Status = ConSplitterTextOutDeleteDevice (&mStdErr, TextOut);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (mStdErr.CurrentNumberOfConsoles == 0) {\r
- gST->StandardErrorHandle = NULL;\r
- gST->StdErr = NULL;\r
- //\r
- // Update the CRC32 in the EFI System Table header\r
- //\r
- gST->Hdr.CRC32 = 0;\r
- gBS->CalculateCrc32 (\r
- (UINT8 *) &gST->Hdr,\r
- gST->Hdr.HeaderSize,\r
- &gST->Hdr.CRC32\r
- );\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-ConSplitterGrowBuffer (\r
- IN UINTN SizeOfCount,\r
- IN UINTN *Count,\r
- IN OUT VOID **Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Take the passed in Buffer of size SizeOfCount and grow the buffer\r
- by MAX (CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT, MaxGrow) * SizeOfCount\r
- bytes. Copy the current data in Buffer to the new version of Buffer\r
- and free the old version of buffer.\r
-\r
-\r
-Arguments:\r
- SizeOfCount - Size of element in array\r
- Count - Current number of elements in array\r
- Buffer - Bigger version of passed in Buffer with all the data\r
-\r
-Returns:\r
- EFI_SUCCESS - Buffer size has grown\r
- EFI_OUT_OF_RESOURCES - Could not grow the buffer size\r
-\r
- None\r
-\r
---*/\r
-{\r
- UINTN NewSize;\r
- UINTN OldSize;\r
- VOID *Ptr;\r
-\r
- //\r
- // grow the buffer to new buffer size,\r
- // copy the old buffer's content to the new-size buffer,\r
- // then free the old buffer.\r
- //\r
- OldSize = *Count * SizeOfCount;\r
- *Count += CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT;\r
- NewSize = *Count * SizeOfCount;\r
-\r
- Ptr = AllocateZeroPool (NewSize);\r
- if (Ptr == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- CopyMem (Ptr, *Buffer, OldSize);\r
-\r
- if (*Buffer != NULL) {\r
- FreePool (*Buffer);\r
- }\r
-\r
- *Buffer = Ptr;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ConSplitterTextInAddDevice (\r
- IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS\r
- EFI_OUT_OF_RESOURCES\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // If the Text In List is full, enlarge it by calling growbuffer().\r
- //\r
- if (Private->CurrentNumberOfConsoles >= Private->TextInListCount) {\r
- Status = ConSplitterGrowBuffer (\r
- sizeof (EFI_SIMPLE_TEXT_IN_PROTOCOL *),\r
- &Private->TextInListCount,\r
- (VOID **) &Private->TextInList\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
- //\r
- // Add the new text-in device data structure into the Text In List.\r
- //\r
- Private->TextInList[Private->CurrentNumberOfConsoles] = TextIn;\r
- Private->CurrentNumberOfConsoles++;\r
-\r
- //\r
- // Extra CheckEvent added to reduce the double CheckEvent() in UI.c\r
- //\r
- gBS->CheckEvent (TextIn->WaitForKey);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ConSplitterTextInDeleteDevice (\r
- IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS\r
- EFI_NOT_FOUND\r
-\r
---*/\r
-{\r
- UINTN Index;\r
- //\r
- // Remove the specified text-in device data structure from the Text In List,\r
- // and rearrange the remaining data structures in the Text In List.\r
- //\r
- for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
- if (Private->TextInList[Index] == TextIn) {\r
- for (Index = Index; Index < Private->CurrentNumberOfConsoles - 1; Index++) {\r
- Private->TextInList[Index] = Private->TextInList[Index + 1];\r
- }\r
-\r
- Private->CurrentNumberOfConsoles--;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-EFI_STATUS\r
-ConSplitterSimplePointerAddDevice (\r
- IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- EFI_OUT_OF_RESOURCES\r
- EFI_SUCCESS\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // If the Text In List is full, enlarge it by calling growbuffer().\r
- //\r
- if (Private->CurrentNumberOfPointers >= Private->PointerListCount) {\r
- Status = ConSplitterGrowBuffer (\r
- sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),\r
- &Private->PointerListCount,\r
- (VOID **) &Private->PointerList\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
- //\r
- // Add the new text-in device data structure into the Text In List.\r
- //\r
- Private->PointerList[Private->CurrentNumberOfPointers] = SimplePointer;\r
- Private->CurrentNumberOfPointers++;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ConSplitterSimplePointerDeleteDevice (\r
- IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- UINTN Index;\r
- //\r
- // Remove the specified text-in device data structure from the Text In List,\r
- // and rearrange the remaining data structures in the Text In List.\r
- //\r
- for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {\r
- if (Private->PointerList[Index] == SimplePointer) {\r
- for (Index = Index; Index < Private->CurrentNumberOfPointers - 1; Index++) {\r
- Private->PointerList[Index] = Private->PointerList[Index + 1];\r
- }\r
-\r
- Private->CurrentNumberOfPointers--;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-ConSplitterGrowMapTable (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- UINTN Size;\r
- UINTN NewSize;\r
- UINTN TotalSize;\r
- INT32 *TextOutModeMap;\r
- INT32 *OldTextOutModeMap;\r
- INT32 *SrcAddress;\r
- INT32 Index;\r
-\r
- NewSize = Private->TextOutListCount * sizeof (INT32);\r
- OldTextOutModeMap = Private->TextOutModeMap;\r
- TotalSize = NewSize * Private->TextOutQueryDataCount;\r
-\r
- TextOutModeMap = AllocateZeroPool (TotalSize);\r
- if (TextOutModeMap == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- SetMem (TextOutModeMap, TotalSize, 0xFF);\r
- Private->TextOutModeMap = TextOutModeMap;\r
-\r
- //\r
- // If TextOutList has been enlarged, need to realloc the mode map table\r
- // The mode map table is regarded as a two dimension array.\r
- //\r
- // Old New\r
- // 0 ---------> TextOutListCount ----> TextOutListCount\r
- // | -------------------------------------------\r
- // | | | |\r
- // | | | |\r
- // | | | |\r
- // | | | |\r
- // | | | |\r
- // \/ | | |\r
- // -------------------------------------------\r
- // QueryDataCount\r
- //\r
- if (OldTextOutModeMap != NULL) {\r
-\r
- Size = Private->CurrentNumberOfConsoles * sizeof (INT32);\r
- Index = 0;\r
- SrcAddress = OldTextOutModeMap;\r
-\r
- //\r
- // Copy the old data to the new one\r
- //\r
- while (Index < Private->TextOutMode.MaxMode) {\r
- CopyMem (TextOutModeMap, SrcAddress, Size);\r
- TextOutModeMap += NewSize;\r
- SrcAddress += Size;\r
- Index++;\r
- }\r
- //\r
- // Free the old buffer\r
- //\r
- FreePool (OldTextOutModeMap);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-ConSplitterAddOutputMode (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- INT32 MaxMode;\r
- INT32 Mode;\r
- UINTN Index;\r
-\r
- MaxMode = TextOut->Mode->MaxMode;\r
- Private->TextOutMode.MaxMode = MaxMode;\r
-\r
- //\r
- // Grow the buffer if query data buffer is not large enough to\r
- // hold all the mode supported by the first console.\r
- //\r
- while (MaxMode > (INT32) Private->TextOutQueryDataCount) {\r
- Status = ConSplitterGrowBuffer (\r
- sizeof (TEXT_OUT_SPLITTER_QUERY_DATA),\r
- &Private->TextOutQueryDataCount,\r
- (VOID **) &Private->TextOutQueryData\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
- //\r
- // Allocate buffer for the output mode map\r
- //\r
- Status = ConSplitterGrowMapTable (Private);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // As the first textout device, directly add the mode in to QueryData\r
- // and at the same time record the mapping between QueryData and TextOut.\r
- //\r
- Mode = 0;\r
- Index = 0;\r
- while (Mode < MaxMode) {\r
- TextOut->QueryMode (\r
- TextOut,\r
- Mode,\r
- &Private->TextOutQueryData[Mode].Columns,\r
- &Private->TextOutQueryData[Mode].Rows\r
- );\r
- Private->TextOutModeMap[Index] = Mode;\r
- Mode++;\r
- Index += Private->TextOutListCount;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-VOID\r
-ConSplitterGetIntersection (\r
- IN INT32 *TextOutModeMap,\r
- IN INT32 *NewlyAddedMap,\r
- IN UINTN MapStepSize,\r
- IN UINTN NewMapStepSize,\r
- OUT INT32 *MaxMode,\r
- OUT INT32 *CurrentMode\r
- )\r
-{\r
- INT32 Index;\r
- INT32 *CurrentMapEntry;\r
- INT32 *NextMapEntry;\r
- INT32 CurrentMaxMode;\r
- INT32 Mode;\r
-\r
- Index = 0;\r
- CurrentMapEntry = TextOutModeMap;\r
- NextMapEntry = TextOutModeMap;\r
- CurrentMaxMode = *MaxMode;\r
- Mode = *CurrentMode;\r
-\r
- while (Index < CurrentMaxMode) {\r
- if (*NewlyAddedMap == -1) {\r
- //\r
- // This mode is not supported any more. Remove it. Special care\r
- // must be taken as this remove will also affect current mode;\r
- //\r
- if (Index == *CurrentMode) {\r
- Mode = -1;\r
- } else if (Index < *CurrentMode) {\r
- Mode--;\r
- }\r
- (*MaxMode)--;\r
- } else {\r
- if (CurrentMapEntry != NextMapEntry) {\r
- CopyMem (NextMapEntry, CurrentMapEntry, MapStepSize * sizeof (INT32));\r
- }\r
-\r
- NextMapEntry += MapStepSize;\r
- }\r
-\r
- CurrentMapEntry += MapStepSize;\r
- NewlyAddedMap += NewMapStepSize;\r
- Index++;\r
- }\r
-\r
- *CurrentMode = Mode;\r
-\r
- return ;\r
-}\r
-\r
-STATIC\r
-VOID\r
-ConSplitterSyncOutputMode (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- Private - Private data structure.\r
- TextOut - Text Out Protocol.\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- INT32 CurrentMaxMode;\r
- INT32 Mode;\r
- INT32 Index;\r
- INT32 *TextOutModeMap;\r
- INT32 *MapTable;\r
- TEXT_OUT_SPLITTER_QUERY_DATA *TextOutQueryData;\r
- UINTN Rows;\r
- UINTN Columns;\r
- UINTN StepSize;\r
-\r
- //\r
- // Must make sure that current mode won't change even if mode number changes\r
- //\r
- CurrentMaxMode = Private->TextOutMode.MaxMode;\r
- TextOutModeMap = Private->TextOutModeMap;\r
- StepSize = Private->TextOutListCount;\r
- TextOutQueryData = Private->TextOutQueryData;\r
-\r
- //\r
- // Query all the mode that the newly added TextOut supports\r
- //\r
- Mode = 0;\r
- MapTable = TextOutModeMap + Private->CurrentNumberOfConsoles;\r
- while (Mode < TextOut->Mode->MaxMode) {\r
- TextOut->QueryMode (TextOut, Mode, &Columns, &Rows);\r
-\r
- //\r
- // Search the QueryData database to see if they intersects\r
- //\r
- Index = 0;\r
- while (Index < CurrentMaxMode) {\r
- if ((TextOutQueryData[Index].Rows == Rows) && (TextOutQueryData[Index].Columns == Columns)) {\r
- MapTable[Index * StepSize] = Mode;\r
- break;\r
- }\r
-\r
- Index++;\r
- }\r
-\r
- Mode++;\r
- }\r
- //\r
- // Now search the TextOutModeMap table to find the intersection of supported\r
- // mode between ConSplitter and the newly added device.\r
- //\r
- ConSplitterGetIntersection (\r
- TextOutModeMap,\r
- MapTable,\r
- StepSize,\r
- StepSize,\r
- &Private->TextOutMode.MaxMode,\r
- &Private->TextOutMode.Mode\r
- );\r
-\r
- return ;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-ConSplitterGetIntersectionBetweenConOutAndStrErr (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
- EFI_OUT_OF_RESOURCES\r
-\r
---*/\r
-{\r
- UINTN ConOutNumOfConsoles;\r
- UINTN StdErrNumOfConsoles;\r
- TEXT_OUT_AND_GOP_DATA *ConOutTextOutList;\r
- TEXT_OUT_AND_GOP_DATA *StdErrTextOutList;\r
- UINTN Indexi;\r
- UINTN Indexj;\r
- UINTN Rows;\r
- UINTN Columns;\r
- INT32 ConOutMaxMode;\r
- INT32 StdErrMaxMode;\r
- INT32 Mode;\r
- INT32 Index;\r
- INT32 *ConOutModeMap;\r
- INT32 *StdErrModeMap;\r
- INT32 *ConOutMapTable;\r
- INT32 *StdErrMapTable;\r
- TEXT_OUT_SPLITTER_QUERY_DATA *ConOutQueryData;\r
- TEXT_OUT_SPLITTER_QUERY_DATA *StdErrQueryData;\r
- BOOLEAN FoundTheSameTextOut;\r
- UINTN ConOutMapTableSize;\r
- UINTN StdErrMapTableSize;\r
-\r
- ConOutNumOfConsoles = mConOut.CurrentNumberOfConsoles;\r
- StdErrNumOfConsoles = mStdErr.CurrentNumberOfConsoles;\r
- ConOutTextOutList = mConOut.TextOutList;\r
- StdErrTextOutList = mStdErr.TextOutList;\r
-\r
- Indexi = 0;\r
- FoundTheSameTextOut = FALSE;\r
- while ((Indexi < ConOutNumOfConsoles) && (!FoundTheSameTextOut)) {\r
- Indexj = 0;\r
- while (Indexj < StdErrNumOfConsoles) {\r
- if (ConOutTextOutList->TextOut == StdErrTextOutList->TextOut) {\r
- FoundTheSameTextOut = TRUE;\r
- break;\r
- }\r
-\r
- Indexj++;\r
- StdErrTextOutList++;\r
- }\r
-\r
- Indexi++;\r
- ConOutTextOutList++;\r
- }\r
-\r
- if (!FoundTheSameTextOut) {\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // Must make sure that current mode won't change even if mode number changes\r
- //\r
- ConOutMaxMode = mConOut.TextOutMode.MaxMode;\r
- ConOutModeMap = mConOut.TextOutModeMap;\r
- ConOutQueryData = mConOut.TextOutQueryData;\r
-\r
- StdErrMaxMode = mStdErr.TextOutMode.MaxMode;\r
- StdErrModeMap = mStdErr.TextOutModeMap;\r
- StdErrQueryData = mStdErr.TextOutQueryData;\r
-\r
- //\r
- // Allocate the map table and set the map table's index to -1.\r
- //\r
- ConOutMapTableSize = ConOutMaxMode * sizeof (INT32);\r
- ConOutMapTable = AllocateZeroPool (ConOutMapTableSize);\r
- if (ConOutMapTable == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- SetMem (ConOutMapTable, ConOutMapTableSize, 0xFF);\r
-\r
- StdErrMapTableSize = StdErrMaxMode * sizeof (INT32);\r
- StdErrMapTable = AllocateZeroPool (StdErrMapTableSize);\r
- if (StdErrMapTable == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- SetMem (StdErrMapTable, StdErrMapTableSize, 0xFF);\r
-\r
- //\r
- // Find the intersection of the two set of modes. If they actually intersect, the\r
- // correponding entry in the map table is set to 1.\r
- //\r
- Mode = 0;\r
- while (Mode < ConOutMaxMode) {\r
- //\r
- // Search the other's QueryData database to see if they intersect\r
- //\r
- Index = 0;\r
- Rows = ConOutQueryData[Mode].Rows;\r
- Columns = ConOutQueryData[Mode].Columns;\r
- while (Index < StdErrMaxMode) {\r
- if ((StdErrQueryData[Index].Rows == Rows) && (StdErrQueryData[Index].Columns == Columns)) {\r
- ConOutMapTable[Mode] = 1;\r
- StdErrMapTable[Index] = 1;\r
- break;\r
- }\r
-\r
- Index++;\r
- }\r
-\r
- Mode++;\r
- }\r
- //\r
- // Now search the TextOutModeMap table to find the intersection of supported\r
- // mode between ConSplitter and the newly added device.\r
- //\r
- ConSplitterGetIntersection (\r
- ConOutModeMap,\r
- ConOutMapTable,\r
- mConOut.TextOutListCount,\r
- 1,\r
- &(mConOut.TextOutMode.MaxMode),\r
- &(mConOut.TextOutMode.Mode)\r
- );\r
- if (mConOut.TextOutMode.Mode < 0) {\r
- mConOut.TextOut.SetMode (&(mConOut.TextOut), 0);\r
- }\r
-\r
- ConSplitterGetIntersection (\r
- StdErrModeMap,\r
- StdErrMapTable,\r
- mStdErr.TextOutListCount,\r
- 1,\r
- &(mStdErr.TextOutMode.MaxMode),\r
- &(mStdErr.TextOutMode.Mode)\r
- );\r
- if (mStdErr.TextOutMode.Mode < 0) {\r
- mStdErr.TextOut.SetMode (&(mStdErr.TextOut), 0);\r
- }\r
-\r
- FreePool (ConOutMapTable);\r
- FreePool (StdErrMapTable);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-ConSplitterAddGraphicsOutputMode (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
- IN EFI_UGA_DRAW_PROTOCOL *UgaDraw\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- TEXT_OUT_GOP_MODE *Mode;\r
- UINTN SizeOfInfo;\r
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
- EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *CurrentGraphicsOutputMode;\r
- TEXT_OUT_GOP_MODE *ModeBuffer;\r
- TEXT_OUT_GOP_MODE *MatchedMode;\r
- UINTN NumberIndex;\r
- BOOLEAN Match;\r
-\r
- if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- CurrentGraphicsOutputMode = Private->GraphicsOutput.Mode;\r
-\r
- if (GraphicsOutput != NULL) {\r
- if (Private->CurrentNumberOfGraphicsOutput == 0) {\r
- //\r
- // This is the first Graphics Output device added\r
- //\r
- CurrentGraphicsOutputMode->MaxMode = GraphicsOutput->Mode->MaxMode;\r
- CurrentGraphicsOutputMode->Mode = GraphicsOutput->Mode->Mode;\r
- CopyMem (CurrentGraphicsOutputMode->Info, GraphicsOutput->Mode->Info, GraphicsOutput->Mode->SizeOfInfo);\r
- CurrentGraphicsOutputMode->SizeOfInfo = GraphicsOutput->Mode->SizeOfInfo;\r
- CurrentGraphicsOutputMode->FrameBufferBase = GraphicsOutput->Mode->FrameBufferBase;\r
- CurrentGraphicsOutputMode->FrameBufferSize = GraphicsOutput->Mode->FrameBufferSize;\r
-\r
- //\r
- // Allocate resource for the private mode buffer\r
- //\r
- ModeBuffer = AllocatePool (sizeof (TEXT_OUT_GOP_MODE) * GraphicsOutput->Mode->MaxMode);\r
- if (ModeBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- FreePool (Private->GraphicsOutputModeBuffer);\r
- Private->GraphicsOutputModeBuffer = ModeBuffer;\r
-\r
- //\r
- // Store all supported display modes to the private mode buffer\r
- //\r
- Mode = ModeBuffer;\r
- for (Index = 0; Index < GraphicsOutput->Mode->MaxMode; Index++) {\r
- Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) Index, &SizeOfInfo, &Info);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- Mode->HorizontalResolution = Info->HorizontalResolution;\r
- Mode->VerticalResolution = Info->VerticalResolution;\r
- Mode++;\r
- FreePool (Info);\r
- }\r
- } else {\r
- //\r
- // Check intersection of display mode\r
- //\r
- ModeBuffer = AllocatePool (sizeof (TEXT_OUT_GOP_MODE) * CurrentGraphicsOutputMode->MaxMode);\r
- if (ModeBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- MatchedMode = ModeBuffer;\r
- Mode = &Private->GraphicsOutputModeBuffer[0];\r
- for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {\r
- Match = FALSE;\r
-\r
- for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex++) {\r
- Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&\r
- (Info->VerticalResolution == Mode->VerticalResolution)){\r
- Match = TRUE;\r
- FreePool (Info);\r
- break;\r
- }\r
- FreePool (Info);\r
- }\r
-\r
- if (Match) {\r
- CopyMem (MatchedMode, Mode, sizeof (TEXT_OUT_GOP_MODE));\r
- MatchedMode++;\r
- }\r
-\r
- Mode++;\r
- }\r
-\r
- //\r
- // Drop the old mode buffer, assign it to a new one\r
- //\r
- FreePool (Private->GraphicsOutputModeBuffer);\r
- Private->GraphicsOutputModeBuffer = ModeBuffer;\r
-\r
- //\r
- // Physical frame buffer is no longer available when there are more than one physical GOP devices\r
- //\r
- CurrentGraphicsOutputMode->MaxMode = (UINT32) (((UINTN) MatchedMode - (UINTN) ModeBuffer) / sizeof (TEXT_OUT_GOP_MODE));\r
- CurrentGraphicsOutputMode->Info->PixelFormat = PixelBltOnly;\r
- ZeroMem (&CurrentGraphicsOutputMode->Info->PixelInformation, sizeof (EFI_PIXEL_BITMASK));\r
- CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
- CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
- CurrentGraphicsOutputMode->FrameBufferSize = 0;\r
- }\r
-\r
- //\r
- // Select a prefered Display mode 800x600\r
- //\r
- for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {\r
- Mode = &Private->GraphicsOutputModeBuffer[Index];\r
- if ((Mode->HorizontalResolution == 800) && (Mode->VerticalResolution == 600)) {\r
- break;\r
- }\r
- }\r
- //\r
- // Prefered mode is not found, set to mode 0\r
- //\r
- if (Index >= CurrentGraphicsOutputMode->MaxMode) {\r
- Index = 0;\r
- }\r
-\r
- //\r
- // Current mode number may need update now, so set it to an invalide mode number\r
- //\r
- CurrentGraphicsOutputMode->Mode = 0xffff;\r
- } else {\r
- //\r
- // For UGA device, it's inconvenient to retrieve all the supported display modes.\r
- // To simplify the implementation, only add one resolution(800x600, 32bit color depth) as defined in UEFI spec\r
- //\r
- CurrentGraphicsOutputMode->MaxMode = 1;\r
- CurrentGraphicsOutputMode->Info->Version = 0;\r
- CurrentGraphicsOutputMode->Info->HorizontalResolution = 800;\r
- CurrentGraphicsOutputMode->Info->VerticalResolution = 600;\r
- CurrentGraphicsOutputMode->Info->PixelFormat = PixelBltOnly;\r
- CurrentGraphicsOutputMode->Info->PixelsPerScanLine = 800;\r
- CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
- CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
- CurrentGraphicsOutputMode->FrameBufferSize = 0;\r
-\r
- //\r
- // Update the private mode buffer\r
- //\r
- ModeBuffer = &Private->GraphicsOutputModeBuffer[0];\r
- ModeBuffer->HorizontalResolution = 800;\r
- ModeBuffer->VerticalResolution = 600;\r
-\r
- //\r
- // Current mode is unknow now, set it to an invalid mode number 0xffff\r
- //\r
- CurrentGraphicsOutputMode->Mode = 0xffff;\r
- Index = 0;\r
- }\r
-\r
- //\r
- // Force GraphicsOutput mode to be set,\r
- // regardless whether the console is in EfiConsoleControlScreenGraphics or EfiConsoleControlScreenText mode\r
- //\r
- Private->HardwareNeedsStarting = TRUE;\r
- Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, (UINT32) Index);\r
-\r
- Private->CurrentNumberOfGraphicsOutput++;\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-ConSplitterTextOutAddDevice (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut,\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
- IN EFI_UGA_DRAW_PROTOCOL *UgaDraw\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINTN CurrentNumOfConsoles;\r
- INT32 CurrentMode;\r
- INT32 MaxMode;\r
- TEXT_OUT_AND_GOP_DATA *TextAndGop;\r
-\r
- Status = EFI_SUCCESS;\r
- CurrentNumOfConsoles = Private->CurrentNumberOfConsoles;\r
-\r
- //\r
- // If the Text Out List is full, enlarge it by calling growbuffer().\r
- //\r
- while (CurrentNumOfConsoles >= Private->TextOutListCount) {\r
- Status = ConSplitterGrowBuffer (\r
- sizeof (TEXT_OUT_AND_GOP_DATA),\r
- &Private->TextOutListCount,\r
- (VOID **) &Private->TextOutList\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Also need to reallocate the TextOutModeMap table\r
- //\r
- Status = ConSplitterGrowMapTable (Private);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
- TextAndGop = &Private->TextOutList[CurrentNumOfConsoles];\r
-\r
- TextAndGop->TextOut = TextOut;\r
- TextAndGop->GraphicsOutput = GraphicsOutput;\r
- TextAndGop->UgaDraw = UgaDraw;\r
-\r
- if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {\r
- //\r
- // If No UGA device then use the ConOut device\r
- //\r
- TextAndGop->TextOutEnabled = TRUE;\r
- } else {\r
- //\r
- // If UGA device use ConOut device only used if UGA screen is in Text mode\r
- //\r
- TextAndGop->TextOutEnabled = (BOOLEAN) (Private->ConsoleOutputMode == EfiConsoleControlScreenText);\r
- }\r
-\r
- if (CurrentNumOfConsoles == 0) {\r
- //\r
- // Add the first device's output mode to console splitter's mode list\r
- //\r
- Status = ConSplitterAddOutputMode (Private, TextOut);\r
- } else {\r
- ConSplitterSyncOutputMode (Private, TextOut);\r
- }\r
-\r
- Private->CurrentNumberOfConsoles++;\r
-\r
- //\r
- // Scan both TextOutList, for the intersection TextOut device\r
- // maybe both ConOut and StdErr incorporate the same Text Out\r
- // device in them, thus the output of both should be synced.\r
- //\r
- ConSplitterGetIntersectionBetweenConOutAndStrErr ();\r
-\r
- CurrentMode = Private->TextOutMode.Mode;\r
- MaxMode = Private->TextOutMode.MaxMode;\r
- ASSERT (MaxMode >= 1);\r
-\r
- if ((GraphicsOutput != NULL) || (UgaDraw != NULL)) {\r
- ConSplitterAddGraphicsOutputMode (Private, GraphicsOutput, UgaDraw);\r
- }\r
-\r
- if (Private->ConsoleOutputMode == EfiConsoleControlScreenGraphics && GraphicsOutput != NULL) {\r
- //\r
- // We just added a new UGA device in graphics mode\r
- //\r
- DevNullGopSync (Private, GraphicsOutput, UgaDraw);\r
- } else if ((CurrentMode >= 0) && ((GraphicsOutput != NULL) || (UgaDraw != NULL)) && (CurrentMode < Private->TextOutMode.MaxMode)) {\r
- //\r
- // The new console supports the same mode of the current console so sync up\r
- //\r
- DevNullSyncGopStdOut (Private);\r
- } else {\r
- //\r
- // If ConOut, then set the mode to Mode #0 which us 80 x 25\r
- //\r
- Private->TextOut.SetMode (&Private->TextOut, 0);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-ConSplitterTextOutDeleteDevice (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- INT32 Index;\r
- UINTN CurrentNumOfConsoles;\r
- TEXT_OUT_AND_GOP_DATA *TextOutList;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Remove the specified text-out device data structure from the Text out List,\r
- // and rearrange the remaining data structures in the Text out List.\r
- //\r
- CurrentNumOfConsoles = Private->CurrentNumberOfConsoles;\r
- Index = (INT32) CurrentNumOfConsoles - 1;\r
- TextOutList = Private->TextOutList;\r
- while (Index >= 0) {\r
- if (TextOutList->TextOut == TextOut) {\r
- CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_GOP_DATA) * Index);\r
- CurrentNumOfConsoles--;\r
- break;\r
- }\r
-\r
- Index--;\r
- TextOutList++;\r
- }\r
- //\r
- // The specified TextOut is not managed by the ConSplitter driver\r
- //\r
- if (Index < 0) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (CurrentNumOfConsoles == 0) {\r
- //\r
- // If the number of consoles is zero clear the Dev NULL device\r
- //\r
- Private->CurrentNumberOfConsoles = 0;\r
- Private->TextOutMode.MaxMode = 1;\r
- Private->TextOutQueryData[0].Columns = 80;\r
- Private->TextOutQueryData[0].Rows = 25;\r
- DevNullTextOutSetMode (Private, 0);\r
-\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // Max Mode is realy an intersection of the QueryMode command to all\r
- // devices. So we must copy the QueryMode of the first device to\r
- // QueryData.\r
- //\r
- ZeroMem (\r
- Private->TextOutQueryData,\r
- Private->TextOutQueryDataCount * sizeof (TEXT_OUT_SPLITTER_QUERY_DATA)\r
- );\r
-\r
- FreePool (Private->TextOutModeMap);\r
- Private->TextOutModeMap = NULL;\r
- TextOutList = Private->TextOutList;\r
-\r
- //\r
- // Add the first TextOut to the QueryData array and ModeMap table\r
- //\r
- Status = ConSplitterAddOutputMode (Private, TextOutList->TextOut);\r
-\r
- //\r
- // Now add one by one\r
- //\r
- Index = 1;\r
- Private->CurrentNumberOfConsoles = 1;\r
- TextOutList++;\r
- while ((UINTN) Index < CurrentNumOfConsoles) {\r
- ConSplitterSyncOutputMode (Private, TextOutList->TextOut);\r
- Index++;\r
- Private->CurrentNumberOfConsoles++;\r
- TextOutList++;\r
- }\r
-\r
- ConSplitterGetIntersectionBetweenConOutAndStrErr ();\r
-\r
- return Status;\r
-}\r
-//\r
-// ConSplitter TextIn member functions\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextInReset (\r
- IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Reset the input device and optionaly run diagnostics\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ExtendedVerification - Driver may perform diagnostics on reset.\r
-\r
- Returns:\r
- EFI_SUCCESS - The device was reset.\r
- EFI_DEVICE_ERROR - The device is not functioning properly and could\r
- not be reset.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS ReturnStatus;\r
- TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
-\r
- Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- Private->KeyEventSignalState = FALSE;\r
-\r
- //\r
- // return the worst status met\r
- //\r
- for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
- Status = Private->TextInList[Index]->Reset (\r
- Private->TextInList[Index],\r
- ExtendedVerification\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
-\r
- return ReturnStatus;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextInPrivateReadKeyStroke (\r
- IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
- OUT EFI_INPUT_KEY *Key\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Reads the next keystroke from the input device. The WaitForKey Event can\r
- be used to test for existance of a keystroke via WaitForEvent () call.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- Key - Driver may perform diagnostics on reset.\r
-\r
- Returns:\r
- EFI_SUCCESS - The keystroke information was returned.\r
- EFI_NOT_READY - There was no keystroke data availiable.\r
- EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
- hardware errors.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- EFI_INPUT_KEY CurrentKey;\r
-\r
- Key->UnicodeChar = 0;\r
- Key->ScanCode = SCAN_NULL;\r
-\r
- //\r
- // if no physical console input device exists, return EFI_NOT_READY;\r
- // if any physical console input device has key input,\r
- // return the key and EFI_SUCCESS.\r
- //\r
- for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
- Status = Private->TextInList[Index]->ReadKeyStroke (\r
- Private->TextInList[Index],\r
- &CurrentKey\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- *Key = CurrentKey;\r
- return Status;\r
- }\r
- }\r
-\r
- return EFI_NOT_READY;\r
-}\r
-\r
-BOOLEAN\r
-ConSpliterConssoleControlStdInLocked (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Return TRUE if StdIn is locked. The ConIn device on the virtual handle is\r
- the only device locked.\r
-\r
-Arguments:\r
- NONE\r
-\r
-Returns:\r
- TRUE - StdIn locked\r
- FALSE - StdIn working normally\r
-\r
---*/\r
-{\r
- return mConIn.PasswordEnabled;\r
-}\r
-\r
-VOID\r
-EFIAPI\r
-ConSpliterConsoleControlLockStdInEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- This timer event will fire when StdIn is locked. It will check the key\r
- sequence on StdIn to see if it matches the password. Any error in the\r
- password will cause the check to reset. As long a mConIn.PasswordEnabled is\r
- TRUE the StdIn splitter will not report any input.\r
-\r
-Arguments:\r
- (Standard EFI_EVENT_NOTIFY)\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_INPUT_KEY Key;\r
- CHAR16 BackSpaceString[2];\r
- CHAR16 SpaceString[2];\r
-\r
- do {\r
- Status = ConSplitterTextInPrivateReadKeyStroke (&mConIn, &Key);\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // if it's an ENTER, match password\r
- //\r
- if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN) && (Key.ScanCode == SCAN_NULL)) {\r
- mConIn.PwdAttempt[mConIn.PwdIndex] = CHAR_NULL;\r
- if (StrCmp (mConIn.Password, mConIn.PwdAttempt)) {\r
- //\r
- // Password not match\r
- //\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"\n\rPassword not correct\n\r");\r
- mConIn.PwdIndex = 0;\r
- } else {\r
- //\r
- // Key matches password sequence\r
- //\r
- gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, 0);\r
- mConIn.PasswordEnabled = FALSE;\r
- Status = EFI_NOT_READY;\r
- }\r
- } else if ((Key.UnicodeChar == CHAR_BACKSPACE) && (Key.ScanCode == SCAN_NULL)) {\r
- //\r
- // BackSpace met\r
- //\r
- if (mConIn.PwdIndex > 0) {\r
- BackSpaceString[0] = CHAR_BACKSPACE;\r
- BackSpaceString[1] = 0;\r
-\r
- SpaceString[0] = ' ';\r
- SpaceString[1] = 0;\r
-\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, BackSpaceString);\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, SpaceString);\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, BackSpaceString);\r
-\r
- mConIn.PwdIndex--;\r
- }\r
- } else if ((Key.ScanCode == SCAN_NULL) && (Key.UnicodeChar >= 32)) {\r
- //\r
- // If it's not an ENTER, neigher a function key, nor a CTRL-X or ALT-X, record the input\r
- //\r
- if (mConIn.PwdIndex < (MAX_STD_IN_PASSWORD - 1)) {\r
- if (mConIn.PwdIndex == 0) {\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"\n\r");\r
- }\r
-\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"*");\r
- mConIn.PwdAttempt[mConIn.PwdIndex] = Key.UnicodeChar;\r
- mConIn.PwdIndex++;\r
- }\r
- }\r
- }\r
- } while (!EFI_ERROR (Status));\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSpliterConsoleControlLockStdIn (\r
- IN EFI_CONSOLE_CONTROL_PROTOCOL *This,\r
- IN CHAR16 *Password\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- If Password is NULL unlock the password state variable and set the event\r
- timer. If the Password is too big return an error. If the Password is valid\r
- Copy the Password and enable state variable and then arm the periodic timer\r
-\r
-Arguments:\r
-\r
-Returns:\r
- EFI_SUCCESS - Lock the StdIn device\r
- EFI_INVALID_PARAMETER - Password is NULL\r
- EFI_OUT_OF_RESOURCES - Buffer allocation to store the password fails\r
-\r
---*/\r
-{\r
- if (Password == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (StrLen (Password) >= MAX_STD_IN_PASSWORD) {\r
- //\r
- // Currently have a max password size\r
- //\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- //\r
- // Save the password, initialize state variables and arm event timer\r
- //\r
- StrCpy (mConIn.Password, Password);\r
- mConIn.PasswordEnabled = TRUE;\r
- mConIn.PwdIndex = 0;\r
- gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, (10000 * 25));\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextInReadKeyStroke (\r
- IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,\r
- OUT EFI_INPUT_KEY *Key\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Reads the next keystroke from the input device. The WaitForKey Event can\r
- be used to test for existance of a keystroke via WaitForEvent () call.\r
- If the ConIn is password locked make it look like no keystroke is availible\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- Key - Driver may perform diagnostics on reset.\r
-\r
- Returns:\r
- EFI_SUCCESS - The keystroke information was returned.\r
- EFI_NOT_READY - There was no keystroke data availiable.\r
- EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
- hardware errors.\r
-\r
---*/\r
-{\r
- TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
-\r
- Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
- if (Private->PasswordEnabled) {\r
- //\r
- // If StdIn Locked return not ready\r
- //\r
- return EFI_NOT_READY;\r
- }\r
-\r
- Private->KeyEventSignalState = FALSE;\r
-\r
- return ConSplitterTextInPrivateReadKeyStroke (Private, Key);\r
-}\r
-\r
-VOID\r
-EFIAPI\r
-ConSplitterTextInWaitForKey (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- This event agregates all the events of the ConIn devices in the spliter.\r
- If the ConIn is password locked then return.\r
- If any events of physical ConIn devices are signaled, signal the ConIn\r
- spliter event. This will cause the calling code to call\r
- ConSplitterTextInReadKeyStroke ().\r
-\r
-Arguments:\r
- Event - The Event assoicated with callback.\r
- Context - Context registered when Event was created.\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
-\r
- Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context;\r
- if (Private->PasswordEnabled) {\r
- //\r
- // If StdIn Locked return not ready\r
- //\r
- return ;\r
- }\r
-\r
- //\r
- // if KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()\r
- //\r
- if (Private->KeyEventSignalState) {\r
- gBS->SignalEvent (Event);\r
- return ;\r
- }\r
- //\r
- // if any physical console input device has key input, signal the event.\r
- //\r
- for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
- Status = gBS->CheckEvent (Private->TextInList[Index]->WaitForKey);\r
- if (!EFI_ERROR (Status)) {\r
- gBS->SignalEvent (Event);\r
- Private->KeyEventSignalState = TRUE;\r
- }\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterSimplePointerReset (\r
- IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Reset the input device and optionaly run diagnostics\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ExtendedVerification - Driver may perform diagnostics on reset.\r
-\r
- Returns:\r
- EFI_SUCCESS - The device was reset.\r
- EFI_DEVICE_ERROR - The device is not functioning properly and could\r
- not be reset.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS ReturnStatus;\r
- TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
-\r
- Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);\r
-\r
- Private->InputEventSignalState = FALSE;\r
-\r
- if (Private->CurrentNumberOfPointers == 0) {\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // return the worst status met\r
- //\r
- for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfPointers; Index++) {\r
- Status = Private->PointerList[Index]->Reset (\r
- Private->PointerList[Index],\r
- ExtendedVerification\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
-\r
- return ReturnStatus;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterSimplePointerPrivateGetState (\r
- IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
- IN OUT EFI_SIMPLE_POINTER_STATE *State\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Reads the next keystroke from the input device. The WaitForKey Event can\r
- be used to test for existance of a keystroke via WaitForEvent () call.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- State -\r
-\r
- Returns:\r
- EFI_SUCCESS - The keystroke information was returned.\r
- EFI_NOT_READY - There was no keystroke data availiable.\r
- EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
- hardware errors.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS ReturnStatus;\r
- UINTN Index;\r
- EFI_SIMPLE_POINTER_STATE CurrentState;\r
-\r
- State->RelativeMovementX = 0;\r
- State->RelativeMovementY = 0;\r
- State->RelativeMovementZ = 0;\r
- State->LeftButton = FALSE;\r
- State->RightButton = FALSE;\r
-\r
- //\r
- // if no physical console input device exists, return EFI_NOT_READY;\r
- // if any physical console input device has key input,\r
- // return the key and EFI_SUCCESS.\r
- //\r
- ReturnStatus = EFI_NOT_READY;\r
- for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {\r
-\r
- Status = Private->PointerList[Index]->GetState (\r
- Private->PointerList[Index],\r
- &CurrentState\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- if (ReturnStatus == EFI_NOT_READY) {\r
- ReturnStatus = EFI_SUCCESS;\r
- }\r
-\r
- if (CurrentState.LeftButton) {\r
- State->LeftButton = TRUE;\r
- }\r
-\r
- if (CurrentState.RightButton) {\r
- State->RightButton = TRUE;\r
- }\r
-\r
- if (CurrentState.RelativeMovementX != 0 && Private->PointerList[Index]->Mode->ResolutionX != 0) {\r
- State->RelativeMovementX += (CurrentState.RelativeMovementX * (INT32) Private->SimplePointerMode.ResolutionX) / (INT32) Private->PointerList[Index]->Mode->ResolutionX;\r
- }\r
-\r
- if (CurrentState.RelativeMovementY != 0 && Private->PointerList[Index]->Mode->ResolutionY != 0) {\r
- State->RelativeMovementY += (CurrentState.RelativeMovementY * (INT32) Private->SimplePointerMode.ResolutionY) / (INT32) Private->PointerList[Index]->Mode->ResolutionY;\r
- }\r
-\r
- if (CurrentState.RelativeMovementZ != 0 && Private->PointerList[Index]->Mode->ResolutionZ != 0) {\r
- State->RelativeMovementZ += (CurrentState.RelativeMovementZ * (INT32) Private->SimplePointerMode.ResolutionZ) / (INT32) Private->PointerList[Index]->Mode->ResolutionZ;\r
- }\r
- } else if (Status == EFI_DEVICE_ERROR) {\r
- ReturnStatus = EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
- return ReturnStatus;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterSimplePointerGetState (\r
- IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
- IN OUT EFI_SIMPLE_POINTER_STATE *State\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Reads the next keystroke from the input device. The WaitForKey Event can\r
- be used to test for existance of a keystroke via WaitForEvent () call.\r
- If the ConIn is password locked make it look like no keystroke is availible\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- State -\r
-\r
- Returns:\r
- EFI_SUCCESS - The keystroke information was returned.\r
- EFI_NOT_READY - There was no keystroke data availiable.\r
- EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
- hardware errors.\r
-\r
---*/\r
-{\r
- TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
-\r
- Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);\r
- if (Private->PasswordEnabled) {\r
- //\r
- // If StdIn Locked return not ready\r
- //\r
- return EFI_NOT_READY;\r
- }\r
-\r
- Private->InputEventSignalState = FALSE;\r
-\r
- return ConSplitterSimplePointerPrivateGetState (Private, State);\r
-}\r
-\r
-VOID\r
-EFIAPI\r
-ConSplitterSimplePointerWaitForInput (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- This event agregates all the events of the ConIn devices in the spliter.\r
- If the ConIn is password locked then return.\r
- If any events of physical ConIn devices are signaled, signal the ConIn\r
- spliter event. This will cause the calling code to call\r
- ConSplitterTextInReadKeyStroke ().\r
-\r
-Arguments:\r
- Event - The Event assoicated with callback.\r
- Context - Context registered when Event was created.\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
-\r
- Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context;\r
- if (Private->PasswordEnabled) {\r
- //\r
- // If StdIn Locked return not ready\r
- //\r
- return ;\r
- }\r
-\r
- //\r
- // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()\r
- //\r
- if (Private->InputEventSignalState) {\r
- gBS->SignalEvent (Event);\r
- return ;\r
- }\r
- //\r
- // if any physical console input device has key input, signal the event.\r
- //\r
- for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {\r
- Status = gBS->CheckEvent (Private->PointerList[Index]->WaitForInput);\r
- if (!EFI_ERROR (Status)) {\r
- gBS->SignalEvent (Event);\r
- Private->InputEventSignalState = TRUE;\r
- }\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextOutReset (\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Reset the text output device hardware and optionaly run diagnostics\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ExtendedVerification - Driver may perform more exhaustive verfication\r
- operation of the device during reset.\r
-\r
- Returns:\r
- EFI_SUCCESS - The text output device was reset.\r
- EFI_DEVICE_ERROR - The text output device is not functioning correctly and\r
- could not be reset.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
- EFI_STATUS ReturnStatus;\r
-\r
- Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- //\r
- // return the worst status met\r
- //\r
- for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
-\r
- Status = Private->TextOutList[Index].TextOut->Reset (\r
- Private->TextOutList[Index].TextOut,\r
- ExtendedVerification\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
- }\r
-\r
- This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
-\r
- Status = DevNullTextOutSetMode (Private, 0);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
-\r
- return ReturnStatus;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextOutOutputString (\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
- IN CHAR16 *WString\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Write a Unicode string to the output device.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- String - The NULL-terminated Unicode string to be displayed on the output\r
- device(s). All output devices must also support the Unicode\r
- drawing defined in this file.\r
-\r
- Returns:\r
- EFI_SUCCESS - The string was output to the device.\r
- EFI_DEVICE_ERROR - The device reported an error while attempting to output\r
- the text.\r
- EFI_UNSUPPORTED - The output device's mode is not currently in a\r
- defined text mode.\r
- EFI_WARN_UNKNOWN_GLYPH - This warning code indicates that some of the\r
- characters in the Unicode string could not be\r
- rendered and were skipped.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
- UINTN BackSpaceCount;\r
- EFI_STATUS ReturnStatus;\r
- CHAR16 *TargetString;\r
-\r
- This->SetAttribute (This, This->Mode->Attribute);\r
-\r
- Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- BackSpaceCount = 0;\r
- for (TargetString = WString; *TargetString; TargetString++) {\r
- if (*TargetString == CHAR_BACKSPACE) {\r
- BackSpaceCount++;\r
- }\r
-\r
- }\r
-\r
- if (BackSpaceCount == 0) {\r
- TargetString = WString;\r
- } else {\r
- TargetString = AllocatePool (sizeof (CHAR16) * (StrLen (WString) + BackSpaceCount + 1));\r
- StrCpy (TargetString, WString);\r
- }\r
- //\r
- // return the worst status met\r
- //\r
- Status = DevNullTextOutOutputString (Private, TargetString);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
-\r
- for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->OutputString (\r
- Private->TextOutList[Index].TextOut,\r
- TargetString\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
- }\r
-\r
- if (BackSpaceCount) {\r
- FreePool (TargetString);\r
- }\r
-\r
- return ReturnStatus;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextOutTestString (\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
- IN CHAR16 *WString\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Verifies that all characters in a Unicode string can be output to the\r
- target device.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- String - The NULL-terminated Unicode string to be examined for the output\r
- device(s).\r
-\r
- Returns:\r
- EFI_SUCCESS - The device(s) are capable of rendering the output string.\r
- EFI_UNSUPPORTED - Some of the characters in the Unicode string cannot be\r
- rendered by one or more of the output devices mapped\r
- by the EFI handle.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
- EFI_STATUS ReturnStatus;\r
-\r
- Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- //\r
- // return the worst status met\r
- //\r
- for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->TestString (\r
- Private->TextOutList[Index].TextOut,\r
- WString\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
- }\r
- //\r
- // There is no DevNullTextOutTestString () since a Unicode buffer would\r
- // always return EFI_SUCCESS.\r
- // ReturnStatus will be EFI_SUCCESS if no consoles are present\r
- //\r
- return ReturnStatus;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextOutQueryMode (\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
- IN UINTN ModeNumber,\r
- OUT UINTN *Columns,\r
- OUT UINTN *Rows\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Returns information for an available text mode that the output device(s)\r
- supports.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ModeNumber - The mode number to return information on.\r
- Columns, Rows - Returns the geometry of the text output device for the\r
- requested ModeNumber.\r
-\r
- Returns:\r
- EFI_SUCCESS - The requested mode information was returned.\r
- EFI_DEVICE_ERROR - The device had an error and could not\r
- complete the request.\r
- EFI_UNSUPPORTED - The mode number was not valid.\r
-\r
---*/\r
-{\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
-\r
- Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- //\r
- // Check whether param ModeNumber is valid.\r
- // ModeNumber should be within range 0 ~ MaxMode - 1.\r
- //\r
- if ( (ModeNumber > (UINTN)(((UINT32)-1)>>1)) ) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if ((INT32) ModeNumber >= This->Mode->MaxMode) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- *Columns = Private->TextOutQueryData[ModeNumber].Columns;\r
- *Rows = Private->TextOutQueryData[ModeNumber].Rows;\r
-\r
- if (*Columns <= 0 && *Rows <= 0) {\r
- return EFI_UNSUPPORTED;\r
-\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextOutSetMode (\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
- IN UINTN ModeNumber\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Sets the output device(s) to a specified mode.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ModeNumber - The mode number to set.\r
-\r
- Returns:\r
- EFI_SUCCESS - The requested text mode was set.\r
- EFI_DEVICE_ERROR - The device had an error and\r
- could not complete the request.\r
- EFI_UNSUPPORTED - The mode number was not valid.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
- INT32 *TextOutModeMap;\r
- EFI_STATUS ReturnStatus;\r
-\r
- Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- //\r
- // Check whether param ModeNumber is valid.\r
- // ModeNumber should be within range 0 ~ MaxMode - 1.\r
- //\r
- if ( (ModeNumber > (UINTN)(((UINT32)-1)>>1)) ) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if ((INT32) ModeNumber >= This->Mode->MaxMode) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- //\r
- // If the mode is being set to the curent mode, then just clear the screen and return.\r
- //\r
- if (Private->TextOutMode.Mode == (INT32) ModeNumber) {\r
- return ConSplitterTextOutClearScreen (This);\r
- }\r
- //\r
- // return the worst status met\r
- //\r
- TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;\r
- for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->SetMode (\r
- Private->TextOutList[Index].TextOut,\r
- TextOutModeMap[Index]\r
- );\r
- //\r
- // If this console device is based on a UGA device, then sync up the bitmap from\r
- // the UGA splitter and reclear the text portion of the display in the new mode.\r
- //\r
- if ((Private->TextOutList[Index].GraphicsOutput != NULL) || (Private->TextOutList[Index].UgaDraw != NULL)) {\r
- Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
- }\r
- //\r
- // The DevNull Console will support any possible mode as it allocates memory\r
- //\r
- Status = DevNullTextOutSetMode (Private, ModeNumber);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
-\r
- return ReturnStatus;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextOutSetAttribute (\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
- IN UINTN Attribute\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Sets the background and foreground colors for the OutputString () and\r
- ClearScreen () functions.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- Attribute - The attribute to set. Bits 0..3 are the foreground color, and\r
- bits 4..6 are the background color. All other bits are undefined\r
- and must be zero. The valid Attributes are defined in this file.\r
-\r
- Returns:\r
- EFI_SUCCESS - The attribute was set.\r
- EFI_DEVICE_ERROR - The device had an error and\r
- could not complete the request.\r
- EFI_UNSUPPORTED - The attribute requested is not defined.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
- EFI_STATUS ReturnStatus;\r
-\r
- Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- //\r
- // Check whether param Attribute is valid.\r
- //\r
- if ( (Attribute > (UINTN)(((UINT32)-1)>>1)) ) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // return the worst status met\r
- //\r
- for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->SetAttribute (\r
- Private->TextOutList[Index].TextOut,\r
- Attribute\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
- }\r
-\r
- Private->TextOutMode.Attribute = (INT32) Attribute;\r
-\r
- return ReturnStatus;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextOutClearScreen (\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Clears the output device(s) display to the currently selected background\r
- color.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
-\r
- Returns:\r
- EFI_SUCCESS - The operation completed successfully.\r
- EFI_DEVICE_ERROR - The device had an error and\r
- could not complete the request.\r
- EFI_UNSUPPORTED - The output device is not in a valid text mode.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
- EFI_STATUS ReturnStatus;\r
-\r
- Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- //\r
- // return the worst status met\r
- //\r
- for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
- }\r
-\r
- Status = DevNullTextOutClearScreen (Private);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
-\r
- return ReturnStatus;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextOutSetCursorPosition (\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
- IN UINTN Column,\r
- IN UINTN Row\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Sets the current coordinates of the cursor position\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- Column, Row - the position to set the cursor to. Must be greater than or\r
- equal to zero and less than the number of columns and rows\r
- by QueryMode ().\r
-\r
- Returns:\r
- EFI_SUCCESS - The operation completed successfully.\r
- EFI_DEVICE_ERROR - The device had an error and\r
- could not complete the request.\r
- EFI_UNSUPPORTED - The output device is not in a valid text mode, or the\r
- cursor position is invalid for the current mode.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
- EFI_STATUS ReturnStatus;\r
- UINTN MaxColumn;\r
- UINTN MaxRow;\r
-\r
- Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- MaxColumn = Private->TextOutQueryData[Private->TextOutMode.Mode].Columns;\r
- MaxRow = Private->TextOutQueryData[Private->TextOutMode.Mode].Rows;\r
-\r
- if (Column >= MaxColumn || Row >= MaxRow) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- //\r
- // return the worst status met\r
- //\r
- for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->SetCursorPosition (\r
- Private->TextOutList[Index].TextOut,\r
- Column,\r
- Row\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
- }\r
-\r
- DevNullTextOutSetCursorPosition (Private, Column, Row);\r
-\r
- return ReturnStatus;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextOutEnableCursor (\r
- IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,\r
- IN BOOLEAN Visible\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Makes the cursor visible or invisible\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- Visible - If TRUE, the cursor is set to be visible. If FALSE, the cursor is\r
- set to be invisible.\r
-\r
- Returns:\r
- EFI_SUCCESS - The operation completed successfully.\r
- EFI_DEVICE_ERROR - The device had an error and could not complete the\r
- request, or the device does not support changing\r
- the cursor mode.\r
- EFI_UNSUPPORTED - The output device is not in a valid text mode.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
- UINTN Index;\r
- EFI_STATUS ReturnStatus;\r
-\r
- Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
-\r
- //\r
- // return the worst status met\r
- //\r
- for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->EnableCursor (\r
- Private->TextOutList[Index].TextOut,\r
- Visible\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
- }\r
- }\r
-\r
- DevNullTextOutEnableCursor (Private, Visible);\r
-\r
- return ReturnStatus;\r
-}\r