2 Produces Simple Text Input Protocol, Simple Text Input Extended Protocol and
3 Simple Text Output Protocol upon Serial IO Protocol.
5 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding
= {
23 TerminalDriverBindingSupported
,
24 TerminalDriverBindingStart
,
25 TerminalDriverBindingStop
,
32 EFI_GUID
*gTerminalType
[] = {
41 TERMINAL_DEV mTerminalDevTemplate
= {
42 TERMINAL_DEV_SIGNATURE
,
49 TerminalConInReadKeyStroke
,
54 TerminalConOutOutputString
,
55 TerminalConOutTestString
,
56 TerminalConOutQueryMode
,
57 TerminalConOutSetMode
,
58 TerminalConOutSetAttribute
,
59 TerminalConOutClearScreen
,
60 TerminalConOutSetCursorPosition
,
61 TerminalConOutEnableCursor
,
64 { // SimpleTextOutputMode
67 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
), // Attribute
72 NULL
, // TerminalConsoleModeData
78 NULL
, // EfiKeyFiFoForNotify
80 NULL
, // ControllerNameTable
82 NULL
, // TwoSecondTimeOut
92 { // SimpleTextInputEx
94 TerminalConInReadKeyStrokeEx
,
96 TerminalConInSetState
,
97 TerminalConInRegisterKeyNotify
,
98 TerminalConInUnregisterKeyNotify
,
104 NULL
// KeyNotifyProcessEvent
107 TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData
[] = {
110 // New modes can be added here.
115 Test to see if this driver supports Controller.
117 @param This Protocol instance pointer.
118 @param Controller Handle of device to test
119 @param RemainingDevicePath Optional parameter use to pick a specific child
122 @retval EFI_SUCCESS This driver supports this device.
123 @retval EFI_ALREADY_STARTED This driver is already running on this device.
124 @retval other This driver does not support this device.
129 TerminalDriverBindingSupported (
130 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
131 IN EFI_HANDLE Controller
,
132 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
136 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
137 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
138 VENDOR_DEVICE_PATH
*Node
;
141 // If remaining device path is not NULL, then make sure it is a
142 // device path that describes a terminal communications protocol.
144 if (RemainingDevicePath
!= NULL
) {
146 // Check if RemainingDevicePath is the End of Device Path Node,
147 // if yes, go on checking other conditions
149 if (!IsDevicePathEnd (RemainingDevicePath
)) {
151 // If RemainingDevicePath isn't the End of Device Path Node,
152 // check its validation
154 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
156 if (Node
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
157 Node
->Header
.SubType
!= MSG_VENDOR_DP
||
158 DevicePathNodeLength(&Node
->Header
) != sizeof(VENDOR_DEVICE_PATH
)) {
160 return EFI_UNSUPPORTED
;
164 // only supports PC ANSI, VT100, VT100+, VT-UTF8, and TtyTerm terminal types
166 if (!CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
) &&
167 !CompareGuid (&Node
->Guid
, &gEfiVT100Guid
) &&
168 !CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
) &&
169 !CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
) &&
170 !CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
172 return EFI_UNSUPPORTED
;
177 // Open the IO Abstraction(s) needed to perform the supported test
178 // The Controller must support the Serial I/O Protocol.
179 // This driver is a bus driver with at most 1 child device, so it is
180 // ok for it to be already started.
182 Status
= gBS
->OpenProtocol (
184 &gEfiSerialIoProtocolGuid
,
186 This
->DriverBindingHandle
,
188 EFI_OPEN_PROTOCOL_BY_DRIVER
190 if (Status
== EFI_ALREADY_STARTED
) {
194 if (EFI_ERROR (Status
)) {
199 // Close the I/O Abstraction(s) used to perform the supported test
203 &gEfiSerialIoProtocolGuid
,
204 This
->DriverBindingHandle
,
209 // Open the EFI Device Path protocol needed to perform the supported test
211 Status
= gBS
->OpenProtocol (
213 &gEfiDevicePathProtocolGuid
,
214 (VOID
**) &ParentDevicePath
,
215 This
->DriverBindingHandle
,
217 EFI_OPEN_PROTOCOL_BY_DRIVER
219 if (Status
== EFI_ALREADY_STARTED
) {
223 if (EFI_ERROR (Status
)) {
228 // Close protocol, don't use device path protocol in the Support() function
232 &gEfiDevicePathProtocolGuid
,
233 This
->DriverBindingHandle
,
241 Build the terminal device path for the child device according to the
244 @param ParentDevicePath Parent device path.
245 @param RemainingDevicePath A specific child device.
247 @return The child device path built.
250 EFI_DEVICE_PATH_PROTOCOL
*
252 BuildTerminalDevpath (
253 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
254 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
257 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
259 VENDOR_DEVICE_PATH
*Node
;
262 TerminalDevicePath
= NULL
;
265 // Use the RemainingDevicePath to determine the terminal type
267 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
269 TerminalType
= PcdGet8 (PcdDefaultTerminalType
);
271 } else if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
273 TerminalType
= PCANSITYPE
;
275 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
277 TerminalType
= VT100TYPE
;
279 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
281 TerminalType
= VT100PLUSTYPE
;
283 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
285 TerminalType
= VTUTF8TYPE
;
287 } else if (CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
289 TerminalType
= TTYTERMTYPE
;
296 // Build the device path for the child device
298 Status
= SetTerminalDevicePath (
303 if (EFI_ERROR (Status
)) {
306 return TerminalDevicePath
;
310 Compare a device path data structure to that of all the nodes of a
311 second device path instance.
313 @param Multi A pointer to a multi-instance device path data structure.
314 @param Single A pointer to a single-instance device path data structure.
316 @retval TRUE If the Single is contained within Multi.
317 @retval FALSE The Single is not match within Multi.
322 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
323 IN EFI_DEVICE_PATH_PROTOCOL
*Single
326 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
327 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
331 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
333 // Search for the match of 'Single' in 'Multi'
335 while (DevicePathInst
!= NULL
) {
337 // If the single device path is found in multiple device paths,
340 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
341 FreePool (DevicePathInst
);
345 FreePool (DevicePathInst
);
346 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
353 Check whether the terminal device path is in the global variable.
355 @param VariableName Pointer to one global variable.
356 @param TerminalDevicePath Pointer to the terminal device's device path.
358 @retval TRUE The devcie is in the global variable.
359 @retval FALSE The devcie is not in the global variable.
363 IsTerminalInConsoleVariable (
364 IN CHAR16
*VariableName
,
365 IN EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
368 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
372 // Get global variable and its size according to the name given.
374 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
375 if (Variable
== NULL
) {
380 // Check whether the terminal device path is one of the variable instances.
382 ReturnFlag
= MatchDevicePaths (Variable
, TerminalDevicePath
);
390 Free notify functions list.
392 @param ListHead The list head
394 @retval EFI_SUCCESS Free the notify list successfully.
395 @retval EFI_INVALID_PARAMETER ListHead is NULL.
399 TerminalFreeNotifyList (
400 IN OUT LIST_ENTRY
*ListHead
403 TERMINAL_CONSOLE_IN_EX_NOTIFY
*NotifyNode
;
405 if (ListHead
== NULL
) {
406 return EFI_INVALID_PARAMETER
;
408 while (!IsListEmpty (ListHead
)) {
410 ListHead
->ForwardLink
,
411 TERMINAL_CONSOLE_IN_EX_NOTIFY
,
413 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
415 RemoveEntryList (ListHead
->ForwardLink
);
416 FreePool (NotifyNode
);
423 Initialize all the text modes which the terminal console supports.
425 It returns information for available text modes that the terminal can support.
427 @param[out] TextModeCount The total number of text modes that terminal console supports.
428 @param[out] TextModeData The buffer to the text modes column and row information.
429 Caller is responsible to free it when it's non-NULL.
431 @retval EFI_SUCCESS The supporting mode information is returned.
432 @retval EFI_INVALID_PARAMETER The parameters are invalid.
436 InitializeTerminalConsoleTextMode (
437 OUT UINTN
*TextModeCount
,
438 OUT TERMINAL_CONSOLE_MODE_DATA
**TextModeData
443 TERMINAL_CONSOLE_MODE_DATA
*ModeBuffer
;
444 TERMINAL_CONSOLE_MODE_DATA
*NewModeBuffer
;
448 if ((TextModeCount
== NULL
) || (TextModeData
== NULL
)) {
449 return EFI_INVALID_PARAMETER
;
452 Count
= sizeof (mTerminalConsoleModeData
) / sizeof (TERMINAL_CONSOLE_MODE_DATA
);
455 // Get defined mode buffer pointer.
457 ModeBuffer
= mTerminalConsoleModeData
;
460 // Here we make sure that the final mode exposed does not include the duplicated modes,
461 // and does not include the invalid modes which exceed the max column and row.
462 // Reserve 2 modes for 80x25, 80x50 of terminal console.
464 NewModeBuffer
= AllocateZeroPool (sizeof (TERMINAL_CONSOLE_MODE_DATA
) * (Count
+ 2));
465 ASSERT (NewModeBuffer
!= NULL
);
468 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
472 NewModeBuffer
[ValidCount
].Columns
= 80;
473 NewModeBuffer
[ValidCount
].Rows
= 25;
476 NewModeBuffer
[ValidCount
].Columns
= 80;
477 NewModeBuffer
[ValidCount
].Rows
= 50;
481 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
483 for (Index
= 0; Index
< Count
; Index
++) {
484 if ((ModeBuffer
[Index
].Columns
== 0) || (ModeBuffer
[Index
].Rows
== 0)) {
486 // Skip the pre-defined mode which is invalid.
490 for (ValidIndex
= 0; ValidIndex
< ValidCount
; ValidIndex
++) {
491 if ((ModeBuffer
[Index
].Columns
== NewModeBuffer
[ValidIndex
].Columns
) &&
492 (ModeBuffer
[Index
].Rows
== NewModeBuffer
[ValidIndex
].Rows
)) {
494 // Skip the duplicated mode.
499 if (ValidIndex
== ValidCount
) {
500 NewModeBuffer
[ValidCount
].Columns
= ModeBuffer
[Index
].Columns
;
501 NewModeBuffer
[ValidCount
].Rows
= ModeBuffer
[Index
].Rows
;
507 for (Index
= 0; Index
< ValidCount
; Index
++) {
508 DEBUG ((EFI_D_INFO
, "Terminal - Mode %d, Column = %d, Row = %d\n",
509 Index
, NewModeBuffer
[Index
].Columns
, NewModeBuffer
[Index
].Rows
));
514 // Return valid mode count and mode information buffer.
516 *TextModeCount
= ValidCount
;
517 *TextModeData
= NewModeBuffer
;
522 Start this driver on Controller by opening a Serial IO protocol,
523 reading Device Path, and creating a child handle with a Simple Text In,
524 Simple Text In Ex and Simple Text Out protocol, and device path protocol.
525 And store Console Device Environment Variables.
527 @param This Protocol instance pointer.
528 @param Controller Handle of device to bind driver to
529 @param RemainingDevicePath Optional parameter use to pick a specific child
532 @retval EFI_SUCCESS This driver is added to Controller.
533 @retval EFI_ALREADY_STARTED This driver is already running on Controller.
534 @retval other This driver does not support this device.
539 TerminalDriverBindingStart (
540 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
541 IN EFI_HANDLE Controller
,
542 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
546 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
547 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
548 VENDOR_DEVICE_PATH
*Node
;
549 EFI_SERIAL_IO_MODE
*Mode
;
550 UINTN SerialInTimeOut
;
551 TERMINAL_DEV
*TerminalDevice
;
553 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
556 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
557 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
558 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleTextInput
;
559 BOOLEAN ConInSelected
;
560 BOOLEAN ConOutSelected
;
561 BOOLEAN NullRemaining
;
562 BOOLEAN SimTxtInInstalled
;
563 BOOLEAN SimTxtOutInstalled
;
567 TerminalDevice
= NULL
;
568 ConInSelected
= FALSE
;
569 ConOutSelected
= FALSE
;
570 NullRemaining
= FALSE
;
571 SimTxtInInstalled
= FALSE
;
572 SimTxtOutInstalled
= FALSE
;
575 // Get the Device Path Protocol to build the device path of the child device
577 Status
= gBS
->OpenProtocol (
579 &gEfiDevicePathProtocolGuid
,
580 (VOID
**) &ParentDevicePath
,
581 This
->DriverBindingHandle
,
583 EFI_OPEN_PROTOCOL_BY_DRIVER
585 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
590 // Open the Serial I/O Protocol BY_DRIVER. It might already be started.
592 Status
= gBS
->OpenProtocol (
594 &gEfiSerialIoProtocolGuid
,
596 This
->DriverBindingHandle
,
598 EFI_OPEN_PROTOCOL_BY_DRIVER
600 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
604 if (Status
!= EFI_ALREADY_STARTED
) {
606 // the serial I/O protocol never be opened before, it is the first
607 // time to start the serial Io controller
613 // Serial I/O is not already open by this driver, then tag the handle
614 // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and
615 // StdErrDev variables with the list of possible terminal types on this
618 Status
= gBS
->OpenProtocol (
622 This
->DriverBindingHandle
,
624 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
626 if (EFI_ERROR (Status
)) {
627 Status
= gBS
->InstallMultipleProtocolInterfaces (
630 DuplicateDevicePath (ParentDevicePath
),
633 if (EFI_ERROR (Status
)) {
637 if (!IsHotPlugDevice (ParentDevicePath
)) {
639 // if the serial device is a hot plug device, do not update the
640 // ConInDev, ConOutDev, and StdErrDev variables.
642 TerminalUpdateConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
643 TerminalUpdateConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
644 TerminalUpdateConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
649 // Check the requirement for the SimpleTxtIn and SimpleTxtOut protocols
651 // Simple In/Out Protocol will not be installed onto the handle if the
652 // device path to the handle is not present in the ConIn/ConOut
653 // environment variable. But If RemainingDevicePath is NULL, then always
654 // produce both Simple In and Simple Text Output Protocols. This is required
655 // for the connect all sequences to make sure all possible consoles are
656 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
658 if (RemainingDevicePath
== NULL
) {
659 NullRemaining
= TRUE
;
662 DevicePath
= BuildTerminalDevpath (ParentDevicePath
, RemainingDevicePath
);
663 if (DevicePath
!= NULL
) {
664 ConInSelected
= IsTerminalInConsoleVariable (L
"ConIn", DevicePath
);
665 ConOutSelected
= IsTerminalInConsoleVariable (L
"ConOut", DevicePath
);
666 FreePool (DevicePath
);
671 // Not create the child terminal handle if both Simple In/In Ex and
672 // Simple text Out protocols are not required to be published
674 if ((!ConInSelected
)&&(!ConOutSelected
)&&(!NullRemaining
)) {
679 // create the child terminal handle during first entry
683 // First enther the start function
687 // Make sure a child handle does not already exist. This driver can only
688 // produce one child per serial port.
690 Status
= gBS
->OpenProtocolInformation (
692 &gEfiSerialIoProtocolGuid
,
696 if (!EFI_ERROR (Status
)) {
697 Status
= EFI_SUCCESS
;
698 for (Index
= 0; Index
< EntryCount
; Index
++) {
699 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
700 Status
= EFI_ALREADY_STARTED
;
704 FreePool (OpenInfoBuffer
);
705 if (EFI_ERROR (Status
)) {
711 // If RemainingDevicePath is NULL, use default terminal type
713 if (RemainingDevicePath
== NULL
) {
714 TerminalType
= PcdGet8 (PcdDefaultTerminalType
);
716 // Must be between PCANSITYPE (0) and TTYTERMTYPE (4)
718 ASSERT (TerminalType
<= TTYTERMTYPE
);
719 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
721 // If RemainingDevicePath isn't the End of Device Path Node,
722 // Use the RemainingDevicePath to determine the terminal type
724 Node
= (VENDOR_DEVICE_PATH
*)RemainingDevicePath
;
725 if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
726 TerminalType
= PCANSITYPE
;
727 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
728 TerminalType
= VT100TYPE
;
729 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
730 TerminalType
= VT100PLUSTYPE
;
731 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
732 TerminalType
= VTUTF8TYPE
;
733 } else if (CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
734 TerminalType
= TTYTERMTYPE
;
740 // If RemainingDevicePath is the End of Device Path Node,
741 // skip enumerate any device and return EFI_SUCESSS
747 // Initialize the Terminal Dev
749 TerminalDevice
= AllocateCopyPool (sizeof (TERMINAL_DEV
), &mTerminalDevTemplate
);
750 if (TerminalDevice
== NULL
) {
751 Status
= EFI_OUT_OF_RESOURCES
;
755 TerminalDevice
->TerminalType
= TerminalType
;
756 TerminalDevice
->SerialIo
= SerialIo
;
758 InitializeListHead (&TerminalDevice
->NotifyList
);
759 Status
= gBS
->CreateEvent (
762 TerminalConInWaitForKeyEx
,
764 &TerminalDevice
->SimpleInputEx
.WaitForKeyEx
766 if (EFI_ERROR (Status
)) {
770 Status
= gBS
->CreateEvent (
773 TerminalConInWaitForKey
,
775 &TerminalDevice
->SimpleInput
.WaitForKey
777 if (EFI_ERROR (Status
)) {
781 // Allocates and initializes the FIFO buffer to be zero, used for accommodating
782 // the pre-read pending characters.
784 TerminalDevice
->RawFiFo
= AllocateZeroPool (sizeof (RAW_DATA_FIFO
));
785 if (TerminalDevice
->RawFiFo
== NULL
) {
788 TerminalDevice
->UnicodeFiFo
= AllocateZeroPool (sizeof (UNICODE_FIFO
));
789 if (TerminalDevice
->UnicodeFiFo
== NULL
) {
792 TerminalDevice
->EfiKeyFiFo
= AllocateZeroPool (sizeof (EFI_KEY_FIFO
));
793 if (TerminalDevice
->EfiKeyFiFo
== NULL
) {
796 TerminalDevice
->EfiKeyFiFoForNotify
= AllocateZeroPool (sizeof (EFI_KEY_FIFO
));
797 if (TerminalDevice
->EfiKeyFiFoForNotify
== NULL
) {
802 // Set the timeout value of serial buffer for
803 // keystroke response performance issue
805 Mode
= TerminalDevice
->SerialIo
->Mode
;
808 if (Mode
->BaudRate
!= 0) {
809 SerialInTimeOut
= (1 + Mode
->DataBits
+ Mode
->StopBits
) * 2 * 1000000 / (UINTN
) Mode
->BaudRate
;
812 Status
= TerminalDevice
->SerialIo
->SetAttributes (
813 TerminalDevice
->SerialIo
,
815 Mode
->ReceiveFifoDepth
,
816 (UINT32
) SerialInTimeOut
,
817 (EFI_PARITY_TYPE
) (Mode
->Parity
),
818 (UINT8
) Mode
->DataBits
,
819 (EFI_STOP_BITS_TYPE
) (Mode
->StopBits
)
821 if (EFI_ERROR (Status
)) {
823 // if set attributes operation fails, invalidate
824 // the value of SerialInTimeOut,thus make it
825 // inconsistent with the default timeout value
826 // of serial buffer. This will invoke the recalculation
827 // in the readkeystroke routine.
829 TerminalDevice
->SerialInTimeOut
= 0;
831 TerminalDevice
->SerialInTimeOut
= SerialInTimeOut
;
834 // Set Simple Text Output Protocol from template.
836 SimpleTextOutput
= CopyMem (
837 &TerminalDevice
->SimpleTextOutput
,
838 &mTerminalDevTemplate
.SimpleTextOutput
,
839 sizeof (mTerminalDevTemplate
.SimpleTextOutput
)
841 SimpleTextOutput
->Mode
= &TerminalDevice
->SimpleTextOutputMode
;
843 Status
= InitializeTerminalConsoleTextMode (&ModeCount
, &TerminalDevice
->TerminalConsoleModeData
);
844 if (EFI_ERROR (Status
)) {
847 TerminalDevice
->SimpleTextOutputMode
.MaxMode
= (INT32
) ModeCount
;
850 // For terminal devices, cursor is always visible
852 TerminalDevice
->SimpleTextOutputMode
.CursorVisible
= TRUE
;
853 Status
= TerminalConOutSetAttribute (
855 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
857 if (EFI_ERROR (Status
)) {
862 // Build the component name for the child device
864 TerminalDevice
->ControllerNameTable
= NULL
;
865 switch (TerminalDevice
->TerminalType
) {
869 gTerminalComponentName
.SupportedLanguages
,
870 &TerminalDevice
->ControllerNameTable
,
871 (CHAR16
*)L
"PC-ANSI Serial Console",
876 gTerminalComponentName2
.SupportedLanguages
,
877 &TerminalDevice
->ControllerNameTable
,
878 (CHAR16
*)L
"PC-ANSI Serial Console",
887 gTerminalComponentName
.SupportedLanguages
,
888 &TerminalDevice
->ControllerNameTable
,
889 (CHAR16
*)L
"VT-100 Serial Console",
894 gTerminalComponentName2
.SupportedLanguages
,
895 &TerminalDevice
->ControllerNameTable
,
896 (CHAR16
*)L
"VT-100 Serial Console",
905 gTerminalComponentName
.SupportedLanguages
,
906 &TerminalDevice
->ControllerNameTable
,
907 (CHAR16
*)L
"VT-100+ Serial Console",
912 gTerminalComponentName2
.SupportedLanguages
,
913 &TerminalDevice
->ControllerNameTable
,
914 (CHAR16
*)L
"VT-100+ Serial Console",
923 gTerminalComponentName
.SupportedLanguages
,
924 &TerminalDevice
->ControllerNameTable
,
925 (CHAR16
*)L
"VT-UTF8 Serial Console",
930 gTerminalComponentName2
.SupportedLanguages
,
931 &TerminalDevice
->ControllerNameTable
,
932 (CHAR16
*)L
"VT-UTF8 Serial Console",
941 gTerminalComponentName
.SupportedLanguages
,
942 &TerminalDevice
->ControllerNameTable
,
943 (CHAR16
*)L
"Tty Terminal Serial Console",
948 gTerminalComponentName2
.SupportedLanguages
,
949 &TerminalDevice
->ControllerNameTable
,
950 (CHAR16
*)L
"Tty Terminal Serial Console",
958 // Build the device path for the child device
960 Status
= SetTerminalDevicePath (
961 TerminalDevice
->TerminalType
,
963 &TerminalDevice
->DevicePath
965 if (EFI_ERROR (Status
)) {
969 Status
= TerminalConOutReset (SimpleTextOutput
, FALSE
);
970 if (EFI_ERROR (Status
)) {
974 Status
= TerminalConOutSetMode (SimpleTextOutput
, 0);
975 if (EFI_ERROR (Status
)) {
979 Status
= TerminalConOutEnableCursor (SimpleTextOutput
, TRUE
);
980 if (EFI_ERROR (Status
)) {
984 Status
= gBS
->CreateEvent (
985 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
987 TerminalConInTimerHandler
,
989 &TerminalDevice
->TimerEvent
991 ASSERT_EFI_ERROR (Status
);
993 Status
= gBS
->SetTimer (
994 TerminalDevice
->TimerEvent
,
996 KEYBOARD_TIMER_INTERVAL
998 ASSERT_EFI_ERROR (Status
);
1000 Status
= gBS
->CreateEvent (
1005 &TerminalDevice
->TwoSecondTimeOut
1007 ASSERT_EFI_ERROR (Status
);
1009 Status
= gBS
->CreateEvent (
1012 KeyNotifyProcessHandler
,
1014 &TerminalDevice
->KeyNotifyProcessEvent
1016 ASSERT_EFI_ERROR (Status
);
1018 Status
= gBS
->InstallProtocolInterface (
1019 &TerminalDevice
->Handle
,
1020 &gEfiDevicePathProtocolGuid
,
1021 EFI_NATIVE_INTERFACE
,
1022 TerminalDevice
->DevicePath
1024 if (EFI_ERROR (Status
)) {
1029 // Register the Parent-Child relationship via
1030 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
1032 Status
= gBS
->OpenProtocol (
1034 &gEfiSerialIoProtocolGuid
,
1035 (VOID
**) &TerminalDevice
->SerialIo
,
1036 This
->DriverBindingHandle
,
1037 TerminalDevice
->Handle
,
1038 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1040 if (EFI_ERROR (Status
)) {
1046 // Find the child handle, and get its TerminalDevice private data
1048 Status
= gBS
->OpenProtocolInformation (
1050 &gEfiSerialIoProtocolGuid
,
1054 if (!EFI_ERROR (Status
)) {
1055 Status
= EFI_NOT_FOUND
;
1056 ASSERT (OpenInfoBuffer
!= NULL
);
1057 for (Index
= 0; Index
< EntryCount
; Index
++) {
1058 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
1060 // Find the child terminal handle.
1061 // Test whether the SimpleTxtIn and SimpleTxtOut have been published
1063 Status
= gBS
->OpenProtocol (
1064 OpenInfoBuffer
[Index
].ControllerHandle
,
1065 &gEfiSimpleTextInProtocolGuid
,
1066 (VOID
**) &SimpleTextInput
,
1067 This
->DriverBindingHandle
,
1068 OpenInfoBuffer
[Index
].ControllerHandle
,
1069 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1071 if (!EFI_ERROR (Status
)) {
1072 SimTxtInInstalled
= TRUE
;
1073 TerminalDevice
= TERMINAL_CON_IN_DEV_FROM_THIS (SimpleTextInput
);
1076 Status
= gBS
->OpenProtocol (
1077 OpenInfoBuffer
[Index
].ControllerHandle
,
1078 &gEfiSimpleTextOutProtocolGuid
,
1079 (VOID
**) &SimpleTextOutput
,
1080 This
->DriverBindingHandle
,
1081 OpenInfoBuffer
[Index
].ControllerHandle
,
1082 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1084 if (!EFI_ERROR (Status
)) {
1085 SimTxtOutInstalled
= TRUE
;
1086 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1088 Status
= EFI_SUCCESS
;
1093 FreePool (OpenInfoBuffer
);
1094 if (EFI_ERROR (Status
)) {
1101 ASSERT (TerminalDevice
!= NULL
);
1103 // Only do the reset if the device path is in the Conout variable
1105 if (ConInSelected
&& !SimTxtInInstalled
) {
1106 Status
= TerminalDevice
->SimpleInput
.Reset (
1107 &TerminalDevice
->SimpleInput
,
1110 if (EFI_ERROR (Status
)) {
1112 // Need to report Error Code first
1119 // Only output the configure string to remote terminal if the device path
1120 // is in the Conout variable
1122 if (ConOutSelected
&& !SimTxtOutInstalled
) {
1123 Status
= TerminalDevice
->SimpleTextOutput
.SetAttribute (
1124 &TerminalDevice
->SimpleTextOutput
,
1125 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
1127 if (EFI_ERROR (Status
)) {
1131 Status
= TerminalDevice
->SimpleTextOutput
.Reset (
1132 &TerminalDevice
->SimpleTextOutput
,
1135 if (EFI_ERROR (Status
)) {
1139 Status
= TerminalDevice
->SimpleTextOutput
.SetMode (
1140 &TerminalDevice
->SimpleTextOutput
,
1143 if (EFI_ERROR (Status
)) {
1147 Status
= TerminalDevice
->SimpleTextOutput
.EnableCursor (
1148 &TerminalDevice
->SimpleTextOutput
,
1151 if (EFI_ERROR (Status
)) {
1157 // Simple In/Out Protocol will not be installed onto the handle if the
1158 // device path to the handle is not present in the ConIn/ConOut
1159 // environment variable. But If RemainingDevicePath is NULL, then always
1160 // produce both Simple In and Simple Text Output Protocols. This is required
1161 // for the connect all sequences to make sure all possible consoles are
1162 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
1164 if (!SimTxtInInstalled
&& (ConInSelected
|| NullRemaining
)) {
1165 Status
= gBS
->InstallMultipleProtocolInterfaces (
1166 &TerminalDevice
->Handle
,
1167 &gEfiSimpleTextInProtocolGuid
,
1168 &TerminalDevice
->SimpleInput
,
1169 &gEfiSimpleTextInputExProtocolGuid
,
1170 &TerminalDevice
->SimpleInputEx
,
1173 if (EFI_ERROR (Status
)) {
1178 if (!SimTxtOutInstalled
&& (ConOutSelected
|| NullRemaining
)) {
1179 Status
= gBS
->InstallProtocolInterface (
1180 &TerminalDevice
->Handle
,
1181 &gEfiSimpleTextOutProtocolGuid
,
1182 EFI_NATIVE_INTERFACE
,
1183 &TerminalDevice
->SimpleTextOutput
1185 if (EFI_ERROR (Status
)) {
1194 // Report error code before exiting
1196 DevicePath
= ParentDevicePath
;
1197 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1198 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1199 (EFI_PERIPHERAL_REMOTE_CONSOLE
| EFI_P_EC_CONTROLLER_ERROR
),
1205 // Use the Stop() function to free all resources allocated in Start()
1207 if (TerminalDevice
!= NULL
) {
1209 if (TerminalDevice
->Handle
!= NULL
) {
1210 This
->Stop (This
, Controller
, 1, &TerminalDevice
->Handle
);
1213 if (TerminalDevice
->TwoSecondTimeOut
!= NULL
) {
1214 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1217 if (TerminalDevice
->TimerEvent
!= NULL
) {
1218 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1221 if (TerminalDevice
->SimpleInput
.WaitForKey
!= NULL
) {
1222 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1225 if (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
!= NULL
) {
1226 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1229 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1231 if (TerminalDevice
->RawFiFo
!= NULL
) {
1232 FreePool (TerminalDevice
->RawFiFo
);
1234 if (TerminalDevice
->UnicodeFiFo
!= NULL
) {
1235 FreePool (TerminalDevice
->UnicodeFiFo
);
1237 if (TerminalDevice
->EfiKeyFiFo
!= NULL
) {
1238 FreePool (TerminalDevice
->EfiKeyFiFo
);
1240 if (TerminalDevice
->EfiKeyFiFoForNotify
!= NULL
) {
1241 FreePool (TerminalDevice
->EfiKeyFiFoForNotify
);
1244 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1245 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1248 if (TerminalDevice
->DevicePath
!= NULL
) {
1249 FreePool (TerminalDevice
->DevicePath
);
1252 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1253 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1256 FreePool (TerminalDevice
);
1260 This
->Stop (This
, Controller
, 0, NULL
);
1266 Stop this driver on Controller by closing Simple Text In, Simple Text
1267 In Ex, Simple Text Out protocol, and removing parent device path from
1268 Console Device Environment Variables.
1270 @param This Protocol instance pointer.
1271 @param Controller Handle of device to stop driver on
1272 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1273 children is zero stop the entire bus driver.
1274 @param ChildHandleBuffer List of Child Handles to Stop.
1276 @retval EFI_SUCCESS This driver is removed Controller.
1277 @retval other This driver could not be removed from this device.
1282 TerminalDriverBindingStop (
1283 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1284 IN EFI_HANDLE Controller
,
1285 IN UINTN NumberOfChildren
,
1286 IN EFI_HANDLE
*ChildHandleBuffer
1291 BOOLEAN AllChildrenStopped
;
1292 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
1293 TERMINAL_DEV
*TerminalDevice
;
1294 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1295 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
1296 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1298 Status
= gBS
->HandleProtocol (
1300 &gEfiDevicePathProtocolGuid
,
1301 (VOID
**) &DevicePath
1303 if (EFI_ERROR (Status
)) {
1308 // Complete all outstanding transactions to Controller.
1309 // Don't allow any new transaction to Controller to be started.
1311 if (NumberOfChildren
== 0) {
1313 // Close the bus driver
1315 Status
= gBS
->OpenProtocol (
1318 (VOID
**) &ParentDevicePath
,
1319 This
->DriverBindingHandle
,
1321 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1323 if (!EFI_ERROR (Status
)) {
1325 // Remove Parent Device Path from
1326 // the Console Device Environment Variables
1328 TerminalRemoveConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
1329 TerminalRemoveConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
1330 TerminalRemoveConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
1333 // Uninstall the Terminal Driver's GUID Tag from the Serial controller
1335 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1343 // Free the ParentDevicePath that was duplicated in Start()
1345 if (!EFI_ERROR (Status
)) {
1346 FreePool (ParentDevicePath
);
1350 gBS
->CloseProtocol (
1352 &gEfiSerialIoProtocolGuid
,
1353 This
->DriverBindingHandle
,
1357 gBS
->CloseProtocol (
1359 &gEfiDevicePathProtocolGuid
,
1360 This
->DriverBindingHandle
,
1367 AllChildrenStopped
= TRUE
;
1369 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
1371 Status
= gBS
->OpenProtocol (
1372 ChildHandleBuffer
[Index
],
1373 &gEfiSimpleTextOutProtocolGuid
,
1374 (VOID
**) &SimpleTextOutput
,
1375 This
->DriverBindingHandle
,
1376 ChildHandleBuffer
[Index
],
1377 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1379 if (!EFI_ERROR (Status
)) {
1381 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1383 gBS
->CloseProtocol (
1385 &gEfiSerialIoProtocolGuid
,
1386 This
->DriverBindingHandle
,
1387 ChildHandleBuffer
[Index
]
1390 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1391 ChildHandleBuffer
[Index
],
1392 &gEfiSimpleTextInProtocolGuid
,
1393 &TerminalDevice
->SimpleInput
,
1394 &gEfiSimpleTextInputExProtocolGuid
,
1395 &TerminalDevice
->SimpleInputEx
,
1396 &gEfiSimpleTextOutProtocolGuid
,
1397 &TerminalDevice
->SimpleTextOutput
,
1398 &gEfiDevicePathProtocolGuid
,
1399 TerminalDevice
->DevicePath
,
1402 if (EFI_ERROR (Status
)) {
1405 &gEfiSerialIoProtocolGuid
,
1406 (VOID
**) &SerialIo
,
1407 This
->DriverBindingHandle
,
1408 ChildHandleBuffer
[Index
],
1409 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1413 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1414 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1417 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1418 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1419 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1420 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1421 gBS
->CloseEvent (TerminalDevice
->KeyNotifyProcessEvent
);
1422 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1423 FreePool (TerminalDevice
->DevicePath
);
1424 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1425 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1427 FreePool (TerminalDevice
);
1431 if (EFI_ERROR (Status
)) {
1432 AllChildrenStopped
= FALSE
;
1436 if (!AllChildrenStopped
) {
1437 return EFI_DEVICE_ERROR
;
1444 Update terminal device path in Console Device Environment Variables.
1446 @param VariableName The Console Device Environment Variable.
1447 @param ParentDevicePath The terminal device path to be updated.
1451 TerminalUpdateConsoleDevVariable (
1452 IN CHAR16
*VariableName
,
1453 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1460 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1461 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1462 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1463 EDKII_SET_VARIABLE_STATUS
*SetVariableStatus
;
1466 // Get global variable and its size according to the name given.
1468 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
1469 if (Variable
== NULL
) {
1474 // Append terminal device path onto the variable.
1476 for (TerminalType
= PCANSITYPE
; TerminalType
<= TTYTERMTYPE
; TerminalType
++) {
1477 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1478 NewVariable
= AppendDevicePathInstance (Variable
, TempDevicePath
);
1479 ASSERT (NewVariable
!= NULL
);
1480 if (Variable
!= NULL
) {
1481 FreePool (Variable
);
1484 if (TempDevicePath
!= NULL
) {
1485 FreePool (TempDevicePath
);
1488 Variable
= NewVariable
;
1491 VariableSize
= GetDevicePathSize (Variable
);
1493 Status
= gRT
->SetVariable (
1495 &gEfiGlobalVariableGuid
,
1496 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1501 if (EFI_ERROR (Status
)) {
1502 NameSize
= StrSize (VariableName
);
1503 SetVariableStatus
= AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS
) + NameSize
+ VariableSize
);
1504 if (SetVariableStatus
!= NULL
) {
1505 CopyGuid (&SetVariableStatus
->Guid
, &gEfiGlobalVariableGuid
);
1506 SetVariableStatus
->NameSize
= NameSize
;
1507 SetVariableStatus
->DataSize
= VariableSize
;
1508 SetVariableStatus
->SetStatus
= Status
;
1509 SetVariableStatus
->Attributes
= EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
;
1510 CopyMem (SetVariableStatus
+ 1, VariableName
, NameSize
);
1511 CopyMem (((UINT8
*) (SetVariableStatus
+ 1)) + NameSize
, Variable
, VariableSize
);
1513 REPORT_STATUS_CODE_EX (
1515 PcdGet32 (PcdErrorCodeSetVariable
),
1518 &gEdkiiStatusCodeDataTypeVariableGuid
,
1520 sizeof (EDKII_SET_VARIABLE_STATUS
) + NameSize
+ VariableSize
1523 FreePool (SetVariableStatus
);
1527 FreePool (Variable
);
1534 Remove terminal device path from Console Device Environment Variables.
1536 @param VariableName Console Device Environment Variables.
1537 @param ParentDevicePath The terminal device path to be updated.
1541 TerminalRemoveConsoleDevVariable (
1542 IN CHAR16
*VariableName
,
1543 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1552 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
1553 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1554 EFI_DEVICE_PATH_PROTOCOL
*OriginalVariable
;
1555 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1556 EFI_DEVICE_PATH_PROTOCOL
*SavedNewVariable
;
1557 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1562 // Get global variable and its size according to the name given.
1564 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
1565 if (Variable
== NULL
) {
1570 OriginalVariable
= Variable
;
1574 // Get first device path instance from Variable
1576 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1577 if (Instance
== NULL
) {
1578 FreePool (OriginalVariable
);
1582 // Loop through all the device path instances of Variable
1586 // Loop through all the terminal types that this driver supports
1589 for (TerminalType
= PCANSITYPE
; TerminalType
<= TTYTERMTYPE
; TerminalType
++) {
1591 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1594 // Compare the generated device path to the current device path instance
1596 if (TempDevicePath
!= NULL
) {
1597 if (CompareMem (Instance
, TempDevicePath
, InstanceSize
) == 0) {
1602 FreePool (TempDevicePath
);
1606 // If a match was not found, then keep the current device path instance
1609 SavedNewVariable
= NewVariable
;
1610 NewVariable
= AppendDevicePathInstance (NewVariable
, Instance
);
1611 if (SavedNewVariable
!= NULL
) {
1612 FreePool (SavedNewVariable
);
1616 // Get next device path instance from Variable
1618 FreePool (Instance
);
1619 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1620 } while (Instance
!= NULL
);
1622 FreePool (OriginalVariable
);
1625 VariableSize
= GetDevicePathSize (NewVariable
);
1627 Status
= gRT
->SetVariable (
1629 &gEfiGlobalVariableGuid
,
1630 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1635 // Shrinking variable with existing variable driver implementation shouldn't fail.
1637 ASSERT_EFI_ERROR (Status
);
1640 if (NewVariable
!= NULL
) {
1641 FreePool (NewVariable
);
1648 Build terminal device path according to terminal type.
1650 @param TerminalType The terminal type is PC ANSI, VT100, VT100+ or VT-UTF8.
1651 @param ParentDevicePath Parent device path.
1652 @param TerminalDevicePath Returned terminal device path, if building successfully.
1654 @retval EFI_UNSUPPORTED Terminal does not belong to the supported type.
1655 @retval EFI_OUT_OF_RESOURCES Generate terminal device path failed.
1656 @retval EFI_SUCCESS Build terminal device path successfully.
1660 SetTerminalDevicePath (
1661 IN UINT8 TerminalType
,
1662 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
1663 OUT EFI_DEVICE_PATH_PROTOCOL
**TerminalDevicePath
1666 VENDOR_DEVICE_PATH Node
;
1668 *TerminalDevicePath
= NULL
;
1669 Node
.Header
.Type
= MESSAGING_DEVICE_PATH
;
1670 Node
.Header
.SubType
= MSG_VENDOR_DP
;
1673 // Generate terminal device path node according to terminal type.
1675 switch (TerminalType
) {
1678 CopyGuid (&Node
.Guid
, &gEfiPcAnsiGuid
);
1682 CopyGuid (&Node
.Guid
, &gEfiVT100Guid
);
1686 CopyGuid (&Node
.Guid
, &gEfiVT100PlusGuid
);
1690 CopyGuid (&Node
.Guid
, &gEfiVTUTF8Guid
);
1694 CopyGuid (&Node
.Guid
, &gEfiTtyTermGuid
);
1698 return EFI_UNSUPPORTED
;
1702 // Get VENDOR_DEVCIE_PATH size and put into Node.Header
1704 SetDevicePathNodeLength (
1706 sizeof (VENDOR_DEVICE_PATH
)
1710 // Append the terminal node onto parent device path
1711 // to generate a complete terminal device path.
1713 *TerminalDevicePath
= AppendDevicePathNode (
1715 (EFI_DEVICE_PATH_PROTOCOL
*) &Node
1717 if (*TerminalDevicePath
== NULL
) {
1718 return EFI_OUT_OF_RESOURCES
;
1725 The user Entry Point for module Terminal. The user code starts with this function.
1727 @param ImageHandle The firmware allocated handle for the EFI image.
1728 @param SystemTable A pointer to the EFI System Table.
1730 @retval EFI_SUCCESS The entry point is executed successfully.
1731 @retval other Some error occurs when executing this entry point.
1737 IN EFI_HANDLE ImageHandle
,
1738 IN EFI_SYSTEM_TABLE
*SystemTable
1744 // Install driver model protocol(s).
1746 Status
= EfiLibInstallDriverBindingComponentName2 (
1749 &gTerminalDriverBinding
,
1751 &gTerminalComponentName
,
1752 &gTerminalComponentName2
1754 ASSERT_EFI_ERROR (Status
);
1760 Check if the device supports hot-plug through its device path.
1762 This function could be updated to check more types of Hot Plug devices.
1763 Currently, it checks USB and PCCard device.
1765 @param DevicePath Pointer to device's device path.
1767 @retval TRUE The devcie is a hot-plug device
1768 @retval FALSE The devcie is not a hot-plug device.
1773 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
1776 EFI_DEVICE_PATH_PROTOCOL
*CheckDevicePath
;
1778 CheckDevicePath
= DevicePath
;
1779 while (!IsDevicePathEnd (CheckDevicePath
)) {
1781 // Check device whether is hot plug device or not throught Device Path
1783 if ((DevicePathType (CheckDevicePath
) == MESSAGING_DEVICE_PATH
) &&
1784 (DevicePathSubType (CheckDevicePath
) == MSG_USB_DP
||
1785 DevicePathSubType (CheckDevicePath
) == MSG_USB_CLASS_DP
||
1786 DevicePathSubType (CheckDevicePath
) == MSG_USB_WWID_DP
)) {
1788 // If Device is USB device
1792 if ((DevicePathType (CheckDevicePath
) == HARDWARE_DEVICE_PATH
) &&
1793 (DevicePathSubType (CheckDevicePath
) == HW_PCCARD_DP
)) {
1795 // If Device is PCCard
1800 CheckDevicePath
= NextDevicePathNode (CheckDevicePath
);