2 Console Splitter Driver. Any Handle that attatched console I/O protocols
3 (Console In device, Console Out device, Console Error device, Simple Pointer
4 protocol, Absolute Pointer protocol) can be bound by this driver.
6 So far it works like any other driver by opening a SimpleTextIn and/or
7 SimpleTextOut protocol with EFI_OPEN_PROTOCOL_BY_DRIVER attributes. The big
8 difference is this driver does not layer a protocol on the passed in
9 handle, or construct a child handle like a standard device or bus driver.
10 This driver produces three virtual handles as children, one for console input
11 splitter, one for console output splitter and one for error output splitter.
12 These 3 virtual handles would be installed on gST.
14 Each virtual handle, that supports the Console I/O protocol, will be produced
15 in the driver entry point. The virtual handle are added on driver entry and
16 never removed. Such design ensures sytem function well during none console
19 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
20 This program and the accompanying materials
21 are licensed and made available under the terms and conditions of the BSD License
22 which accompanies this distribution. The full text of the license may be found at
23 http://opensource.org/licenses/bsd-license.php
25 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
26 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
30 #include "ConSplitter.h"
33 // Text In Splitter Private Data template
35 GLOBAL_REMOVE_IF_UNREFERENCED TEXT_IN_SPLITTER_PRIVATE_DATA mConIn
= {
36 TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE
,
40 ConSplitterTextInReset
,
41 ConSplitterTextInReadKeyStroke
,
45 (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
**) NULL
,
49 ConSplitterTextInResetEx
,
50 ConSplitterTextInReadKeyStrokeEx
,
52 ConSplitterTextInSetState
,
53 ConSplitterTextInRegisterKeyNotify
,
54 ConSplitterTextInUnregisterKeyNotify
57 (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
**) NULL
,
65 ConSplitterSimplePointerReset
,
66 ConSplitterSimplePointerGetState
,
68 (EFI_SIMPLE_POINTER_MODE
*) NULL
78 (EFI_SIMPLE_POINTER_PROTOCOL
**) NULL
,
82 ConSplitterAbsolutePointerReset
,
83 ConSplitterAbsolutePointerGetState
,
85 (EFI_ABSOLUTE_POINTER_MODE
*) NULL
91 0x10000, // AbsoluteMaxX
92 0x10000, // AbsoluteMaxY
93 0x10000, // AbsoluteMaxZ
97 (EFI_ABSOLUTE_POINTER_PROTOCOL
**) NULL
,
107 // Uga Draw Protocol Private Data template
109 GLOBAL_REMOVE_IF_UNREFERENCED EFI_UGA_DRAW_PROTOCOL mUgaDrawProtocolTemplate
= {
110 ConSplitterUgaDrawGetMode
,
111 ConSplitterUgaDrawSetMode
,
112 ConSplitterUgaDrawBlt
116 // Graphics Output Protocol Private Data template
118 GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_PROTOCOL mGraphicsOutputProtocolTemplate
= {
119 ConSplitterGraphicsOutputQueryMode
,
120 ConSplitterGraphicsOutputSetMode
,
121 ConSplitterGraphicsOutputBlt
,
127 // Text Out Splitter Private Data template
129 GLOBAL_REMOVE_IF_UNREFERENCED TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut
= {
130 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
133 ConSplitterTextOutReset
,
134 ConSplitterTextOutOutputString
,
135 ConSplitterTextOutTestString
,
136 ConSplitterTextOutQueryMode
,
137 ConSplitterTextOutSetMode
,
138 ConSplitterTextOutSetAttribute
,
139 ConSplitterTextOutClearScreen
,
140 ConSplitterTextOutSetCursorPosition
,
141 ConSplitterTextOutEnableCursor
,
142 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
169 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
174 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
176 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
182 // Standard Error Text Out Splitter Data Template
184 GLOBAL_REMOVE_IF_UNREFERENCED TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr
= {
185 TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE
,
188 ConSplitterTextOutReset
,
189 ConSplitterTextOutOutputString
,
190 ConSplitterTextOutTestString
,
191 ConSplitterTextOutQueryMode
,
192 ConSplitterTextOutSetMode
,
193 ConSplitterTextOutSetAttribute
,
194 ConSplitterTextOutClearScreen
,
195 ConSplitterTextOutSetCursorPosition
,
196 ConSplitterTextOutEnableCursor
,
197 (EFI_SIMPLE_TEXT_OUTPUT_MODE
*) NULL
224 (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*) NULL
,
229 (TEXT_OUT_AND_GOP_DATA
*) NULL
,
231 (TEXT_OUT_SPLITTER_QUERY_DATA
*) NULL
,
237 // Driver binding instance for Console Input Device
239 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConInDriverBinding
= {
240 ConSplitterConInDriverBindingSupported
,
241 ConSplitterConInDriverBindingStart
,
242 ConSplitterConInDriverBindingStop
,
249 // Driver binding instance for Console Out device
251 EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding
= {
252 ConSplitterConOutDriverBindingSupported
,
253 ConSplitterConOutDriverBindingStart
,
254 ConSplitterConOutDriverBindingStop
,
261 // Driver binding instance for Standard Error device
263 EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding
= {
264 ConSplitterStdErrDriverBindingSupported
,
265 ConSplitterStdErrDriverBindingStart
,
266 ConSplitterStdErrDriverBindingStop
,
273 // Driver binding instance for Simple Pointer protocol
275 EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding
= {
276 ConSplitterSimplePointerDriverBindingSupported
,
277 ConSplitterSimplePointerDriverBindingStart
,
278 ConSplitterSimplePointerDriverBindingStop
,
285 // Driver binding instance for Absolute Pointer protocol
287 EFI_DRIVER_BINDING_PROTOCOL gConSplitterAbsolutePointerDriverBinding
= {
288 ConSplitterAbsolutePointerDriverBindingSupported
,
289 ConSplitterAbsolutePointerDriverBindingStart
,
290 ConSplitterAbsolutePointerDriverBindingStop
,
297 The Entry Point for module ConSplitter. The user code starts with this function.
299 Installs driver module protocols and. Creates virtual device handles for ConIn,
300 ConOut, and StdErr. Installs Simple Text In protocol, Simple Text In Ex protocol,
301 Simple Pointer protocol, Absolute Pointer protocol on those virtual handlers.
302 Installs Graphics Output protocol and/or UGA Draw protocol if needed.
304 @param[in] ImageHandle The firmware allocated handle for the EFI image.
305 @param[in] SystemTable A pointer to the EFI System Table.
307 @retval EFI_SUCCESS The entry point is executed successfully.
308 @retval other Some error occurs when executing this entry point.
313 ConSplitterDriverEntry(
314 IN EFI_HANDLE ImageHandle
,
315 IN EFI_SYSTEM_TABLE
*SystemTable
321 // Install driver model protocol(s).
323 Status
= EfiLibInstallDriverBindingComponentName2 (
326 &gConSplitterConInDriverBinding
,
328 &gConSplitterConInComponentName
,
329 &gConSplitterConInComponentName2
331 ASSERT_EFI_ERROR (Status
);
333 Status
= EfiLibInstallDriverBindingComponentName2 (
336 &gConSplitterSimplePointerDriverBinding
,
338 &gConSplitterSimplePointerComponentName
,
339 &gConSplitterSimplePointerComponentName2
341 ASSERT_EFI_ERROR (Status
);
343 Status
= EfiLibInstallDriverBindingComponentName2 (
346 &gConSplitterAbsolutePointerDriverBinding
,
348 &gConSplitterAbsolutePointerComponentName
,
349 &gConSplitterAbsolutePointerComponentName2
351 ASSERT_EFI_ERROR (Status
);
353 Status
= EfiLibInstallDriverBindingComponentName2 (
356 &gConSplitterConOutDriverBinding
,
358 &gConSplitterConOutComponentName
,
359 &gConSplitterConOutComponentName2
361 ASSERT_EFI_ERROR (Status
);
363 Status
= EfiLibInstallDriverBindingComponentName2 (
366 &gConSplitterStdErrDriverBinding
,
368 &gConSplitterStdErrComponentName
,
369 &gConSplitterStdErrComponentName2
371 ASSERT_EFI_ERROR (Status
);
374 // Either Graphics Output protocol or UGA Draw protocol must be supported.
376 ASSERT (FeaturePcdGet (PcdConOutGopSupport
) ||
377 FeaturePcdGet (PcdConOutUgaSupport
));
380 // The driver creates virtual handles for ConIn, ConOut.
381 // The virtual handles will always exist even if no console exist in the
382 // system. This is need to support hotplug devices like USB.
385 // Create virtual device handle for ConIn Splitter
387 Status
= ConSplitterTextInConstructor (&mConIn
);
388 if (!EFI_ERROR (Status
)) {
389 Status
= gBS
->InstallMultipleProtocolInterfaces (
390 &mConIn
.VirtualHandle
,
391 &gEfiSimpleTextInProtocolGuid
,
393 &gEfiSimpleTextInputExProtocolGuid
,
395 &gEfiSimplePointerProtocolGuid
,
396 &mConIn
.SimplePointer
,
397 &gEfiAbsolutePointerProtocolGuid
,
398 &mConIn
.AbsolutePointer
,
401 if (!EFI_ERROR (Status
)) {
403 // Update the EFI System Table with new virtual console
404 // and update the pointer to Simple Text Input protocol.
406 gST
->ConsoleInHandle
= mConIn
.VirtualHandle
;
407 gST
->ConIn
= &mConIn
.TextIn
;
411 // Create virtual device handle for ConOut Splitter
413 Status
= ConSplitterTextOutConstructor (&mConOut
);
414 if (!EFI_ERROR (Status
)) {
415 if (!FeaturePcdGet (PcdConOutGopSupport
)) {
417 // If Graphics Outpurt protocol not supported, UGA Draw protocol is installed
418 // on the virtual handle.
420 Status
= gBS
->InstallMultipleProtocolInterfaces (
421 &mConOut
.VirtualHandle
,
422 &gEfiSimpleTextOutProtocolGuid
,
424 &gEfiUgaDrawProtocolGuid
,
428 } else if (!FeaturePcdGet (PcdConOutUgaSupport
)) {
430 // If UGA Draw protocol not supported, Graphics Output Protocol is installed
431 // on virtual handle.
433 Status
= gBS
->InstallMultipleProtocolInterfaces (
434 &mConOut
.VirtualHandle
,
435 &gEfiSimpleTextOutProtocolGuid
,
437 &gEfiGraphicsOutputProtocolGuid
,
438 &mConOut
.GraphicsOutput
,
443 // Boot Graphics Output protocol and UGA Draw protocol are supported,
444 // both they will be installed on virtual handle.
446 Status
= gBS
->InstallMultipleProtocolInterfaces (
447 &mConOut
.VirtualHandle
,
448 &gEfiSimpleTextOutProtocolGuid
,
450 &gEfiGraphicsOutputProtocolGuid
,
451 &mConOut
.GraphicsOutput
,
452 &gEfiUgaDrawProtocolGuid
,
458 if (!EFI_ERROR (Status
)) {
460 // Update the EFI System Table with new virtual console
461 // and Update the pointer to Text Output protocol.
463 gST
->ConsoleOutHandle
= mConOut
.VirtualHandle
;
464 gST
->ConOut
= &mConOut
.TextOut
;
469 // Update the CRC32 in the EFI System Table header
472 gBS
->CalculateCrc32 (
483 Construct console input devices' private data.
485 @param ConInPrivate A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA
488 @retval EFI_OUT_OF_RESOURCES Out of resources.
489 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
490 @retval other Failed to construct private data.
494 ConSplitterTextInConstructor (
495 TEXT_IN_SPLITTER_PRIVATE_DATA
*ConInPrivate
501 // Allocate buffer for Simple Text Input device
503 Status
= ConSplitterGrowBuffer (
504 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
505 &ConInPrivate
->TextInListCount
,
506 (VOID
**) &ConInPrivate
->TextInList
508 if (EFI_ERROR (Status
)) {
509 return EFI_OUT_OF_RESOURCES
;
513 // Create Event to wait for a key
515 Status
= gBS
->CreateEvent (
518 ConSplitterTextInWaitForKey
,
520 &ConInPrivate
->TextIn
.WaitForKey
522 ASSERT_EFI_ERROR (Status
);
525 // Allocate buffer for Simple Text Input Ex device
527 Status
= ConSplitterGrowBuffer (
528 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
529 &ConInPrivate
->TextInExListCount
,
530 (VOID
**) &ConInPrivate
->TextInExList
532 if (EFI_ERROR (Status
)) {
533 return EFI_OUT_OF_RESOURCES
;
536 // Create Event to wait for a key Ex
538 Status
= gBS
->CreateEvent (
541 ConSplitterTextInWaitForKey
,
543 &ConInPrivate
->TextInEx
.WaitForKeyEx
545 ASSERT_EFI_ERROR (Status
);
547 InitializeListHead (&ConInPrivate
->NotifyList
);
549 ConInPrivate
->AbsolutePointer
.Mode
= &ConInPrivate
->AbsolutePointerMode
;
551 // Allocate buffer for Absolute Pointer device
553 Status
= ConSplitterGrowBuffer (
554 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
555 &ConInPrivate
->AbsolutePointerListCount
,
556 (VOID
**) &ConInPrivate
->AbsolutePointerList
558 if (EFI_ERROR (Status
)) {
559 return EFI_OUT_OF_RESOURCES
;
562 // Create Event to wait for device input for Absolute pointer device
564 Status
= gBS
->CreateEvent (
567 ConSplitterAbsolutePointerWaitForInput
,
569 &ConInPrivate
->AbsolutePointer
.WaitForInput
571 ASSERT_EFI_ERROR (Status
);
573 ConInPrivate
->SimplePointer
.Mode
= &ConInPrivate
->SimplePointerMode
;
575 // Allocate buffer for Simple Pointer device
577 Status
= ConSplitterGrowBuffer (
578 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
579 &ConInPrivate
->PointerListCount
,
580 (VOID
**) &ConInPrivate
->PointerList
582 if (EFI_ERROR (Status
)) {
583 return EFI_OUT_OF_RESOURCES
;
586 // Create Event to wait for device input for Simple pointer device
588 Status
= gBS
->CreateEvent (
591 ConSplitterSimplePointerWaitForInput
,
593 &ConInPrivate
->SimplePointer
.WaitForInput
600 Construct console output devices' private data.
602 @param ConOutPrivate A pointer to the TEXT_OUT_SPLITTER_PRIVATE_DATA
605 @retval EFI_OUT_OF_RESOURCES Out of resources.
606 @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.
610 ConSplitterTextOutConstructor (
611 TEXT_OUT_SPLITTER_PRIVATE_DATA
*ConOutPrivate
615 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
618 // Copy protocols template
620 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
621 CopyMem (&ConOutPrivate
->UgaDraw
, &mUgaDrawProtocolTemplate
, sizeof (EFI_UGA_DRAW_PROTOCOL
));
623 if (FeaturePcdGet (PcdConOutGopSupport
)) {
624 CopyMem (&ConOutPrivate
->GraphicsOutput
, &mGraphicsOutputProtocolTemplate
, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL
));
628 // Initilize console output splitter's private data.
630 ConOutPrivate
->TextOut
.Mode
= &ConOutPrivate
->TextOutMode
;
633 // When new console device is added, the new mode will be set later,
634 // so put current mode back to init state.
636 ConOutPrivate
->TextOutMode
.Mode
= 0xFF;
638 // Allocate buffer for Console Out device
640 Status
= ConSplitterGrowBuffer (
641 sizeof (TEXT_OUT_AND_GOP_DATA
),
642 &ConOutPrivate
->TextOutListCount
,
643 (VOID
**) &ConOutPrivate
->TextOutList
645 if (EFI_ERROR (Status
)) {
646 return EFI_OUT_OF_RESOURCES
;
649 // Allocate buffer for Text Out query data
651 Status
= ConSplitterGrowBuffer (
652 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
653 &ConOutPrivate
->TextOutQueryDataCount
,
654 (VOID
**) &ConOutPrivate
->TextOutQueryData
656 if (EFI_ERROR (Status
)) {
657 return EFI_OUT_OF_RESOURCES
;
661 // Setup the default console to 80 x 25 and mode to 0
663 ConOutPrivate
->TextOutQueryData
[0].Columns
= 80;
664 ConOutPrivate
->TextOutQueryData
[0].Rows
= 25;
665 TextOutSetMode (ConOutPrivate
, 0);
668 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
670 // Setup the UgaDraw to 800 x 600 x 32 bits per pixel, 60Hz.
672 ConSplitterUgaDrawSetMode (&ConOutPrivate
->UgaDraw
, 800, 600, 32, 60);
674 if (FeaturePcdGet (PcdConOutGopSupport
)) {
676 // Setup resource for mode information in Graphics Output Protocol interface
678 if ((ConOutPrivate
->GraphicsOutput
.Mode
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
))) == NULL
) {
679 return EFI_OUT_OF_RESOURCES
;
681 if ((ConOutPrivate
->GraphicsOutput
.Mode
->Info
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
682 return EFI_OUT_OF_RESOURCES
;
685 // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel
686 // DevNull will be updated to user-defined mode after driver has started.
688 if ((ConOutPrivate
->GraphicsOutputModeBuffer
= AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
))) == NULL
) {
689 return EFI_OUT_OF_RESOURCES
;
691 Info
= &ConOutPrivate
->GraphicsOutputModeBuffer
[0];
693 Info
->HorizontalResolution
= 800;
694 Info
->VerticalResolution
= 600;
695 Info
->PixelFormat
= PixelBltOnly
;
696 Info
->PixelsPerScanLine
= 800;
697 CopyMem (ConOutPrivate
->GraphicsOutput
.Mode
->Info
, Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
698 ConOutPrivate
->GraphicsOutput
.Mode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
701 // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()
702 // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
704 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
705 ConOutPrivate
->GraphicsOutput
.Mode
->FrameBufferSize
= 0;
707 ConOutPrivate
->GraphicsOutput
.Mode
->MaxMode
= 1;
709 // Initial current mode to unknown state, and then set to mode 0
711 ConOutPrivate
->GraphicsOutput
.Mode
->Mode
= 0xffff;
712 ConOutPrivate
->GraphicsOutput
.SetMode (&ConOutPrivate
->GraphicsOutput
, 0);
720 Test to see if the specified protocol could be supported on the specified device.
722 @param This Driver Binding protocol pointer.
723 @param ControllerHandle Handle of device to test.
724 @param Guid The specified protocol.
726 @retval EFI_SUCCESS The specified protocol is supported on this device.
727 @retval EFI_UNSUPPORTED The specified protocol attempts to be installed on virtul handle.
728 @retval other Failed to open specified protocol on this device.
732 ConSplitterSupported (
733 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
734 IN EFI_HANDLE ControllerHandle
,
742 // Make sure the Console Splitter does not attempt to attach to itself
744 if (ControllerHandle
== mConIn
.VirtualHandle
||
745 ControllerHandle
== mConOut
.VirtualHandle
||
746 ControllerHandle
== mStdErr
.VirtualHandle
748 return EFI_UNSUPPORTED
;
752 // Check to see whether the specific protocol could be opened BY_DRIVER
754 Status
= gBS
->OpenProtocol (
758 This
->DriverBindingHandle
,
760 EFI_OPEN_PROTOCOL_BY_DRIVER
763 if (EFI_ERROR (Status
)) {
770 This
->DriverBindingHandle
,
778 Test to see if Console In Device could be supported on the Controller.
780 @param This Driver Binding protocol instance pointer.
781 @param ControllerHandle Handle of device to test.
782 @param RemainingDevicePath Optional parameter use to pick a specific child
785 @retval EFI_SUCCESS This driver supports this device.
786 @retval other This driver does not support this device.
791 ConSplitterConInDriverBindingSupported (
792 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
793 IN EFI_HANDLE ControllerHandle
,
794 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
797 return ConSplitterSupported (
800 &gEfiConsoleInDeviceGuid
805 Test to see if Simple Pointer protocol could be supported on the Controller.
807 @param This Driver Binding protocol instance pointer.
808 @param ControllerHandle Handle of device to test.
809 @param RemainingDevicePath Optional parameter use to pick a specific child
812 @retval EFI_SUCCESS This driver supports this device.
813 @retval other This driver does not support this device.
818 ConSplitterSimplePointerDriverBindingSupported (
819 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
820 IN EFI_HANDLE ControllerHandle
,
821 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
824 return ConSplitterSupported (
827 &gEfiSimplePointerProtocolGuid
832 Test to see if Absolute Pointer protocol could be supported on the Controller.
834 @param This Driver Binding protocol instance pointer.
835 @param ControllerHandle Handle of device to test.
836 @param RemainingDevicePath Optional parameter use to pick a specific child
839 @retval EFI_SUCCESS This driver supports this device.
840 @retval other This driver does not support this device.
845 ConSplitterAbsolutePointerDriverBindingSupported (
846 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
847 IN EFI_HANDLE ControllerHandle
,
848 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
851 return ConSplitterSupported (
854 &gEfiAbsolutePointerProtocolGuid
860 Test to see if Console Out Device could be supported on the Controller.
862 @param This Driver Binding protocol instance pointer.
863 @param ControllerHandle Handle of device to test.
864 @param RemainingDevicePath Optional parameter use to pick a specific child
867 @retval EFI_SUCCESS This driver supports this device.
868 @retval other This driver does not support this device.
873 ConSplitterConOutDriverBindingSupported (
874 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
875 IN EFI_HANDLE ControllerHandle
,
876 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
879 return ConSplitterSupported (
882 &gEfiConsoleOutDeviceGuid
887 Test to see if Standard Error Device could be supported on the Controller.
889 @param This Driver Binding protocol instance pointer.
890 @param ControllerHandle Handle of device to test.
891 @param RemainingDevicePath Optional parameter use to pick a specific child
894 @retval EFI_SUCCESS This driver supports this device.
895 @retval other This driver does not support this device.
900 ConSplitterStdErrDriverBindingSupported (
901 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
902 IN EFI_HANDLE ControllerHandle
,
903 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
906 return ConSplitterSupported (
909 &gEfiStandardErrorDeviceGuid
915 Start ConSplitter on devcie handle by opening Console Device Guid on device handle
916 and the console virtual handle. And Get the console interface on controller handle.
918 @param This Driver Binding protocol instance pointer.
919 @param ControllerHandle Handle of device.
920 @param ConSplitterVirtualHandle Console virtual Handle.
921 @param DeviceGuid The specified Console Device, such as ConInDev,
923 @param InterfaceGuid The specified protocol to be opened.
924 @param Interface Protocol interface returned.
926 @retval EFI_SUCCESS This driver supports this device.
927 @retval other Failed to open the specified Console Device Guid
928 or specified protocol.
933 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
934 IN EFI_HANDLE ControllerHandle
,
935 IN EFI_HANDLE ConSplitterVirtualHandle
,
936 IN EFI_GUID
*DeviceGuid
,
937 IN EFI_GUID
*InterfaceGuid
,
945 // Check to see whether the ControllerHandle has the DeviceGuid on it.
947 Status
= gBS
->OpenProtocol (
951 This
->DriverBindingHandle
,
953 EFI_OPEN_PROTOCOL_BY_DRIVER
955 if (EFI_ERROR (Status
)) {
960 // Open the Parent Handle for the child.
962 Status
= gBS
->OpenProtocol (
966 This
->DriverBindingHandle
,
967 ConSplitterVirtualHandle
,
968 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
970 if (EFI_ERROR (Status
)) {
975 // Open InterfaceGuid on the virtul handle.
977 Status
= gBS
->OpenProtocol (
981 This
->DriverBindingHandle
,
982 ConSplitterVirtualHandle
,
983 EFI_OPEN_PROTOCOL_GET_PROTOCOL
986 if (!EFI_ERROR (Status
)) {
991 // close the DeviceGuid on ConSplitter VirtualHandle.
996 This
->DriverBindingHandle
,
997 ConSplitterVirtualHandle
1002 // close the DeviceGuid on ControllerHandle.
1004 gBS
->CloseProtocol (
1007 This
->DriverBindingHandle
,
1016 Start Console In Consplitter on device handle.
1018 @param This Driver Binding protocol instance pointer.
1019 @param ControllerHandle Handle of device to bind driver to.
1020 @param RemainingDevicePath Optional parameter use to pick a specific child
1023 @retval EFI_SUCCESS Console In Consplitter is added to ControllerHandle.
1024 @retval other Console In Consplitter does not support this device.
1029 ConSplitterConInDriverBindingStart (
1030 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1031 IN EFI_HANDLE ControllerHandle
,
1032 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1036 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1037 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1040 // Start ConSplitter on ControllerHandle, and create the virtual
1041 // agrogated console device on first call Start for a SimpleTextIn handle.
1043 Status
= ConSplitterStart (
1046 mConIn
.VirtualHandle
,
1047 &gEfiConsoleInDeviceGuid
,
1048 &gEfiSimpleTextInProtocolGuid
,
1051 if (EFI_ERROR (Status
)) {
1056 // Add this device into Text In devices list.
1058 Status
= ConSplitterTextInAddDevice (&mConIn
, TextIn
);
1059 if (EFI_ERROR (Status
)) {
1063 Status
= gBS
->OpenProtocol (
1065 &gEfiSimpleTextInputExProtocolGuid
,
1066 (VOID
**) &TextInEx
,
1067 This
->DriverBindingHandle
,
1068 mConIn
.VirtualHandle
,
1069 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1071 if (!EFI_ERROR (Status
)) {
1073 // If Simple Text Input Ex protocol exists,
1074 // add this device into Text In Ex devices list.
1076 Status
= ConSplitterTextInExAddDevice (&mConIn
, TextInEx
);
1084 Start Simple Pointer Consplitter on device handle.
1086 @param This Driver Binding protocol instance pointer.
1087 @param ControllerHandle Handle of device to bind driver to.
1088 @param RemainingDevicePath Optional parameter use to pick a specific child
1091 @retval EFI_SUCCESS Simple Pointer Consplitter is added to ControllerHandle.
1092 @retval other Simple Pointer Consplitter does not support this device.
1097 ConSplitterSimplePointerDriverBindingStart (
1098 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1099 IN EFI_HANDLE ControllerHandle
,
1100 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1104 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1107 // Start ConSplitter on ControllerHandle, and create the virtual
1108 // agrogated console device on first call Start for a SimplePointer handle.
1110 Status
= ConSplitterStart (
1113 mConIn
.VirtualHandle
,
1114 &gEfiSimplePointerProtocolGuid
,
1115 &gEfiSimplePointerProtocolGuid
,
1116 (VOID
**) &SimplePointer
1118 if (EFI_ERROR (Status
)) {
1123 // Add this devcie into Simple Pointer devices list.
1125 return ConSplitterSimplePointerAddDevice (&mConIn
, SimplePointer
);
1130 Start Absolute Pointer Consplitter on device handle.
1132 @param This Driver Binding protocol instance pointer.
1133 @param ControllerHandle Handle of device to bind driver to.
1134 @param RemainingDevicePath Optional parameter use to pick a specific child
1137 @retval EFI_SUCCESS Absolute Pointer Consplitter is added to ControllerHandle.
1138 @retval other Absolute Pointer Consplitter does not support this device.
1143 ConSplitterAbsolutePointerDriverBindingStart (
1144 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1145 IN EFI_HANDLE ControllerHandle
,
1146 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1150 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1153 // Start ConSplitter on ControllerHandle, and create the virtual
1154 // agrogated console device on first call Start for a AbsolutePointer handle.
1156 Status
= ConSplitterStart (
1159 mConIn
.VirtualHandle
,
1160 &gEfiAbsolutePointerProtocolGuid
,
1161 &gEfiAbsolutePointerProtocolGuid
,
1162 (VOID
**) &AbsolutePointer
1165 if (EFI_ERROR (Status
)) {
1170 // Add this devcie into Absolute Pointer devices list.
1172 return ConSplitterAbsolutePointerAddDevice (&mConIn
, AbsolutePointer
);
1177 Start Console Out Consplitter on device handle.
1179 @param This Driver Binding protocol instance pointer.
1180 @param ControllerHandle Handle of device to bind driver to.
1181 @param RemainingDevicePath Optional parameter use to pick a specific child
1184 @retval EFI_SUCCESS Console Out Consplitter is added to ControllerHandle.
1185 @retval other Console Out Consplitter does not support this device.
1190 ConSplitterConOutDriverBindingStart (
1191 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1192 IN EFI_HANDLE ControllerHandle
,
1193 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1197 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1198 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
1199 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
1201 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
1204 // Start ConSplitter on ControllerHandle, and create the virtual
1205 // agrogated console device on first call Start for a ConsoleOut handle.
1207 Status
= ConSplitterStart (
1210 mConOut
.VirtualHandle
,
1211 &gEfiConsoleOutDeviceGuid
,
1212 &gEfiSimpleTextOutProtocolGuid
,
1215 if (EFI_ERROR (Status
)) {
1219 GraphicsOutput
= NULL
;
1222 // Try to Open Graphics Output protocol
1224 Status
= gBS
->OpenProtocol (
1226 &gEfiGraphicsOutputProtocolGuid
,
1227 (VOID
**) &GraphicsOutput
,
1228 This
->DriverBindingHandle
,
1229 mConOut
.VirtualHandle
,
1230 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1233 if (EFI_ERROR (Status
) && FeaturePcdGet (PcdUgaConsumeSupport
)) {
1235 // Open UGA DRAW protocol
1239 &gEfiUgaDrawProtocolGuid
,
1241 This
->DriverBindingHandle
,
1242 mConOut
.VirtualHandle
,
1243 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1248 // When new console device is added, the new mode will be set later,
1249 // so put current mode back to init state.
1251 mConOut
.TextOutMode
.Mode
= 0xFF;
1254 // If both ConOut and StdErr incorporate the same Text Out device,
1255 // their MaxMode and QueryData should be the intersection of both.
1257 Status
= ConSplitterTextOutAddDevice (&mConOut
, TextOut
, GraphicsOutput
, UgaDraw
);
1258 ConSplitterTextOutSetAttribute (&mConOut
.TextOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
1260 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
1262 // Get the UGA mode data of ConOut from the current mode
1264 if (GraphicsOutput
!= NULL
) {
1265 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, GraphicsOutput
->Mode
->Mode
, &SizeOfInfo
, &Info
);
1266 if (EFI_ERROR (Status
)) {
1269 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
1271 mConOut
.UgaHorizontalResolution
= Info
->HorizontalResolution
;
1272 mConOut
.UgaVerticalResolution
= Info
->VerticalResolution
;
1273 mConOut
.UgaColorDepth
= 32;
1274 mConOut
.UgaRefreshRate
= 60;
1278 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
1279 Status
= UgaDraw
->GetMode (
1281 &mConOut
.UgaHorizontalResolution
,
1282 &mConOut
.UgaVerticalResolution
,
1283 &mConOut
.UgaColorDepth
,
1284 &mConOut
.UgaRefreshRate
1294 Start Standard Error Consplitter on device handle.
1296 @param This Driver Binding protocol instance pointer.
1297 @param ControllerHandle Handle of device to bind driver to.
1298 @param RemainingDevicePath Optional parameter use to pick a specific child
1301 @retval EFI_SUCCESS Standard Error Consplitter is added to ControllerHandle.
1302 @retval other Standard Error Consplitter does not support this device.
1307 ConSplitterStdErrDriverBindingStart (
1308 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1309 IN EFI_HANDLE ControllerHandle
,
1310 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1314 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1316 if (mStdErr
.CurrentNumberOfConsoles
== 0) {
1318 // Construct console output devices' private data
1320 Status
= ConSplitterTextOutConstructor (&mStdErr
);
1321 if (!EFI_ERROR (Status
)) {
1323 // Create virtual device handle for StdErr Splitter
1325 Status
= gBS
->InstallMultipleProtocolInterfaces (
1326 &mStdErr
.VirtualHandle
,
1327 &gEfiSimpleTextOutProtocolGuid
,
1332 if (EFI_ERROR (Status
)) {
1338 // Start ConSplitter on ControllerHandle, and create the virtual
1339 // agrogated console device on first call Start for a StandardError handle.
1341 Status
= ConSplitterStart (
1344 mStdErr
.VirtualHandle
,
1345 &gEfiStandardErrorDeviceGuid
,
1346 &gEfiSimpleTextOutProtocolGuid
,
1349 if (EFI_ERROR (Status
)) {
1354 // When new console device is added, the new mode will be set later,
1355 // so put current mode back to init state.
1357 mStdErr
.TextOutMode
.Mode
= 0xFF;
1360 // If both ConOut and StdErr incorporate the same Text Out device,
1361 // their MaxMode and QueryData should be the intersection of both.
1363 Status
= ConSplitterTextOutAddDevice (&mStdErr
, TextOut
, NULL
, NULL
);
1364 ConSplitterTextOutSetAttribute (&mStdErr
.TextOut
, EFI_TEXT_ATTR (EFI_MAGENTA
, EFI_BLACK
));
1365 if (EFI_ERROR (Status
)) {
1369 if (mStdErr
.CurrentNumberOfConsoles
== 1) {
1370 gST
->StandardErrorHandle
= mStdErr
.VirtualHandle
;
1371 gST
->StdErr
= &mStdErr
.TextOut
;
1373 // Update the CRC32 in the EFI System Table header
1376 gBS
->CalculateCrc32 (
1377 (UINT8
*) &gST
->Hdr
,
1378 gST
->Hdr
.HeaderSize
,
1388 Stop ConSplitter on device handle by closing Console Device Guid on device handle
1389 and the console virtual handle.
1391 @param This Protocol instance pointer.
1392 @param ControllerHandle Handle of device.
1393 @param ConSplitterVirtualHandle Console virtual Handle.
1394 @param DeviceGuid The specified Console Device, such as ConInDev,
1396 @param InterfaceGuid The specified protocol to be opened.
1397 @param Interface Protocol interface returned.
1399 @retval EFI_SUCCESS Stop ConSplitter on ControllerHandle successfully.
1400 @retval other Failed to Stop ConSplitter on ControllerHandle.
1405 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1406 IN EFI_HANDLE ControllerHandle
,
1407 IN EFI_HANDLE ConSplitterVirtualHandle
,
1408 IN EFI_GUID
*DeviceGuid
,
1409 IN EFI_GUID
*InterfaceGuid
,
1415 Status
= gBS
->OpenProtocol (
1419 This
->DriverBindingHandle
,
1421 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1423 if (EFI_ERROR (Status
)) {
1427 // close the protocol refered.
1429 gBS
->CloseProtocol (
1432 This
->DriverBindingHandle
,
1433 ConSplitterVirtualHandle
1436 gBS
->CloseProtocol (
1439 This
->DriverBindingHandle
,
1448 Stop Console In ConSplitter on ControllerHandle by closing Console In Devcice GUID.
1450 @param This Driver Binding protocol instance pointer.
1451 @param ControllerHandle Handle of device to stop driver on
1452 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1453 children is zero stop the entire bus driver.
1454 @param ChildHandleBuffer List of Child Handles to Stop.
1456 @retval EFI_SUCCESS This driver is removed ControllerHandle
1457 @retval other This driver was not removed from this device
1462 ConSplitterConInDriverBindingStop (
1463 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1464 IN EFI_HANDLE ControllerHandle
,
1465 IN UINTN NumberOfChildren
,
1466 IN EFI_HANDLE
*ChildHandleBuffer
1470 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
1471 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
;
1473 if (NumberOfChildren
== 0) {
1477 Status
= gBS
->OpenProtocol (
1479 &gEfiSimpleTextInputExProtocolGuid
,
1480 (VOID
**) &TextInEx
,
1481 This
->DriverBindingHandle
,
1483 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1485 if (!EFI_ERROR (Status
)) {
1487 // If Simple Text Input Ex protocol exists,
1488 // remove device from Text Input Ex devices list.
1490 Status
= ConSplitterTextInExDeleteDevice (&mConIn
, TextInEx
);
1491 if (EFI_ERROR (Status
)) {
1497 // Close Simple Text In protocol on controller handle and virtual handle.
1499 Status
= ConSplitterStop (
1502 mConIn
.VirtualHandle
,
1503 &gEfiConsoleInDeviceGuid
,
1504 &gEfiSimpleTextInProtocolGuid
,
1507 if (EFI_ERROR (Status
)) {
1512 // Remove device from Text Input devices list.
1514 return ConSplitterTextInDeleteDevice (&mConIn
, TextIn
);
1519 Stop Simple Pointer protocol ConSplitter on ControllerHandle by closing
1520 Simple Pointer protocol.
1522 @param This Driver Binding protocol instance pointer.
1523 @param ControllerHandle Handle of device to stop driver on
1524 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1525 children is zero stop the entire bus driver.
1526 @param ChildHandleBuffer List of Child Handles to Stop.
1528 @retval EFI_SUCCESS This driver is removed ControllerHandle
1529 @retval other This driver was not removed from this device
1534 ConSplitterSimplePointerDriverBindingStop (
1535 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1536 IN EFI_HANDLE ControllerHandle
,
1537 IN UINTN NumberOfChildren
,
1538 IN EFI_HANDLE
*ChildHandleBuffer
1542 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
;
1544 if (NumberOfChildren
== 0) {
1549 // Close Simple Pointer protocol on controller handle and virtual handle.
1551 Status
= ConSplitterStop (
1554 mConIn
.VirtualHandle
,
1555 &gEfiSimplePointerProtocolGuid
,
1556 &gEfiSimplePointerProtocolGuid
,
1557 (VOID
**) &SimplePointer
1559 if (EFI_ERROR (Status
)) {
1564 // Remove this device from Simple Pointer device list.
1566 return ConSplitterSimplePointerDeleteDevice (&mConIn
, SimplePointer
);
1571 Stop Absolute Pointer protocol ConSplitter on ControllerHandle by closing
1572 Absolute Pointer protocol.
1574 @param This Driver Binding protocol instance pointer.
1575 @param ControllerHandle Handle of device to stop driver on
1576 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1577 children is zero stop the entire bus driver.
1578 @param ChildHandleBuffer List of Child Handles to Stop.
1580 @retval EFI_SUCCESS This driver is removed ControllerHandle
1581 @retval other This driver was not removed from this device
1586 ConSplitterAbsolutePointerDriverBindingStop (
1587 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1588 IN EFI_HANDLE ControllerHandle
,
1589 IN UINTN NumberOfChildren
,
1590 IN EFI_HANDLE
*ChildHandleBuffer
1594 EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
;
1596 if (NumberOfChildren
== 0) {
1601 // Close Absolute Pointer protocol on controller handle and virtual handle.
1603 Status
= ConSplitterStop (
1606 mConIn
.VirtualHandle
,
1607 &gEfiAbsolutePointerProtocolGuid
,
1608 &gEfiAbsolutePointerProtocolGuid
,
1609 (VOID
**) &AbsolutePointer
1611 if (EFI_ERROR (Status
)) {
1616 // Remove this device from Absolute Pointer device list.
1618 return ConSplitterAbsolutePointerDeleteDevice (&mConIn
, AbsolutePointer
);
1623 Stop Console Out ConSplitter on device handle by closing Console Out Devcice GUID.
1625 @param This Driver Binding protocol instance pointer.
1626 @param ControllerHandle Handle of device to stop driver on
1627 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1628 children is zero stop the entire bus driver.
1629 @param ChildHandleBuffer List of Child Handles to Stop.
1631 @retval EFI_SUCCESS This driver is removed ControllerHandle
1632 @retval other This driver was not removed from this device
1637 ConSplitterConOutDriverBindingStop (
1638 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1639 IN EFI_HANDLE ControllerHandle
,
1640 IN UINTN NumberOfChildren
,
1641 IN EFI_HANDLE
*ChildHandleBuffer
1645 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1647 if (NumberOfChildren
== 0) {
1652 // Close Absolute Pointer protocol on controller handle and virtual handle.
1654 Status
= ConSplitterStop (
1657 mConOut
.VirtualHandle
,
1658 &gEfiConsoleOutDeviceGuid
,
1659 &gEfiSimpleTextOutProtocolGuid
,
1662 if (EFI_ERROR (Status
)) {
1667 // Remove this device from Text Out device list.
1669 return ConSplitterTextOutDeleteDevice (&mConOut
, TextOut
);
1674 Stop Standard Error ConSplitter on ControllerHandle by closing Standard Error GUID.
1676 @param This Driver Binding protocol instance pointer.
1677 @param ControllerHandle Handle of device to stop driver on
1678 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1679 children is zero stop the entire bus driver.
1680 @param ChildHandleBuffer List of Child Handles to Stop.
1682 @retval EFI_SUCCESS This driver is removed ControllerHandle
1683 @retval other This driver was not removed from this device
1688 ConSplitterStdErrDriverBindingStop (
1689 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1690 IN EFI_HANDLE ControllerHandle
,
1691 IN UINTN NumberOfChildren
,
1692 IN EFI_HANDLE
*ChildHandleBuffer
1696 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
1698 if (NumberOfChildren
== 0) {
1703 // Close Standard Error Device on controller handle and virtual handle.
1705 Status
= ConSplitterStop (
1708 mStdErr
.VirtualHandle
,
1709 &gEfiStandardErrorDeviceGuid
,
1710 &gEfiSimpleTextOutProtocolGuid
,
1713 if (EFI_ERROR (Status
)) {
1717 // Delete this console error out device's data structures.
1719 Status
= ConSplitterTextOutDeleteDevice (&mStdErr
, TextOut
);
1720 if (EFI_ERROR (Status
)) {
1724 if (mStdErr
.CurrentNumberOfConsoles
== 0) {
1725 mStdErr
.VirtualHandle
= NULL
;
1727 gST
->StandardErrorHandle
= NULL
;
1730 // Update the CRC32 in the EFI System Table header
1733 gBS
->CalculateCrc32 (
1734 (UINT8
*) &gST
->Hdr
,
1735 gST
->Hdr
.HeaderSize
,
1740 // Uninstall Simple Text Output protocol from StdErr Handle.
1742 gBS
->UninstallMultipleProtocolInterfaces (
1743 mStdErr
.VirtualHandle
,
1744 &gEfiSimpleTextOutProtocolGuid
,
1755 Take the passed in Buffer of size SizeOfCount and grow the buffer
1756 by MAX (CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT, MaxGrow) * SizeOfCount
1757 bytes. Copy the current data in Buffer to the new version of Buffer
1758 and free the old version of buffer.
1760 @param SizeOfCount Size of element in array.
1761 @param Count Current number of elements in array.
1762 @param Buffer Bigger version of passed in Buffer with all the
1765 @retval EFI_SUCCESS Buffer size has grown.
1766 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1770 ConSplitterGrowBuffer (
1771 IN UINTN SizeOfCount
,
1772 IN OUT UINTN
*Count
,
1773 IN OUT VOID
**Buffer
1779 // grow the buffer to new buffer size,
1780 // copy the old buffer's content to the new-size buffer,
1781 // then free the old buffer.
1783 *Count
+= CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT
;
1784 Ptr
= ReallocatePool (
1785 SizeOfCount
* ((*Count
) - CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT
),
1786 SizeOfCount
* (*Count
),
1790 return EFI_OUT_OF_RESOURCES
;
1798 Add Text Input Device in Consplitter Text Input list.
1800 @param Private Text In Splitter pointer.
1801 @param TextIn Simple Text Input protocol pointer.
1803 @retval EFI_SUCCESS Text Input Device added successfully.
1804 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1808 ConSplitterTextInAddDevice (
1809 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1810 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1816 // If the Text In List is full, enlarge it by calling ConSplitterGrowBuffer().
1818 if (Private
->CurrentNumberOfConsoles
>= Private
->TextInListCount
) {
1819 Status
= ConSplitterGrowBuffer (
1820 sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*),
1821 &Private
->TextInListCount
,
1822 (VOID
**) &Private
->TextInList
1824 if (EFI_ERROR (Status
)) {
1825 return EFI_OUT_OF_RESOURCES
;
1829 // Add the new text-in device data structure into the Text In List.
1831 Private
->TextInList
[Private
->CurrentNumberOfConsoles
] = TextIn
;
1832 Private
->CurrentNumberOfConsoles
++;
1835 // Extra CheckEvent added to reduce the double CheckEvent().
1837 gBS
->CheckEvent (TextIn
->WaitForKey
);
1844 Remove Text Input Device from Consplitter Text Input list.
1846 @param Private Text In Splitter pointer.
1847 @param TextIn Simple Text protocol pointer.
1849 @retval EFI_SUCCESS Simple Text Device removed successfully.
1850 @retval EFI_NOT_FOUND No Simple Text Device found.
1854 ConSplitterTextInDeleteDevice (
1855 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1856 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
1861 // Remove the specified text-in device data structure from the Text In List,
1862 // and rearrange the remaining data structures in the Text In List.
1864 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
1865 if (Private
->TextInList
[Index
] == TextIn
) {
1866 for (; Index
< Private
->CurrentNumberOfConsoles
- 1; Index
++) {
1867 Private
->TextInList
[Index
] = Private
->TextInList
[Index
+ 1];
1870 Private
->CurrentNumberOfConsoles
--;
1875 return EFI_NOT_FOUND
;
1879 Add Text Input Ex Device in Consplitter Text Input Ex list.
1881 @param Private Text In Splitter pointer.
1882 @param TextInEx Simple Text Input Ex Input protocol pointer.
1884 @retval EFI_SUCCESS Text Input Ex Device added successfully.
1885 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1889 ConSplitterTextInExAddDevice (
1890 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1891 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1897 // If the Text Input Ex List is full, enlarge it by calling ConSplitterGrowBuffer().
1899 if (Private
->CurrentNumberOfExConsoles
>= Private
->TextInExListCount
) {
1900 Status
= ConSplitterGrowBuffer (
1901 sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*),
1902 &Private
->TextInExListCount
,
1903 (VOID
**) &Private
->TextInExList
1905 if (EFI_ERROR (Status
)) {
1906 return EFI_OUT_OF_RESOURCES
;
1910 // Add the new text-in device data structure into the Text Input Ex List.
1912 Private
->TextInExList
[Private
->CurrentNumberOfExConsoles
] = TextInEx
;
1913 Private
->CurrentNumberOfExConsoles
++;
1916 // Extra CheckEvent added to reduce the double CheckEvent().
1918 gBS
->CheckEvent (TextInEx
->WaitForKeyEx
);
1924 Remove Text Ex Device from Consplitter Text Input Ex list.
1926 @param Private Text In Splitter pointer.
1927 @param TextInEx Simple Text Ex protocol pointer.
1929 @retval EFI_SUCCESS Simple Text Input Ex Device removed successfully.
1930 @retval EFI_NOT_FOUND No Simple Text Input Ex Device found.
1934 ConSplitterTextInExDeleteDevice (
1935 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1936 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*TextInEx
1941 // Remove the specified text-in device data structure from the Text Input Ex List,
1942 // and rearrange the remaining data structures in the Text In List.
1944 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
1945 if (Private
->TextInExList
[Index
] == TextInEx
) {
1946 for (; Index
< Private
->CurrentNumberOfExConsoles
- 1; Index
++) {
1947 Private
->TextInExList
[Index
] = Private
->TextInExList
[Index
+ 1];
1950 Private
->CurrentNumberOfExConsoles
--;
1955 return EFI_NOT_FOUND
;
1960 Add Simple Pointer Device in Consplitter Simple Pointer list.
1962 @param Private Text In Splitter pointer.
1963 @param SimplePointer Simple Pointer protocol pointer.
1965 @retval EFI_SUCCESS Simple Pointer Device added successfully.
1966 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
1970 ConSplitterSimplePointerAddDevice (
1971 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
1972 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
1978 // If the Simple Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().
1980 if (Private
->CurrentNumberOfPointers
>= Private
->PointerListCount
) {
1981 Status
= ConSplitterGrowBuffer (
1982 sizeof (EFI_SIMPLE_POINTER_PROTOCOL
*),
1983 &Private
->PointerListCount
,
1984 (VOID
**) &Private
->PointerList
1986 if (EFI_ERROR (Status
)) {
1987 return EFI_OUT_OF_RESOURCES
;
1991 // Add the new text-in device data structure into the Simple Pointer List.
1993 Private
->PointerList
[Private
->CurrentNumberOfPointers
] = SimplePointer
;
1994 Private
->CurrentNumberOfPointers
++;
2001 Remove Simple Pointer Device from Consplitter Simple Pointer list.
2003 @param Private Text In Splitter pointer.
2004 @param SimplePointer Simple Pointer protocol pointer.
2006 @retval EFI_SUCCESS Simple Pointer Device removed successfully.
2007 @retval EFI_NOT_FOUND No Simple Pointer Device found.
2011 ConSplitterSimplePointerDeleteDevice (
2012 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2013 IN EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointer
2018 // Remove the specified text-in device data structure from the Simple Pointer List,
2019 // and rearrange the remaining data structures in the Text In List.
2021 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
2022 if (Private
->PointerList
[Index
] == SimplePointer
) {
2023 for (; Index
< Private
->CurrentNumberOfPointers
- 1; Index
++) {
2024 Private
->PointerList
[Index
] = Private
->PointerList
[Index
+ 1];
2027 Private
->CurrentNumberOfPointers
--;
2032 return EFI_NOT_FOUND
;
2037 Add Absolute Pointer Device in Consplitter Absolute Pointer list.
2039 @param Private Text In Splitter pointer.
2040 @param AbsolutePointer Absolute Pointer protocol pointer.
2042 @retval EFI_SUCCESS Absolute Pointer Device added successfully.
2043 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2047 ConSplitterAbsolutePointerAddDevice (
2048 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2049 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2055 // If the Absolute Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().
2057 if (Private
->CurrentNumberOfAbsolutePointers
>= Private
->AbsolutePointerListCount
) {
2058 Status
= ConSplitterGrowBuffer (
2059 sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL
*),
2060 &Private
->AbsolutePointerListCount
,
2061 (VOID
**) &Private
->AbsolutePointerList
2063 if (EFI_ERROR (Status
)) {
2064 return EFI_OUT_OF_RESOURCES
;
2068 // Add the new text-in device data structure into the Absolute Pointer List.
2070 Private
->AbsolutePointerList
[Private
->CurrentNumberOfAbsolutePointers
] = AbsolutePointer
;
2071 Private
->CurrentNumberOfAbsolutePointers
++;
2078 Remove Absolute Pointer Device from Consplitter Absolute Pointer list.
2080 @param Private Text In Splitter pointer.
2081 @param AbsolutePointer Absolute Pointer protocol pointer.
2083 @retval EFI_SUCCESS Absolute Pointer Device removed successfully.
2084 @retval EFI_NOT_FOUND No Absolute Pointer Device found.
2088 ConSplitterAbsolutePointerDeleteDevice (
2089 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
2090 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*AbsolutePointer
2095 // Remove the specified text-in device data structure from the Absolute Pointer List,
2096 // and rearrange the remaining data structures from the Absolute Pointer List.
2098 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
2099 if (Private
->AbsolutePointerList
[Index
] == AbsolutePointer
) {
2100 for (; Index
< Private
->CurrentNumberOfAbsolutePointers
- 1; Index
++) {
2101 Private
->AbsolutePointerList
[Index
] = Private
->AbsolutePointerList
[Index
+ 1];
2104 Private
->CurrentNumberOfAbsolutePointers
--;
2109 return EFI_NOT_FOUND
;
2113 Reallocate Text Out mode map.
2115 Allocate new buffer and copy original buffer into the new buffer.
2117 @param Private Consplitter Text Out pointer.
2119 @retval EFI_SUCCESS Buffer size has grown
2120 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2124 ConSplitterGrowMapTable (
2125 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2131 INT32
*TextOutModeMap
;
2132 INT32
*OldTextOutModeMap
;
2136 NewSize
= Private
->TextOutListCount
* sizeof (INT32
);
2137 OldTextOutModeMap
= Private
->TextOutModeMap
;
2138 TotalSize
= NewSize
* (Private
->TextOutQueryDataCount
);
2141 // Allocate new buffer for Text Out List.
2143 TextOutModeMap
= AllocatePool (TotalSize
);
2144 if (TextOutModeMap
== NULL
) {
2145 return EFI_OUT_OF_RESOURCES
;
2148 SetMem (TextOutModeMap
, TotalSize
, 0xFF);
2149 Private
->TextOutModeMap
= TextOutModeMap
;
2152 // If TextOutList has been enlarged, need to realloc the mode map table
2153 // The mode map table is regarded as a two dimension array.
2156 // 0 ---------> TextOutListCount ----> TextOutListCount
2157 // | -------------------------------------------
2164 // -------------------------------------------
2167 if (OldTextOutModeMap
!= NULL
) {
2169 Size
= Private
->CurrentNumberOfConsoles
* sizeof (INT32
);
2171 SrcAddress
= OldTextOutModeMap
;
2174 // Copy the old data to the new one
2176 while (Index
< Private
->TextOutMode
.MaxMode
) {
2177 CopyMem (TextOutModeMap
, SrcAddress
, Size
);
2178 TextOutModeMap
+= NewSize
;
2183 // Free the old buffer
2185 FreePool (OldTextOutModeMap
);
2193 Add new device's output mode to console splitter's mode list.
2195 @param Private Text Out Splitter pointer
2196 @param TextOut Simple Text Output protocol pointer.
2198 @retval EFI_SUCCESS Device added successfully.
2199 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2203 ConSplitterAddOutputMode (
2204 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2205 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2213 MaxMode
= TextOut
->Mode
->MaxMode
;
2214 Private
->TextOutMode
.MaxMode
= MaxMode
;
2217 // Grow the buffer if query data buffer is not large enough to
2218 // hold all the mode supported by the first console.
2220 while (MaxMode
> (INT32
) Private
->TextOutQueryDataCount
) {
2221 Status
= ConSplitterGrowBuffer (
2222 sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
),
2223 &Private
->TextOutQueryDataCount
,
2224 (VOID
**) &Private
->TextOutQueryData
2226 if (EFI_ERROR (Status
)) {
2227 return EFI_OUT_OF_RESOURCES
;
2231 // Allocate buffer for the output mode map
2233 Status
= ConSplitterGrowMapTable (Private
);
2234 if (EFI_ERROR (Status
)) {
2235 return EFI_OUT_OF_RESOURCES
;
2238 // As the first textout device, directly add the mode in to QueryData
2239 // and at the same time record the mapping between QueryData and TextOut.
2243 while (Mode
< MaxMode
) {
2244 Status
= TextOut
->QueryMode (
2247 &Private
->TextOutQueryData
[Mode
].Columns
,
2248 &Private
->TextOutQueryData
[Mode
].Rows
2251 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2254 if ((EFI_ERROR(Status
)) && (Mode
== 1)) {
2255 Private
->TextOutQueryData
[Mode
].Columns
= 0;
2256 Private
->TextOutQueryData
[Mode
].Rows
= 0;
2258 Private
->TextOutModeMap
[Index
] = Mode
;
2260 Index
+= Private
->TextOutListCount
;
2267 Reconstruct TextOutModeMap to get intersection of modes.
2269 This routine reconstruct TextOutModeMap to get the intersection
2270 of modes for all console out devices. Because EFI/UEFI spec require
2271 mode 0 is 80x25, mode 1 is 80x50, this routine will not check the
2272 intersection for mode 0 and mode 1.
2274 @param TextOutModeMap Current text out mode map, begin with the mode 80x25
2275 @param NewlyAddedMap New text out mode map, begin with the mode 80x25
2276 @param MapStepSize Mode step size for one console device
2277 @param NewMapStepSize New Mode step size for one console device
2278 @param MaxMode IN: Current max text mode, OUT: Updated max text mode.
2279 @param CurrentMode IN: Current text mode, OUT: Updated current text mode.
2283 ConSplitterGetIntersection (
2284 IN INT32
*TextOutModeMap
,
2285 IN INT32
*NewlyAddedMap
,
2286 IN UINTN MapStepSize
,
2287 IN UINTN NewMapStepSize
,
2288 IN OUT INT32
*MaxMode
,
2289 IN OUT INT32
*CurrentMode
2293 INT32
*CurrentMapEntry
;
2294 INT32
*NextMapEntry
;
2296 INT32 CurrentMaxMode
;
2300 // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved
2301 // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection
2302 // for mode 0 and mode 1, mode number starts from 2.
2305 CurrentMapEntry
= &TextOutModeMap
[MapStepSize
* 2];
2306 NextMapEntry
= CurrentMapEntry
;
2307 NewMapEntry
= &NewlyAddedMap
[NewMapStepSize
* 2];
2309 CurrentMaxMode
= *MaxMode
;
2310 Mode
= *CurrentMode
;
2312 while (Index
< CurrentMaxMode
) {
2313 if (*NewMapEntry
== -1) {
2315 // This mode is not supported any more. Remove it. Special care
2316 // must be taken as this remove will also affect current mode;
2318 if (Index
== *CurrentMode
) {
2320 } else if (Index
< *CurrentMode
) {
2325 if (CurrentMapEntry
!= NextMapEntry
) {
2326 CopyMem (NextMapEntry
, CurrentMapEntry
, MapStepSize
* sizeof (INT32
));
2329 NextMapEntry
+= MapStepSize
;
2332 CurrentMapEntry
+= MapStepSize
;
2333 NewMapEntry
+= NewMapStepSize
;
2337 *CurrentMode
= Mode
;
2343 Sync the device's output mode to console splitter's mode list.
2345 @param Private Text Out Splitter pointer.
2346 @param TextOut Simple Text Output protocol pointer.
2350 ConSplitterSyncOutputMode (
2351 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2352 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
2355 INT32 CurrentMaxMode
;
2358 INT32
*TextOutModeMap
;
2361 TEXT_OUT_SPLITTER_QUERY_DATA
*TextOutQueryData
;
2368 // Must make sure that current mode won't change even if mode number changes
2370 CurrentMaxMode
= Private
->TextOutMode
.MaxMode
;
2371 TextOutModeMap
= Private
->TextOutModeMap
;
2372 StepSize
= Private
->TextOutListCount
;
2373 TextOutQueryData
= Private
->TextOutQueryData
;
2376 // Query all the mode that the newly added TextOut supports
2379 MapTable
= TextOutModeMap
+ Private
->CurrentNumberOfConsoles
;
2380 while (Mode
< TextOut
->Mode
->MaxMode
) {
2381 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Columns
, &Rows
);
2383 if (EFI_ERROR(Status
)) {
2386 // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData
2389 MapTable
[StepSize
] = Mode
;
2390 TextOutQueryData
[Mode
].Columns
= 0;
2391 TextOutQueryData
[Mode
].Rows
= 0;
2397 // Search the intersection map and QueryData database to see if they intersects
2400 while (Index
< CurrentMaxMode
) {
2401 QueryMode
= *(TextOutModeMap
+ Index
* StepSize
);
2402 if ((TextOutQueryData
[QueryMode
].Rows
== Rows
) && (TextOutQueryData
[QueryMode
].Columns
== Columns
)) {
2403 MapTable
[Index
* StepSize
] = Mode
;
2411 // Now search the TextOutModeMap table to find the intersection of supported
2412 // mode between ConSplitter and the newly added device.
2414 ConSplitterGetIntersection (
2419 &Private
->TextOutMode
.MaxMode
,
2420 &Private
->TextOutMode
.Mode
2428 Sync output device between ConOut and StdErr output.
2430 @retval EFI_SUCCESS Sync implemented successfully.
2431 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2435 ConSplitterGetIntersectionBetweenConOutAndStrErr (
2439 UINTN ConOutNumOfConsoles
;
2440 UINTN StdErrNumOfConsoles
;
2441 TEXT_OUT_AND_GOP_DATA
*ConOutTextOutList
;
2442 TEXT_OUT_AND_GOP_DATA
*StdErrTextOutList
;
2446 UINTN ConOutColumns
;
2448 UINTN StdErrColumns
;
2449 INT32 ConOutMaxMode
;
2450 INT32 StdErrMaxMode
;
2455 INT32
*ConOutModeMap
;
2456 INT32
*StdErrModeMap
;
2457 INT32
*ConOutMapTable
;
2458 INT32
*StdErrMapTable
;
2459 TEXT_OUT_SPLITTER_QUERY_DATA
*ConOutQueryData
;
2460 TEXT_OUT_SPLITTER_QUERY_DATA
*StdErrQueryData
;
2461 UINTN ConOutStepSize
;
2462 UINTN StdErrStepSize
;
2463 BOOLEAN FoundTheSameTextOut
;
2464 UINTN ConOutMapTableSize
;
2465 UINTN StdErrMapTableSize
;
2467 ConOutNumOfConsoles
= mConOut
.CurrentNumberOfConsoles
;
2468 StdErrNumOfConsoles
= mStdErr
.CurrentNumberOfConsoles
;
2469 ConOutTextOutList
= mConOut
.TextOutList
;
2470 StdErrTextOutList
= mStdErr
.TextOutList
;
2473 FoundTheSameTextOut
= FALSE
;
2474 while ((Indexi
< ConOutNumOfConsoles
) && (!FoundTheSameTextOut
)) {
2476 while (Indexj
< StdErrNumOfConsoles
) {
2477 if (ConOutTextOutList
->TextOut
== StdErrTextOutList
->TextOut
) {
2478 FoundTheSameTextOut
= TRUE
;
2483 StdErrTextOutList
++;
2487 ConOutTextOutList
++;
2490 if (!FoundTheSameTextOut
) {
2494 // Must make sure that current mode won't change even if mode number changes
2496 ConOutMaxMode
= mConOut
.TextOutMode
.MaxMode
;
2497 ConOutModeMap
= mConOut
.TextOutModeMap
;
2498 ConOutStepSize
= mConOut
.TextOutListCount
;
2499 ConOutQueryData
= mConOut
.TextOutQueryData
;
2501 StdErrMaxMode
= mStdErr
.TextOutMode
.MaxMode
;
2502 StdErrModeMap
= mStdErr
.TextOutModeMap
;
2503 StdErrStepSize
= mStdErr
.TextOutListCount
;
2504 StdErrQueryData
= mStdErr
.TextOutQueryData
;
2507 // Allocate the map table and set the map table's index to -1.
2509 ConOutMapTableSize
= ConOutMaxMode
* sizeof (INT32
);
2510 ConOutMapTable
= AllocateZeroPool (ConOutMapTableSize
);
2511 if (ConOutMapTable
== NULL
) {
2512 return EFI_OUT_OF_RESOURCES
;
2515 SetMem (ConOutMapTable
, ConOutMapTableSize
, 0xFF);
2517 StdErrMapTableSize
= StdErrMaxMode
* sizeof (INT32
);
2518 StdErrMapTable
= AllocateZeroPool (StdErrMapTableSize
);
2519 if (StdErrMapTable
== NULL
) {
2520 return EFI_OUT_OF_RESOURCES
;
2523 SetMem (StdErrMapTable
, StdErrMapTableSize
, 0xFF);
2526 // Find the intersection of the two set of modes. If they actually intersect, the
2527 // correponding entry in the map table is set to 1.
2530 while (Mode
< ConOutMaxMode
) {
2532 // Search the intersection map and QueryData database to see if they intersect
2535 ConOutMode
= *(ConOutModeMap
+ Mode
* ConOutStepSize
);
2536 ConOutRows
= ConOutQueryData
[ConOutMode
].Rows
;
2537 ConOutColumns
= ConOutQueryData
[ConOutMode
].Columns
;
2538 while (Index
< StdErrMaxMode
) {
2539 StdErrMode
= *(StdErrModeMap
+ Index
* StdErrStepSize
);
2540 StdErrRows
= StdErrQueryData
[StdErrMode
].Rows
;
2541 StdErrColumns
= StdErrQueryData
[StdErrMode
].Columns
;
2542 if ((StdErrRows
== ConOutRows
) && (StdErrColumns
== ConOutColumns
)) {
2543 ConOutMapTable
[Mode
] = 1;
2544 StdErrMapTable
[Index
] = 1;
2554 // Now search the TextOutModeMap table to find the intersection of supported
2555 // mode between ConSplitter and the newly added device.
2557 ConSplitterGetIntersection (
2560 mConOut
.TextOutListCount
,
2562 &(mConOut
.TextOutMode
.MaxMode
),
2563 &(mConOut
.TextOutMode
.Mode
)
2566 if (mConOut
.TextOutMode
.Mode
< 0) {
2567 mConOut
.TextOut
.SetMode (&(mConOut
.TextOut
), 0);
2570 ConSplitterGetIntersection (
2573 mStdErr
.TextOutListCount
,
2575 &(mStdErr
.TextOutMode
.MaxMode
),
2576 &(mStdErr
.TextOutMode
.Mode
)
2579 if (mStdErr
.TextOutMode
.Mode
< 0) {
2580 mStdErr
.TextOut
.SetMode (&(mStdErr
.TextOut
), 0);
2583 FreePool (ConOutMapTable
);
2584 FreePool (StdErrMapTable
);
2591 Add Grahpics Output modes into Consplitter Text Out list.
2593 @param Private Text Out Splitter pointer.
2594 @param GraphicsOutput Graphics Output protocol pointer.
2595 @param UgaDraw UGA Draw protocol pointer.
2597 @retval EFI_SUCCESS Output mode added successfully.
2598 @retval other Failed to add output mode.
2602 ConSplitterAddGraphicsOutputMode (
2603 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2604 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2605 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2611 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
;
2613 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2614 EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*CurrentGraphicsOutputMode
;
2615 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*ModeBuffer
;
2616 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*MatchedMode
;
2619 BOOLEAN AlreadyExist
;
2620 UINT32 UgaHorizontalResolution
;
2621 UINT32 UgaVerticalResolution
;
2622 UINT32 UgaColorDepth
;
2623 UINT32 UgaRefreshRate
;
2625 ASSERT (GraphicsOutput
!= NULL
|| UgaDraw
!= NULL
);
2627 CurrentGraphicsOutputMode
= Private
->GraphicsOutput
.Mode
;
2631 Status
= EFI_SUCCESS
;
2633 if (Private
->CurrentNumberOfUgaDraw
!= 0) {
2635 // If any UGA device has already been added, then there is no need to
2636 // calculate intersection of display mode of different GOP/UGA device,
2637 // since only one display mode will be exported (i.e. user-defined mode)
2642 if (GraphicsOutput
!= NULL
) {
2643 if (Private
->CurrentNumberOfGraphicsOutput
== 0) {
2645 // This is the first Graphics Output device added
2647 CurrentGraphicsOutputMode
->MaxMode
= GraphicsOutput
->Mode
->MaxMode
;
2648 CurrentGraphicsOutputMode
->Mode
= GraphicsOutput
->Mode
->Mode
;
2649 CopyMem (CurrentGraphicsOutputMode
->Info
, GraphicsOutput
->Mode
->Info
, GraphicsOutput
->Mode
->SizeOfInfo
);
2650 CurrentGraphicsOutputMode
->SizeOfInfo
= GraphicsOutput
->Mode
->SizeOfInfo
;
2651 CurrentGraphicsOutputMode
->FrameBufferBase
= GraphicsOutput
->Mode
->FrameBufferBase
;
2652 CurrentGraphicsOutputMode
->FrameBufferSize
= GraphicsOutput
->Mode
->FrameBufferSize
;
2655 // Allocate resource for the private mode buffer
2657 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * GraphicsOutput
->Mode
->MaxMode
);
2658 if (ModeBuffer
== NULL
) {
2659 return EFI_OUT_OF_RESOURCES
;
2661 FreePool (Private
->GraphicsOutputModeBuffer
);
2662 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2665 // Store all supported display modes to the private mode buffer
2668 for (Index
= 0; Index
< GraphicsOutput
->Mode
->MaxMode
; Index
++) {
2670 // The Info buffer would be allocated by callee
2672 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) Index
, &SizeOfInfo
, &Info
);
2673 if (EFI_ERROR (Status
)) {
2676 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2677 CopyMem (Mode
, Info
, SizeOfInfo
);
2683 // Check intersection of display mode
2685 ModeBuffer
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
) * CurrentGraphicsOutputMode
->MaxMode
);
2686 if (ModeBuffer
== NULL
) {
2687 return EFI_OUT_OF_RESOURCES
;
2690 MatchedMode
= ModeBuffer
;
2691 Mode
= &Private
->GraphicsOutputModeBuffer
[0];
2692 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2695 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2697 // The Info buffer would be allocated by callee
2699 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2700 if (EFI_ERROR (Status
)) {
2703 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2704 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2706 // If GOP device supports one mode in current mode buffer,
2707 // it will be added into matched mode buffer
2717 AlreadyExist
= FALSE
;
2720 // Check if GOP mode has been in the mode buffer, ModeBuffer = MatchedMode at begin.
2722 for (Info
= ModeBuffer
; Info
< MatchedMode
; Info
++) {
2723 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) &&
2724 (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2725 AlreadyExist
= TRUE
;
2730 if (!AlreadyExist
) {
2731 CopyMem (MatchedMode
, Mode
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2734 // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly
2736 MatchedMode
->Version
= 0;
2737 MatchedMode
->PixelFormat
= PixelBltOnly
;
2738 ZeroMem (&MatchedMode
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2748 // Drop the old mode buffer, assign it to a new one
2750 FreePool (Private
->GraphicsOutputModeBuffer
);
2751 Private
->GraphicsOutputModeBuffer
= ModeBuffer
;
2754 // Physical frame buffer is no longer available when there are more than one physical GOP devices
2756 CurrentGraphicsOutputMode
->MaxMode
= (UINT32
) (((UINTN
) MatchedMode
- (UINTN
) ModeBuffer
) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2757 CurrentGraphicsOutputMode
->Info
->PixelFormat
= PixelBltOnly
;
2758 ZeroMem (&CurrentGraphicsOutputMode
->Info
->PixelInformation
, sizeof (EFI_PIXEL_BITMASK
));
2759 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2760 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2761 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2765 // Graphics console driver can ensure the same mode for all GOP devices
2767 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2768 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2769 if ((Mode
->HorizontalResolution
== GraphicsOutput
->Mode
->Info
->HorizontalResolution
) &&
2770 (Mode
->VerticalResolution
== GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2771 CurrentIndex
= Index
;
2775 if (Index
>= CurrentGraphicsOutputMode
->MaxMode
) {
2777 // if user defined mode is not found, set to default mode 800x600
2779 for (Index
= 0; Index
< CurrentGraphicsOutputMode
->MaxMode
; Index
++) {
2780 Mode
= &Private
->GraphicsOutputModeBuffer
[Index
];
2781 if ((Mode
->HorizontalResolution
== 800) && (Mode
->VerticalResolution
== 600)) {
2782 CurrentIndex
= Index
;
2787 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2789 // Graphics console driver can ensure the same mode for all GOP devices
2790 // so we can get the current mode from this video device
2794 &UgaHorizontalResolution
,
2795 &UgaVerticalResolution
,
2800 CurrentGraphicsOutputMode
->MaxMode
= 1;
2801 Info
= CurrentGraphicsOutputMode
->Info
;
2803 Info
->HorizontalResolution
= UgaHorizontalResolution
;
2804 Info
->VerticalResolution
= UgaVerticalResolution
;
2805 Info
->PixelFormat
= PixelBltOnly
;
2806 Info
->PixelsPerScanLine
= UgaHorizontalResolution
;
2807 CurrentGraphicsOutputMode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
2808 CurrentGraphicsOutputMode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
2809 CurrentGraphicsOutputMode
->FrameBufferSize
= 0;
2812 // Update the private mode buffer
2814 CopyMem (&Private
->GraphicsOutputModeBuffer
[0], Info
, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
2817 // Only mode 0 is available to be set
2824 if (GraphicsOutput
!= NULL
) {
2825 Private
->CurrentNumberOfGraphicsOutput
++;
2827 if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
2828 Private
->CurrentNumberOfUgaDraw
++;
2832 // Force GraphicsOutput mode to be set,
2835 Mode
= &Private
->GraphicsOutputModeBuffer
[CurrentIndex
];
2836 if ((GraphicsOutput
!= NULL
) &&
2837 (Mode
->HorizontalResolution
== CurrentGraphicsOutputMode
->Info
->HorizontalResolution
) &&
2838 (Mode
->VerticalResolution
== CurrentGraphicsOutputMode
->Info
->VerticalResolution
)) {
2839 CurrentGraphicsOutputMode
->Mode
= (UINT32
) CurrentIndex
;
2840 if ((Mode
->HorizontalResolution
!= GraphicsOutput
->Mode
->Info
->HorizontalResolution
) ||
2841 (Mode
->VerticalResolution
!= GraphicsOutput
->Mode
->Info
->VerticalResolution
)) {
2843 // If all existing video device has been set to common mode, only set new GOP device to
2846 for (NumberIndex
= 0; NumberIndex
< GraphicsOutput
->Mode
->MaxMode
; NumberIndex
++) {
2847 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, (UINT32
) NumberIndex
, &SizeOfInfo
, &Info
);
2848 if (EFI_ERROR (Status
)) {
2851 if ((Info
->HorizontalResolution
== Mode
->HorizontalResolution
) && (Info
->VerticalResolution
== Mode
->VerticalResolution
)) {
2857 Status
= GraphicsOutput
->SetMode (GraphicsOutput
, (UINT32
) NumberIndex
);
2861 // Current mode number may need update now, so set it to an invalid mode number
2863 CurrentGraphicsOutputMode
->Mode
= 0xffff;
2865 // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.
2867 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, (UINT32
) CurrentIndex
);
2868 if (EFI_ERROR(Status
)) {
2870 // If user defined mode is not valid for display device, set to the default mode 800x600.
2872 (Private
->GraphicsOutputModeBuffer
[0]).HorizontalResolution
= 800;
2873 (Private
->GraphicsOutputModeBuffer
[0]).VerticalResolution
= 600;
2874 Status
= Private
->GraphicsOutput
.SetMode (&Private
->GraphicsOutput
, 0);
2882 Set the current console out mode.
2884 This routine will get the current console mode information (column, row)
2885 from ConsoleOutMode variable and set it; if the variable does not exist,
2886 set to user defined console mode.
2888 @param Private Consplitter Text Out pointer.
2892 ConsplitterSetConsoleOutMode (
2893 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
2903 CONSOLE_OUT_MODE ModeInfo
;
2904 CONSOLE_OUT_MODE MaxModeInfo
;
2905 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
2909 TextOut
= &Private
->TextOut
;
2910 MaxMode
= (UINTN
) (TextOut
->Mode
->MaxMode
);
2912 MaxModeInfo
.Column
= 0;
2913 MaxModeInfo
.Row
= 0;
2914 ModeInfo
.Column
= PcdGet32 (PcdConOutColumn
);
2915 ModeInfo
.Row
= PcdGet32 (PcdConOutRow
);
2918 // To find the prefer mode and basic mode from Text Out mode list
2920 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
2921 Status
= TextOut
->QueryMode (TextOut
, Mode
, &Col
, &Row
);
2922 if (!EFI_ERROR(Status
)) {
2923 if ((ModeInfo
.Column
!= 0) && (ModeInfo
.Row
!= 0)) {
2925 // Use user defined column and row
2927 if (Col
== ModeInfo
.Column
&& Row
== ModeInfo
.Row
) {
2932 // If user sets PcdConOutColumn or PcdConOutRow to 0,
2933 // find and set the highest text mode.
2935 if ((Col
>= MaxModeInfo
.Column
) && (Row
>= MaxModeInfo
.Row
)) {
2936 MaxModeInfo
.Column
= Col
;
2937 MaxModeInfo
.Row
= Row
;
2941 if (Col
== 80 && Row
== 25) {
2948 // Set prefer mode to Text Out devices.
2950 Status
= TextOut
->SetMode (TextOut
, PreferMode
);
2951 if (EFI_ERROR(Status
)) {
2953 // if current mode setting is failed, default 80x25 mode will be set.
2955 Status
= TextOut
->SetMode (TextOut
, BaseMode
);
2956 ASSERT(!EFI_ERROR(Status
));
2958 PcdSet32 (PcdConOutColumn
, 80);
2959 PcdSet32 (PcdConOutRow
, 25);
2967 Add Text Output Device in Consplitter Text Output list.
2969 @param Private Text Out Splitter pointer.
2970 @param TextOut Simple Text Output protocol pointer.
2971 @param GraphicsOutput Graphics Output protocol pointer.
2972 @param UgaDraw UGA Draw protocol pointer.
2974 @retval EFI_SUCCESS Text Output Device added successfully.
2975 @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.
2979 ConSplitterTextOutAddDevice (
2980 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
2981 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
,
2982 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
2983 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
2987 UINTN CurrentNumOfConsoles
;
2989 UINT32 UgaHorizontalResolution
;
2990 UINT32 UgaVerticalResolution
;
2991 UINT32 UgaColorDepth
;
2992 UINT32 UgaRefreshRate
;
2993 TEXT_OUT_AND_GOP_DATA
*TextAndGop
;
2995 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
2996 EFI_STATUS DeviceStatus
;
2998 Status
= EFI_SUCCESS
;
2999 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
3002 // If the Text Out List is full, enlarge it by calling ConSplitterGrowBuffer().
3004 while (CurrentNumOfConsoles
>= Private
->TextOutListCount
) {
3005 Status
= ConSplitterGrowBuffer (
3006 sizeof (TEXT_OUT_AND_GOP_DATA
),
3007 &Private
->TextOutListCount
,
3008 (VOID
**) &Private
->TextOutList
3010 if (EFI_ERROR (Status
)) {
3011 return EFI_OUT_OF_RESOURCES
;
3014 // Also need to reallocate the TextOutModeMap table
3016 Status
= ConSplitterGrowMapTable (Private
);
3017 if (EFI_ERROR (Status
)) {
3018 return EFI_OUT_OF_RESOURCES
;
3022 TextAndGop
= &Private
->TextOutList
[CurrentNumOfConsoles
];
3024 TextAndGop
->TextOut
= TextOut
;
3025 TextAndGop
->GraphicsOutput
= GraphicsOutput
;
3026 TextAndGop
->UgaDraw
= UgaDraw
;
3028 if (CurrentNumOfConsoles
== 0) {
3030 // Add the first device's output mode to console splitter's mode list
3032 Status
= ConSplitterAddOutputMode (Private
, TextOut
);
3034 ConSplitterSyncOutputMode (Private
, TextOut
);
3037 Private
->CurrentNumberOfConsoles
++;
3040 // Scan both TextOutList, for the intersection TextOut device
3041 // maybe both ConOut and StdErr incorporate the same Text Out
3042 // device in them, thus the output of both should be synced.
3044 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3046 MaxMode
= Private
->TextOutMode
.MaxMode
;
3047 ASSERT (MaxMode
>= 1);
3049 DeviceStatus
= EFI_DEVICE_ERROR
;
3050 if (FeaturePcdGet (PcdConOutGopSupport
)) {
3052 // If GOP is produced by Consplitter, this device display mode will be added into Graphics Ouput modes.
3054 if ((GraphicsOutput
!= NULL
) || (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
))) {
3055 DeviceStatus
= ConSplitterAddGraphicsOutputMode (Private
, GraphicsOutput
, UgaDraw
);
3059 if (FeaturePcdGet (PcdConOutUgaSupport
)) {
3061 // If UGA is produced by Consplitter
3063 if (GraphicsOutput
!= NULL
) {
3064 Status
= GraphicsOutput
->QueryMode (GraphicsOutput
, GraphicsOutput
->Mode
->Mode
, &SizeOfInfo
, &Info
);
3065 if (EFI_ERROR (Status
)) {
3068 ASSERT ( SizeOfInfo
<= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
3070 UgaHorizontalResolution
= Info
->HorizontalResolution
;
3071 UgaVerticalResolution
= Info
->VerticalResolution
;
3075 } else if (UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3076 Status
= UgaDraw
->GetMode (
3078 &UgaHorizontalResolution
,
3079 &UgaVerticalResolution
,
3083 if (!EFI_ERROR (Status
) && EFI_ERROR (DeviceStatus
)) {
3085 // if GetMode is successfully and UGA device hasn't been set, set it
3087 Status
= ConSplitterUgaDrawSetMode (
3089 UgaHorizontalResolution
,
3090 UgaVerticalResolution
,
3096 // If GetMode/SetMode is failed, set to 800x600 mode
3098 if(EFI_ERROR (Status
)) {
3099 Status
= ConSplitterUgaDrawSetMode (
3111 // After adding new console device, all existing console devices should be
3112 // synced to the current shared mode.
3114 ConsplitterSetConsoleOutMode (Private
);
3121 Remove Text Out Device in Consplitter Text Out list.
3123 @param Private Text Out Splitter pointer.
3124 @param TextOut Simple Text Output Pointer protocol pointer.
3126 @retval EFI_SUCCESS Text Out Device removed successfully.
3127 @retval EFI_NOT_FOUND No Text Out Device found.
3131 ConSplitterTextOutDeleteDevice (
3132 IN TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
,
3133 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
3137 UINTN CurrentNumOfConsoles
;
3138 TEXT_OUT_AND_GOP_DATA
*TextOutList
;
3142 // Remove the specified text-out device data structure from the Text out List,
3143 // and rearrange the remaining data structures in the Text out List.
3145 CurrentNumOfConsoles
= Private
->CurrentNumberOfConsoles
;
3146 Index
= (INT32
) CurrentNumOfConsoles
- 1;
3147 TextOutList
= Private
->TextOutList
;
3148 while (Index
>= 0) {
3149 if (TextOutList
->TextOut
== TextOut
) {
3150 if (TextOutList
->UgaDraw
!= NULL
&& FeaturePcdGet (PcdUgaConsumeSupport
)) {
3151 Private
->CurrentNumberOfUgaDraw
--;
3153 if (TextOutList
->GraphicsOutput
!= NULL
) {
3154 Private
->CurrentNumberOfGraphicsOutput
--;
3156 CopyMem (TextOutList
, TextOutList
+ 1, sizeof (TEXT_OUT_AND_GOP_DATA
) * Index
);
3157 CurrentNumOfConsoles
--;
3165 // The specified TextOut is not managed by the ConSplitter driver
3168 return EFI_NOT_FOUND
;
3171 if (CurrentNumOfConsoles
== 0) {
3173 // If the number of consoles is zero, reset all parameters
3175 Private
->CurrentNumberOfConsoles
= 0;
3176 Private
->TextOutMode
.MaxMode
= 1;
3177 Private
->TextOutQueryData
[0].Columns
= 80;
3178 Private
->TextOutQueryData
[0].Rows
= 25;
3179 TextOutSetMode (Private
, 0);
3184 // Max Mode is realy an intersection of the QueryMode command to all
3185 // devices. So we must copy the QueryMode of the first device to
3189 Private
->TextOutQueryData
,
3190 Private
->TextOutQueryDataCount
* sizeof (TEXT_OUT_SPLITTER_QUERY_DATA
)
3193 FreePool (Private
->TextOutModeMap
);
3194 Private
->TextOutModeMap
= NULL
;
3195 TextOutList
= Private
->TextOutList
;
3198 // Add the first TextOut to the QueryData array and ModeMap table
3200 Status
= ConSplitterAddOutputMode (Private
, TextOutList
->TextOut
);
3203 // Now add one by one
3206 Private
->CurrentNumberOfConsoles
= 1;
3208 while ((UINTN
) Index
< CurrentNumOfConsoles
) {
3209 ConSplitterSyncOutputMode (Private
, TextOutList
->TextOut
);
3211 Private
->CurrentNumberOfConsoles
++;
3215 ConSplitterGetIntersectionBetweenConOutAndStrErr ();
3222 Reset the input device and optionaly run diagnostics
3224 @param This Protocol instance pointer.
3225 @param ExtendedVerification Driver may perform diagnostics on reset.
3227 @retval EFI_SUCCESS The device was reset.
3228 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3234 ConSplitterTextInReset (
3235 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3236 IN BOOLEAN ExtendedVerification
3240 EFI_STATUS ReturnStatus
;
3241 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3244 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3246 Private
->KeyEventSignalState
= FALSE
;
3249 // return the worst status met
3251 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3252 Status
= Private
->TextInList
[Index
]->Reset (
3253 Private
->TextInList
[Index
],
3254 ExtendedVerification
3256 if (EFI_ERROR (Status
)) {
3257 ReturnStatus
= Status
;
3261 return ReturnStatus
;
3266 Reads the next keystroke from the input device. The WaitForKey Event can
3267 be used to test for existance of a keystroke via WaitForEvent () call.
3269 @param Private Protocol instance pointer.
3270 @param Key Driver may perform diagnostics on reset.
3272 @retval EFI_SUCCESS The keystroke information was returned.
3273 @retval EFI_NOT_READY There was no keystroke data availiable.
3274 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3280 ConSplitterTextInPrivateReadKeyStroke (
3281 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3282 OUT EFI_INPUT_KEY
*Key
3287 EFI_INPUT_KEY CurrentKey
;
3289 Key
->UnicodeChar
= 0;
3290 Key
->ScanCode
= SCAN_NULL
;
3293 // if no physical console input device exists, return EFI_NOT_READY;
3294 // if any physical console input device has key input,
3295 // return the key and EFI_SUCCESS.
3297 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3298 Status
= Private
->TextInList
[Index
]->ReadKeyStroke (
3299 Private
->TextInList
[Index
],
3302 if (!EFI_ERROR (Status
)) {
3308 return EFI_NOT_READY
;
3313 Reads the next keystroke from the input device. The WaitForKey Event can
3314 be used to test for existance of a keystroke via WaitForEvent () call.
3316 @param This Protocol instance pointer.
3317 @param Key Driver may perform diagnostics on reset.
3319 @retval EFI_SUCCESS The keystroke information was returned.
3320 @retval EFI_NOT_READY There was no keystroke data availiable.
3321 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3327 ConSplitterTextInReadKeyStroke (
3328 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
3329 OUT EFI_INPUT_KEY
*Key
3332 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3334 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3336 Private
->KeyEventSignalState
= FALSE
;
3338 return ConSplitterTextInPrivateReadKeyStroke (Private
, Key
);
3343 This event aggregates all the events of the ConIn devices in the spliter.
3345 If any events of physical ConIn devices are signaled, signal the ConIn
3346 spliter event. This will cause the calling code to call
3347 ConSplitterTextInReadKeyStroke ().
3349 @param Event The Event assoicated with callback.
3350 @param Context Context registered when Event was created.
3355 ConSplitterTextInWaitForKey (
3361 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3364 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3366 if (Private
->KeyEventSignalState
) {
3368 // If KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3370 gBS
->SignalEvent (Event
);
3375 // If any physical console input device has key input, signal the event.
3377 for (Index
= 0; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
3378 Status
= gBS
->CheckEvent (Private
->TextInList
[Index
]->WaitForKey
);
3379 if (!EFI_ERROR (Status
)) {
3380 gBS
->SignalEvent (Event
);
3381 Private
->KeyEventSignalState
= TRUE
;
3389 Test if the key has been registered on input device.
3391 @param RegsiteredData A pointer to a buffer that is filled in with the
3392 keystroke state data for the key that was
3394 @param InputData A pointer to a buffer that is filled in with the
3395 keystroke state data for the key that was
3398 @retval TRUE Key be pressed matches a registered key.
3399 @retval FLASE Match failed.
3404 IN EFI_KEY_DATA
*RegsiteredData
,
3405 IN EFI_KEY_DATA
*InputData
3408 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
3410 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
3411 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
3416 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
3418 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
3419 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
3422 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
3423 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
3433 Reset the input device and optionaly run diagnostics
3435 @param This Protocol instance pointer.
3436 @param ExtendedVerification Driver may perform diagnostics on reset.
3438 @retval EFI_SUCCESS The device was reset.
3439 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3445 ConSplitterTextInResetEx (
3446 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3447 IN BOOLEAN ExtendedVerification
3451 EFI_STATUS ReturnStatus
;
3452 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3455 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3457 Private
->KeyEventSignalState
= FALSE
;
3460 // return the worst status met
3462 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3463 Status
= Private
->TextInExList
[Index
]->Reset (
3464 Private
->TextInExList
[Index
],
3465 ExtendedVerification
3467 if (EFI_ERROR (Status
)) {
3468 ReturnStatus
= Status
;
3472 return ReturnStatus
;
3478 Reads the next keystroke from the input device. The WaitForKey Event can
3479 be used to test for existance of a keystroke via WaitForEvent () call.
3481 @param This Protocol instance pointer.
3482 @param KeyData A pointer to a buffer that is filled in with the
3483 keystroke state data for the key that was
3486 @retval EFI_SUCCESS The keystroke information was returned.
3487 @retval EFI_NOT_READY There was no keystroke data availiable.
3488 @retval EFI_DEVICE_ERROR The keystroke information was not returned due
3490 @retval EFI_INVALID_PARAMETER KeyData is NULL.
3495 ConSplitterTextInReadKeyStrokeEx (
3496 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3497 OUT EFI_KEY_DATA
*KeyData
3500 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3503 EFI_KEY_DATA CurrentKeyData
;
3506 if (KeyData
== NULL
) {
3507 return EFI_INVALID_PARAMETER
;
3510 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3512 Private
->KeyEventSignalState
= FALSE
;
3514 KeyData
->Key
.UnicodeChar
= 0;
3515 KeyData
->Key
.ScanCode
= SCAN_NULL
;
3518 // if no physical console input device exists, return EFI_NOT_READY;
3519 // if any physical console input device has key input,
3520 // return the key and EFI_SUCCESS.
3522 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3523 Status
= Private
->TextInExList
[Index
]->ReadKeyStrokeEx (
3524 Private
->TextInExList
[Index
],
3527 if (!EFI_ERROR (Status
)) {
3528 CopyMem (KeyData
, &CurrentKeyData
, sizeof (CurrentKeyData
));
3533 return EFI_NOT_READY
;
3538 Set certain state for the input device.
3540 @param This Protocol instance pointer.
3541 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
3542 state for the input device.
3544 @retval EFI_SUCCESS The device state was set successfully.
3545 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3546 could not have the setting adjusted.
3547 @retval EFI_UNSUPPORTED The device does not have the ability to set its
3549 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
3554 ConSplitterTextInSetState (
3555 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3556 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
3559 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3563 if (KeyToggleState
== NULL
) {
3564 return EFI_INVALID_PARAMETER
;
3567 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3570 // if no physical console input device exists, return EFI_SUCCESS;
3571 // otherwise return the status of setting state of physical console input device
3573 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3574 Status
= Private
->TextInExList
[Index
]->SetState (
3575 Private
->TextInExList
[Index
],
3578 if (EFI_ERROR (Status
)) {
3589 Register a notification function for a particular keystroke for the input device.
3591 @param This Protocol instance pointer.
3592 @param KeyData A pointer to a buffer that is filled in with the
3593 keystroke information data for the key that was
3595 @param KeyNotificationFunction Points to the function to be called when the key
3596 sequence is typed specified by KeyData.
3597 @param NotifyHandle Points to the unique handle assigned to the
3598 registered notification.
3600 @retval EFI_SUCCESS The notification function was registered
3602 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data
3604 @retval EFI_INVALID_PARAMETER KeyData or KeyNotificationFunction or NotifyHandle is NULL.
3609 ConSplitterTextInRegisterKeyNotify (
3610 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3611 IN EFI_KEY_DATA
*KeyData
,
3612 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
3613 OUT EFI_HANDLE
*NotifyHandle
3616 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3619 TEXT_IN_EX_SPLITTER_NOTIFY
*NewNotify
;
3621 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3624 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
3625 return EFI_INVALID_PARAMETER
;
3628 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3631 // If no physical console input device exists,
3632 // return EFI_SUCCESS directly.
3634 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3639 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
3641 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3642 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
3643 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
3644 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
3645 *NotifyHandle
= CurrentNotify
->NotifyHandle
;
3652 // Allocate resource to save the notification function
3654 NewNotify
= (TEXT_IN_EX_SPLITTER_NOTIFY
*) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY
));
3655 if (NewNotify
== NULL
) {
3656 return EFI_OUT_OF_RESOURCES
;
3658 NewNotify
->NotifyHandleList
= (EFI_HANDLE
*) AllocateZeroPool (sizeof (EFI_HANDLE
) * Private
->CurrentNumberOfExConsoles
);
3659 if (NewNotify
->NotifyHandleList
== NULL
) {
3660 gBS
->FreePool (NewNotify
);
3661 return EFI_OUT_OF_RESOURCES
;
3663 NewNotify
->Signature
= TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
;
3664 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
3665 NewNotify
->NotifyHandle
= (EFI_HANDLE
) NewNotify
;
3666 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (EFI_KEY_DATA
));
3669 // Return the wrong status of registering key notify of
3670 // physical console input device if meet problems
3672 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3673 Status
= Private
->TextInExList
[Index
]->RegisterKeyNotify (
3674 Private
->TextInExList
[Index
],
3676 KeyNotificationFunction
,
3677 &NewNotify
->NotifyHandleList
[Index
]
3679 if (EFI_ERROR (Status
)) {
3680 gBS
->FreePool (NewNotify
->NotifyHandleList
);
3681 gBS
->FreePool (NewNotify
);
3686 InsertTailList (&mConIn
.NotifyList
, &NewNotify
->NotifyEntry
);
3688 *NotifyHandle
= NewNotify
->NotifyHandle
;
3696 Remove a registered notification function from a particular keystroke.
3698 @param This Protocol instance pointer.
3699 @param NotificationHandle The handle of the notification function being
3702 @retval EFI_SUCCESS The notification function was unregistered
3704 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
3709 ConSplitterTextInUnregisterKeyNotify (
3710 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
3711 IN EFI_HANDLE NotificationHandle
3714 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3717 TEXT_IN_EX_SPLITTER_NOTIFY
*CurrentNotify
;
3720 if (NotificationHandle
== NULL
) {
3721 return EFI_INVALID_PARAMETER
;
3724 if (((TEXT_IN_EX_SPLITTER_NOTIFY
*) NotificationHandle
)->Signature
!= TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
) {
3725 return EFI_INVALID_PARAMETER
;
3728 Private
= TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
3731 // if no physical console input device exists,
3732 // return EFI_SUCCESS directly.
3734 if (Private
->CurrentNumberOfExConsoles
<= 0) {
3738 for (Link
= Private
->NotifyList
.ForwardLink
; Link
!= &Private
->NotifyList
; Link
= Link
->ForwardLink
) {
3739 CurrentNotify
= TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link
);
3740 if (CurrentNotify
->NotifyHandle
== NotificationHandle
) {
3741 for (Index
= 0; Index
< Private
->CurrentNumberOfExConsoles
; Index
++) {
3742 Status
= Private
->TextInExList
[Index
]->UnregisterKeyNotify (
3743 Private
->TextInExList
[Index
],
3744 CurrentNotify
->NotifyHandleList
[Index
]
3746 if (EFI_ERROR (Status
)) {
3750 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
3752 gBS
->FreePool (CurrentNotify
->NotifyHandleList
);
3753 gBS
->FreePool (CurrentNotify
);
3759 // NotificationHandle is not found in database
3761 return EFI_INVALID_PARAMETER
;
3766 Reset the input device and optionaly run diagnostics
3768 @param This Protocol instance pointer.
3769 @param ExtendedVerification Driver may perform diagnostics on reset.
3771 @retval EFI_SUCCESS The device was reset.
3772 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
3778 ConSplitterSimplePointerReset (
3779 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3780 IN BOOLEAN ExtendedVerification
3784 EFI_STATUS ReturnStatus
;
3785 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3788 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3790 Private
->InputEventSignalState
= FALSE
;
3792 if (Private
->CurrentNumberOfPointers
== 0) {
3796 // return the worst status met
3798 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3799 Status
= Private
->PointerList
[Index
]->Reset (
3800 Private
->PointerList
[Index
],
3801 ExtendedVerification
3803 if (EFI_ERROR (Status
)) {
3804 ReturnStatus
= Status
;
3808 return ReturnStatus
;
3813 Reads the next keystroke from the input device. The WaitForKey Event can
3814 be used to test for existance of a keystroke via WaitForEvent () call.
3816 @param Private Protocol instance pointer.
3817 @param State The state information of simple pointer device.
3819 @retval EFI_SUCCESS The keystroke information was returned.
3820 @retval EFI_NOT_READY There was no keystroke data availiable.
3821 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3827 ConSplitterSimplePointerPrivateGetState (
3828 IN TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
,
3829 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3833 EFI_STATUS ReturnStatus
;
3835 EFI_SIMPLE_POINTER_STATE CurrentState
;
3837 State
->RelativeMovementX
= 0;
3838 State
->RelativeMovementY
= 0;
3839 State
->RelativeMovementZ
= 0;
3840 State
->LeftButton
= FALSE
;
3841 State
->RightButton
= FALSE
;
3844 // if no physical console input device exists, return EFI_NOT_READY;
3845 // if any physical console input device has key input,
3846 // return the key and EFI_SUCCESS.
3848 ReturnStatus
= EFI_NOT_READY
;
3849 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3851 Status
= Private
->PointerList
[Index
]->GetState (
3852 Private
->PointerList
[Index
],
3855 if (!EFI_ERROR (Status
)) {
3856 if (ReturnStatus
== EFI_NOT_READY
) {
3857 ReturnStatus
= EFI_SUCCESS
;
3860 if (CurrentState
.LeftButton
) {
3861 State
->LeftButton
= TRUE
;
3864 if (CurrentState
.RightButton
) {
3865 State
->RightButton
= TRUE
;
3868 if (CurrentState
.RelativeMovementX
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionX
!= 0) {
3869 State
->RelativeMovementX
+= (CurrentState
.RelativeMovementX
* (INT32
) Private
->SimplePointerMode
.ResolutionX
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionX
;
3872 if (CurrentState
.RelativeMovementY
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionY
!= 0) {
3873 State
->RelativeMovementY
+= (CurrentState
.RelativeMovementY
* (INT32
) Private
->SimplePointerMode
.ResolutionY
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionY
;
3876 if (CurrentState
.RelativeMovementZ
!= 0 && Private
->PointerList
[Index
]->Mode
->ResolutionZ
!= 0) {
3877 State
->RelativeMovementZ
+= (CurrentState
.RelativeMovementZ
* (INT32
) Private
->SimplePointerMode
.ResolutionZ
) / (INT32
) Private
->PointerList
[Index
]->Mode
->ResolutionZ
;
3879 } else if (Status
== EFI_DEVICE_ERROR
) {
3880 ReturnStatus
= EFI_DEVICE_ERROR
;
3884 return ReturnStatus
;
3889 Reads the next keystroke from the input device. The WaitForKey Event can
3890 be used to test for existance of a keystroke via WaitForEvent () call.
3892 @param This A pointer to protocol instance.
3893 @param State A pointer to state information on the pointer device
3895 @retval EFI_SUCCESS The keystroke information was returned in State.
3896 @retval EFI_NOT_READY There was no keystroke data availiable.
3897 @retval EFI_DEVICE_ERROR The keydtroke information was not returned due
3903 ConSplitterSimplePointerGetState (
3904 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
3905 IN OUT EFI_SIMPLE_POINTER_STATE
*State
3908 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3910 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This
);
3912 Private
->InputEventSignalState
= FALSE
;
3914 return ConSplitterSimplePointerPrivateGetState (Private
, State
);
3919 This event agregates all the events of the ConIn devices in the spliter.
3920 If any events of physical ConIn devices are signaled, signal the ConIn
3921 spliter event. This will cause the calling code to call
3922 ConSplitterTextInReadKeyStroke ().
3924 @param Event The Event assoicated with callback.
3925 @param Context Context registered when Event was created.
3930 ConSplitterSimplePointerWaitForInput (
3936 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3939 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
3942 // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
3944 if (Private
->InputEventSignalState
) {
3945 gBS
->SignalEvent (Event
);
3949 // if any physical console input device has key input, signal the event.
3951 for (Index
= 0; Index
< Private
->CurrentNumberOfPointers
; Index
++) {
3952 Status
= gBS
->CheckEvent (Private
->PointerList
[Index
]->WaitForInput
);
3953 if (!EFI_ERROR (Status
)) {
3954 gBS
->SignalEvent (Event
);
3955 Private
->InputEventSignalState
= TRUE
;
3961 Resets the pointer device hardware.
3963 @param This Protocol instance pointer.
3964 @param ExtendedVerification Driver may perform diagnostics on reset.
3966 @retval EFI_SUCCESS The device was reset.
3967 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
3973 ConSplitterAbsolutePointerReset (
3974 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
3975 IN BOOLEAN ExtendedVerification
3979 EFI_STATUS ReturnStatus
;
3980 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
3983 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
3985 Private
->AbsoluteInputEventSignalState
= FALSE
;
3987 if (Private
->CurrentNumberOfAbsolutePointers
== 0) {
3991 // return the worst status met
3993 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
3994 Status
= Private
->AbsolutePointerList
[Index
]->Reset (
3995 Private
->AbsolutePointerList
[Index
],
3996 ExtendedVerification
3998 if (EFI_ERROR (Status
)) {
3999 ReturnStatus
= Status
;
4003 return ReturnStatus
;
4008 Retrieves the current state of a pointer device.
4010 @param This Protocol instance pointer.
4011 @param State A pointer to the state information on the
4014 @retval EFI_SUCCESS The state of the pointer device was returned in
4016 @retval EFI_NOT_READY The state of the pointer device has not changed
4017 since the last call to GetState().
4018 @retval EFI_DEVICE_ERROR A device error occurred while attempting to
4019 retrieve the pointer device's current state.
4024 ConSplitterAbsolutePointerGetState (
4025 IN EFI_ABSOLUTE_POINTER_PROTOCOL
*This
,
4026 IN OUT EFI_ABSOLUTE_POINTER_STATE
*State
4029 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4031 EFI_STATUS ReturnStatus
;
4033 EFI_ABSOLUTE_POINTER_STATE CurrentState
;
4036 Private
= TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This
);
4038 Private
->AbsoluteInputEventSignalState
= FALSE
;
4040 State
->CurrentX
= 0;
4041 State
->CurrentY
= 0;
4042 State
->CurrentZ
= 0;
4043 State
->ActiveButtons
= 0;
4046 // if no physical pointer device exists, return EFI_NOT_READY;
4047 // if any physical pointer device has changed state,
4048 // return the state and EFI_SUCCESS.
4050 ReturnStatus
= EFI_NOT_READY
;
4051 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4053 Status
= Private
->AbsolutePointerList
[Index
]->GetState (
4054 Private
->AbsolutePointerList
[Index
],
4057 if (!EFI_ERROR (Status
)) {
4058 if (ReturnStatus
== EFI_NOT_READY
) {
4059 ReturnStatus
= EFI_SUCCESS
;
4062 State
->ActiveButtons
= CurrentState
.ActiveButtons
;
4064 if (!(Private
->AbsolutePointerMode
.AbsoluteMinX
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxX
== 0)) {
4065 State
->CurrentX
= CurrentState
.CurrentX
;
4067 if (!(Private
->AbsolutePointerMode
.AbsoluteMinY
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxY
== 0)) {
4068 State
->CurrentY
= CurrentState
.CurrentY
;
4070 if (!(Private
->AbsolutePointerMode
.AbsoluteMinZ
== 0 && Private
->AbsolutePointerMode
.AbsoluteMaxZ
== 0)) {
4071 State
->CurrentZ
= CurrentState
.CurrentZ
;
4074 } else if (Status
== EFI_DEVICE_ERROR
) {
4075 ReturnStatus
= EFI_DEVICE_ERROR
;
4079 return ReturnStatus
;
4084 This event agregates all the events of the pointer devices in the splitter.
4085 If any events of physical pointer devices are signaled, signal the pointer
4086 splitter event. This will cause the calling code to call
4087 ConSplitterAbsolutePointerGetState ().
4089 @param Event The Event assoicated with callback.
4090 @param Context Context registered when Event was created.
4095 ConSplitterAbsolutePointerWaitForInput (
4101 TEXT_IN_SPLITTER_PRIVATE_DATA
*Private
;
4104 Private
= (TEXT_IN_SPLITTER_PRIVATE_DATA
*) Context
;
4107 // if AbsoluteInputEventSignalState is flagged before,
4108 // and not cleared by Reset() or GetState(), signal it
4110 if (Private
->AbsoluteInputEventSignalState
) {
4111 gBS
->SignalEvent (Event
);
4115 // if any physical console input device has key input, signal the event.
4117 for (Index
= 0; Index
< Private
->CurrentNumberOfAbsolutePointers
; Index
++) {
4118 Status
= gBS
->CheckEvent (Private
->AbsolutePointerList
[Index
]->WaitForInput
);
4119 if (!EFI_ERROR (Status
)) {
4120 gBS
->SignalEvent (Event
);
4121 Private
->AbsoluteInputEventSignalState
= TRUE
;
4128 Reset the text output device hardware and optionaly run diagnostics
4130 @param This Protocol instance pointer.
4131 @param ExtendedVerification Driver may perform more exhaustive verfication
4132 operation of the device during reset.
4134 @retval EFI_SUCCESS The text output device was reset.
4135 @retval EFI_DEVICE_ERROR The text output device is not functioning
4136 correctly and could not be reset.
4141 ConSplitterTextOutReset (
4142 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4143 IN BOOLEAN ExtendedVerification
4147 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4149 EFI_STATUS ReturnStatus
;
4151 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4154 // return the worst status met
4156 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4157 Status
= Private
->TextOutList
[Index
].TextOut
->Reset (
4158 Private
->TextOutList
[Index
].TextOut
,
4159 ExtendedVerification
4161 if (EFI_ERROR (Status
)) {
4162 ReturnStatus
= Status
;
4166 This
->SetAttribute (This
, EFI_TEXT_ATTR (This
->Mode
->Attribute
& 0x0F, EFI_BLACK
));
4169 // reset all mode parameters
4171 TextOutSetMode (Private
, 0);
4173 return ReturnStatus
;
4178 Write a Unicode string to the output device.
4180 @param This Protocol instance pointer.
4181 @param WString The NULL-terminated Unicode string to be
4182 displayed on the output device(s). All output
4183 devices must also support the Unicode drawing
4184 defined in this file.
4186 @retval EFI_SUCCESS The string was output to the device.
4187 @retval EFI_DEVICE_ERROR The device reported an error while attempting to
4189 @retval EFI_UNSUPPORTED The output device's mode is not currently in a
4191 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
4192 characters in the Unicode string could not be
4193 rendered and were skipped.
4198 ConSplitterTextOutOutputString (
4199 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4204 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4206 UINTN BackSpaceCount
;
4207 EFI_STATUS ReturnStatus
;
4208 CHAR16
*TargetString
;
4210 This
->SetAttribute (This
, This
->Mode
->Attribute
);
4212 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4216 for (TargetString
= WString
; *TargetString
!= L
'\0'; TargetString
++) {
4217 if (*TargetString
== CHAR_BACKSPACE
) {
4222 if (BackSpaceCount
== 0) {
4223 TargetString
= WString
;
4225 TargetString
= AllocatePool (sizeof (CHAR16
) * (StrLen (WString
) + BackSpaceCount
+ 1));
4226 ASSERT (TargetString
!= NULL
);
4228 StrCpy (TargetString
, WString
);
4231 // return the worst status met
4233 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4234 Status
= Private
->TextOutList
[Index
].TextOut
->OutputString (
4235 Private
->TextOutList
[Index
].TextOut
,
4238 if (EFI_ERROR (Status
)) {
4239 ReturnStatus
= Status
;
4243 if (Private
->CurrentNumberOfConsoles
> 0) {
4244 Private
->TextOutMode
.CursorColumn
= Private
->TextOutList
[0].TextOut
->Mode
->CursorColumn
;
4245 Private
->TextOutMode
.CursorRow
= Private
->TextOutList
[0].TextOut
->Mode
->CursorRow
;
4248 if (BackSpaceCount
> 0) {
4249 FreePool (TargetString
);
4252 return ReturnStatus
;
4257 Verifies that all characters in a Unicode string can be output to the
4260 @param This Protocol instance pointer.
4261 @param WString The NULL-terminated Unicode string to be
4262 examined for the output device(s).
4264 @retval EFI_SUCCESS The device(s) are capable of rendering the
4266 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string
4267 cannot be rendered by one or more of the output
4268 devices mapped by the EFI handle.
4273 ConSplitterTextOutTestString (
4274 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4279 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4281 EFI_STATUS ReturnStatus
;
4283 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4286 // return the worst status met
4288 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4289 Status
= Private
->TextOutList
[Index
].TextOut
->TestString (
4290 Private
->TextOutList
[Index
].TextOut
,
4293 if (EFI_ERROR (Status
)) {
4294 ReturnStatus
= Status
;
4298 // There is no DevNullTextOutTestString () since a Unicode buffer would
4299 // always return EFI_SUCCESS.
4300 // ReturnStatus will be EFI_SUCCESS if no consoles are present
4302 return ReturnStatus
;
4307 Returns information for an available text mode that the output device(s)
4310 @param This Protocol instance pointer.
4311 @param ModeNumber The mode number to return information on.
4312 @param Columns Returns the columns of the text output device
4313 for the requested ModeNumber.
4314 @param Rows Returns the rows of the text output device
4315 for the requested ModeNumber.
4317 @retval EFI_SUCCESS The requested mode information was returned.
4318 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4320 @retval EFI_UNSUPPORTED The mode number was not valid.
4325 ConSplitterTextOutQueryMode (
4326 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4327 IN UINTN ModeNumber
,
4332 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4334 INT32
*TextOutModeMap
;
4336 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4339 // Check whether param ModeNumber is valid.
4340 // ModeNumber should be within range 0 ~ MaxMode - 1.
4342 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4343 return EFI_UNSUPPORTED
;
4346 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4347 return EFI_UNSUPPORTED
;
4351 // We get the available mode from mode intersection map if it's available
4353 if (Private
->TextOutModeMap
!= NULL
) {
4354 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4355 CurrentMode
= (UINTN
)(*TextOutModeMap
);
4356 *Columns
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4357 *Rows
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4359 *Columns
= Private
->TextOutQueryData
[ModeNumber
].Columns
;
4360 *Rows
= Private
->TextOutQueryData
[ModeNumber
].Rows
;
4363 if (*Columns
<= 0 && *Rows
<= 0) {
4364 return EFI_UNSUPPORTED
;
4373 Sets the output device(s) to a specified mode.
4375 @param This Protocol instance pointer.
4376 @param ModeNumber The mode number to set.
4378 @retval EFI_SUCCESS The requested text mode was set.
4379 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4381 @retval EFI_UNSUPPORTED The mode number was not valid.
4386 ConSplitterTextOutSetMode (
4387 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4392 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4394 INT32
*TextOutModeMap
;
4395 EFI_STATUS ReturnStatus
;
4397 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4400 // Check whether param ModeNumber is valid.
4401 // ModeNumber should be within range 0 ~ MaxMode - 1.
4403 if ( (ModeNumber
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4404 return EFI_UNSUPPORTED
;
4407 if ((INT32
) ModeNumber
>= This
->Mode
->MaxMode
) {
4408 return EFI_UNSUPPORTED
;
4411 // If the mode is being set to the curent mode, then just clear the screen and return.
4413 if (Private
->TextOutMode
.Mode
== (INT32
) ModeNumber
) {
4414 return ConSplitterTextOutClearScreen (This
);
4417 // return the worst status met
4419 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4420 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4421 Status
= Private
->TextOutList
[Index
].TextOut
->SetMode (
4422 Private
->TextOutList
[Index
].TextOut
,
4423 TextOutModeMap
[Index
]
4425 if (EFI_ERROR (Status
)) {
4426 ReturnStatus
= Status
;
4431 // Set mode parameter to specified mode number
4433 TextOutSetMode (Private
, ModeNumber
);
4435 return ReturnStatus
;
4440 Sets the background and foreground colors for the OutputString () and
4441 ClearScreen () functions.
4443 @param This Protocol instance pointer.
4444 @param Attribute The attribute to set. Bits 0..3 are the
4445 foreground color, and bits 4..6 are the
4446 background color. All other bits are undefined
4447 and must be zero. The valid Attributes are
4448 defined in this file.
4450 @retval EFI_SUCCESS The attribute was set.
4451 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4453 @retval EFI_UNSUPPORTED The attribute requested is not defined.
4458 ConSplitterTextOutSetAttribute (
4459 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4464 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4466 EFI_STATUS ReturnStatus
;
4468 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4471 // Check whether param Attribute is valid.
4473 if ( (Attribute
> (UINTN
)(((UINT32
)-1)>>1)) ) {
4474 return EFI_UNSUPPORTED
;
4478 // return the worst status met
4480 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4481 Status
= Private
->TextOutList
[Index
].TextOut
->SetAttribute (
4482 Private
->TextOutList
[Index
].TextOut
,
4485 if (EFI_ERROR (Status
)) {
4486 ReturnStatus
= Status
;
4490 Private
->TextOutMode
.Attribute
= (INT32
) Attribute
;
4492 return ReturnStatus
;
4497 Clears the output device(s) display to the currently selected background
4500 @param This Protocol instance pointer.
4502 @retval EFI_SUCCESS The operation completed successfully.
4503 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4505 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4510 ConSplitterTextOutClearScreen (
4511 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
4515 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4517 EFI_STATUS ReturnStatus
;
4519 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4522 // return the worst status met
4524 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4525 Status
= Private
->TextOutList
[Index
].TextOut
->ClearScreen (Private
->TextOutList
[Index
].TextOut
);
4526 if (EFI_ERROR (Status
)) {
4527 ReturnStatus
= Status
;
4532 // No need to do extra check here as whether (Column, Row) is valid has
4533 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
4534 // always be supported.
4536 Private
->TextOutMode
.CursorColumn
= 0;
4537 Private
->TextOutMode
.CursorRow
= 0;
4538 Private
->TextOutMode
.CursorVisible
= TRUE
;
4540 return ReturnStatus
;
4545 Sets the current coordinates of the cursor position
4547 @param This Protocol instance pointer.
4548 @param Column The column position to set the cursor to. Must be
4549 greater than or equal to zero and less than the
4550 number of columns by QueryMode ().
4551 @param Row The row position to set the cursor to. Must be
4552 greater than or equal to zero and less than the
4553 number of rows by QueryMode ().
4555 @retval EFI_SUCCESS The operation completed successfully.
4556 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4558 @retval EFI_UNSUPPORTED The output device is not in a valid text mode,
4559 or the cursor position is invalid for the
4565 ConSplitterTextOutSetCursorPosition (
4566 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4572 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4574 EFI_STATUS ReturnStatus
;
4577 INT32
*TextOutModeMap
;
4581 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4582 TextOutModeMap
= NULL
;
4583 ModeNumber
= Private
->TextOutMode
.Mode
;
4586 // Get current MaxColumn and MaxRow from intersection map
4588 if (Private
->TextOutModeMap
!= NULL
) {
4589 TextOutModeMap
= Private
->TextOutModeMap
+ Private
->TextOutListCount
* ModeNumber
;
4590 CurrentMode
= *TextOutModeMap
;
4592 CurrentMode
= ModeNumber
;
4595 MaxColumn
= Private
->TextOutQueryData
[CurrentMode
].Columns
;
4596 MaxRow
= Private
->TextOutQueryData
[CurrentMode
].Rows
;
4598 if (Column
>= MaxColumn
|| Row
>= MaxRow
) {
4599 return EFI_UNSUPPORTED
;
4602 // return the worst status met
4604 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4605 Status
= Private
->TextOutList
[Index
].TextOut
->SetCursorPosition (
4606 Private
->TextOutList
[Index
].TextOut
,
4610 if (EFI_ERROR (Status
)) {
4611 ReturnStatus
= Status
;
4616 // No need to do extra check here as whether (Column, Row) is valid has
4617 // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should
4618 // always be supported.
4620 Private
->TextOutMode
.CursorColumn
= (INT32
) Column
;
4621 Private
->TextOutMode
.CursorRow
= (INT32
) Row
;
4623 return ReturnStatus
;
4628 Makes the cursor visible or invisible
4630 @param This Protocol instance pointer.
4631 @param Visible If TRUE, the cursor is set to be visible. If
4632 FALSE, the cursor is set to be invisible.
4634 @retval EFI_SUCCESS The operation completed successfully.
4635 @retval EFI_DEVICE_ERROR The device had an error and could not complete
4636 the request, or the device does not support
4637 changing the cursor mode.
4638 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.
4643 ConSplitterTextOutEnableCursor (
4644 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*This
,
4649 TEXT_OUT_SPLITTER_PRIVATE_DATA
*Private
;
4651 EFI_STATUS ReturnStatus
;
4653 Private
= TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This
);
4656 // return the worst status met
4658 for (Index
= 0, ReturnStatus
= EFI_SUCCESS
; Index
< Private
->CurrentNumberOfConsoles
; Index
++) {
4659 Status
= Private
->TextOutList
[Index
].TextOut
->EnableCursor (
4660 Private
->TextOutList
[Index
].TextOut
,
4663 if (EFI_ERROR (Status
)) {
4664 ReturnStatus
= Status
;
4668 Private
->TextOutMode
.CursorVisible
= Visible
;
4670 return ReturnStatus
;