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
91 { // SimpleTextInputEx
93 TerminalConInReadKeyStrokeEx
,
95 TerminalConInSetState
,
96 TerminalConInRegisterKeyNotify
,
97 TerminalConInUnregisterKeyNotify
,
105 TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData
[] = {
108 // New modes can be added here.
113 Test to see if this driver supports Controller.
115 @param This Protocol instance pointer.
116 @param Controller Handle of device to test
117 @param RemainingDevicePath Optional parameter use to pick a specific child
120 @retval EFI_SUCCESS This driver supports this device.
121 @retval EFI_ALREADY_STARTED This driver is already running on this device.
122 @retval other This driver does not support this device.
127 TerminalDriverBindingSupported (
128 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
129 IN EFI_HANDLE Controller
,
130 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
134 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
135 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
136 VENDOR_DEVICE_PATH
*Node
;
139 // If remaining device path is not NULL, then make sure it is a
140 // device path that describes a terminal communications protocol.
142 if (RemainingDevicePath
!= NULL
) {
144 // Check if RemainingDevicePath is the End of Device Path Node,
145 // if yes, go on checking other conditions
147 if (!IsDevicePathEnd (RemainingDevicePath
)) {
149 // If RemainingDevicePath isn't the End of Device Path Node,
150 // check its validation
152 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
154 if (Node
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
155 Node
->Header
.SubType
!= MSG_VENDOR_DP
||
156 DevicePathNodeLength(&Node
->Header
) != sizeof(VENDOR_DEVICE_PATH
)) {
158 return EFI_UNSUPPORTED
;
162 // only supports PC ANSI, VT100, VT100+, VT-UTF8, and TtyTerm terminal types
164 if (!CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
) &&
165 !CompareGuid (&Node
->Guid
, &gEfiVT100Guid
) &&
166 !CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
) &&
167 !CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
) &&
168 !CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
170 return EFI_UNSUPPORTED
;
175 // Open the IO Abstraction(s) needed to perform the supported test
176 // The Controller must support the Serial I/O Protocol.
177 // This driver is a bus driver with at most 1 child device, so it is
178 // ok for it to be already started.
180 Status
= gBS
->OpenProtocol (
182 &gEfiSerialIoProtocolGuid
,
184 This
->DriverBindingHandle
,
186 EFI_OPEN_PROTOCOL_BY_DRIVER
188 if (Status
== EFI_ALREADY_STARTED
) {
192 if (EFI_ERROR (Status
)) {
197 // Close the I/O Abstraction(s) used to perform the supported test
201 &gEfiSerialIoProtocolGuid
,
202 This
->DriverBindingHandle
,
207 // Open the EFI Device Path protocol needed to perform the supported test
209 Status
= gBS
->OpenProtocol (
211 &gEfiDevicePathProtocolGuid
,
212 (VOID
**) &ParentDevicePath
,
213 This
->DriverBindingHandle
,
215 EFI_OPEN_PROTOCOL_BY_DRIVER
217 if (Status
== EFI_ALREADY_STARTED
) {
221 if (EFI_ERROR (Status
)) {
226 // Close protocol, don't use device path protocol in the Support() function
230 &gEfiDevicePathProtocolGuid
,
231 This
->DriverBindingHandle
,
239 Build the terminal device path for the child device according to the
242 @param ParentDevicePath Parent device path.
243 @param RemainingDevicePath A specific child device.
245 @return The child device path built.
248 EFI_DEVICE_PATH_PROTOCOL
*
250 BuildTerminalDevpath (
251 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
252 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
255 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
257 VENDOR_DEVICE_PATH
*Node
;
260 TerminalDevicePath
= NULL
;
263 // Use the RemainingDevicePath to determine the terminal type
265 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
267 TerminalType
= PcdGet8 (PcdDefaultTerminalType
);
269 } else if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
271 TerminalType
= PCANSITYPE
;
273 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
275 TerminalType
= VT100TYPE
;
277 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
279 TerminalType
= VT100PLUSTYPE
;
281 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
283 TerminalType
= VTUTF8TYPE
;
285 } else if (CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
287 TerminalType
= TTYTERMTYPE
;
294 // Build the device path for the child device
296 Status
= SetTerminalDevicePath (
301 if (EFI_ERROR (Status
)) {
304 return TerminalDevicePath
;
308 Compare a device path data structure to that of all the nodes of a
309 second device path instance.
311 @param Multi A pointer to a multi-instance device path data structure.
312 @param Single A pointer to a single-instance device path data structure.
314 @retval TRUE If the Single is contained within Multi.
315 @retval FALSE The Single is not match within Multi.
320 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
321 IN EFI_DEVICE_PATH_PROTOCOL
*Single
324 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
325 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
329 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
331 // Search for the match of 'Single' in 'Multi'
333 while (DevicePathInst
!= NULL
) {
335 // If the single device path is found in multiple device paths,
338 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
339 FreePool (DevicePathInst
);
343 FreePool (DevicePathInst
);
344 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
351 Check whether the terminal device path is in the global variable.
353 @param VariableName Pointer to one global variable.
354 @param TerminalDevicePath Pointer to the terminal device's device path.
356 @retval TRUE The devcie is in the global variable.
357 @retval FALSE The devcie is not in the global variable.
361 IsTerminalInConsoleVariable (
362 IN CHAR16
*VariableName
,
363 IN EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
366 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
370 // Get global variable and its size according to the name given.
372 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
373 if (Variable
== NULL
) {
378 // Check whether the terminal device path is one of the variable instances.
380 ReturnFlag
= MatchDevicePaths (Variable
, TerminalDevicePath
);
388 Free notify functions list.
390 @param ListHead The list head
392 @retval EFI_SUCCESS Free the notify list successfully.
393 @retval EFI_INVALID_PARAMETER ListHead is NULL.
397 TerminalFreeNotifyList (
398 IN OUT LIST_ENTRY
*ListHead
401 TERMINAL_CONSOLE_IN_EX_NOTIFY
*NotifyNode
;
403 if (ListHead
== NULL
) {
404 return EFI_INVALID_PARAMETER
;
406 while (!IsListEmpty (ListHead
)) {
408 ListHead
->ForwardLink
,
409 TERMINAL_CONSOLE_IN_EX_NOTIFY
,
411 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
413 RemoveEntryList (ListHead
->ForwardLink
);
414 FreePool (NotifyNode
);
421 Initialize all the text modes which the terminal console supports.
423 It returns information for available text modes that the terminal can support.
425 @param[out] TextModeCount The total number of text modes that terminal console supports.
426 @param[out] TextModeData The buffer to the text modes column and row information.
427 Caller is responsible to free it when it's non-NULL.
429 @retval EFI_SUCCESS The supporting mode information is returned.
430 @retval EFI_INVALID_PARAMETER The parameters are invalid.
434 InitializeTerminalConsoleTextMode (
435 OUT UINTN
*TextModeCount
,
436 OUT TERMINAL_CONSOLE_MODE_DATA
**TextModeData
441 TERMINAL_CONSOLE_MODE_DATA
*ModeBuffer
;
442 TERMINAL_CONSOLE_MODE_DATA
*NewModeBuffer
;
446 if ((TextModeCount
== NULL
) || (TextModeData
== NULL
)) {
447 return EFI_INVALID_PARAMETER
;
450 Count
= sizeof (mTerminalConsoleModeData
) / sizeof (TERMINAL_CONSOLE_MODE_DATA
);
453 // Get defined mode buffer pointer.
455 ModeBuffer
= mTerminalConsoleModeData
;
458 // Here we make sure that the final mode exposed does not include the duplicated modes,
459 // and does not include the invalid modes which exceed the max column and row.
460 // Reserve 2 modes for 80x25, 80x50 of terminal console.
462 NewModeBuffer
= AllocateZeroPool (sizeof (TERMINAL_CONSOLE_MODE_DATA
) * (Count
+ 2));
463 ASSERT (NewModeBuffer
!= NULL
);
466 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
470 NewModeBuffer
[ValidCount
].Columns
= 80;
471 NewModeBuffer
[ValidCount
].Rows
= 25;
474 NewModeBuffer
[ValidCount
].Columns
= 80;
475 NewModeBuffer
[ValidCount
].Rows
= 50;
479 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
481 for (Index
= 0; Index
< Count
; Index
++) {
482 if ((ModeBuffer
[Index
].Columns
== 0) || (ModeBuffer
[Index
].Rows
== 0)) {
484 // Skip the pre-defined mode which is invalid.
488 for (ValidIndex
= 0; ValidIndex
< ValidCount
; ValidIndex
++) {
489 if ((ModeBuffer
[Index
].Columns
== NewModeBuffer
[ValidIndex
].Columns
) &&
490 (ModeBuffer
[Index
].Rows
== NewModeBuffer
[ValidIndex
].Rows
)) {
492 // Skip the duplicated mode.
497 if (ValidIndex
== ValidCount
) {
498 NewModeBuffer
[ValidCount
].Columns
= ModeBuffer
[Index
].Columns
;
499 NewModeBuffer
[ValidCount
].Rows
= ModeBuffer
[Index
].Rows
;
505 for (Index
= 0; Index
< ValidCount
; Index
++) {
506 DEBUG ((EFI_D_INFO
, "Terminal - Mode %d, Column = %d, Row = %d\n",
507 Index
, NewModeBuffer
[Index
].Columns
, NewModeBuffer
[Index
].Rows
));
512 // Return valid mode count and mode information buffer.
514 *TextModeCount
= ValidCount
;
515 *TextModeData
= NewModeBuffer
;
520 Start this driver on Controller by opening a Serial IO protocol,
521 reading Device Path, and creating a child handle with a Simple Text In,
522 Simple Text In Ex and Simple Text Out protocol, and device path protocol.
523 And store Console Device Environment Variables.
525 @param This Protocol instance pointer.
526 @param Controller Handle of device to bind driver to
527 @param RemainingDevicePath Optional parameter use to pick a specific child
530 @retval EFI_SUCCESS This driver is added to Controller.
531 @retval EFI_ALREADY_STARTED This driver is already running on Controller.
532 @retval other This driver does not support this device.
537 TerminalDriverBindingStart (
538 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
539 IN EFI_HANDLE Controller
,
540 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
544 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
545 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
546 VENDOR_DEVICE_PATH
*Node
;
547 EFI_SERIAL_IO_MODE
*Mode
;
548 UINTN SerialInTimeOut
;
549 TERMINAL_DEV
*TerminalDevice
;
551 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
554 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
555 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
556 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleTextInput
;
557 BOOLEAN ConInSelected
;
558 BOOLEAN ConOutSelected
;
559 BOOLEAN NullRemaining
;
560 BOOLEAN SimTxtInInstalled
;
561 BOOLEAN SimTxtOutInstalled
;
565 TerminalDevice
= NULL
;
566 ConInSelected
= FALSE
;
567 ConOutSelected
= FALSE
;
568 NullRemaining
= FALSE
;
569 SimTxtInInstalled
= FALSE
;
570 SimTxtOutInstalled
= FALSE
;
573 // Get the Device Path Protocol to build the device path of the child device
575 Status
= gBS
->OpenProtocol (
577 &gEfiDevicePathProtocolGuid
,
578 (VOID
**) &ParentDevicePath
,
579 This
->DriverBindingHandle
,
581 EFI_OPEN_PROTOCOL_BY_DRIVER
583 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
588 // Open the Serial I/O Protocol BY_DRIVER. It might already be started.
590 Status
= gBS
->OpenProtocol (
592 &gEfiSerialIoProtocolGuid
,
594 This
->DriverBindingHandle
,
596 EFI_OPEN_PROTOCOL_BY_DRIVER
598 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
602 if (Status
!= EFI_ALREADY_STARTED
) {
604 // the serial I/O protocol never be opened before, it is the first
605 // time to start the serial Io controller
611 // Serial I/O is not already open by this driver, then tag the handle
612 // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and
613 // StdErrDev variables with the list of possible terminal types on this
616 Status
= gBS
->OpenProtocol (
620 This
->DriverBindingHandle
,
622 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
624 if (EFI_ERROR (Status
)) {
625 Status
= gBS
->InstallMultipleProtocolInterfaces (
628 DuplicateDevicePath (ParentDevicePath
),
631 if (EFI_ERROR (Status
)) {
635 if (!IsHotPlugDevice (ParentDevicePath
)) {
637 // if the serial device is a hot plug device, do not update the
638 // ConInDev, ConOutDev, and StdErrDev variables.
640 TerminalUpdateConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
641 TerminalUpdateConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
642 TerminalUpdateConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
647 // Check the requirement for the SimpleTxtIn and SimpleTxtOut protocols
649 // Simple In/Out Protocol will not be installed onto the handle if the
650 // device path to the handle is not present in the ConIn/ConOut
651 // environment variable. But If RemainingDevicePath is NULL, then always
652 // produce both Simple In and Simple Text Output Protocols. This is required
653 // for the connect all sequences to make sure all possible consoles are
654 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
656 if (RemainingDevicePath
== NULL
) {
657 NullRemaining
= TRUE
;
660 DevicePath
= BuildTerminalDevpath (ParentDevicePath
, RemainingDevicePath
);
661 if (DevicePath
!= NULL
) {
662 ConInSelected
= IsTerminalInConsoleVariable (L
"ConIn", DevicePath
);
663 ConOutSelected
= IsTerminalInConsoleVariable (L
"ConOut", DevicePath
);
664 FreePool (DevicePath
);
669 // Not create the child terminal handle if both Simple In/In Ex and
670 // Simple text Out protocols are not required to be published
672 if ((!ConInSelected
)&&(!ConOutSelected
)&&(!NullRemaining
)) {
677 // create the child terminal handle during first entry
681 // First enther the start function
685 // Make sure a child handle does not already exist. This driver can only
686 // produce one child per serial port.
688 Status
= gBS
->OpenProtocolInformation (
690 &gEfiSerialIoProtocolGuid
,
694 if (!EFI_ERROR (Status
)) {
695 Status
= EFI_SUCCESS
;
696 for (Index
= 0; Index
< EntryCount
; Index
++) {
697 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
698 Status
= EFI_ALREADY_STARTED
;
702 FreePool (OpenInfoBuffer
);
703 if (EFI_ERROR (Status
)) {
709 // If RemainingDevicePath is NULL, use default terminal type
711 if (RemainingDevicePath
== NULL
) {
712 TerminalType
= PcdGet8 (PcdDefaultTerminalType
);
714 // Must be between PCANSITYPE (0) and TTYTERMTYPE (4)
716 ASSERT (TerminalType
<= TTYTERMTYPE
);
717 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
719 // If RemainingDevicePath isn't the End of Device Path Node,
720 // Use the RemainingDevicePath to determine the terminal type
722 Node
= (VENDOR_DEVICE_PATH
*)RemainingDevicePath
;
723 if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
724 TerminalType
= PCANSITYPE
;
725 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
726 TerminalType
= VT100TYPE
;
727 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
728 TerminalType
= VT100PLUSTYPE
;
729 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
730 TerminalType
= VTUTF8TYPE
;
731 } else if (CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
732 TerminalType
= TTYTERMTYPE
;
738 // If RemainingDevicePath is the End of Device Path Node,
739 // skip enumerate any device and return EFI_SUCESSS
745 // Initialize the Terminal Dev
747 TerminalDevice
= AllocateCopyPool (sizeof (TERMINAL_DEV
), &mTerminalDevTemplate
);
748 if (TerminalDevice
== NULL
) {
749 Status
= EFI_OUT_OF_RESOURCES
;
753 TerminalDevice
->TerminalType
= TerminalType
;
754 TerminalDevice
->SerialIo
= SerialIo
;
756 InitializeListHead (&TerminalDevice
->NotifyList
);
757 Status
= gBS
->CreateEvent (
760 TerminalConInWaitForKeyEx
,
762 &TerminalDevice
->SimpleInputEx
.WaitForKeyEx
764 if (EFI_ERROR (Status
)) {
768 Status
= gBS
->CreateEvent (
771 TerminalConInWaitForKey
,
773 &TerminalDevice
->SimpleInput
.WaitForKey
775 if (EFI_ERROR (Status
)) {
779 // Allocates and initializes the FIFO buffer to be zero, used for accommodating
780 // the pre-read pending characters.
782 TerminalDevice
->RawFiFo
= AllocateZeroPool (sizeof (RAW_DATA_FIFO
));
783 if (TerminalDevice
->RawFiFo
== NULL
) {
786 TerminalDevice
->UnicodeFiFo
= AllocateZeroPool (sizeof (UNICODE_FIFO
));
787 if (TerminalDevice
->UnicodeFiFo
== NULL
) {
790 TerminalDevice
->EfiKeyFiFo
= AllocateZeroPool (sizeof (EFI_KEY_FIFO
));
791 if (TerminalDevice
->EfiKeyFiFo
== NULL
) {
796 // Set the timeout value of serial buffer for
797 // keystroke response performance issue
799 Mode
= TerminalDevice
->SerialIo
->Mode
;
802 if (Mode
->BaudRate
!= 0) {
803 SerialInTimeOut
= (1 + Mode
->DataBits
+ Mode
->StopBits
) * 2 * 1000000 / (UINTN
) Mode
->BaudRate
;
806 Status
= TerminalDevice
->SerialIo
->SetAttributes (
807 TerminalDevice
->SerialIo
,
809 Mode
->ReceiveFifoDepth
,
810 (UINT32
) SerialInTimeOut
,
811 (EFI_PARITY_TYPE
) (Mode
->Parity
),
812 (UINT8
) Mode
->DataBits
,
813 (EFI_STOP_BITS_TYPE
) (Mode
->StopBits
)
815 if (EFI_ERROR (Status
)) {
817 // if set attributes operation fails, invalidate
818 // the value of SerialInTimeOut,thus make it
819 // inconsistent with the default timeout value
820 // of serial buffer. This will invoke the recalculation
821 // in the readkeystroke routine.
823 TerminalDevice
->SerialInTimeOut
= 0;
825 TerminalDevice
->SerialInTimeOut
= SerialInTimeOut
;
828 // Set Simple Text Output Protocol from template.
830 SimpleTextOutput
= CopyMem (
831 &TerminalDevice
->SimpleTextOutput
,
832 &mTerminalDevTemplate
.SimpleTextOutput
,
833 sizeof (mTerminalDevTemplate
.SimpleTextOutput
)
835 SimpleTextOutput
->Mode
= &TerminalDevice
->SimpleTextOutputMode
;
837 Status
= InitializeTerminalConsoleTextMode (&ModeCount
, &TerminalDevice
->TerminalConsoleModeData
);
838 if (EFI_ERROR (Status
)) {
841 TerminalDevice
->SimpleTextOutputMode
.MaxMode
= (INT32
) ModeCount
;
844 // For terminal devices, cursor is always visible
846 TerminalDevice
->SimpleTextOutputMode
.CursorVisible
= TRUE
;
847 Status
= TerminalConOutSetAttribute (
849 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
851 if (EFI_ERROR (Status
)) {
856 // Build the component name for the child device
858 TerminalDevice
->ControllerNameTable
= NULL
;
859 switch (TerminalDevice
->TerminalType
) {
863 gTerminalComponentName
.SupportedLanguages
,
864 &TerminalDevice
->ControllerNameTable
,
865 (CHAR16
*)L
"PC-ANSI Serial Console",
870 gTerminalComponentName2
.SupportedLanguages
,
871 &TerminalDevice
->ControllerNameTable
,
872 (CHAR16
*)L
"PC-ANSI Serial Console",
881 gTerminalComponentName
.SupportedLanguages
,
882 &TerminalDevice
->ControllerNameTable
,
883 (CHAR16
*)L
"VT-100 Serial Console",
888 gTerminalComponentName2
.SupportedLanguages
,
889 &TerminalDevice
->ControllerNameTable
,
890 (CHAR16
*)L
"VT-100 Serial Console",
899 gTerminalComponentName
.SupportedLanguages
,
900 &TerminalDevice
->ControllerNameTable
,
901 (CHAR16
*)L
"VT-100+ Serial Console",
906 gTerminalComponentName2
.SupportedLanguages
,
907 &TerminalDevice
->ControllerNameTable
,
908 (CHAR16
*)L
"VT-100+ Serial Console",
917 gTerminalComponentName
.SupportedLanguages
,
918 &TerminalDevice
->ControllerNameTable
,
919 (CHAR16
*)L
"VT-UTF8 Serial Console",
924 gTerminalComponentName2
.SupportedLanguages
,
925 &TerminalDevice
->ControllerNameTable
,
926 (CHAR16
*)L
"VT-UTF8 Serial Console",
935 gTerminalComponentName
.SupportedLanguages
,
936 &TerminalDevice
->ControllerNameTable
,
937 (CHAR16
*)L
"Tty Terminal Serial Console",
942 gTerminalComponentName2
.SupportedLanguages
,
943 &TerminalDevice
->ControllerNameTable
,
944 (CHAR16
*)L
"Tty Terminal Serial Console",
952 // Build the device path for the child device
954 Status
= SetTerminalDevicePath (
955 TerminalDevice
->TerminalType
,
957 &TerminalDevice
->DevicePath
959 if (EFI_ERROR (Status
)) {
963 Status
= TerminalConOutReset (SimpleTextOutput
, FALSE
);
964 if (EFI_ERROR (Status
)) {
968 Status
= TerminalConOutSetMode (SimpleTextOutput
, 0);
969 if (EFI_ERROR (Status
)) {
973 Status
= TerminalConOutEnableCursor (SimpleTextOutput
, TRUE
);
974 if (EFI_ERROR (Status
)) {
978 Status
= gBS
->CreateEvent (
979 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
981 TerminalConInTimerHandler
,
983 &TerminalDevice
->TimerEvent
985 ASSERT_EFI_ERROR (Status
);
987 Status
= gBS
->SetTimer (
988 TerminalDevice
->TimerEvent
,
990 KEYBOARD_TIMER_INTERVAL
992 ASSERT_EFI_ERROR (Status
);
994 Status
= gBS
->CreateEvent (
999 &TerminalDevice
->TwoSecondTimeOut
1001 ASSERT_EFI_ERROR (Status
);
1003 Status
= gBS
->InstallProtocolInterface (
1004 &TerminalDevice
->Handle
,
1005 &gEfiDevicePathProtocolGuid
,
1006 EFI_NATIVE_INTERFACE
,
1007 TerminalDevice
->DevicePath
1009 if (EFI_ERROR (Status
)) {
1014 // Register the Parent-Child relationship via
1015 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
1017 Status
= gBS
->OpenProtocol (
1019 &gEfiSerialIoProtocolGuid
,
1020 (VOID
**) &TerminalDevice
->SerialIo
,
1021 This
->DriverBindingHandle
,
1022 TerminalDevice
->Handle
,
1023 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1025 if (EFI_ERROR (Status
)) {
1031 // Find the child handle, and get its TerminalDevice private data
1033 Status
= gBS
->OpenProtocolInformation (
1035 &gEfiSerialIoProtocolGuid
,
1039 if (!EFI_ERROR (Status
)) {
1040 Status
= EFI_NOT_FOUND
;
1041 ASSERT (OpenInfoBuffer
!= NULL
);
1042 for (Index
= 0; Index
< EntryCount
; Index
++) {
1043 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
1045 // Find the child terminal handle.
1046 // Test whether the SimpleTxtIn and SimpleTxtOut have been published
1048 Status
= gBS
->OpenProtocol (
1049 OpenInfoBuffer
[Index
].ControllerHandle
,
1050 &gEfiSimpleTextInProtocolGuid
,
1051 (VOID
**) &SimpleTextInput
,
1052 This
->DriverBindingHandle
,
1053 OpenInfoBuffer
[Index
].ControllerHandle
,
1054 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1056 if (!EFI_ERROR (Status
)) {
1057 SimTxtInInstalled
= TRUE
;
1058 TerminalDevice
= TERMINAL_CON_IN_DEV_FROM_THIS (SimpleTextInput
);
1061 Status
= gBS
->OpenProtocol (
1062 OpenInfoBuffer
[Index
].ControllerHandle
,
1063 &gEfiSimpleTextOutProtocolGuid
,
1064 (VOID
**) &SimpleTextOutput
,
1065 This
->DriverBindingHandle
,
1066 OpenInfoBuffer
[Index
].ControllerHandle
,
1067 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1069 if (!EFI_ERROR (Status
)) {
1070 SimTxtOutInstalled
= TRUE
;
1071 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1073 Status
= EFI_SUCCESS
;
1078 FreePool (OpenInfoBuffer
);
1079 if (EFI_ERROR (Status
)) {
1086 ASSERT (TerminalDevice
!= NULL
);
1088 // Only do the reset if the device path is in the Conout variable
1090 if (ConInSelected
&& !SimTxtInInstalled
) {
1091 Status
= TerminalDevice
->SimpleInput
.Reset (
1092 &TerminalDevice
->SimpleInput
,
1095 if (EFI_ERROR (Status
)) {
1097 // Need to report Error Code first
1104 // Only output the configure string to remote terminal if the device path
1105 // is in the Conout variable
1107 if (ConOutSelected
&& !SimTxtOutInstalled
) {
1108 Status
= TerminalDevice
->SimpleTextOutput
.SetAttribute (
1109 &TerminalDevice
->SimpleTextOutput
,
1110 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
1112 if (EFI_ERROR (Status
)) {
1116 Status
= TerminalDevice
->SimpleTextOutput
.Reset (
1117 &TerminalDevice
->SimpleTextOutput
,
1120 if (EFI_ERROR (Status
)) {
1124 Status
= TerminalDevice
->SimpleTextOutput
.SetMode (
1125 &TerminalDevice
->SimpleTextOutput
,
1128 if (EFI_ERROR (Status
)) {
1132 Status
= TerminalDevice
->SimpleTextOutput
.EnableCursor (
1133 &TerminalDevice
->SimpleTextOutput
,
1136 if (EFI_ERROR (Status
)) {
1142 // Simple In/Out Protocol will not be installed onto the handle if the
1143 // device path to the handle is not present in the ConIn/ConOut
1144 // environment variable. But If RemainingDevicePath is NULL, then always
1145 // produce both Simple In and Simple Text Output Protocols. This is required
1146 // for the connect all sequences to make sure all possible consoles are
1147 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
1149 if (!SimTxtInInstalled
&& (ConInSelected
|| NullRemaining
)) {
1150 Status
= gBS
->InstallMultipleProtocolInterfaces (
1151 &TerminalDevice
->Handle
,
1152 &gEfiSimpleTextInProtocolGuid
,
1153 &TerminalDevice
->SimpleInput
,
1154 &gEfiSimpleTextInputExProtocolGuid
,
1155 &TerminalDevice
->SimpleInputEx
,
1158 if (EFI_ERROR (Status
)) {
1163 if (!SimTxtOutInstalled
&& (ConOutSelected
|| NullRemaining
)) {
1164 Status
= gBS
->InstallProtocolInterface (
1165 &TerminalDevice
->Handle
,
1166 &gEfiSimpleTextOutProtocolGuid
,
1167 EFI_NATIVE_INTERFACE
,
1168 &TerminalDevice
->SimpleTextOutput
1170 if (EFI_ERROR (Status
)) {
1179 // Report error code before exiting
1181 DevicePath
= ParentDevicePath
;
1182 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1183 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1184 (EFI_PERIPHERAL_REMOTE_CONSOLE
| EFI_P_EC_CONTROLLER_ERROR
),
1190 // Use the Stop() function to free all resources allocated in Start()
1192 if (TerminalDevice
!= NULL
) {
1194 if (TerminalDevice
->Handle
!= NULL
) {
1195 This
->Stop (This
, Controller
, 1, &TerminalDevice
->Handle
);
1198 if (TerminalDevice
->TwoSecondTimeOut
!= NULL
) {
1199 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1202 if (TerminalDevice
->TimerEvent
!= NULL
) {
1203 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1206 if (TerminalDevice
->SimpleInput
.WaitForKey
!= NULL
) {
1207 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1210 if (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
!= NULL
) {
1211 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1214 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1216 if (TerminalDevice
->RawFiFo
!= NULL
) {
1217 FreePool (TerminalDevice
->RawFiFo
);
1219 if (TerminalDevice
->UnicodeFiFo
!= NULL
) {
1220 FreePool (TerminalDevice
->UnicodeFiFo
);
1222 if (TerminalDevice
->EfiKeyFiFo
!= NULL
) {
1223 FreePool (TerminalDevice
->EfiKeyFiFo
);
1226 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1227 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1230 if (TerminalDevice
->DevicePath
!= NULL
) {
1231 FreePool (TerminalDevice
->DevicePath
);
1234 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1235 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1238 FreePool (TerminalDevice
);
1242 This
->Stop (This
, Controller
, 0, NULL
);
1248 Stop this driver on Controller by closing Simple Text In, Simple Text
1249 In Ex, Simple Text Out protocol, and removing parent device path from
1250 Console Device Environment Variables.
1252 @param This Protocol instance pointer.
1253 @param Controller Handle of device to stop driver on
1254 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1255 children is zero stop the entire bus driver.
1256 @param ChildHandleBuffer List of Child Handles to Stop.
1258 @retval EFI_SUCCESS This driver is removed Controller.
1259 @retval other This driver could not be removed from this device.
1264 TerminalDriverBindingStop (
1265 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1266 IN EFI_HANDLE Controller
,
1267 IN UINTN NumberOfChildren
,
1268 IN EFI_HANDLE
*ChildHandleBuffer
1273 BOOLEAN AllChildrenStopped
;
1274 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
1275 TERMINAL_DEV
*TerminalDevice
;
1276 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1277 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
1278 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1280 Status
= gBS
->HandleProtocol (
1282 &gEfiDevicePathProtocolGuid
,
1283 (VOID
**) &DevicePath
1285 if (EFI_ERROR (Status
)) {
1290 // Complete all outstanding transactions to Controller.
1291 // Don't allow any new transaction to Controller to be started.
1293 if (NumberOfChildren
== 0) {
1295 // Close the bus driver
1297 Status
= gBS
->OpenProtocol (
1300 (VOID
**) &ParentDevicePath
,
1301 This
->DriverBindingHandle
,
1303 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1305 if (!EFI_ERROR (Status
)) {
1307 // Remove Parent Device Path from
1308 // the Console Device Environment Variables
1310 TerminalRemoveConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
1311 TerminalRemoveConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
1312 TerminalRemoveConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
1315 // Uninstall the Terminal Driver's GUID Tag from the Serial controller
1317 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1325 // Free the ParentDevicePath that was duplicated in Start()
1327 if (!EFI_ERROR (Status
)) {
1328 FreePool (ParentDevicePath
);
1332 gBS
->CloseProtocol (
1334 &gEfiSerialIoProtocolGuid
,
1335 This
->DriverBindingHandle
,
1339 gBS
->CloseProtocol (
1341 &gEfiDevicePathProtocolGuid
,
1342 This
->DriverBindingHandle
,
1349 AllChildrenStopped
= TRUE
;
1351 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
1353 Status
= gBS
->OpenProtocol (
1354 ChildHandleBuffer
[Index
],
1355 &gEfiSimpleTextOutProtocolGuid
,
1356 (VOID
**) &SimpleTextOutput
,
1357 This
->DriverBindingHandle
,
1358 ChildHandleBuffer
[Index
],
1359 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1361 if (!EFI_ERROR (Status
)) {
1363 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1365 gBS
->CloseProtocol (
1367 &gEfiSerialIoProtocolGuid
,
1368 This
->DriverBindingHandle
,
1369 ChildHandleBuffer
[Index
]
1372 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1373 ChildHandleBuffer
[Index
],
1374 &gEfiSimpleTextInProtocolGuid
,
1375 &TerminalDevice
->SimpleInput
,
1376 &gEfiSimpleTextInputExProtocolGuid
,
1377 &TerminalDevice
->SimpleInputEx
,
1378 &gEfiSimpleTextOutProtocolGuid
,
1379 &TerminalDevice
->SimpleTextOutput
,
1380 &gEfiDevicePathProtocolGuid
,
1381 TerminalDevice
->DevicePath
,
1384 if (EFI_ERROR (Status
)) {
1387 &gEfiSerialIoProtocolGuid
,
1388 (VOID
**) &SerialIo
,
1389 This
->DriverBindingHandle
,
1390 ChildHandleBuffer
[Index
],
1391 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1395 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1396 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1399 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1400 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1401 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1402 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1403 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1404 FreePool (TerminalDevice
->DevicePath
);
1405 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1406 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1408 FreePool (TerminalDevice
);
1412 if (EFI_ERROR (Status
)) {
1413 AllChildrenStopped
= FALSE
;
1417 if (!AllChildrenStopped
) {
1418 return EFI_DEVICE_ERROR
;
1425 Update terminal device path in Console Device Environment Variables.
1427 @param VariableName The Console Device Environment Variable.
1428 @param ParentDevicePath The terminal device path to be updated.
1432 TerminalUpdateConsoleDevVariable (
1433 IN CHAR16
*VariableName
,
1434 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1441 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1442 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1443 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1444 EDKII_SET_VARIABLE_STATUS
*SetVariableStatus
;
1447 // Get global variable and its size according to the name given.
1449 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
1450 if (Variable
== NULL
) {
1455 // Append terminal device path onto the variable.
1457 for (TerminalType
= PCANSITYPE
; TerminalType
<= TTYTERMTYPE
; TerminalType
++) {
1458 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1459 NewVariable
= AppendDevicePathInstance (Variable
, TempDevicePath
);
1460 ASSERT (NewVariable
!= NULL
);
1461 if (Variable
!= NULL
) {
1462 FreePool (Variable
);
1465 if (TempDevicePath
!= NULL
) {
1466 FreePool (TempDevicePath
);
1469 Variable
= NewVariable
;
1472 VariableSize
= GetDevicePathSize (Variable
);
1474 Status
= gRT
->SetVariable (
1476 &gEfiGlobalVariableGuid
,
1477 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1482 if (EFI_ERROR (Status
)) {
1483 NameSize
= StrSize (VariableName
);
1484 SetVariableStatus
= AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS
) + NameSize
+ VariableSize
);
1485 if (SetVariableStatus
!= NULL
) {
1486 CopyGuid (&SetVariableStatus
->Guid
, &gEfiGlobalVariableGuid
);
1487 SetVariableStatus
->NameSize
= NameSize
;
1488 SetVariableStatus
->DataSize
= VariableSize
;
1489 SetVariableStatus
->SetStatus
= Status
;
1490 SetVariableStatus
->Attributes
= EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
;
1491 CopyMem (SetVariableStatus
+ 1, VariableName
, NameSize
);
1492 CopyMem (((UINT8
*) (SetVariableStatus
+ 1)) + NameSize
, Variable
, VariableSize
);
1494 REPORT_STATUS_CODE_EX (
1496 PcdGet32 (PcdErrorCodeSetVariable
),
1499 &gEdkiiStatusCodeDataTypeVariableGuid
,
1501 sizeof (EDKII_SET_VARIABLE_STATUS
) + NameSize
+ VariableSize
1504 FreePool (SetVariableStatus
);
1508 FreePool (Variable
);
1515 Remove terminal device path from Console Device Environment Variables.
1517 @param VariableName Console Device Environment Variables.
1518 @param ParentDevicePath The terminal device path to be updated.
1522 TerminalRemoveConsoleDevVariable (
1523 IN CHAR16
*VariableName
,
1524 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1533 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
1534 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1535 EFI_DEVICE_PATH_PROTOCOL
*OriginalVariable
;
1536 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1537 EFI_DEVICE_PATH_PROTOCOL
*SavedNewVariable
;
1538 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1543 // Get global variable and its size according to the name given.
1545 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
1546 if (Variable
== NULL
) {
1551 OriginalVariable
= Variable
;
1555 // Get first device path instance from Variable
1557 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1558 if (Instance
== NULL
) {
1559 FreePool (OriginalVariable
);
1563 // Loop through all the device path instances of Variable
1567 // Loop through all the terminal types that this driver supports
1570 for (TerminalType
= PCANSITYPE
; TerminalType
<= TTYTERMTYPE
; TerminalType
++) {
1572 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1575 // Compare the generated device path to the current device path instance
1577 if (TempDevicePath
!= NULL
) {
1578 if (CompareMem (Instance
, TempDevicePath
, InstanceSize
) == 0) {
1583 FreePool (TempDevicePath
);
1587 // If a match was not found, then keep the current device path instance
1590 SavedNewVariable
= NewVariable
;
1591 NewVariable
= AppendDevicePathInstance (NewVariable
, Instance
);
1592 if (SavedNewVariable
!= NULL
) {
1593 FreePool (SavedNewVariable
);
1597 // Get next device path instance from Variable
1599 FreePool (Instance
);
1600 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1601 } while (Instance
!= NULL
);
1603 FreePool (OriginalVariable
);
1606 VariableSize
= GetDevicePathSize (NewVariable
);
1608 Status
= gRT
->SetVariable (
1610 &gEfiGlobalVariableGuid
,
1611 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1616 // Shrinking variable with existing variable driver implementation shouldn't fail.
1618 ASSERT_EFI_ERROR (Status
);
1621 if (NewVariable
!= NULL
) {
1622 FreePool (NewVariable
);
1629 Build terminal device path according to terminal type.
1631 @param TerminalType The terminal type is PC ANSI, VT100, VT100+ or VT-UTF8.
1632 @param ParentDevicePath Parent device path.
1633 @param TerminalDevicePath Returned terminal device path, if building successfully.
1635 @retval EFI_UNSUPPORTED Terminal does not belong to the supported type.
1636 @retval EFI_OUT_OF_RESOURCES Generate terminal device path failed.
1637 @retval EFI_SUCCESS Build terminal device path successfully.
1641 SetTerminalDevicePath (
1642 IN UINT8 TerminalType
,
1643 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
1644 OUT EFI_DEVICE_PATH_PROTOCOL
**TerminalDevicePath
1647 VENDOR_DEVICE_PATH Node
;
1649 *TerminalDevicePath
= NULL
;
1650 Node
.Header
.Type
= MESSAGING_DEVICE_PATH
;
1651 Node
.Header
.SubType
= MSG_VENDOR_DP
;
1654 // Generate terminal device path node according to terminal type.
1656 switch (TerminalType
) {
1659 CopyGuid (&Node
.Guid
, &gEfiPcAnsiGuid
);
1663 CopyGuid (&Node
.Guid
, &gEfiVT100Guid
);
1667 CopyGuid (&Node
.Guid
, &gEfiVT100PlusGuid
);
1671 CopyGuid (&Node
.Guid
, &gEfiVTUTF8Guid
);
1675 CopyGuid (&Node
.Guid
, &gEfiTtyTermGuid
);
1679 return EFI_UNSUPPORTED
;
1683 // Get VENDOR_DEVCIE_PATH size and put into Node.Header
1685 SetDevicePathNodeLength (
1687 sizeof (VENDOR_DEVICE_PATH
)
1691 // Append the terminal node onto parent device path
1692 // to generate a complete terminal device path.
1694 *TerminalDevicePath
= AppendDevicePathNode (
1696 (EFI_DEVICE_PATH_PROTOCOL
*) &Node
1698 if (*TerminalDevicePath
== NULL
) {
1699 return EFI_OUT_OF_RESOURCES
;
1706 The user Entry Point for module Terminal. The user code starts with this function.
1708 @param ImageHandle The firmware allocated handle for the EFI image.
1709 @param SystemTable A pointer to the EFI System Table.
1711 @retval EFI_SUCCESS The entry point is executed successfully.
1712 @retval other Some error occurs when executing this entry point.
1718 IN EFI_HANDLE ImageHandle
,
1719 IN EFI_SYSTEM_TABLE
*SystemTable
1725 // Install driver model protocol(s).
1727 Status
= EfiLibInstallDriverBindingComponentName2 (
1730 &gTerminalDriverBinding
,
1732 &gTerminalComponentName
,
1733 &gTerminalComponentName2
1735 ASSERT_EFI_ERROR (Status
);
1741 Check if the device supports hot-plug through its device path.
1743 This function could be updated to check more types of Hot Plug devices.
1744 Currently, it checks USB and PCCard device.
1746 @param DevicePath Pointer to device's device path.
1748 @retval TRUE The devcie is a hot-plug device
1749 @retval FALSE The devcie is not a hot-plug device.
1754 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
1757 EFI_DEVICE_PATH_PROTOCOL
*CheckDevicePath
;
1759 CheckDevicePath
= DevicePath
;
1760 while (!IsDevicePathEnd (CheckDevicePath
)) {
1762 // Check device whether is hot plug device or not throught Device Path
1764 if ((DevicePathType (CheckDevicePath
) == MESSAGING_DEVICE_PATH
) &&
1765 (DevicePathSubType (CheckDevicePath
) == MSG_USB_DP
||
1766 DevicePathSubType (CheckDevicePath
) == MSG_USB_CLASS_DP
||
1767 DevicePathSubType (CheckDevicePath
) == MSG_USB_WWID_DP
)) {
1769 // If Device is USB device
1773 if ((DevicePathType (CheckDevicePath
) == HARDWARE_DEVICE_PATH
) &&
1774 (DevicePathSubType (CheckDevicePath
) == HW_PCCARD_DP
)) {
1776 // If Device is PCCard
1781 CheckDevicePath
= NextDevicePathNode (CheckDevicePath
);