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 - 2017, 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
*mTerminalType
[] = {
41 CHAR16
*mSerialConsoleNames
[] = {
42 L
"PC-ANSI Serial Console",
43 L
"VT-100 Serial Console",
44 L
"VT-100+ Serial Console",
45 L
"VT-UTF8 Serial Console",
46 L
"Tty Terminal Serial Console"
49 TERMINAL_DEV mTerminalDevTemplate
= {
50 TERMINAL_DEV_SIGNATURE
,
57 TerminalConInReadKeyStroke
,
62 TerminalConOutOutputString
,
63 TerminalConOutTestString
,
64 TerminalConOutQueryMode
,
65 TerminalConOutSetMode
,
66 TerminalConOutSetAttribute
,
67 TerminalConOutClearScreen
,
68 TerminalConOutSetCursorPosition
,
69 TerminalConOutEnableCursor
,
72 { // SimpleTextOutputMode
75 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
), // Attribute
80 NULL
, // TerminalConsoleModeData
86 NULL
, // EfiKeyFiFoForNotify
88 NULL
, // ControllerNameTable
90 NULL
, // TwoSecondTimeOut
100 { // SimpleTextInputEx
101 TerminalConInResetEx
,
102 TerminalConInReadKeyStrokeEx
,
104 TerminalConInSetState
,
105 TerminalConInRegisterKeyNotify
,
106 TerminalConInUnregisterKeyNotify
,
112 NULL
// KeyNotifyProcessEvent
115 TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData
[] = {
118 // New modes can be added here.
123 Convert the GUID representation of terminal type to enum type.
125 @param Guid The GUID representation of terminal type.
127 @return The terminal type in enum type.
130 TerminalTypeFromGuid (
136 for (Type
= 0; Type
< ARRAY_SIZE (mTerminalType
); Type
++) {
137 if (CompareGuid (Guid
, mTerminalType
[Type
])) {
145 Test to see if this driver supports Controller.
147 @param This Protocol instance pointer.
148 @param Controller Handle of device to test
149 @param RemainingDevicePath Optional parameter use to pick a specific child
152 @retval EFI_SUCCESS This driver supports this device.
153 @retval EFI_ALREADY_STARTED This driver is already running on this device.
154 @retval other This driver does not support this device.
159 TerminalDriverBindingSupported (
160 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
161 IN EFI_HANDLE Controller
,
162 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
166 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
167 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
168 VENDOR_DEVICE_PATH
*Node
;
171 // If remaining device path is not NULL, then make sure it is a
172 // device path that describes a terminal communications protocol.
174 if (RemainingDevicePath
!= NULL
) {
176 // Check if RemainingDevicePath is the End of Device Path Node,
177 // if yes, go on checking other conditions
179 if (!IsDevicePathEnd (RemainingDevicePath
)) {
181 // If RemainingDevicePath isn't the End of Device Path Node,
182 // check its validation
184 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
186 if (Node
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
187 Node
->Header
.SubType
!= MSG_VENDOR_DP
||
188 DevicePathNodeLength(&Node
->Header
) != sizeof(VENDOR_DEVICE_PATH
)) {
190 return EFI_UNSUPPORTED
;
194 // only supports PC ANSI, VT100, VT100+, VT-UTF8, and TtyTerm terminal types
196 if (TerminalTypeFromGuid (&Node
->Guid
) == ARRAY_SIZE (mTerminalType
)) {
197 return EFI_UNSUPPORTED
;
202 // Open the IO Abstraction(s) needed to perform the supported test
203 // The Controller must support the Serial I/O Protocol.
204 // This driver is a bus driver with at most 1 child device, so it is
205 // ok for it to be already started.
207 Status
= gBS
->OpenProtocol (
209 &gEfiSerialIoProtocolGuid
,
211 This
->DriverBindingHandle
,
213 EFI_OPEN_PROTOCOL_BY_DRIVER
215 if (Status
== EFI_ALREADY_STARTED
) {
219 if (EFI_ERROR (Status
)) {
224 // Close the I/O Abstraction(s) used to perform the supported test
228 &gEfiSerialIoProtocolGuid
,
229 This
->DriverBindingHandle
,
234 // Open the EFI Device Path protocol needed to perform the supported test
236 Status
= gBS
->OpenProtocol (
238 &gEfiDevicePathProtocolGuid
,
239 (VOID
**) &ParentDevicePath
,
240 This
->DriverBindingHandle
,
242 EFI_OPEN_PROTOCOL_BY_DRIVER
244 if (Status
== EFI_ALREADY_STARTED
) {
248 if (EFI_ERROR (Status
)) {
253 // Close protocol, don't use device path protocol in the Support() function
257 &gEfiDevicePathProtocolGuid
,
258 This
->DriverBindingHandle
,
266 Build the terminal device path for the child device according to the
269 @param ParentDevicePath Parent device path.
270 @param RemainingDevicePath A specific child device.
272 @return The child device path built.
275 EFI_DEVICE_PATH_PROTOCOL
*
277 BuildTerminalDevpath (
278 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
279 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
282 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
283 TERMINAL_TYPE TerminalType
;
284 VENDOR_DEVICE_PATH
*Node
;
287 TerminalDevicePath
= NULL
;
290 // Use the RemainingDevicePath to determine the terminal type
292 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
294 TerminalType
= PcdGet8 (PcdDefaultTerminalType
);
296 } else if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
298 TerminalType
= TerminalTypePcAnsi
;
300 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
302 TerminalType
= TerminalTypeVt100
;
304 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
306 TerminalType
= TerminalTypeVt100Plus
;
308 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
310 TerminalType
= TerminalTypeVtUtf8
;
312 } else if (CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
314 TerminalType
= TerminalTypeTtyTerm
;
321 // Build the device path for the child device
323 Status
= SetTerminalDevicePath (
328 if (EFI_ERROR (Status
)) {
331 return TerminalDevicePath
;
335 Compare a device path data structure to that of all the nodes of a
336 second device path instance.
338 @param Multi A pointer to a multi-instance device path data structure.
339 @param Single A pointer to a single-instance device path data structure.
341 @retval TRUE If the Single is contained within Multi.
342 @retval FALSE The Single is not match within Multi.
347 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
348 IN EFI_DEVICE_PATH_PROTOCOL
*Single
351 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
352 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
356 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
358 // Search for the match of 'Single' in 'Multi'
360 while (DevicePathInst
!= NULL
) {
362 // If the single device path is found in multiple device paths,
365 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
366 FreePool (DevicePathInst
);
370 FreePool (DevicePathInst
);
371 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
378 Check whether the terminal device path is in the global variable.
380 @param VariableName Pointer to one global variable.
381 @param TerminalDevicePath Pointer to the terminal device's device path.
383 @retval TRUE The devcie is in the global variable.
384 @retval FALSE The devcie is not in the global variable.
388 IsTerminalInConsoleVariable (
389 IN CHAR16
*VariableName
,
390 IN EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
393 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
397 // Get global variable and its size according to the name given.
399 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
400 if (Variable
== NULL
) {
405 // Check whether the terminal device path is one of the variable instances.
407 ReturnFlag
= MatchDevicePaths (Variable
, TerminalDevicePath
);
415 Free notify functions list.
417 @param ListHead The list head
419 @retval EFI_SUCCESS Free the notify list successfully.
420 @retval EFI_INVALID_PARAMETER ListHead is NULL.
424 TerminalFreeNotifyList (
425 IN OUT LIST_ENTRY
*ListHead
428 TERMINAL_CONSOLE_IN_EX_NOTIFY
*NotifyNode
;
430 if (ListHead
== NULL
) {
431 return EFI_INVALID_PARAMETER
;
433 while (!IsListEmpty (ListHead
)) {
435 ListHead
->ForwardLink
,
436 TERMINAL_CONSOLE_IN_EX_NOTIFY
,
438 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
440 RemoveEntryList (ListHead
->ForwardLink
);
441 FreePool (NotifyNode
);
448 Initialize all the text modes which the terminal console supports.
450 It returns information for available text modes that the terminal can support.
452 @param[out] TextModeCount The total number of text modes that terminal console supports.
453 @param[out] TextModeData The buffer to the text modes column and row information.
454 Caller is responsible to free it when it's non-NULL.
456 @retval EFI_SUCCESS The supporting mode information is returned.
457 @retval EFI_INVALID_PARAMETER The parameters are invalid.
461 InitializeTerminalConsoleTextMode (
462 OUT UINTN
*TextModeCount
,
463 OUT TERMINAL_CONSOLE_MODE_DATA
**TextModeData
468 TERMINAL_CONSOLE_MODE_DATA
*ModeBuffer
;
469 TERMINAL_CONSOLE_MODE_DATA
*NewModeBuffer
;
473 if ((TextModeCount
== NULL
) || (TextModeData
== NULL
)) {
474 return EFI_INVALID_PARAMETER
;
477 Count
= sizeof (mTerminalConsoleModeData
) / sizeof (TERMINAL_CONSOLE_MODE_DATA
);
480 // Get defined mode buffer pointer.
482 ModeBuffer
= mTerminalConsoleModeData
;
485 // Here we make sure that the final mode exposed does not include the duplicated modes,
486 // and does not include the invalid modes which exceed the max column and row.
487 // Reserve 2 modes for 80x25, 80x50 of terminal console.
489 NewModeBuffer
= AllocateZeroPool (sizeof (TERMINAL_CONSOLE_MODE_DATA
) * (Count
+ 2));
490 ASSERT (NewModeBuffer
!= NULL
);
493 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
497 NewModeBuffer
[ValidCount
].Columns
= 80;
498 NewModeBuffer
[ValidCount
].Rows
= 25;
501 NewModeBuffer
[ValidCount
].Columns
= 80;
502 NewModeBuffer
[ValidCount
].Rows
= 50;
506 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
508 for (Index
= 0; Index
< Count
; Index
++) {
509 if ((ModeBuffer
[Index
].Columns
== 0) || (ModeBuffer
[Index
].Rows
== 0)) {
511 // Skip the pre-defined mode which is invalid.
515 for (ValidIndex
= 0; ValidIndex
< ValidCount
; ValidIndex
++) {
516 if ((ModeBuffer
[Index
].Columns
== NewModeBuffer
[ValidIndex
].Columns
) &&
517 (ModeBuffer
[Index
].Rows
== NewModeBuffer
[ValidIndex
].Rows
)) {
519 // Skip the duplicated mode.
524 if (ValidIndex
== ValidCount
) {
525 NewModeBuffer
[ValidCount
].Columns
= ModeBuffer
[Index
].Columns
;
526 NewModeBuffer
[ValidCount
].Rows
= ModeBuffer
[Index
].Rows
;
532 for (Index
= 0; Index
< ValidCount
; Index
++) {
533 DEBUG ((EFI_D_INFO
, "Terminal - Mode %d, Column = %d, Row = %d\n",
534 Index
, NewModeBuffer
[Index
].Columns
, NewModeBuffer
[Index
].Rows
));
539 // Return valid mode count and mode information buffer.
541 *TextModeCount
= ValidCount
;
542 *TextModeData
= NewModeBuffer
;
547 Initialize the controller name table.
549 @param TerminalType The terminal type.
550 @param ControllerNameTable The controller name table.
552 @retval EFI_SUCCESS The controller name table is initialized successfully.
553 @retval others Return status of AddUnicodeString2 ().
556 InitializeControllerNameTable (
557 TERMINAL_TYPE TerminalType
,
558 EFI_UNICODE_STRING_TABLE
**ControllerNameTable
562 EFI_UNICODE_STRING_TABLE
*Table
;
564 ASSERT (TerminalType
< ARRAY_SIZE (mTerminalType
));
566 Status
= AddUnicodeString2 (
568 gTerminalComponentName
.SupportedLanguages
,
570 mSerialConsoleNames
[TerminalType
],
573 if (!EFI_ERROR (Status
)) {
574 Status
= AddUnicodeString2 (
576 gTerminalComponentName2
.SupportedLanguages
,
578 mSerialConsoleNames
[TerminalType
],
581 if (EFI_ERROR (Status
)) {
582 FreeUnicodeStringTable (Table
);
585 if (!EFI_ERROR (Status
)) {
586 *ControllerNameTable
= Table
;
592 Start this driver on Controller by opening a Serial IO protocol,
593 reading Device Path, and creating a child handle with a Simple Text In,
594 Simple Text In Ex and Simple Text Out protocol, and device path protocol.
595 And store Console Device Environment Variables.
597 @param This Protocol instance pointer.
598 @param Controller Handle of device to bind driver to
599 @param RemainingDevicePath Optional parameter use to pick a specific child
602 @retval EFI_SUCCESS This driver is added to Controller.
603 @retval EFI_ALREADY_STARTED This driver is already running on Controller.
604 @retval other This driver does not support this device.
609 TerminalDriverBindingStart (
610 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
611 IN EFI_HANDLE Controller
,
612 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
616 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
617 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
618 VENDOR_DEVICE_PATH
*Node
;
619 EFI_SERIAL_IO_MODE
*Mode
;
620 UINTN SerialInTimeOut
;
621 TERMINAL_DEV
*TerminalDevice
;
622 TERMINAL_TYPE TerminalType
;
623 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
626 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
627 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
628 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleTextInput
;
629 BOOLEAN ConInSelected
;
630 BOOLEAN ConOutSelected
;
631 BOOLEAN NullRemaining
;
632 BOOLEAN SimTxtInInstalled
;
633 BOOLEAN SimTxtOutInstalled
;
637 TerminalDevice
= NULL
;
638 ConInSelected
= FALSE
;
639 ConOutSelected
= FALSE
;
640 NullRemaining
= FALSE
;
641 SimTxtInInstalled
= FALSE
;
642 SimTxtOutInstalled
= FALSE
;
645 // Get the Device Path Protocol to build the device path of the child device
647 Status
= gBS
->OpenProtocol (
649 &gEfiDevicePathProtocolGuid
,
650 (VOID
**) &ParentDevicePath
,
651 This
->DriverBindingHandle
,
653 EFI_OPEN_PROTOCOL_BY_DRIVER
655 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
660 // Open the Serial I/O Protocol BY_DRIVER. It might already be started.
662 Status
= gBS
->OpenProtocol (
664 &gEfiSerialIoProtocolGuid
,
666 This
->DriverBindingHandle
,
668 EFI_OPEN_PROTOCOL_BY_DRIVER
670 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
674 if (Status
!= EFI_ALREADY_STARTED
) {
676 // the serial I/O protocol never be opened before, it is the first
677 // time to start the serial Io controller
683 // Serial I/O is not already open by this driver, then tag the handle
684 // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and
685 // StdErrDev variables with the list of possible terminal types on this
688 Status
= gBS
->OpenProtocol (
692 This
->DriverBindingHandle
,
694 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
696 if (EFI_ERROR (Status
)) {
697 Status
= gBS
->InstallMultipleProtocolInterfaces (
700 DuplicateDevicePath (ParentDevicePath
),
703 if (EFI_ERROR (Status
)) {
707 if (!IsHotPlugDevice (ParentDevicePath
)) {
709 // if the serial device is a hot plug device, do not update the
710 // ConInDev, ConOutDev, and StdErrDev variables.
712 TerminalUpdateConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
713 TerminalUpdateConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
714 TerminalUpdateConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
719 // Check the requirement for the SimpleTxtIn and SimpleTxtOut protocols
721 // Simple In/Out Protocol will not be installed onto the handle if the
722 // device path to the handle is not present in the ConIn/ConOut
723 // environment variable. But If RemainingDevicePath is NULL, then always
724 // produce both Simple In and Simple Text Output Protocols. This is required
725 // for the connect all sequences to make sure all possible consoles are
726 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
728 if (RemainingDevicePath
== NULL
) {
729 NullRemaining
= TRUE
;
732 DevicePath
= BuildTerminalDevpath (ParentDevicePath
, RemainingDevicePath
);
733 if (DevicePath
!= NULL
) {
734 ConInSelected
= IsTerminalInConsoleVariable (L
"ConIn", DevicePath
);
735 ConOutSelected
= IsTerminalInConsoleVariable (L
"ConOut", DevicePath
);
736 FreePool (DevicePath
);
741 // Not create the child terminal handle if both Simple In/In Ex and
742 // Simple text Out protocols are not required to be published
744 if ((!ConInSelected
)&&(!ConOutSelected
)&&(!NullRemaining
)) {
749 // create the child terminal handle during first entry
753 // First enther the start function
757 // Make sure a child handle does not already exist. This driver can only
758 // produce one child per serial port.
760 Status
= gBS
->OpenProtocolInformation (
762 &gEfiSerialIoProtocolGuid
,
766 if (!EFI_ERROR (Status
)) {
767 Status
= EFI_SUCCESS
;
768 for (Index
= 0; Index
< EntryCount
; Index
++) {
769 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
770 Status
= EFI_ALREADY_STARTED
;
774 FreePool (OpenInfoBuffer
);
775 if (EFI_ERROR (Status
)) {
781 // If RemainingDevicePath is NULL, use default terminal type
783 if (RemainingDevicePath
== NULL
) {
784 TerminalType
= PcdGet8 (PcdDefaultTerminalType
);
785 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
787 // If RemainingDevicePath isn't the End of Device Path Node,
788 // Use the RemainingDevicePath to determine the terminal type
790 Node
= (VENDOR_DEVICE_PATH
*)RemainingDevicePath
;
791 TerminalType
= TerminalTypeFromGuid (&Node
->Guid
);
794 // If RemainingDevicePath is the End of Device Path Node,
795 // skip enumerate any device and return EFI_SUCESSS
800 ASSERT (TerminalType
< ARRAY_SIZE (mTerminalType
));
803 // Initialize the Terminal Dev
805 TerminalDevice
= AllocateCopyPool (sizeof (TERMINAL_DEV
), &mTerminalDevTemplate
);
806 if (TerminalDevice
== NULL
) {
807 Status
= EFI_OUT_OF_RESOURCES
;
811 TerminalDevice
->TerminalType
= TerminalType
;
812 TerminalDevice
->SerialIo
= SerialIo
;
814 InitializeListHead (&TerminalDevice
->NotifyList
);
815 Status
= gBS
->CreateEvent (
818 TerminalConInWaitForKeyEx
,
820 &TerminalDevice
->SimpleInputEx
.WaitForKeyEx
822 if (EFI_ERROR (Status
)) {
826 Status
= gBS
->CreateEvent (
829 TerminalConInWaitForKey
,
831 &TerminalDevice
->SimpleInput
.WaitForKey
833 if (EFI_ERROR (Status
)) {
837 // Allocates and initializes the FIFO buffer to be zero, used for accommodating
838 // the pre-read pending characters.
840 TerminalDevice
->RawFiFo
= AllocateZeroPool (sizeof (RAW_DATA_FIFO
));
841 if (TerminalDevice
->RawFiFo
== NULL
) {
844 TerminalDevice
->UnicodeFiFo
= AllocateZeroPool (sizeof (UNICODE_FIFO
));
845 if (TerminalDevice
->UnicodeFiFo
== NULL
) {
848 TerminalDevice
->EfiKeyFiFo
= AllocateZeroPool (sizeof (EFI_KEY_FIFO
));
849 if (TerminalDevice
->EfiKeyFiFo
== NULL
) {
852 TerminalDevice
->EfiKeyFiFoForNotify
= AllocateZeroPool (sizeof (EFI_KEY_FIFO
));
853 if (TerminalDevice
->EfiKeyFiFoForNotify
== NULL
) {
858 // Set the timeout value of serial buffer for
859 // keystroke response performance issue
861 Mode
= TerminalDevice
->SerialIo
->Mode
;
864 if (Mode
->BaudRate
!= 0) {
865 SerialInTimeOut
= (1 + Mode
->DataBits
+ Mode
->StopBits
) * 2 * 1000000 / (UINTN
) Mode
->BaudRate
;
868 Status
= TerminalDevice
->SerialIo
->SetAttributes (
869 TerminalDevice
->SerialIo
,
871 Mode
->ReceiveFifoDepth
,
872 (UINT32
) SerialInTimeOut
,
873 (EFI_PARITY_TYPE
) (Mode
->Parity
),
874 (UINT8
) Mode
->DataBits
,
875 (EFI_STOP_BITS_TYPE
) (Mode
->StopBits
)
877 if (EFI_ERROR (Status
)) {
879 // if set attributes operation fails, invalidate
880 // the value of SerialInTimeOut,thus make it
881 // inconsistent with the default timeout value
882 // of serial buffer. This will invoke the recalculation
883 // in the readkeystroke routine.
885 TerminalDevice
->SerialInTimeOut
= 0;
887 TerminalDevice
->SerialInTimeOut
= SerialInTimeOut
;
890 // Set Simple Text Output Protocol from template.
892 SimpleTextOutput
= CopyMem (
893 &TerminalDevice
->SimpleTextOutput
,
894 &mTerminalDevTemplate
.SimpleTextOutput
,
895 sizeof (mTerminalDevTemplate
.SimpleTextOutput
)
897 SimpleTextOutput
->Mode
= &TerminalDevice
->SimpleTextOutputMode
;
899 Status
= InitializeTerminalConsoleTextMode (&ModeCount
, &TerminalDevice
->TerminalConsoleModeData
);
900 if (EFI_ERROR (Status
)) {
903 TerminalDevice
->SimpleTextOutputMode
.MaxMode
= (INT32
) ModeCount
;
906 // For terminal devices, cursor is always visible
908 TerminalDevice
->SimpleTextOutputMode
.CursorVisible
= TRUE
;
909 Status
= TerminalConOutSetAttribute (
911 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
913 if (EFI_ERROR (Status
)) {
918 // Build the component name for the child device
920 Status
= InitializeControllerNameTable (TerminalDevice
->TerminalType
, &TerminalDevice
->ControllerNameTable
);
921 if (EFI_ERROR (Status
)) {
926 // Build the device path for the child device
928 Status
= SetTerminalDevicePath (
929 TerminalDevice
->TerminalType
,
931 &TerminalDevice
->DevicePath
933 if (EFI_ERROR (Status
)) {
937 Status
= TerminalConOutReset (SimpleTextOutput
, FALSE
);
938 if (EFI_ERROR (Status
)) {
942 Status
= TerminalConOutSetMode (SimpleTextOutput
, 0);
943 if (EFI_ERROR (Status
)) {
947 Status
= TerminalConOutEnableCursor (SimpleTextOutput
, TRUE
);
948 if (EFI_ERROR (Status
)) {
952 Status
= gBS
->CreateEvent (
953 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
955 TerminalConInTimerHandler
,
957 &TerminalDevice
->TimerEvent
959 ASSERT_EFI_ERROR (Status
);
961 Status
= gBS
->SetTimer (
962 TerminalDevice
->TimerEvent
,
964 KEYBOARD_TIMER_INTERVAL
966 ASSERT_EFI_ERROR (Status
);
968 Status
= gBS
->CreateEvent (
973 &TerminalDevice
->TwoSecondTimeOut
975 ASSERT_EFI_ERROR (Status
);
977 Status
= gBS
->CreateEvent (
980 KeyNotifyProcessHandler
,
982 &TerminalDevice
->KeyNotifyProcessEvent
984 ASSERT_EFI_ERROR (Status
);
986 Status
= gBS
->InstallProtocolInterface (
987 &TerminalDevice
->Handle
,
988 &gEfiDevicePathProtocolGuid
,
989 EFI_NATIVE_INTERFACE
,
990 TerminalDevice
->DevicePath
992 if (EFI_ERROR (Status
)) {
997 // Register the Parent-Child relationship via
998 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
1000 Status
= gBS
->OpenProtocol (
1002 &gEfiSerialIoProtocolGuid
,
1003 (VOID
**) &TerminalDevice
->SerialIo
,
1004 This
->DriverBindingHandle
,
1005 TerminalDevice
->Handle
,
1006 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1008 if (EFI_ERROR (Status
)) {
1014 // Find the child handle, and get its TerminalDevice private data
1016 Status
= gBS
->OpenProtocolInformation (
1018 &gEfiSerialIoProtocolGuid
,
1022 if (!EFI_ERROR (Status
)) {
1023 Status
= EFI_NOT_FOUND
;
1024 ASSERT (OpenInfoBuffer
!= NULL
);
1025 for (Index
= 0; Index
< EntryCount
; Index
++) {
1026 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
1028 // Find the child terminal handle.
1029 // Test whether the SimpleTxtIn and SimpleTxtOut have been published
1031 Status
= gBS
->OpenProtocol (
1032 OpenInfoBuffer
[Index
].ControllerHandle
,
1033 &gEfiSimpleTextInProtocolGuid
,
1034 (VOID
**) &SimpleTextInput
,
1035 This
->DriverBindingHandle
,
1036 OpenInfoBuffer
[Index
].ControllerHandle
,
1037 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1039 if (!EFI_ERROR (Status
)) {
1040 SimTxtInInstalled
= TRUE
;
1041 TerminalDevice
= TERMINAL_CON_IN_DEV_FROM_THIS (SimpleTextInput
);
1044 Status
= gBS
->OpenProtocol (
1045 OpenInfoBuffer
[Index
].ControllerHandle
,
1046 &gEfiSimpleTextOutProtocolGuid
,
1047 (VOID
**) &SimpleTextOutput
,
1048 This
->DriverBindingHandle
,
1049 OpenInfoBuffer
[Index
].ControllerHandle
,
1050 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1052 if (!EFI_ERROR (Status
)) {
1053 SimTxtOutInstalled
= TRUE
;
1054 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1056 Status
= EFI_SUCCESS
;
1061 FreePool (OpenInfoBuffer
);
1062 if (EFI_ERROR (Status
)) {
1069 ASSERT (TerminalDevice
!= NULL
);
1071 // Only do the reset if the device path is in the Conout variable
1073 if (ConInSelected
&& !SimTxtInInstalled
) {
1074 Status
= TerminalDevice
->SimpleInput
.Reset (
1075 &TerminalDevice
->SimpleInput
,
1078 if (EFI_ERROR (Status
)) {
1080 // Need to report Error Code first
1087 // Only output the configure string to remote terminal if the device path
1088 // is in the Conout variable
1090 if (ConOutSelected
&& !SimTxtOutInstalled
) {
1091 Status
= TerminalDevice
->SimpleTextOutput
.SetAttribute (
1092 &TerminalDevice
->SimpleTextOutput
,
1093 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
1095 if (EFI_ERROR (Status
)) {
1099 Status
= TerminalDevice
->SimpleTextOutput
.Reset (
1100 &TerminalDevice
->SimpleTextOutput
,
1103 if (EFI_ERROR (Status
)) {
1107 Status
= TerminalDevice
->SimpleTextOutput
.SetMode (
1108 &TerminalDevice
->SimpleTextOutput
,
1111 if (EFI_ERROR (Status
)) {
1115 Status
= TerminalDevice
->SimpleTextOutput
.EnableCursor (
1116 &TerminalDevice
->SimpleTextOutput
,
1119 if (EFI_ERROR (Status
)) {
1125 // Simple In/Out Protocol will not be installed onto the handle if the
1126 // device path to the handle is not present in the ConIn/ConOut
1127 // environment variable. But If RemainingDevicePath is NULL, then always
1128 // produce both Simple In and Simple Text Output Protocols. This is required
1129 // for the connect all sequences to make sure all possible consoles are
1130 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
1132 if (!SimTxtInInstalled
&& (ConInSelected
|| NullRemaining
)) {
1133 Status
= gBS
->InstallMultipleProtocolInterfaces (
1134 &TerminalDevice
->Handle
,
1135 &gEfiSimpleTextInProtocolGuid
,
1136 &TerminalDevice
->SimpleInput
,
1137 &gEfiSimpleTextInputExProtocolGuid
,
1138 &TerminalDevice
->SimpleInputEx
,
1141 if (EFI_ERROR (Status
)) {
1146 if (!SimTxtOutInstalled
&& (ConOutSelected
|| NullRemaining
)) {
1147 Status
= gBS
->InstallProtocolInterface (
1148 &TerminalDevice
->Handle
,
1149 &gEfiSimpleTextOutProtocolGuid
,
1150 EFI_NATIVE_INTERFACE
,
1151 &TerminalDevice
->SimpleTextOutput
1153 if (EFI_ERROR (Status
)) {
1162 // Report error code before exiting
1164 DevicePath
= ParentDevicePath
;
1165 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1166 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1167 (EFI_PERIPHERAL_REMOTE_CONSOLE
| EFI_P_EC_CONTROLLER_ERROR
),
1173 // Use the Stop() function to free all resources allocated in Start()
1175 if (TerminalDevice
!= NULL
) {
1177 if (TerminalDevice
->Handle
!= NULL
) {
1178 This
->Stop (This
, Controller
, 1, &TerminalDevice
->Handle
);
1181 if (TerminalDevice
->TwoSecondTimeOut
!= NULL
) {
1182 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1185 if (TerminalDevice
->TimerEvent
!= NULL
) {
1186 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1189 if (TerminalDevice
->SimpleInput
.WaitForKey
!= NULL
) {
1190 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1193 if (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
!= NULL
) {
1194 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1197 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1199 if (TerminalDevice
->RawFiFo
!= NULL
) {
1200 FreePool (TerminalDevice
->RawFiFo
);
1202 if (TerminalDevice
->UnicodeFiFo
!= NULL
) {
1203 FreePool (TerminalDevice
->UnicodeFiFo
);
1205 if (TerminalDevice
->EfiKeyFiFo
!= NULL
) {
1206 FreePool (TerminalDevice
->EfiKeyFiFo
);
1208 if (TerminalDevice
->EfiKeyFiFoForNotify
!= NULL
) {
1209 FreePool (TerminalDevice
->EfiKeyFiFoForNotify
);
1212 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1213 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1216 if (TerminalDevice
->DevicePath
!= NULL
) {
1217 FreePool (TerminalDevice
->DevicePath
);
1220 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1221 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1224 FreePool (TerminalDevice
);
1228 This
->Stop (This
, Controller
, 0, NULL
);
1234 Stop this driver on Controller by closing Simple Text In, Simple Text
1235 In Ex, Simple Text Out protocol, and removing parent device path from
1236 Console Device Environment Variables.
1238 @param This Protocol instance pointer.
1239 @param Controller Handle of device to stop driver on
1240 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1241 children is zero stop the entire bus driver.
1242 @param ChildHandleBuffer List of Child Handles to Stop.
1244 @retval EFI_SUCCESS This driver is removed Controller.
1245 @retval other This driver could not be removed from this device.
1250 TerminalDriverBindingStop (
1251 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1252 IN EFI_HANDLE Controller
,
1253 IN UINTN NumberOfChildren
,
1254 IN EFI_HANDLE
*ChildHandleBuffer
1259 BOOLEAN AllChildrenStopped
;
1260 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
1261 TERMINAL_DEV
*TerminalDevice
;
1262 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1263 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
1264 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1266 Status
= gBS
->HandleProtocol (
1268 &gEfiDevicePathProtocolGuid
,
1269 (VOID
**) &DevicePath
1271 if (EFI_ERROR (Status
)) {
1276 // Complete all outstanding transactions to Controller.
1277 // Don't allow any new transaction to Controller to be started.
1279 if (NumberOfChildren
== 0) {
1281 // Close the bus driver
1283 Status
= gBS
->OpenProtocol (
1286 (VOID
**) &ParentDevicePath
,
1287 This
->DriverBindingHandle
,
1289 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1291 if (!EFI_ERROR (Status
)) {
1293 // Remove Parent Device Path from
1294 // the Console Device Environment Variables
1296 TerminalRemoveConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
1297 TerminalRemoveConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
1298 TerminalRemoveConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
1301 // Uninstall the Terminal Driver's GUID Tag from the Serial controller
1303 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1311 // Free the ParentDevicePath that was duplicated in Start()
1313 if (!EFI_ERROR (Status
)) {
1314 FreePool (ParentDevicePath
);
1318 gBS
->CloseProtocol (
1320 &gEfiSerialIoProtocolGuid
,
1321 This
->DriverBindingHandle
,
1325 gBS
->CloseProtocol (
1327 &gEfiDevicePathProtocolGuid
,
1328 This
->DriverBindingHandle
,
1335 AllChildrenStopped
= TRUE
;
1337 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
1339 Status
= gBS
->OpenProtocol (
1340 ChildHandleBuffer
[Index
],
1341 &gEfiSimpleTextOutProtocolGuid
,
1342 (VOID
**) &SimpleTextOutput
,
1343 This
->DriverBindingHandle
,
1344 ChildHandleBuffer
[Index
],
1345 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1347 if (!EFI_ERROR (Status
)) {
1349 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1351 gBS
->CloseProtocol (
1353 &gEfiSerialIoProtocolGuid
,
1354 This
->DriverBindingHandle
,
1355 ChildHandleBuffer
[Index
]
1358 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1359 ChildHandleBuffer
[Index
],
1360 &gEfiSimpleTextInProtocolGuid
,
1361 &TerminalDevice
->SimpleInput
,
1362 &gEfiSimpleTextInputExProtocolGuid
,
1363 &TerminalDevice
->SimpleInputEx
,
1364 &gEfiSimpleTextOutProtocolGuid
,
1365 &TerminalDevice
->SimpleTextOutput
,
1366 &gEfiDevicePathProtocolGuid
,
1367 TerminalDevice
->DevicePath
,
1370 if (EFI_ERROR (Status
)) {
1373 &gEfiSerialIoProtocolGuid
,
1374 (VOID
**) &SerialIo
,
1375 This
->DriverBindingHandle
,
1376 ChildHandleBuffer
[Index
],
1377 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1381 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1382 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1385 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1386 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1387 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1388 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1389 gBS
->CloseEvent (TerminalDevice
->KeyNotifyProcessEvent
);
1390 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1391 FreePool (TerminalDevice
->DevicePath
);
1392 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1393 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1395 FreePool (TerminalDevice
);
1399 if (EFI_ERROR (Status
)) {
1400 AllChildrenStopped
= FALSE
;
1404 if (!AllChildrenStopped
) {
1405 return EFI_DEVICE_ERROR
;
1412 Update terminal device path in Console Device Environment Variables.
1414 @param VariableName The Console Device Environment Variable.
1415 @param ParentDevicePath The terminal device path to be updated.
1419 TerminalUpdateConsoleDevVariable (
1420 IN CHAR16
*VariableName
,
1421 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1427 TERMINAL_TYPE TerminalType
;
1428 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1429 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1430 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1431 EDKII_SET_VARIABLE_STATUS
*SetVariableStatus
;
1434 // Get global variable and its size according to the name given.
1436 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
1437 if (Variable
== NULL
) {
1442 // Append terminal device path onto the variable.
1444 for (TerminalType
= 0; TerminalType
< ARRAY_SIZE (mTerminalType
); TerminalType
++) {
1445 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1446 NewVariable
= AppendDevicePathInstance (Variable
, TempDevicePath
);
1447 ASSERT (NewVariable
!= NULL
);
1448 if (Variable
!= NULL
) {
1449 FreePool (Variable
);
1452 if (TempDevicePath
!= NULL
) {
1453 FreePool (TempDevicePath
);
1456 Variable
= NewVariable
;
1459 VariableSize
= GetDevicePathSize (Variable
);
1461 Status
= gRT
->SetVariable (
1463 &gEfiGlobalVariableGuid
,
1464 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1469 if (EFI_ERROR (Status
)) {
1470 NameSize
= StrSize (VariableName
);
1471 SetVariableStatus
= AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS
) + NameSize
+ VariableSize
);
1472 if (SetVariableStatus
!= NULL
) {
1473 CopyGuid (&SetVariableStatus
->Guid
, &gEfiGlobalVariableGuid
);
1474 SetVariableStatus
->NameSize
= NameSize
;
1475 SetVariableStatus
->DataSize
= VariableSize
;
1476 SetVariableStatus
->SetStatus
= Status
;
1477 SetVariableStatus
->Attributes
= EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
;
1478 CopyMem (SetVariableStatus
+ 1, VariableName
, NameSize
);
1479 CopyMem (((UINT8
*) (SetVariableStatus
+ 1)) + NameSize
, Variable
, VariableSize
);
1481 REPORT_STATUS_CODE_EX (
1483 PcdGet32 (PcdErrorCodeSetVariable
),
1486 &gEdkiiStatusCodeDataTypeVariableGuid
,
1488 sizeof (EDKII_SET_VARIABLE_STATUS
) + NameSize
+ VariableSize
1491 FreePool (SetVariableStatus
);
1495 FreePool (Variable
);
1502 Remove terminal device path from Console Device Environment Variables.
1504 @param VariableName Console Device Environment Variables.
1505 @param ParentDevicePath The terminal device path to be updated.
1509 TerminalRemoveConsoleDevVariable (
1510 IN CHAR16
*VariableName
,
1511 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1519 TERMINAL_TYPE TerminalType
;
1520 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
1521 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1522 EFI_DEVICE_PATH_PROTOCOL
*OriginalVariable
;
1523 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1524 EFI_DEVICE_PATH_PROTOCOL
*SavedNewVariable
;
1525 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1530 // Get global variable and its size according to the name given.
1532 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
1533 if (Variable
== NULL
) {
1538 OriginalVariable
= Variable
;
1542 // Get first device path instance from Variable
1544 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1545 if (Instance
== NULL
) {
1546 FreePool (OriginalVariable
);
1550 // Loop through all the device path instances of Variable
1554 // Loop through all the terminal types that this driver supports
1557 for (TerminalType
= 0; TerminalType
< ARRAY_SIZE (mTerminalType
); TerminalType
++) {
1559 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1562 // Compare the generated device path to the current device path instance
1564 if (TempDevicePath
!= NULL
) {
1565 if (CompareMem (Instance
, TempDevicePath
, InstanceSize
) == 0) {
1570 FreePool (TempDevicePath
);
1574 // If a match was not found, then keep the current device path instance
1577 SavedNewVariable
= NewVariable
;
1578 NewVariable
= AppendDevicePathInstance (NewVariable
, Instance
);
1579 if (SavedNewVariable
!= NULL
) {
1580 FreePool (SavedNewVariable
);
1584 // Get next device path instance from Variable
1586 FreePool (Instance
);
1587 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1588 } while (Instance
!= NULL
);
1590 FreePool (OriginalVariable
);
1593 VariableSize
= GetDevicePathSize (NewVariable
);
1595 Status
= gRT
->SetVariable (
1597 &gEfiGlobalVariableGuid
,
1598 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1603 // Shrinking variable with existing variable driver implementation shouldn't fail.
1605 ASSERT_EFI_ERROR (Status
);
1608 if (NewVariable
!= NULL
) {
1609 FreePool (NewVariable
);
1616 Build terminal device path according to terminal type.
1618 @param TerminalType The terminal type is PC ANSI, VT100, VT100+ or VT-UTF8.
1619 @param ParentDevicePath Parent device path.
1620 @param TerminalDevicePath Returned terminal device path, if building successfully.
1622 @retval EFI_UNSUPPORTED Terminal does not belong to the supported type.
1623 @retval EFI_OUT_OF_RESOURCES Generate terminal device path failed.
1624 @retval EFI_SUCCESS Build terminal device path successfully.
1628 SetTerminalDevicePath (
1629 IN TERMINAL_TYPE TerminalType
,
1630 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
1631 OUT EFI_DEVICE_PATH_PROTOCOL
**TerminalDevicePath
1634 VENDOR_DEVICE_PATH Node
;
1636 *TerminalDevicePath
= NULL
;
1637 Node
.Header
.Type
= MESSAGING_DEVICE_PATH
;
1638 Node
.Header
.SubType
= MSG_VENDOR_DP
;
1641 // Generate terminal device path node according to terminal type.
1643 switch (TerminalType
) {
1645 case TerminalTypePcAnsi
:
1646 CopyGuid (&Node
.Guid
, &gEfiPcAnsiGuid
);
1649 case TerminalTypeVt100
:
1650 CopyGuid (&Node
.Guid
, &gEfiVT100Guid
);
1653 case TerminalTypeVt100Plus
:
1654 CopyGuid (&Node
.Guid
, &gEfiVT100PlusGuid
);
1657 case TerminalTypeVtUtf8
:
1658 CopyGuid (&Node
.Guid
, &gEfiVTUTF8Guid
);
1661 case TerminalTypeTtyTerm
:
1662 CopyGuid (&Node
.Guid
, &gEfiTtyTermGuid
);
1666 return EFI_UNSUPPORTED
;
1670 // Get VENDOR_DEVCIE_PATH size and put into Node.Header
1672 SetDevicePathNodeLength (
1674 sizeof (VENDOR_DEVICE_PATH
)
1678 // Append the terminal node onto parent device path
1679 // to generate a complete terminal device path.
1681 *TerminalDevicePath
= AppendDevicePathNode (
1683 (EFI_DEVICE_PATH_PROTOCOL
*) &Node
1685 if (*TerminalDevicePath
== NULL
) {
1686 return EFI_OUT_OF_RESOURCES
;
1693 The user Entry Point for module Terminal. The user code starts with this function.
1695 @param ImageHandle The firmware allocated handle for the EFI image.
1696 @param SystemTable A pointer to the EFI System Table.
1698 @retval EFI_SUCCESS The entry point is executed successfully.
1699 @retval other Some error occurs when executing this entry point.
1705 IN EFI_HANDLE ImageHandle
,
1706 IN EFI_SYSTEM_TABLE
*SystemTable
1712 // Install driver model protocol(s).
1714 Status
= EfiLibInstallDriverBindingComponentName2 (
1717 &gTerminalDriverBinding
,
1719 &gTerminalComponentName
,
1720 &gTerminalComponentName2
1722 ASSERT_EFI_ERROR (Status
);
1728 Check if the device supports hot-plug through its device path.
1730 This function could be updated to check more types of Hot Plug devices.
1731 Currently, it checks USB and PCCard device.
1733 @param DevicePath Pointer to device's device path.
1735 @retval TRUE The devcie is a hot-plug device
1736 @retval FALSE The devcie is not a hot-plug device.
1741 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
1744 EFI_DEVICE_PATH_PROTOCOL
*CheckDevicePath
;
1746 CheckDevicePath
= DevicePath
;
1747 while (!IsDevicePathEnd (CheckDevicePath
)) {
1749 // Check device whether is hot plug device or not throught Device Path
1751 if ((DevicePathType (CheckDevicePath
) == MESSAGING_DEVICE_PATH
) &&
1752 (DevicePathSubType (CheckDevicePath
) == MSG_USB_DP
||
1753 DevicePathSubType (CheckDevicePath
) == MSG_USB_CLASS_DP
||
1754 DevicePathSubType (CheckDevicePath
) == MSG_USB_WWID_DP
)) {
1756 // If Device is USB device
1760 if ((DevicePathType (CheckDevicePath
) == HARDWARE_DEVICE_PATH
) &&
1761 (DevicePathSubType (CheckDevicePath
) == HW_PCCARD_DP
)) {
1763 // If Device is PCCard
1768 CheckDevicePath
= NextDevicePathNode (CheckDevicePath
);