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
;
261 TerminalType
= PCANSITYPE
;
264 // Use the RemainingDevicePath to determine the terminal type
266 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
268 TerminalType
= PCANSITYPE
;
270 } else if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
272 TerminalType
= PCANSITYPE
;
274 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
276 TerminalType
= VT100TYPE
;
278 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
280 TerminalType
= VT100PLUSTYPE
;
282 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
284 TerminalType
= VTUTF8TYPE
;
286 } else if (CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
288 TerminalType
= TTYTERMTYPE
;
295 // Build the device path for the child device
297 Status
= SetTerminalDevicePath (
302 if (EFI_ERROR (Status
)) {
305 return TerminalDevicePath
;
309 Compare a device path data structure to that of all the nodes of a
310 second device path instance.
312 @param Multi A pointer to a multi-instance device path data structure.
313 @param Single A pointer to a single-instance device path data structure.
315 @retval TRUE If the Single is contained within Multi.
316 @retval FALSE The Single is not match within Multi.
321 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
322 IN EFI_DEVICE_PATH_PROTOCOL
*Single
325 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
326 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
330 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
332 // Search for the match of 'Single' in 'Multi'
334 while (DevicePathInst
!= NULL
) {
336 // If the single device path is found in multiple device paths,
339 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
340 FreePool (DevicePathInst
);
344 FreePool (DevicePathInst
);
345 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
352 Check whether the terminal device path is in the global variable.
354 @param VariableName Pointer to one global variable.
355 @param TerminalDevicePath Pointer to the terminal device's device path.
357 @retval TRUE The devcie is in the global variable.
358 @retval FALSE The devcie is not in the global variable.
362 IsTerminalInConsoleVariable (
363 IN CHAR16
*VariableName
,
364 IN EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
367 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
371 // Get global variable and its size according to the name given.
373 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
374 if (Variable
== NULL
) {
379 // Check whether the terminal device path is one of the variable instances.
381 ReturnFlag
= MatchDevicePaths (Variable
, TerminalDevicePath
);
389 Free notify functions list.
391 @param ListHead The list head
393 @retval EFI_SUCCESS Free the notify list successfully.
394 @retval EFI_INVALID_PARAMETER ListHead is NULL.
398 TerminalFreeNotifyList (
399 IN OUT LIST_ENTRY
*ListHead
402 TERMINAL_CONSOLE_IN_EX_NOTIFY
*NotifyNode
;
404 if (ListHead
== NULL
) {
405 return EFI_INVALID_PARAMETER
;
407 while (!IsListEmpty (ListHead
)) {
409 ListHead
->ForwardLink
,
410 TERMINAL_CONSOLE_IN_EX_NOTIFY
,
412 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
414 RemoveEntryList (ListHead
->ForwardLink
);
415 FreePool (NotifyNode
);
422 Initialize all the text modes which the terminal console supports.
424 It returns information for available text modes that the terminal can support.
426 @param[out] TextModeCount The total number of text modes that terminal console supports.
427 @param[out] TextModeData The buffer to the text modes column and row information.
428 Caller is responsible to free it when it's non-NULL.
430 @retval EFI_SUCCESS The supporting mode information is returned.
431 @retval EFI_INVALID_PARAMETER The parameters are invalid.
435 InitializeTerminalConsoleTextMode (
436 OUT UINTN
*TextModeCount
,
437 OUT TERMINAL_CONSOLE_MODE_DATA
**TextModeData
442 TERMINAL_CONSOLE_MODE_DATA
*ModeBuffer
;
443 TERMINAL_CONSOLE_MODE_DATA
*NewModeBuffer
;
447 if ((TextModeCount
== NULL
) || (TextModeData
== NULL
)) {
448 return EFI_INVALID_PARAMETER
;
451 Count
= sizeof (mTerminalConsoleModeData
) / sizeof (TERMINAL_CONSOLE_MODE_DATA
);
454 // Get defined mode buffer pointer.
456 ModeBuffer
= mTerminalConsoleModeData
;
459 // Here we make sure that the final mode exposed does not include the duplicated modes,
460 // and does not include the invalid modes which exceed the max column and row.
461 // Reserve 2 modes for 80x25, 80x50 of terminal console.
463 NewModeBuffer
= AllocateZeroPool (sizeof (TERMINAL_CONSOLE_MODE_DATA
) * (Count
+ 2));
464 ASSERT (NewModeBuffer
!= NULL
);
467 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
471 NewModeBuffer
[ValidCount
].Columns
= 80;
472 NewModeBuffer
[ValidCount
].Rows
= 25;
475 NewModeBuffer
[ValidCount
].Columns
= 80;
476 NewModeBuffer
[ValidCount
].Rows
= 50;
480 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
482 for (Index
= 0; Index
< Count
; Index
++) {
483 if ((ModeBuffer
[Index
].Columns
== 0) || (ModeBuffer
[Index
].Rows
== 0)) {
485 // Skip the pre-defined mode which is invalid.
489 for (ValidIndex
= 0; ValidIndex
< ValidCount
; ValidIndex
++) {
490 if ((ModeBuffer
[Index
].Columns
== NewModeBuffer
[ValidIndex
].Columns
) &&
491 (ModeBuffer
[Index
].Rows
== NewModeBuffer
[ValidIndex
].Rows
)) {
493 // Skip the duplicated mode.
498 if (ValidIndex
== ValidCount
) {
499 NewModeBuffer
[ValidCount
].Columns
= ModeBuffer
[Index
].Columns
;
500 NewModeBuffer
[ValidCount
].Rows
= ModeBuffer
[Index
].Rows
;
506 for (Index
= 0; Index
< ValidCount
; Index
++) {
507 DEBUG ((EFI_D_INFO
, "Terminal - Mode %d, Column = %d, Row = %d\n",
508 Index
, NewModeBuffer
[Index
].Columns
, NewModeBuffer
[Index
].Rows
));
513 // Return valid mode count and mode information buffer.
515 *TextModeCount
= ValidCount
;
516 *TextModeData
= NewModeBuffer
;
521 Start this driver on Controller by opening a Serial IO protocol,
522 reading Device Path, and creating a child handle with a Simple Text In,
523 Simple Text In Ex and Simple Text Out protocol, and device path protocol.
524 And store Console Device Environment Variables.
526 @param This Protocol instance pointer.
527 @param Controller Handle of device to bind driver to
528 @param RemainingDevicePath Optional parameter use to pick a specific child
531 @retval EFI_SUCCESS This driver is added to Controller.
532 @retval EFI_ALREADY_STARTED This driver is already running on Controller.
533 @retval other This driver does not support this device.
538 TerminalDriverBindingStart (
539 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
540 IN EFI_HANDLE Controller
,
541 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
545 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
546 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
547 VENDOR_DEVICE_PATH
*Node
;
548 VENDOR_DEVICE_PATH
*DefaultNode
;
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
;
569 ConInSelected
= FALSE
;
570 ConOutSelected
= FALSE
;
571 NullRemaining
= TRUE
;
572 SimTxtInInstalled
= FALSE
;
573 SimTxtOutInstalled
= FALSE
;
576 // Get the Device Path Protocol to build the device path of the child device
578 Status
= gBS
->OpenProtocol (
580 &gEfiDevicePathProtocolGuid
,
581 (VOID
**) &ParentDevicePath
,
582 This
->DriverBindingHandle
,
584 EFI_OPEN_PROTOCOL_BY_DRIVER
586 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
591 // Open the Serial I/O Protocol BY_DRIVER. It might already be started.
593 Status
= gBS
->OpenProtocol (
595 &gEfiSerialIoProtocolGuid
,
597 This
->DriverBindingHandle
,
599 EFI_OPEN_PROTOCOL_BY_DRIVER
601 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
605 if (Status
!= EFI_ALREADY_STARTED
) {
607 // the serial I/O protocol never be opened before, it is the first
608 // time to start the serial Io controller
614 // Serial I/O is not already open by this driver, then tag the handle
615 // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and
616 // StdErrDev variables with the list of possible terminal types on this
619 Status
= gBS
->OpenProtocol (
623 This
->DriverBindingHandle
,
625 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
627 if (EFI_ERROR (Status
)) {
628 Status
= gBS
->InstallMultipleProtocolInterfaces (
631 DuplicateDevicePath (ParentDevicePath
),
634 if (EFI_ERROR (Status
)) {
638 if (!IsHotPlugDevice (ParentDevicePath
)) {
640 // if the serial device is a hot plug device, do not update the
641 // ConInDev, ConOutDev, and StdErrDev variables.
643 TerminalUpdateConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
644 TerminalUpdateConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
645 TerminalUpdateConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
650 // Check the requirement for the SimpleTxtIn and SimpleTxtOut protocols
652 // Simple In/Out Protocol will not be installed onto the handle if the
653 // device path to the handle is not present in the ConIn/ConOut
654 // environment variable. But If RemainingDevicePath is NULL, then always
655 // produce both Simple In and Simple Text Output Protocols. This is required
656 // for the connect all sequences to make sure all possible consoles are
657 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
659 if (RemainingDevicePath
== NULL
) {
660 NullRemaining
= TRUE
;
663 DevicePath
= BuildTerminalDevpath (ParentDevicePath
, RemainingDevicePath
);
664 if (DevicePath
!= NULL
) {
665 ConInSelected
= IsTerminalInConsoleVariable (L
"ConIn", DevicePath
);
666 ConOutSelected
= IsTerminalInConsoleVariable (L
"ConOut", DevicePath
);
667 FreePool (DevicePath
);
672 // Not create the child terminal handle if both Simple In/In Ex and
673 // Simple text Out protocols are not required to be published
675 if ((!ConInSelected
)&&(!ConOutSelected
)&&(!NullRemaining
)) {
680 // create the child terminal handle during first entry
684 // First enther the start funciton
688 // Make sure a child handle does not already exist. This driver can only
689 // produce one child per serial port.
691 Status
= gBS
->OpenProtocolInformation (
693 &gEfiSerialIoProtocolGuid
,
697 if (!EFI_ERROR (Status
)) {
698 Status
= EFI_SUCCESS
;
699 for (Index
= 0; Index
< EntryCount
; Index
++) {
700 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
701 Status
= EFI_ALREADY_STARTED
;
705 FreePool (OpenInfoBuffer
);
706 if (EFI_ERROR (Status
)) {
712 // If RemainingDevicePath is NULL, then create default device path node
714 if (RemainingDevicePath
== NULL
) {
715 DefaultNode
= AllocateZeroPool (sizeof (VENDOR_DEVICE_PATH
));
716 if (DefaultNode
== NULL
) {
717 Status
= EFI_OUT_OF_RESOURCES
;
721 TerminalType
= PcdGet8 (PcdDefaultTerminalType
);
723 // Must be between PCANSITYPE (0) and TTYTERMTYPE (4)
725 ASSERT (TerminalType
<= TTYTERMTYPE
);
727 CopyMem (&DefaultNode
->Guid
, gTerminalType
[TerminalType
], sizeof (EFI_GUID
));
728 RemainingDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) DefaultNode
;
729 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
731 // If RemainingDevicePath isn't the End of Device Path Node,
732 // Use the RemainingDevicePath to determine the terminal type
734 Node
= (VENDOR_DEVICE_PATH
*)RemainingDevicePath
;
735 if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
736 TerminalType
= PCANSITYPE
;
737 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
738 TerminalType
= VT100TYPE
;
739 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
740 TerminalType
= VT100PLUSTYPE
;
741 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
742 TerminalType
= VTUTF8TYPE
;
743 } else if (CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
744 TerminalType
= TTYTERMTYPE
;
750 // If RemainingDevicePath is the End of Device Path Node,
751 // skip enumerate any device and return EFI_SUCESSS
757 // Initialize the Terminal Dev
759 TerminalDevice
= AllocateCopyPool (sizeof (TERMINAL_DEV
), &mTerminalDevTemplate
);
760 if (TerminalDevice
== NULL
) {
761 Status
= EFI_OUT_OF_RESOURCES
;
765 TerminalDevice
->TerminalType
= TerminalType
;
766 TerminalDevice
->SerialIo
= SerialIo
;
768 InitializeListHead (&TerminalDevice
->NotifyList
);
769 Status
= gBS
->CreateEvent (
772 TerminalConInWaitForKeyEx
,
774 &TerminalDevice
->SimpleInputEx
.WaitForKeyEx
776 if (EFI_ERROR (Status
)) {
780 Status
= gBS
->CreateEvent (
783 TerminalConInWaitForKey
,
785 &TerminalDevice
->SimpleInput
.WaitForKey
787 if (EFI_ERROR (Status
)) {
791 // Allocates and initializes the FIFO buffer to be zero, used for accommodating
792 // the pre-read pending characters.
794 TerminalDevice
->RawFiFo
= AllocateZeroPool (sizeof (RAW_DATA_FIFO
));
795 if (TerminalDevice
->RawFiFo
== NULL
) {
798 TerminalDevice
->UnicodeFiFo
= AllocateZeroPool (sizeof (UNICODE_FIFO
));
799 if (TerminalDevice
->UnicodeFiFo
== NULL
) {
802 TerminalDevice
->EfiKeyFiFo
= AllocateZeroPool (sizeof (EFI_KEY_FIFO
));
803 if (TerminalDevice
->EfiKeyFiFo
== NULL
) {
808 // Set the timeout value of serial buffer for
809 // keystroke response performance issue
811 Mode
= TerminalDevice
->SerialIo
->Mode
;
814 if (Mode
->BaudRate
!= 0) {
815 SerialInTimeOut
= (1 + Mode
->DataBits
+ Mode
->StopBits
) * 2 * 1000000 / (UINTN
) Mode
->BaudRate
;
818 Status
= TerminalDevice
->SerialIo
->SetAttributes (
819 TerminalDevice
->SerialIo
,
821 Mode
->ReceiveFifoDepth
,
822 (UINT32
) SerialInTimeOut
,
823 (EFI_PARITY_TYPE
) (Mode
->Parity
),
824 (UINT8
) Mode
->DataBits
,
825 (EFI_STOP_BITS_TYPE
) (Mode
->StopBits
)
827 if (EFI_ERROR (Status
)) {
829 // if set attributes operation fails, invalidate
830 // the value of SerialInTimeOut,thus make it
831 // inconsistent with the default timeout value
832 // of serial buffer. This will invoke the recalculation
833 // in the readkeystroke routine.
835 TerminalDevice
->SerialInTimeOut
= 0;
837 TerminalDevice
->SerialInTimeOut
= SerialInTimeOut
;
840 // Set Simple Text Output Protocol from template.
842 SimpleTextOutput
= CopyMem (
843 &TerminalDevice
->SimpleTextOutput
,
844 &mTerminalDevTemplate
.SimpleTextOutput
,
845 sizeof (mTerminalDevTemplate
.SimpleTextOutput
)
847 SimpleTextOutput
->Mode
= &TerminalDevice
->SimpleTextOutputMode
;
849 Status
= InitializeTerminalConsoleTextMode (&ModeCount
, &TerminalDevice
->TerminalConsoleModeData
);
850 if (EFI_ERROR (Status
)) {
853 TerminalDevice
->SimpleTextOutputMode
.MaxMode
= (INT32
) ModeCount
;
856 // For terminal devices, cursor is always visible
858 TerminalDevice
->SimpleTextOutputMode
.CursorVisible
= TRUE
;
859 Status
= TerminalConOutSetAttribute (
861 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
863 if (EFI_ERROR (Status
)) {
868 // Build the component name for the child device
870 TerminalDevice
->ControllerNameTable
= NULL
;
871 switch (TerminalDevice
->TerminalType
) {
875 gTerminalComponentName
.SupportedLanguages
,
876 &TerminalDevice
->ControllerNameTable
,
877 (CHAR16
*)L
"PC-ANSI Serial Console",
882 gTerminalComponentName2
.SupportedLanguages
,
883 &TerminalDevice
->ControllerNameTable
,
884 (CHAR16
*)L
"PC-ANSI Serial Console",
893 gTerminalComponentName
.SupportedLanguages
,
894 &TerminalDevice
->ControllerNameTable
,
895 (CHAR16
*)L
"VT-100 Serial Console",
900 gTerminalComponentName2
.SupportedLanguages
,
901 &TerminalDevice
->ControllerNameTable
,
902 (CHAR16
*)L
"VT-100 Serial Console",
911 gTerminalComponentName
.SupportedLanguages
,
912 &TerminalDevice
->ControllerNameTable
,
913 (CHAR16
*)L
"VT-100+ Serial Console",
918 gTerminalComponentName2
.SupportedLanguages
,
919 &TerminalDevice
->ControllerNameTable
,
920 (CHAR16
*)L
"VT-100+ Serial Console",
929 gTerminalComponentName
.SupportedLanguages
,
930 &TerminalDevice
->ControllerNameTable
,
931 (CHAR16
*)L
"VT-UTF8 Serial Console",
936 gTerminalComponentName2
.SupportedLanguages
,
937 &TerminalDevice
->ControllerNameTable
,
938 (CHAR16
*)L
"VT-UTF8 Serial Console",
947 gTerminalComponentName
.SupportedLanguages
,
948 &TerminalDevice
->ControllerNameTable
,
949 (CHAR16
*)L
"Tty Terminal Serial Console",
954 gTerminalComponentName2
.SupportedLanguages
,
955 &TerminalDevice
->ControllerNameTable
,
956 (CHAR16
*)L
"Tty Terminal Serial Console",
964 // Build the device path for the child device
966 Status
= SetTerminalDevicePath (
967 TerminalDevice
->TerminalType
,
969 &TerminalDevice
->DevicePath
971 if (EFI_ERROR (Status
)) {
975 Status
= TerminalConOutReset (SimpleTextOutput
, FALSE
);
976 if (EFI_ERROR (Status
)) {
980 Status
= TerminalConOutSetMode (SimpleTextOutput
, 0);
981 if (EFI_ERROR (Status
)) {
985 Status
= TerminalConOutEnableCursor (SimpleTextOutput
, TRUE
);
986 if (EFI_ERROR (Status
)) {
990 Status
= gBS
->CreateEvent (
991 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
993 TerminalConInTimerHandler
,
995 &TerminalDevice
->TimerEvent
997 ASSERT_EFI_ERROR (Status
);
999 Status
= gBS
->SetTimer (
1000 TerminalDevice
->TimerEvent
,
1002 KEYBOARD_TIMER_INTERVAL
1004 ASSERT_EFI_ERROR (Status
);
1006 Status
= gBS
->CreateEvent (
1011 &TerminalDevice
->TwoSecondTimeOut
1013 ASSERT_EFI_ERROR (Status
);
1015 Status
= gBS
->InstallProtocolInterface (
1016 &TerminalDevice
->Handle
,
1017 &gEfiDevicePathProtocolGuid
,
1018 EFI_NATIVE_INTERFACE
,
1019 TerminalDevice
->DevicePath
1021 if (EFI_ERROR (Status
)) {
1026 // Register the Parent-Child relationship via
1027 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
1029 Status
= gBS
->OpenProtocol (
1031 &gEfiSerialIoProtocolGuid
,
1032 (VOID
**) &TerminalDevice
->SerialIo
,
1033 This
->DriverBindingHandle
,
1034 TerminalDevice
->Handle
,
1035 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1037 if (EFI_ERROR (Status
)) {
1043 // Find the child handle, and get its TerminalDevice private data
1045 Status
= gBS
->OpenProtocolInformation (
1047 &gEfiSerialIoProtocolGuid
,
1051 if (!EFI_ERROR (Status
)) {
1052 Status
= EFI_NOT_FOUND
;
1053 ASSERT (OpenInfoBuffer
!= NULL
);
1054 for (Index
= 0; Index
< EntryCount
; Index
++) {
1055 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
1057 // Find the child terminal handle.
1058 // Test whether the SimpleTxtIn and SimpleTxtOut have been published
1060 Status
= gBS
->OpenProtocol (
1061 OpenInfoBuffer
[Index
].ControllerHandle
,
1062 &gEfiSimpleTextInProtocolGuid
,
1063 (VOID
**) &SimpleTextInput
,
1064 This
->DriverBindingHandle
,
1065 OpenInfoBuffer
[Index
].ControllerHandle
,
1066 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1068 if (!EFI_ERROR (Status
)) {
1069 SimTxtInInstalled
= TRUE
;
1070 TerminalDevice
= TERMINAL_CON_IN_DEV_FROM_THIS (SimpleTextInput
);
1073 Status
= gBS
->OpenProtocol (
1074 OpenInfoBuffer
[Index
].ControllerHandle
,
1075 &gEfiSimpleTextOutProtocolGuid
,
1076 (VOID
**) &SimpleTextOutput
,
1077 This
->DriverBindingHandle
,
1078 OpenInfoBuffer
[Index
].ControllerHandle
,
1079 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1081 if (!EFI_ERROR (Status
)) {
1082 SimTxtOutInstalled
= TRUE
;
1083 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1085 Status
= EFI_SUCCESS
;
1090 FreePool (OpenInfoBuffer
);
1091 if (EFI_ERROR (Status
)) {
1098 ASSERT (TerminalDevice
!= NULL
);
1100 // Only do the reset if the device path is in the Conout variable
1102 if (ConInSelected
&& !SimTxtInInstalled
) {
1103 Status
= TerminalDevice
->SimpleInput
.Reset (
1104 &TerminalDevice
->SimpleInput
,
1107 if (EFI_ERROR (Status
)) {
1109 // Need to report Error Code first
1116 // Only output the configure string to remote terminal if the device path
1117 // is in the Conout variable
1119 if (ConOutSelected
&& !SimTxtOutInstalled
) {
1120 Status
= TerminalDevice
->SimpleTextOutput
.SetAttribute (
1121 &TerminalDevice
->SimpleTextOutput
,
1122 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
1124 if (EFI_ERROR (Status
)) {
1128 Status
= TerminalDevice
->SimpleTextOutput
.Reset (
1129 &TerminalDevice
->SimpleTextOutput
,
1132 if (EFI_ERROR (Status
)) {
1136 Status
= TerminalDevice
->SimpleTextOutput
.SetMode (
1137 &TerminalDevice
->SimpleTextOutput
,
1140 if (EFI_ERROR (Status
)) {
1144 Status
= TerminalDevice
->SimpleTextOutput
.EnableCursor (
1145 &TerminalDevice
->SimpleTextOutput
,
1148 if (EFI_ERROR (Status
)) {
1154 // Simple In/Out Protocol will not be installed onto the handle if the
1155 // device path to the handle is not present in the ConIn/ConOut
1156 // environment variable. But If RemainingDevicePath is NULL, then always
1157 // produce both Simple In and Simple Text Output Protocols. This is required
1158 // for the connect all sequences to make sure all possible consoles are
1159 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
1161 if (!SimTxtInInstalled
&& (ConInSelected
|| NullRemaining
)) {
1162 Status
= gBS
->InstallMultipleProtocolInterfaces (
1163 &TerminalDevice
->Handle
,
1164 &gEfiSimpleTextInProtocolGuid
,
1165 &TerminalDevice
->SimpleInput
,
1166 &gEfiSimpleTextInputExProtocolGuid
,
1167 &TerminalDevice
->SimpleInputEx
,
1170 if (EFI_ERROR (Status
)) {
1175 if (!SimTxtOutInstalled
&& (ConOutSelected
|| NullRemaining
)) {
1176 Status
= gBS
->InstallProtocolInterface (
1177 &TerminalDevice
->Handle
,
1178 &gEfiSimpleTextOutProtocolGuid
,
1179 EFI_NATIVE_INTERFACE
,
1180 &TerminalDevice
->SimpleTextOutput
1182 if (EFI_ERROR (Status
)) {
1186 if (DefaultNode
!= NULL
) {
1187 FreePool (DefaultNode
);
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
);
1241 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1242 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1245 if (TerminalDevice
->DevicePath
!= NULL
) {
1246 FreePool (TerminalDevice
->DevicePath
);
1249 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1250 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1253 FreePool (TerminalDevice
);
1257 if (DefaultNode
!= NULL
) {
1258 FreePool (DefaultNode
);
1261 This
->Stop (This
, Controller
, 0, NULL
);
1267 Stop this driver on Controller by closing Simple Text In, Simple Text
1268 In Ex, Simple Text Out protocol, and removing parent device path from
1269 Console Device Environment Variables.
1271 @param This Protocol instance pointer.
1272 @param Controller Handle of device to stop driver on
1273 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1274 children is zero stop the entire bus driver.
1275 @param ChildHandleBuffer List of Child Handles to Stop.
1277 @retval EFI_SUCCESS This driver is removed Controller.
1278 @retval other This driver could not be removed from this device.
1283 TerminalDriverBindingStop (
1284 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1285 IN EFI_HANDLE Controller
,
1286 IN UINTN NumberOfChildren
,
1287 IN EFI_HANDLE
*ChildHandleBuffer
1292 BOOLEAN AllChildrenStopped
;
1293 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
1294 TERMINAL_DEV
*TerminalDevice
;
1295 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1296 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
1297 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1299 Status
= gBS
->HandleProtocol (
1301 &gEfiDevicePathProtocolGuid
,
1302 (VOID
**) &DevicePath
1304 if (EFI_ERROR (Status
)) {
1309 // Complete all outstanding transactions to Controller.
1310 // Don't allow any new transaction to Controller to be started.
1312 if (NumberOfChildren
== 0) {
1314 // Close the bus driver
1316 Status
= gBS
->OpenProtocol (
1319 (VOID
**) &ParentDevicePath
,
1320 This
->DriverBindingHandle
,
1322 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1324 if (!EFI_ERROR (Status
)) {
1326 // Remove Parent Device Path from
1327 // the Console Device Environment Variables
1329 TerminalRemoveConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
1330 TerminalRemoveConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
1331 TerminalRemoveConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
1334 // Uninstall the Terminal Driver's GUID Tag from the Serial controller
1336 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1344 // Free the ParentDevicePath that was duplicated in Start()
1346 if (!EFI_ERROR (Status
)) {
1347 FreePool (ParentDevicePath
);
1351 gBS
->CloseProtocol (
1353 &gEfiSerialIoProtocolGuid
,
1354 This
->DriverBindingHandle
,
1358 gBS
->CloseProtocol (
1360 &gEfiDevicePathProtocolGuid
,
1361 This
->DriverBindingHandle
,
1368 AllChildrenStopped
= TRUE
;
1370 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
1372 Status
= gBS
->OpenProtocol (
1373 ChildHandleBuffer
[Index
],
1374 &gEfiSimpleTextOutProtocolGuid
,
1375 (VOID
**) &SimpleTextOutput
,
1376 This
->DriverBindingHandle
,
1377 ChildHandleBuffer
[Index
],
1378 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1380 if (!EFI_ERROR (Status
)) {
1382 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1384 gBS
->CloseProtocol (
1386 &gEfiSerialIoProtocolGuid
,
1387 This
->DriverBindingHandle
,
1388 ChildHandleBuffer
[Index
]
1391 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1392 ChildHandleBuffer
[Index
],
1393 &gEfiSimpleTextInProtocolGuid
,
1394 &TerminalDevice
->SimpleInput
,
1395 &gEfiSimpleTextInputExProtocolGuid
,
1396 &TerminalDevice
->SimpleInputEx
,
1397 &gEfiSimpleTextOutProtocolGuid
,
1398 &TerminalDevice
->SimpleTextOutput
,
1399 &gEfiDevicePathProtocolGuid
,
1400 TerminalDevice
->DevicePath
,
1403 if (EFI_ERROR (Status
)) {
1406 &gEfiSerialIoProtocolGuid
,
1407 (VOID
**) &SerialIo
,
1408 This
->DriverBindingHandle
,
1409 ChildHandleBuffer
[Index
],
1410 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1414 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1415 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1418 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1419 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1420 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1421 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
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
);