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 - 2014, 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
79 NULL
, // ControllerNameTable
81 NULL
, // TwoSecondTimeOut
85 { // SimpleTextInputEx
87 TerminalConInReadKeyStrokeEx
,
89 TerminalConInSetState
,
90 TerminalConInRegisterKeyNotify
,
91 TerminalConInUnregisterKeyNotify
,
99 TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData
[] = {
102 // New modes can be added here.
107 Test to see if this driver supports Controller.
109 @param This Protocol instance pointer.
110 @param Controller Handle of device to test
111 @param RemainingDevicePath Optional parameter use to pick a specific child
114 @retval EFI_SUCCESS This driver supports this device.
115 @retval EFI_ALREADY_STARTED This driver is already running on this device.
116 @retval other This driver does not support this device.
121 TerminalDriverBindingSupported (
122 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
123 IN EFI_HANDLE Controller
,
124 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
128 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
129 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
130 VENDOR_DEVICE_PATH
*Node
;
133 // If remaining device path is not NULL, then make sure it is a
134 // device path that describes a terminal communications protocol.
136 if (RemainingDevicePath
!= NULL
) {
138 // Check if RemainingDevicePath is the End of Device Path Node,
139 // if yes, go on checking other conditions
141 if (!IsDevicePathEnd (RemainingDevicePath
)) {
143 // If RemainingDevicePath isn't the End of Device Path Node,
144 // check its validation
146 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
148 if (Node
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
149 Node
->Header
.SubType
!= MSG_VENDOR_DP
||
150 DevicePathNodeLength(&Node
->Header
) != sizeof(VENDOR_DEVICE_PATH
)) {
152 return EFI_UNSUPPORTED
;
156 // only supports PC ANSI, VT100, VT100+, VT-UTF8, and TtyTerm terminal types
158 if (!CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
) &&
159 !CompareGuid (&Node
->Guid
, &gEfiVT100Guid
) &&
160 !CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
) &&
161 !CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
) &&
162 !CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
164 return EFI_UNSUPPORTED
;
169 // Open the IO Abstraction(s) needed to perform the supported test
170 // The Controller must support the Serial I/O Protocol.
171 // This driver is a bus driver with at most 1 child device, so it is
172 // ok for it to be already started.
174 Status
= gBS
->OpenProtocol (
176 &gEfiSerialIoProtocolGuid
,
178 This
->DriverBindingHandle
,
180 EFI_OPEN_PROTOCOL_BY_DRIVER
182 if (Status
== EFI_ALREADY_STARTED
) {
186 if (EFI_ERROR (Status
)) {
191 // Close the I/O Abstraction(s) used to perform the supported test
195 &gEfiSerialIoProtocolGuid
,
196 This
->DriverBindingHandle
,
201 // Open the EFI Device Path protocol needed to perform the supported test
203 Status
= gBS
->OpenProtocol (
205 &gEfiDevicePathProtocolGuid
,
206 (VOID
**) &ParentDevicePath
,
207 This
->DriverBindingHandle
,
209 EFI_OPEN_PROTOCOL_BY_DRIVER
211 if (Status
== EFI_ALREADY_STARTED
) {
215 if (EFI_ERROR (Status
)) {
220 // Close protocol, don't use device path protocol in the Support() function
224 &gEfiDevicePathProtocolGuid
,
225 This
->DriverBindingHandle
,
233 Build the terminal device path for the child device according to the
236 @param ParentDevicePath Parent device path.
237 @param RemainingDevicePath A specific child device.
239 @return The child device path built.
242 EFI_DEVICE_PATH_PROTOCOL
*
244 BuildTerminalDevpath (
245 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
246 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
249 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
251 VENDOR_DEVICE_PATH
*Node
;
254 TerminalDevicePath
= NULL
;
255 TerminalType
= PCANSITYPE
;
258 // Use the RemainingDevicePath to determine the terminal type
260 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
262 TerminalType
= PCANSITYPE
;
264 } else if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
266 TerminalType
= PCANSITYPE
;
268 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
270 TerminalType
= VT100TYPE
;
272 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
274 TerminalType
= VT100PLUSTYPE
;
276 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
278 TerminalType
= VTUTF8TYPE
;
280 } else if (CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
282 TerminalType
= TTYTERMTYPE
;
289 // Build the device path for the child device
291 Status
= SetTerminalDevicePath (
296 if (EFI_ERROR (Status
)) {
299 return TerminalDevicePath
;
303 Compare a device path data structure to that of all the nodes of a
304 second device path instance.
306 @param Multi A pointer to a multi-instance device path data structure.
307 @param Single A pointer to a single-instance device path data structure.
309 @retval TRUE If the Single is contained within Multi.
310 @retval FALSE The Single is not match within Multi.
315 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
316 IN EFI_DEVICE_PATH_PROTOCOL
*Single
319 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
320 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
324 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
326 // Search for the match of 'Single' in 'Multi'
328 while (DevicePathInst
!= NULL
) {
330 // If the single device path is found in multiple device paths,
333 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
334 FreePool (DevicePathInst
);
338 FreePool (DevicePathInst
);
339 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
346 Check whether the terminal device path is in the global variable.
348 @param VariableName Pointer to one global variable.
349 @param TerminalDevicePath Pointer to the terminal device's device path.
351 @retval TRUE The devcie is in the global variable.
352 @retval FALSE The devcie is not in the global variable.
356 IsTerminalInConsoleVariable (
357 IN CHAR16
*VariableName
,
358 IN EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
361 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
365 // Get global variable and its size according to the name given.
367 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
368 if (Variable
== NULL
) {
373 // Check whether the terminal device path is one of the variable instances.
375 ReturnFlag
= MatchDevicePaths (Variable
, TerminalDevicePath
);
383 Free notify functions list.
385 @param ListHead The list head
387 @retval EFI_SUCCESS Free the notify list successfully.
388 @retval EFI_INVALID_PARAMETER ListHead is NULL.
392 TerminalFreeNotifyList (
393 IN OUT LIST_ENTRY
*ListHead
396 TERMINAL_CONSOLE_IN_EX_NOTIFY
*NotifyNode
;
398 if (ListHead
== NULL
) {
399 return EFI_INVALID_PARAMETER
;
401 while (!IsListEmpty (ListHead
)) {
403 ListHead
->ForwardLink
,
404 TERMINAL_CONSOLE_IN_EX_NOTIFY
,
406 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
408 RemoveEntryList (ListHead
->ForwardLink
);
409 FreePool (NotifyNode
);
416 Initialize all the text modes which the terminal console supports.
418 It returns information for available text modes that the terminal can support.
420 @param[out] TextModeCount The total number of text modes that terminal console supports.
421 @param[out] TextModeData The buffer to the text modes column and row information.
422 Caller is responsible to free it when it's non-NULL.
424 @retval EFI_SUCCESS The supporting mode information is returned.
425 @retval EFI_INVALID_PARAMETER The parameters are invalid.
429 InitializeTerminalConsoleTextMode (
430 OUT UINTN
*TextModeCount
,
431 OUT TERMINAL_CONSOLE_MODE_DATA
**TextModeData
436 TERMINAL_CONSOLE_MODE_DATA
*ModeBuffer
;
437 TERMINAL_CONSOLE_MODE_DATA
*NewModeBuffer
;
441 if ((TextModeCount
== NULL
) || (TextModeData
== NULL
)) {
442 return EFI_INVALID_PARAMETER
;
445 Count
= sizeof (mTerminalConsoleModeData
) / sizeof (TERMINAL_CONSOLE_MODE_DATA
);
448 // Get defined mode buffer pointer.
450 ModeBuffer
= mTerminalConsoleModeData
;
453 // Here we make sure that the final mode exposed does not include the duplicated modes,
454 // and does not include the invalid modes which exceed the max column and row.
455 // Reserve 2 modes for 80x25, 80x50 of terminal console.
457 NewModeBuffer
= AllocateZeroPool (sizeof (TERMINAL_CONSOLE_MODE_DATA
) * (Count
+ 2));
458 ASSERT (NewModeBuffer
!= NULL
);
461 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
465 NewModeBuffer
[ValidCount
].Columns
= 80;
466 NewModeBuffer
[ValidCount
].Rows
= 25;
469 NewModeBuffer
[ValidCount
].Columns
= 80;
470 NewModeBuffer
[ValidCount
].Rows
= 50;
474 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
476 for (Index
= 0; Index
< Count
; Index
++) {
477 if ((ModeBuffer
[Index
].Columns
== 0) || (ModeBuffer
[Index
].Rows
== 0)) {
479 // Skip the pre-defined mode which is invalid.
483 for (ValidIndex
= 0; ValidIndex
< ValidCount
; ValidIndex
++) {
484 if ((ModeBuffer
[Index
].Columns
== NewModeBuffer
[ValidIndex
].Columns
) &&
485 (ModeBuffer
[Index
].Rows
== NewModeBuffer
[ValidIndex
].Rows
)) {
487 // Skip the duplicated mode.
492 if (ValidIndex
== ValidCount
) {
493 NewModeBuffer
[ValidCount
].Columns
= ModeBuffer
[Index
].Columns
;
494 NewModeBuffer
[ValidCount
].Rows
= ModeBuffer
[Index
].Rows
;
500 for (Index
= 0; Index
< ValidCount
; Index
++) {
501 DEBUG ((EFI_D_INFO
, "Terminal - Mode %d, Column = %d, Row = %d\n",
502 Index
, NewModeBuffer
[Index
].Columns
, NewModeBuffer
[Index
].Rows
));
507 // Return valid mode count and mode information buffer.
509 *TextModeCount
= ValidCount
;
510 *TextModeData
= NewModeBuffer
;
515 Start this driver on Controller by opening a Serial IO protocol,
516 reading Device Path, and creating a child handle with a Simple Text In,
517 Simple Text In Ex and Simple Text Out protocol, and device path protocol.
518 And store Console Device Environment Variables.
520 @param This Protocol instance pointer.
521 @param Controller Handle of device to bind driver to
522 @param RemainingDevicePath Optional parameter use to pick a specific child
525 @retval EFI_SUCCESS This driver is added to Controller.
526 @retval EFI_ALREADY_STARTED This driver is already running on Controller.
527 @retval other This driver does not support this device.
532 TerminalDriverBindingStart (
533 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
534 IN EFI_HANDLE Controller
,
535 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
539 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
540 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
541 VENDOR_DEVICE_PATH
*Node
;
542 VENDOR_DEVICE_PATH
*DefaultNode
;
543 EFI_SERIAL_IO_MODE
*Mode
;
544 UINTN SerialInTimeOut
;
545 TERMINAL_DEV
*TerminalDevice
;
547 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
550 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
551 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
552 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleTextInput
;
553 BOOLEAN ConInSelected
;
554 BOOLEAN ConOutSelected
;
555 BOOLEAN NullRemaining
;
556 BOOLEAN SimTxtInInstalled
;
557 BOOLEAN SimTxtOutInstalled
;
561 TerminalDevice
= NULL
;
563 ConInSelected
= FALSE
;
564 ConOutSelected
= FALSE
;
565 NullRemaining
= TRUE
;
566 SimTxtInInstalled
= FALSE
;
567 SimTxtOutInstalled
= FALSE
;
570 // Get the Device Path Protocol to build the device path of the child device
572 Status
= gBS
->OpenProtocol (
574 &gEfiDevicePathProtocolGuid
,
575 (VOID
**) &ParentDevicePath
,
576 This
->DriverBindingHandle
,
578 EFI_OPEN_PROTOCOL_BY_DRIVER
580 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
585 // Open the Serial I/O Protocol BY_DRIVER. It might already be started.
587 Status
= gBS
->OpenProtocol (
589 &gEfiSerialIoProtocolGuid
,
591 This
->DriverBindingHandle
,
593 EFI_OPEN_PROTOCOL_BY_DRIVER
595 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
599 if (Status
!= EFI_ALREADY_STARTED
) {
601 // the serial I/O protocol never be opened before, it is the first
602 // time to start the serial Io controller
608 // Serial I/O is not already open by this driver, then tag the handle
609 // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and
610 // StdErrDev variables with the list of possible terminal types on this
613 Status
= gBS
->OpenProtocol (
617 This
->DriverBindingHandle
,
619 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
621 if (EFI_ERROR (Status
)) {
622 Status
= gBS
->InstallMultipleProtocolInterfaces (
625 DuplicateDevicePath (ParentDevicePath
),
628 if (EFI_ERROR (Status
)) {
632 if (!IsHotPlugDevice (ParentDevicePath
)) {
634 // if the serial device is a hot plug device, do not update the
635 // ConInDev, ConOutDev, and StdErrDev variables.
637 TerminalUpdateConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
638 TerminalUpdateConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
639 TerminalUpdateConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
644 // Check the requirement for the SimpleTxtIn and SimpleTxtOut protocols
646 // Simple In/Out Protocol will not be installed onto the handle if the
647 // device path to the handle is not present in the ConIn/ConOut
648 // environment variable. But If RemainingDevicePath is NULL, then always
649 // produce both Simple In and Simple Text Output Protocols. This is required
650 // for the connect all sequences to make sure all possible consoles are
651 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
653 if (RemainingDevicePath
== NULL
) {
654 NullRemaining
= TRUE
;
657 DevicePath
= BuildTerminalDevpath (ParentDevicePath
, RemainingDevicePath
);
658 if (DevicePath
!= NULL
) {
659 ConInSelected
= IsTerminalInConsoleVariable (L
"ConIn", DevicePath
);
660 ConOutSelected
= IsTerminalInConsoleVariable (L
"ConOut", DevicePath
);
661 FreePool (DevicePath
);
666 // Not create the child terminal handle if both Simple In/In Ex and
667 // Simple text Out protocols are not required to be published
669 if ((!ConInSelected
)&&(!ConOutSelected
)&&(!NullRemaining
)) {
674 // create the child terminal handle during first entry
678 // First enther the start funciton
682 // Make sure a child handle does not already exist. This driver can only
683 // produce one child per serial port.
685 Status
= gBS
->OpenProtocolInformation (
687 &gEfiSerialIoProtocolGuid
,
691 if (!EFI_ERROR (Status
)) {
692 Status
= EFI_SUCCESS
;
693 for (Index
= 0; Index
< EntryCount
; Index
++) {
694 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
695 Status
= EFI_ALREADY_STARTED
;
699 FreePool (OpenInfoBuffer
);
700 if (EFI_ERROR (Status
)) {
706 // If RemainingDevicePath is NULL, then create default device path node
708 if (RemainingDevicePath
== NULL
) {
709 DefaultNode
= AllocateZeroPool (sizeof (VENDOR_DEVICE_PATH
));
710 if (DefaultNode
== NULL
) {
711 Status
= EFI_OUT_OF_RESOURCES
;
715 TerminalType
= PcdGet8 (PcdDefaultTerminalType
);
717 // Must be between PCANSITYPE (0) and TTYTERMTYPE (4)
719 ASSERT (TerminalType
<= TTYTERMTYPE
);
721 CopyMem (&DefaultNode
->Guid
, gTerminalType
[TerminalType
], sizeof (EFI_GUID
));
722 RemainingDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) DefaultNode
;
723 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
725 // If RemainingDevicePath isn't the End of Device Path Node,
726 // Use the RemainingDevicePath to determine the terminal type
728 Node
= (VENDOR_DEVICE_PATH
*)RemainingDevicePath
;
729 if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
730 TerminalType
= PCANSITYPE
;
731 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
732 TerminalType
= VT100TYPE
;
733 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
734 TerminalType
= VT100PLUSTYPE
;
735 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
736 TerminalType
= VTUTF8TYPE
;
737 } else if (CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
738 TerminalType
= TTYTERMTYPE
;
744 // If RemainingDevicePath is the End of Device Path Node,
745 // skip enumerate any device and return EFI_SUCESSS
751 // Initialize the Terminal Dev
753 TerminalDevice
= AllocateCopyPool (sizeof (TERMINAL_DEV
), &mTerminalDevTemplate
);
754 if (TerminalDevice
== NULL
) {
755 Status
= EFI_OUT_OF_RESOURCES
;
759 TerminalDevice
->TerminalType
= TerminalType
;
760 TerminalDevice
->SerialIo
= SerialIo
;
762 InitializeListHead (&TerminalDevice
->NotifyList
);
763 Status
= gBS
->CreateEvent (
766 TerminalConInWaitForKeyEx
,
768 &TerminalDevice
->SimpleInputEx
.WaitForKeyEx
770 if (EFI_ERROR (Status
)) {
774 Status
= gBS
->CreateEvent (
777 TerminalConInWaitForKey
,
779 &TerminalDevice
->SimpleInput
.WaitForKey
781 if (EFI_ERROR (Status
)) {
785 // Allocates and initializes the FIFO buffer to be zero, used for accommodating
786 // the pre-read pending characters.
788 TerminalDevice
->RawFiFo
= AllocateZeroPool (sizeof (RAW_DATA_FIFO
));
789 if (TerminalDevice
->RawFiFo
== NULL
) {
792 TerminalDevice
->UnicodeFiFo
= AllocateZeroPool (sizeof (UNICODE_FIFO
));
793 if (TerminalDevice
->UnicodeFiFo
== NULL
) {
796 TerminalDevice
->EfiKeyFiFo
= AllocateZeroPool (sizeof (EFI_KEY_FIFO
));
797 if (TerminalDevice
->EfiKeyFiFo
== 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
->InstallProtocolInterface (
1010 &TerminalDevice
->Handle
,
1011 &gEfiDevicePathProtocolGuid
,
1012 EFI_NATIVE_INTERFACE
,
1013 TerminalDevice
->DevicePath
1015 if (EFI_ERROR (Status
)) {
1020 // Register the Parent-Child relationship via
1021 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
1023 Status
= gBS
->OpenProtocol (
1025 &gEfiSerialIoProtocolGuid
,
1026 (VOID
**) &TerminalDevice
->SerialIo
,
1027 This
->DriverBindingHandle
,
1028 TerminalDevice
->Handle
,
1029 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1031 if (EFI_ERROR (Status
)) {
1037 // Find the child handle, and get its TerminalDevice private data
1039 Status
= gBS
->OpenProtocolInformation (
1041 &gEfiSerialIoProtocolGuid
,
1045 if (!EFI_ERROR (Status
)) {
1046 Status
= EFI_NOT_FOUND
;
1047 ASSERT (OpenInfoBuffer
!= NULL
);
1048 for (Index
= 0; Index
< EntryCount
; Index
++) {
1049 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
1051 // Find the child terminal handle.
1052 // Test whether the SimpleTxtIn and SimpleTxtOut have been published
1054 Status
= gBS
->OpenProtocol (
1055 OpenInfoBuffer
[Index
].ControllerHandle
,
1056 &gEfiSimpleTextInProtocolGuid
,
1057 (VOID
**) &SimpleTextInput
,
1058 This
->DriverBindingHandle
,
1059 OpenInfoBuffer
[Index
].ControllerHandle
,
1060 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1062 if (!EFI_ERROR (Status
)) {
1063 SimTxtInInstalled
= TRUE
;
1064 TerminalDevice
= TERMINAL_CON_IN_DEV_FROM_THIS (SimpleTextInput
);
1067 Status
= gBS
->OpenProtocol (
1068 OpenInfoBuffer
[Index
].ControllerHandle
,
1069 &gEfiSimpleTextOutProtocolGuid
,
1070 (VOID
**) &SimpleTextOutput
,
1071 This
->DriverBindingHandle
,
1072 OpenInfoBuffer
[Index
].ControllerHandle
,
1073 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1075 if (!EFI_ERROR (Status
)) {
1076 SimTxtOutInstalled
= TRUE
;
1077 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1079 Status
= EFI_SUCCESS
;
1084 FreePool (OpenInfoBuffer
);
1085 if (EFI_ERROR (Status
)) {
1092 ASSERT (TerminalDevice
!= NULL
);
1094 // Only do the reset if the device path is in the Conout variable
1096 if (ConInSelected
&& !SimTxtInInstalled
) {
1097 Status
= TerminalDevice
->SimpleInput
.Reset (
1098 &TerminalDevice
->SimpleInput
,
1101 if (EFI_ERROR (Status
)) {
1103 // Need to report Error Code first
1110 // Only output the configure string to remote terminal if the device path
1111 // is in the Conout variable
1113 if (ConOutSelected
&& !SimTxtOutInstalled
) {
1114 Status
= TerminalDevice
->SimpleTextOutput
.SetAttribute (
1115 &TerminalDevice
->SimpleTextOutput
,
1116 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
1118 if (EFI_ERROR (Status
)) {
1122 Status
= TerminalDevice
->SimpleTextOutput
.Reset (
1123 &TerminalDevice
->SimpleTextOutput
,
1126 if (EFI_ERROR (Status
)) {
1130 Status
= TerminalDevice
->SimpleTextOutput
.SetMode (
1131 &TerminalDevice
->SimpleTextOutput
,
1134 if (EFI_ERROR (Status
)) {
1138 Status
= TerminalDevice
->SimpleTextOutput
.EnableCursor (
1139 &TerminalDevice
->SimpleTextOutput
,
1142 if (EFI_ERROR (Status
)) {
1148 // Simple In/Out Protocol will not be installed onto the handle if the
1149 // device path to the handle is not present in the ConIn/ConOut
1150 // environment variable. But If RemainingDevicePath is NULL, then always
1151 // produce both Simple In and Simple Text Output Protocols. This is required
1152 // for the connect all sequences to make sure all possible consoles are
1153 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
1155 if (!SimTxtInInstalled
&& (ConInSelected
|| NullRemaining
)) {
1156 Status
= gBS
->InstallMultipleProtocolInterfaces (
1157 &TerminalDevice
->Handle
,
1158 &gEfiSimpleTextInProtocolGuid
,
1159 &TerminalDevice
->SimpleInput
,
1160 &gEfiSimpleTextInputExProtocolGuid
,
1161 &TerminalDevice
->SimpleInputEx
,
1164 if (EFI_ERROR (Status
)) {
1169 if (!SimTxtOutInstalled
&& (ConOutSelected
|| NullRemaining
)) {
1170 Status
= gBS
->InstallProtocolInterface (
1171 &TerminalDevice
->Handle
,
1172 &gEfiSimpleTextOutProtocolGuid
,
1173 EFI_NATIVE_INTERFACE
,
1174 &TerminalDevice
->SimpleTextOutput
1176 if (EFI_ERROR (Status
)) {
1180 if (DefaultNode
!= NULL
) {
1181 FreePool (DefaultNode
);
1188 // Report error code before exiting
1190 DevicePath
= ParentDevicePath
;
1191 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1192 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1193 (EFI_PERIPHERAL_REMOTE_CONSOLE
| EFI_P_EC_CONTROLLER_ERROR
),
1199 // Use the Stop() function to free all resources allocated in Start()
1201 if (TerminalDevice
!= NULL
) {
1203 if (TerminalDevice
->Handle
!= NULL
) {
1204 This
->Stop (This
, Controller
, 1, &TerminalDevice
->Handle
);
1207 if (TerminalDevice
->TwoSecondTimeOut
!= NULL
) {
1208 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1211 if (TerminalDevice
->TimerEvent
!= NULL
) {
1212 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1215 if (TerminalDevice
->SimpleInput
.WaitForKey
!= NULL
) {
1216 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1219 if (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
!= NULL
) {
1220 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1223 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1225 if (TerminalDevice
->RawFiFo
!= NULL
) {
1226 FreePool (TerminalDevice
->RawFiFo
);
1228 if (TerminalDevice
->UnicodeFiFo
!= NULL
) {
1229 FreePool (TerminalDevice
->UnicodeFiFo
);
1231 if (TerminalDevice
->EfiKeyFiFo
!= NULL
) {
1232 FreePool (TerminalDevice
->EfiKeyFiFo
);
1235 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1236 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1239 if (TerminalDevice
->DevicePath
!= NULL
) {
1240 FreePool (TerminalDevice
->DevicePath
);
1243 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1244 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1247 FreePool (TerminalDevice
);
1251 if (DefaultNode
!= NULL
) {
1252 FreePool (DefaultNode
);
1255 This
->Stop (This
, Controller
, 0, NULL
);
1261 Stop this driver on Controller by closing Simple Text In, Simple Text
1262 In Ex, Simple Text Out protocol, and removing parent device path from
1263 Console Device Environment Variables.
1265 @param This Protocol instance pointer.
1266 @param Controller Handle of device to stop driver on
1267 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1268 children is zero stop the entire bus driver.
1269 @param ChildHandleBuffer List of Child Handles to Stop.
1271 @retval EFI_SUCCESS This driver is removed Controller.
1272 @retval other This driver could not be removed from this device.
1277 TerminalDriverBindingStop (
1278 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1279 IN EFI_HANDLE Controller
,
1280 IN UINTN NumberOfChildren
,
1281 IN EFI_HANDLE
*ChildHandleBuffer
1286 BOOLEAN AllChildrenStopped
;
1287 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
1288 TERMINAL_DEV
*TerminalDevice
;
1289 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1290 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
1291 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1293 Status
= gBS
->HandleProtocol (
1295 &gEfiDevicePathProtocolGuid
,
1296 (VOID
**) &DevicePath
1298 if (EFI_ERROR (Status
)) {
1303 // Complete all outstanding transactions to Controller.
1304 // Don't allow any new transaction to Controller to be started.
1306 if (NumberOfChildren
== 0) {
1308 // Close the bus driver
1310 Status
= gBS
->OpenProtocol (
1313 (VOID
**) &ParentDevicePath
,
1314 This
->DriverBindingHandle
,
1316 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1318 if (!EFI_ERROR (Status
)) {
1320 // Remove Parent Device Path from
1321 // the Console Device Environment Variables
1323 TerminalRemoveConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
1324 TerminalRemoveConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
1325 TerminalRemoveConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
1328 // Uninstall the Terminal Driver's GUID Tag from the Serial controller
1330 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1338 // Free the ParentDevicePath that was duplicated in Start()
1340 if (!EFI_ERROR (Status
)) {
1341 FreePool (ParentDevicePath
);
1345 gBS
->CloseProtocol (
1347 &gEfiSerialIoProtocolGuid
,
1348 This
->DriverBindingHandle
,
1352 gBS
->CloseProtocol (
1354 &gEfiDevicePathProtocolGuid
,
1355 This
->DriverBindingHandle
,
1362 AllChildrenStopped
= TRUE
;
1364 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
1366 Status
= gBS
->OpenProtocol (
1367 ChildHandleBuffer
[Index
],
1368 &gEfiSimpleTextOutProtocolGuid
,
1369 (VOID
**) &SimpleTextOutput
,
1370 This
->DriverBindingHandle
,
1371 ChildHandleBuffer
[Index
],
1372 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1374 if (!EFI_ERROR (Status
)) {
1376 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1378 gBS
->CloseProtocol (
1380 &gEfiSerialIoProtocolGuid
,
1381 This
->DriverBindingHandle
,
1382 ChildHandleBuffer
[Index
]
1385 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1386 ChildHandleBuffer
[Index
],
1387 &gEfiSimpleTextInProtocolGuid
,
1388 &TerminalDevice
->SimpleInput
,
1389 &gEfiSimpleTextInputExProtocolGuid
,
1390 &TerminalDevice
->SimpleInputEx
,
1391 &gEfiSimpleTextOutProtocolGuid
,
1392 &TerminalDevice
->SimpleTextOutput
,
1393 &gEfiDevicePathProtocolGuid
,
1394 TerminalDevice
->DevicePath
,
1397 if (EFI_ERROR (Status
)) {
1400 &gEfiSerialIoProtocolGuid
,
1401 (VOID
**) &SerialIo
,
1402 This
->DriverBindingHandle
,
1403 ChildHandleBuffer
[Index
],
1404 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1408 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1409 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1412 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1413 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1414 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1415 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1416 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1417 FreePool (TerminalDevice
->DevicePath
);
1418 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1419 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1421 FreePool (TerminalDevice
);
1425 if (EFI_ERROR (Status
)) {
1426 AllChildrenStopped
= FALSE
;
1430 if (!AllChildrenStopped
) {
1431 return EFI_DEVICE_ERROR
;
1438 Update terminal device path in Console Device Environment Variables.
1440 @param VariableName The Console Device Environment Variable.
1441 @param ParentDevicePath The terminal device path to be updated.
1445 TerminalUpdateConsoleDevVariable (
1446 IN CHAR16
*VariableName
,
1447 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1454 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1455 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1456 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1457 EDKII_SET_VARIABLE_STATUS
*SetVariableStatus
;
1460 // Get global variable and its size according to the name given.
1462 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
1463 if (Variable
== NULL
) {
1468 // Append terminal device path onto the variable.
1470 for (TerminalType
= PCANSITYPE
; TerminalType
<= TTYTERMTYPE
; TerminalType
++) {
1471 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1472 NewVariable
= AppendDevicePathInstance (Variable
, TempDevicePath
);
1473 ASSERT (NewVariable
!= NULL
);
1474 if (Variable
!= NULL
) {
1475 FreePool (Variable
);
1478 if (TempDevicePath
!= NULL
) {
1479 FreePool (TempDevicePath
);
1482 Variable
= NewVariable
;
1485 VariableSize
= GetDevicePathSize (Variable
);
1487 Status
= gRT
->SetVariable (
1489 &gEfiGlobalVariableGuid
,
1490 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1495 if (EFI_ERROR (Status
)) {
1496 NameSize
= StrSize (VariableName
);
1497 SetVariableStatus
= AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS
) + NameSize
+ VariableSize
);
1498 if (SetVariableStatus
!= NULL
) {
1499 CopyGuid (&SetVariableStatus
->Guid
, &gEfiGlobalVariableGuid
);
1500 SetVariableStatus
->NameSize
= NameSize
;
1501 SetVariableStatus
->DataSize
= VariableSize
;
1502 SetVariableStatus
->SetStatus
= Status
;
1503 SetVariableStatus
->Attributes
= EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
;
1504 CopyMem (SetVariableStatus
+ 1, VariableName
, NameSize
);
1505 CopyMem (((UINT8
*) (SetVariableStatus
+ 1)) + NameSize
, Variable
, VariableSize
);
1507 REPORT_STATUS_CODE_EX (
1509 PcdGet32 (PcdErrorCodeSetVariable
),
1512 &gEdkiiStatusCodeDataTypeVariableGuid
,
1514 sizeof (EDKII_SET_VARIABLE_STATUS
) + NameSize
+ VariableSize
1517 FreePool (SetVariableStatus
);
1521 FreePool (Variable
);
1528 Remove terminal device path from Console Device Environment Variables.
1530 @param VariableName Console Device Environment Variables.
1531 @param ParentDevicePath The terminal device path to be updated.
1535 TerminalRemoveConsoleDevVariable (
1536 IN CHAR16
*VariableName
,
1537 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1546 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
1547 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1548 EFI_DEVICE_PATH_PROTOCOL
*OriginalVariable
;
1549 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1550 EFI_DEVICE_PATH_PROTOCOL
*SavedNewVariable
;
1551 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1556 // Get global variable and its size according to the name given.
1558 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
1559 if (Variable
== NULL
) {
1564 OriginalVariable
= Variable
;
1568 // Get first device path instance from Variable
1570 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1571 if (Instance
== NULL
) {
1572 FreePool (OriginalVariable
);
1576 // Loop through all the device path instances of Variable
1580 // Loop through all the terminal types that this driver supports
1583 for (TerminalType
= PCANSITYPE
; TerminalType
<= TTYTERMTYPE
; TerminalType
++) {
1585 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1588 // Compare the generated device path to the current device path instance
1590 if (TempDevicePath
!= NULL
) {
1591 if (CompareMem (Instance
, TempDevicePath
, InstanceSize
) == 0) {
1596 FreePool (TempDevicePath
);
1600 // If a match was not found, then keep the current device path instance
1603 SavedNewVariable
= NewVariable
;
1604 NewVariable
= AppendDevicePathInstance (NewVariable
, Instance
);
1605 if (SavedNewVariable
!= NULL
) {
1606 FreePool (SavedNewVariable
);
1610 // Get next device path instance from Variable
1612 FreePool (Instance
);
1613 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1614 } while (Instance
!= NULL
);
1616 FreePool (OriginalVariable
);
1619 VariableSize
= GetDevicePathSize (NewVariable
);
1621 Status
= gRT
->SetVariable (
1623 &gEfiGlobalVariableGuid
,
1624 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1629 // Shrinking variable with existing variable driver implementation shouldn't fail.
1631 ASSERT_EFI_ERROR (Status
);
1634 if (NewVariable
!= NULL
) {
1635 FreePool (NewVariable
);
1642 Build terminal device path according to terminal type.
1644 @param TerminalType The terminal type is PC ANSI, VT100, VT100+ or VT-UTF8.
1645 @param ParentDevicePath Parent device path.
1646 @param TerminalDevicePath Returned terminal device path, if building successfully.
1648 @retval EFI_UNSUPPORTED Terminal does not belong to the supported type.
1649 @retval EFI_OUT_OF_RESOURCES Generate terminal device path failed.
1650 @retval EFI_SUCCESS Build terminal device path successfully.
1654 SetTerminalDevicePath (
1655 IN UINT8 TerminalType
,
1656 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
1657 OUT EFI_DEVICE_PATH_PROTOCOL
**TerminalDevicePath
1660 VENDOR_DEVICE_PATH Node
;
1662 *TerminalDevicePath
= NULL
;
1663 Node
.Header
.Type
= MESSAGING_DEVICE_PATH
;
1664 Node
.Header
.SubType
= MSG_VENDOR_DP
;
1667 // Generate terminal device path node according to terminal type.
1669 switch (TerminalType
) {
1672 CopyGuid (&Node
.Guid
, &gEfiPcAnsiGuid
);
1676 CopyGuid (&Node
.Guid
, &gEfiVT100Guid
);
1680 CopyGuid (&Node
.Guid
, &gEfiVT100PlusGuid
);
1684 CopyGuid (&Node
.Guid
, &gEfiVTUTF8Guid
);
1688 CopyGuid (&Node
.Guid
, &gEfiTtyTermGuid
);
1692 return EFI_UNSUPPORTED
;
1696 // Get VENDOR_DEVCIE_PATH size and put into Node.Header
1698 SetDevicePathNodeLength (
1700 sizeof (VENDOR_DEVICE_PATH
)
1704 // Append the terminal node onto parent device path
1705 // to generate a complete terminal device path.
1707 *TerminalDevicePath
= AppendDevicePathNode (
1709 (EFI_DEVICE_PATH_PROTOCOL
*) &Node
1711 if (*TerminalDevicePath
== NULL
) {
1712 return EFI_OUT_OF_RESOURCES
;
1719 The user Entry Point for module Terminal. The user code starts with this function.
1721 @param ImageHandle The firmware allocated handle for the EFI image.
1722 @param SystemTable A pointer to the EFI System Table.
1724 @retval EFI_SUCCESS The entry point is executed successfully.
1725 @retval other Some error occurs when executing this entry point.
1731 IN EFI_HANDLE ImageHandle
,
1732 IN EFI_SYSTEM_TABLE
*SystemTable
1738 // Install driver model protocol(s).
1740 Status
= EfiLibInstallDriverBindingComponentName2 (
1743 &gTerminalDriverBinding
,
1745 &gTerminalComponentName
,
1746 &gTerminalComponentName2
1748 ASSERT_EFI_ERROR (Status
);
1754 Check if the device supports hot-plug through its device path.
1756 This function could be updated to check more types of Hot Plug devices.
1757 Currently, it checks USB and PCCard device.
1759 @param DevicePath Pointer to device's device path.
1761 @retval TRUE The devcie is a hot-plug device
1762 @retval FALSE The devcie is not a hot-plug device.
1767 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
1770 EFI_DEVICE_PATH_PROTOCOL
*CheckDevicePath
;
1772 CheckDevicePath
= DevicePath
;
1773 while (!IsDevicePathEnd (CheckDevicePath
)) {
1775 // Check device whether is hot plug device or not throught Device Path
1777 if ((DevicePathType (CheckDevicePath
) == MESSAGING_DEVICE_PATH
) &&
1778 (DevicePathSubType (CheckDevicePath
) == MSG_USB_DP
||
1779 DevicePathSubType (CheckDevicePath
) == MSG_USB_CLASS_DP
||
1780 DevicePathSubType (CheckDevicePath
) == MSG_USB_WWID_DP
)) {
1782 // If Device is USB device
1786 if ((DevicePathType (CheckDevicePath
) == HARDWARE_DEVICE_PATH
) &&
1787 (DevicePathSubType (CheckDevicePath
) == HW_PCCARD_DP
)) {
1789 // If Device is PCCard
1794 CheckDevicePath
= NextDevicePathNode (CheckDevicePath
);