3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
27 TerminalFreeNotifyList (
28 IN OUT LIST_ENTRY
*ListHead
34 EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding
= {
35 TerminalDriverBindingSupported
,
36 TerminalDriverBindingStart
,
37 TerminalDriverBindingStop
,
44 EFI_GUID
*gTerminalType
[] = {
52 TERMINAL_DEV gTerminalDevTemplate
= {
53 TERMINAL_DEV_SIGNATURE
,
60 TerminalConInReadKeyStroke
,
65 TerminalConOutOutputString
,
66 TerminalConOutTestString
,
67 TerminalConOutQueryMode
,
68 TerminalConOutSetMode
,
69 TerminalConOutSetAttribute
,
70 TerminalConOutClearScreen
,
71 TerminalConOutSetCursorPosition
,
72 TerminalConOutEnableCursor
,
75 { // SimpleTextOutputMode
78 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
), // Attribute
99 NULL
, // ControllerNameTable
104 { // SimpleTextInputEx
105 TerminalConInResetEx
,
106 TerminalConInReadKeyStrokeEx
,
108 TerminalConInSetState
,
109 TerminalConInRegisterKeyNotify
,
110 TerminalConInUnregisterKeyNotify
,
122 TerminalDriverBindingSupported (
123 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
124 IN EFI_HANDLE Controller
,
125 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
129 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
130 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
131 VENDOR_DEVICE_PATH
*Node
;
134 // If remaining device path is not NULL, then make sure it is a
135 // device path that describes a terminal communications protocol.
137 if (RemainingDevicePath
!= NULL
) {
139 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
141 if (Node
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
142 Node
->Header
.SubType
!= MSG_VENDOR_DP
||
143 DevicePathNodeLength(&Node
->Header
) != sizeof(VENDOR_DEVICE_PATH
)) {
145 return EFI_UNSUPPORTED
;
149 // only supports PC ANSI, VT100, VT100+ and VT-UTF8 terminal types
151 if (!CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
) &&
152 !CompareGuid (&Node
->Guid
, &gEfiVT100Guid
) &&
153 !CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
) &&
154 !CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
156 return EFI_UNSUPPORTED
;
160 // Open the IO Abstraction(s) needed to perform the supported test
162 Status
= gBS
->OpenProtocol (
164 &gEfiDevicePathProtocolGuid
,
165 (VOID
**) &ParentDevicePath
,
166 This
->DriverBindingHandle
,
168 EFI_OPEN_PROTOCOL_BY_DRIVER
170 if (Status
== EFI_ALREADY_STARTED
) {
174 if (EFI_ERROR (Status
)) {
180 &gEfiDevicePathProtocolGuid
,
181 This
->DriverBindingHandle
,
186 // The Controller must support the Serial I/O Protocol.
187 // This driver is a bus driver with at most 1 child device, so it is
188 // ok for it to be already started.
190 Status
= gBS
->OpenProtocol (
192 &gEfiSerialIoProtocolGuid
,
194 This
->DriverBindingHandle
,
196 EFI_OPEN_PROTOCOL_BY_DRIVER
198 if (Status
== EFI_ALREADY_STARTED
) {
202 if (EFI_ERROR (Status
)) {
206 // Close the I/O Abstraction(s) used to perform the supported test
210 &gEfiSerialIoProtocolGuid
,
211 This
->DriverBindingHandle
,
220 TerminalDriverBindingStart (
221 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
222 IN EFI_HANDLE Controller
,
223 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
229 Start the controller.
233 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
234 Controller - The handle of the controller to start.
235 RemainingDevicePath - A pointer to the remaining portion of a devcie path.
244 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
245 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
246 VENDOR_DEVICE_PATH
*Node
;
247 VENDOR_DEVICE_PATH
*DefaultNode
;
248 EFI_SERIAL_IO_MODE
*Mode
;
249 UINTN SerialInTimeOut
;
250 TERMINAL_DEV
*TerminalDevice
;
252 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
255 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
257 TerminalDevice
= NULL
;
260 // Get the Device Path Protocol to build the device path of the child device
262 Status
= gBS
->OpenProtocol (
264 &gEfiDevicePathProtocolGuid
,
265 (VOID
**) &ParentDevicePath
,
266 This
->DriverBindingHandle
,
268 EFI_OPEN_PROTOCOL_BY_DRIVER
270 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
275 // Open the Serial I/O Protocol BY_DRIVER. It might already be started.
277 Status
= gBS
->OpenProtocol (
279 &gEfiSerialIoProtocolGuid
,
281 This
->DriverBindingHandle
,
283 EFI_OPEN_PROTOCOL_BY_DRIVER
285 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
289 if (Status
!= EFI_ALREADY_STARTED
) {
291 // If Serial I/O is not already open by this driver, then tag the handle
292 // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and
293 // StdErrDev variables with the list of possible terminal types on this
296 Status
= gBS
->OpenProtocol (
300 This
->DriverBindingHandle
,
302 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
304 if (EFI_ERROR (Status
)) {
305 Status
= gBS
->InstallMultipleProtocolInterfaces (
308 DuplicateDevicePath (ParentDevicePath
),
311 if (EFI_ERROR (Status
)) {
315 // if the serial device is a hot plug device, do not update the
316 // ConInDev, ConOutDev, and StdErrDev variables.
318 Status
= gBS
->OpenProtocol (
320 &gEfiHotPlugDeviceGuid
,
322 This
->DriverBindingHandle
,
324 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
326 if (EFI_ERROR (Status
)) {
327 TerminalUpdateConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
328 TerminalUpdateConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
329 TerminalUpdateConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
334 // Make sure a child handle does not already exist. This driver can only
335 // produce one child per serial port.
337 Status
= gBS
->OpenProtocolInformation (
339 &gEfiSerialIoProtocolGuid
,
343 if (!EFI_ERROR (Status
)) {
344 Status
= EFI_SUCCESS
;
345 for (Index
= 0; Index
< EntryCount
; Index
++) {
346 if (OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
347 Status
= EFI_ALREADY_STARTED
;
351 FreePool (OpenInfoBuffer
);
352 if (EFI_ERROR (Status
)) {
357 // If RemainingDevicePath is NULL, then create default device path node
359 if (RemainingDevicePath
== NULL
) {
360 DefaultNode
= AllocateZeroPool (sizeof (VENDOR_DEVICE_PATH
));
361 if (DefaultNode
== NULL
) {
362 Status
= EFI_OUT_OF_RESOURCES
;
366 TerminalType
= FixedPcdGet8 (PcdDefaultTerminalType
);
367 // must be between PcAnsiType (0) and VTUTF8Type (3)
368 ASSERT (TerminalType
<= VTUTF8Type
);
370 CopyMem (&DefaultNode
->Guid
, gTerminalType
[TerminalType
], sizeof (EFI_GUID
));
371 RemainingDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*)DefaultNode
;
374 // Use the RemainingDevicePath to determine the terminal type
376 Node
= (VENDOR_DEVICE_PATH
*)RemainingDevicePath
;
377 if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
378 TerminalType
= PcAnsiType
;
379 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
380 TerminalType
= VT100Type
;
381 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
382 TerminalType
= VT100PlusType
;
383 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
384 TerminalType
= VTUTF8Type
;
391 // Initialize the Terminal Dev
393 TerminalDevice
= AllocateCopyPool (sizeof (TERMINAL_DEV
), &gTerminalDevTemplate
);
394 if (TerminalDevice
== NULL
) {
395 Status
= EFI_OUT_OF_RESOURCES
;
399 TerminalDevice
->TerminalType
= TerminalType
;
400 TerminalDevice
->SerialIo
= SerialIo
;
402 InitializeListHead (&TerminalDevice
->NotifyList
);
403 Status
= gBS
->CreateEvent (
406 TerminalConInWaitForKeyEx
,
407 &TerminalDevice
->SimpleInputEx
,
408 &TerminalDevice
->SimpleInputEx
.WaitForKeyEx
410 if (EFI_ERROR (Status
)) {
415 Status
= gBS
->CreateEvent (
418 TerminalConInWaitForKey
,
419 &TerminalDevice
->SimpleInput
,
420 &TerminalDevice
->SimpleInput
.WaitForKey
422 if (EFI_ERROR (Status
)) {
426 // initialize the FIFO buffer used for accommodating
427 // the pre-read pending characters
429 InitializeRawFiFo (TerminalDevice
);
430 InitializeUnicodeFiFo (TerminalDevice
);
431 InitializeEfiKeyFiFo (TerminalDevice
);
434 // Set the timeout value of serial buffer for
435 // keystroke response performance issue
437 Mode
= TerminalDevice
->SerialIo
->Mode
;
440 if (Mode
->BaudRate
!= 0) {
441 SerialInTimeOut
= (1 + Mode
->DataBits
+ Mode
->StopBits
) * 2 * 1000000 / (UINTN
) Mode
->BaudRate
;
444 Status
= TerminalDevice
->SerialIo
->SetAttributes (
445 TerminalDevice
->SerialIo
,
447 Mode
->ReceiveFifoDepth
,
448 (UINT32
) SerialInTimeOut
,
449 (EFI_PARITY_TYPE
) (Mode
->Parity
),
450 (UINT8
) Mode
->DataBits
,
451 (EFI_STOP_BITS_TYPE
) (Mode
->StopBits
)
453 if (EFI_ERROR (Status
)) {
455 // if set attributes operation fails, invalidate
456 // the value of SerialInTimeOut,thus make it
457 // inconsistent with the default timeout value
458 // of serial buffer. This will invoke the recalculation
459 // in the readkeystroke routine.
461 TerminalDevice
->SerialInTimeOut
= 0;
463 TerminalDevice
->SerialInTimeOut
= SerialInTimeOut
;
466 // Build the device path for the child device
468 Status
= SetTerminalDevicePath (
469 TerminalDevice
->TerminalType
,
471 &TerminalDevice
->DevicePath
473 if (EFI_ERROR (Status
)) {
477 DevicePath
= TerminalDevice
->DevicePath
;
479 Status
= TerminalDevice
->SimpleInput
.Reset (
480 &TerminalDevice
->SimpleInput
,
483 if (EFI_ERROR (Status
)) {
485 // Need to report Error Code first
490 // Simple Text Output Protocol
492 TerminalDevice
->SimpleTextOutput
.Mode
= &TerminalDevice
->SimpleTextOutputMode
;
494 Status
= TerminalDevice
->SimpleTextOutput
.Reset (
495 &TerminalDevice
->SimpleTextOutput
,
498 if (EFI_ERROR (Status
)) {
502 Status
= TerminalDevice
->SimpleTextOutput
.SetMode (
503 &TerminalDevice
->SimpleTextOutput
,
506 if (EFI_ERROR (Status
)) {
510 Status
= TerminalDevice
->SimpleTextOutput
.EnableCursor (
511 &TerminalDevice
->SimpleTextOutput
,
514 if (EFI_ERROR (Status
)) {
518 Status
= gBS
->CreateEvent (
523 &TerminalDevice
->TwoSecondTimeOut
527 // Build the component name for the child device
529 TerminalDevice
->ControllerNameTable
= NULL
;
530 switch (TerminalDevice
->TerminalType
) {
534 gTerminalComponentName
.SupportedLanguages
,
535 &TerminalDevice
->ControllerNameTable
,
536 (CHAR16
*)L
"PC-ANSI Serial Console",
541 gTerminalComponentName2
.SupportedLanguages
,
542 &TerminalDevice
->ControllerNameTable
,
543 (CHAR16
*)L
"PC-ANSI Serial Console",
552 gTerminalComponentName
.SupportedLanguages
,
553 &TerminalDevice
->ControllerNameTable
,
554 (CHAR16
*)L
"VT-100 Serial Console",
559 gTerminalComponentName2
.SupportedLanguages
,
560 &TerminalDevice
->ControllerNameTable
,
561 (CHAR16
*)L
"VT-100 Serial Console",
570 gTerminalComponentName
.SupportedLanguages
,
571 &TerminalDevice
->ControllerNameTable
,
572 (CHAR16
*)L
"VT-100+ Serial Console",
577 gTerminalComponentName2
.SupportedLanguages
,
578 &TerminalDevice
->ControllerNameTable
,
579 (CHAR16
*)L
"VT-100+ Serial Console",
588 gTerminalComponentName
.SupportedLanguages
,
589 &TerminalDevice
->ControllerNameTable
,
590 (CHAR16
*)L
"VT-UTF8 Serial Console",
595 gTerminalComponentName2
.SupportedLanguages
,
596 &TerminalDevice
->ControllerNameTable
,
597 (CHAR16
*)L
"VT-UTF8 Serial Console",
604 // Install protocol interfaces for the serial device.
606 Status
= gBS
->InstallMultipleProtocolInterfaces (
607 &TerminalDevice
->Handle
,
608 &gEfiDevicePathProtocolGuid
,
609 TerminalDevice
->DevicePath
,
610 &gEfiSimpleTextInProtocolGuid
,
611 &TerminalDevice
->SimpleInput
,
612 &gEfiSimpleTextInputExProtocolGuid
,
613 &TerminalDevice
->SimpleInputEx
,
614 &gEfiSimpleTextOutProtocolGuid
,
615 &TerminalDevice
->SimpleTextOutput
,
618 if (EFI_ERROR (Status
)) {
622 // if the serial device is a hot plug device, attaches the HotPlugGuid
623 // onto the terminal device handle.
625 Status
= gBS
->OpenProtocol (
627 &gEfiHotPlugDeviceGuid
,
629 This
->DriverBindingHandle
,
631 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
633 if (!EFI_ERROR (Status
)) {
634 Status
= gBS
->InstallMultipleProtocolInterfaces (
635 &TerminalDevice
->Handle
,
636 &gEfiHotPlugDeviceGuid
,
642 // Register the Parent-Child relationship via
643 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
645 Status
= gBS
->OpenProtocol (
647 &gEfiSerialIoProtocolGuid
,
648 (VOID
**) &TerminalDevice
->SerialIo
,
649 This
->DriverBindingHandle
,
650 TerminalDevice
->Handle
,
651 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
653 if (EFI_ERROR (Status
)) {
657 if (DefaultNode
!= NULL
) {
658 FreePool (DefaultNode
);
665 // Report error code before exiting
667 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
668 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
669 PcdGet32 (PcdStatusCodeValueRemoteConsoleError
),
675 // Use the Stop() function to free all resources allocated in Start()
677 if (TerminalDevice
!= NULL
) {
679 if (TerminalDevice
->Handle
!= NULL
) {
680 This
->Stop (This
, Controller
, 1, &TerminalDevice
->Handle
);
683 if (TerminalDevice
->TwoSecondTimeOut
!= NULL
) {
684 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
687 if (TerminalDevice
->SimpleInput
.WaitForKey
!= NULL
) {
688 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
691 if (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
!= NULL
) {
692 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
695 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
697 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
698 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
701 if (TerminalDevice
->DevicePath
!= NULL
) {
702 FreePool (TerminalDevice
->DevicePath
);
705 FreePool (TerminalDevice
);
709 if (DefaultNode
!= NULL
) {
710 FreePool (DefaultNode
);
713 This
->Stop (This
, Controller
, 0, NULL
);
720 TerminalDriverBindingStop (
721 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
722 IN EFI_HANDLE Controller
,
723 IN UINTN NumberOfChildren
,
724 IN EFI_HANDLE
*ChildHandleBuffer
730 Stop a device controller.
734 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
735 Controller - A handle to the device being stopped.
736 NumberOfChildren - The number of child device handles in ChildHandleBuffer.
737 ChildHandleBuffer - An array of child handles to be freed.
741 EFI_SUCCESS - Operation successful.
742 EFI_DEVICE_ERROR - Devices error.
748 BOOLEAN AllChildrenStopped
;
749 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
750 TERMINAL_DEV
*TerminalDevice
;
751 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
752 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
753 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
755 Status
= gBS
->HandleProtocol (
757 &gEfiDevicePathProtocolGuid
,
758 (VOID
**) &DevicePath
760 if (EFI_ERROR (Status
)) {
765 // Complete all outstanding transactions to Controller.
766 // Don't allow any new transaction to Controller to be started.
768 if (NumberOfChildren
== 0) {
770 // Close the bus driver
772 Status
= gBS
->OpenProtocol (
775 (VOID
**) &ParentDevicePath
,
776 This
->DriverBindingHandle
,
778 EFI_OPEN_PROTOCOL_GET_PROTOCOL
780 if (!EFI_ERROR (Status
)) {
782 // Remove Parent Device Path from
783 // the Console Device Environment Variables
785 TerminalRemoveConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
786 TerminalRemoveConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
787 TerminalRemoveConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
790 // Uninstall the Terminal Driver's GUID Tag from the Serial controller
792 Status
= gBS
->UninstallMultipleProtocolInterfaces (
800 // Free the ParentDevicePath that was duplicated in Start()
802 if (!EFI_ERROR (Status
)) {
803 FreePool (ParentDevicePath
);
809 &gEfiSerialIoProtocolGuid
,
810 This
->DriverBindingHandle
,
816 &gEfiDevicePathProtocolGuid
,
817 This
->DriverBindingHandle
,
824 AllChildrenStopped
= TRUE
;
826 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
828 Status
= gBS
->OpenProtocol (
829 ChildHandleBuffer
[Index
],
830 &gEfiSimpleTextOutProtocolGuid
,
831 (VOID
**) &SimpleTextOutput
,
832 This
->DriverBindingHandle
,
833 ChildHandleBuffer
[Index
],
834 EFI_OPEN_PROTOCOL_GET_PROTOCOL
836 if (!EFI_ERROR (Status
)) {
838 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
842 &gEfiSerialIoProtocolGuid
,
843 This
->DriverBindingHandle
,
844 ChildHandleBuffer
[Index
]
847 Status
= gBS
->UninstallMultipleProtocolInterfaces (
848 ChildHandleBuffer
[Index
],
849 &gEfiSimpleTextInProtocolGuid
,
850 &TerminalDevice
->SimpleInput
,
851 &gEfiSimpleTextInputExProtocolGuid
,
852 &TerminalDevice
->SimpleInputEx
,
853 &gEfiSimpleTextOutProtocolGuid
,
854 &TerminalDevice
->SimpleTextOutput
,
855 &gEfiDevicePathProtocolGuid
,
856 TerminalDevice
->DevicePath
,
859 if (EFI_ERROR (Status
)) {
862 &gEfiSerialIoProtocolGuid
,
864 This
->DriverBindingHandle
,
865 ChildHandleBuffer
[Index
],
866 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
870 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
871 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
874 Status
= gBS
->OpenProtocol (
875 ChildHandleBuffer
[Index
],
876 &gEfiHotPlugDeviceGuid
,
878 This
->DriverBindingHandle
,
880 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
882 if (!EFI_ERROR (Status
)) {
883 Status
= gBS
->UninstallMultipleProtocolInterfaces (
884 ChildHandleBuffer
[Index
],
885 &gEfiHotPlugDeviceGuid
,
890 Status
= EFI_SUCCESS
;
893 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
894 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
895 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
896 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
897 FreePool (TerminalDevice
->DevicePath
);
898 FreePool (TerminalDevice
);
902 if (EFI_ERROR (Status
)) {
903 AllChildrenStopped
= FALSE
;
907 if (!AllChildrenStopped
) {
908 return EFI_DEVICE_ERROR
;
916 TerminalFreeNotifyList (
917 IN OUT LIST_ENTRY
*ListHead
925 ListHead - The list head
929 EFI_SUCCESS - Free the notify list successfully
930 EFI_INVALID_PARAMETER - ListHead is invalid.
934 TERMINAL_CONSOLE_IN_EX_NOTIFY
*NotifyNode
;
936 if (ListHead
== NULL
) {
937 return EFI_INVALID_PARAMETER
;
939 while (!IsListEmpty (ListHead
)) {
941 ListHead
->ForwardLink
,
942 TERMINAL_CONSOLE_IN_EX_NOTIFY
,
944 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
946 RemoveEntryList (ListHead
->ForwardLink
);
947 gBS
->FreePool (NotifyNode
);
956 TerminalUpdateConsoleDevVariable (
957 IN CHAR16
*VariableName
,
958 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
964 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
965 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
966 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
971 // Get global variable and its size according to the name given.
973 Variable
= TerminalGetVariableAndSize (
975 &gEfiGlobalVariableGuid
,
979 // Append terminal device path onto the variable.
981 for (TerminalType
= PcAnsiType
; TerminalType
<= VTUTF8Type
; TerminalType
++) {
982 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
983 NewVariable
= AppendDevicePathInstance (Variable
, TempDevicePath
);
984 if (Variable
!= NULL
) {
988 if (TempDevicePath
!= NULL
) {
989 FreePool (TempDevicePath
);
992 Variable
= NewVariable
;
995 VariableSize
= GetDevicePathSize (Variable
);
997 Status
= gRT
->SetVariable (
999 &gEfiGlobalVariableGuid
,
1000 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1004 ASSERT_EFI_ERROR (Status
);
1005 FreePool (Variable
);
1011 TerminalRemoveConsoleDevVariable (
1012 IN CHAR16
*VariableName
,
1013 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1017 Routine Description:
1019 Remove console device variable.
1023 VariableName - A pointer to the variable name.
1024 ParentDevicePath - A pointer to the parent device path.
1036 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
1037 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1038 EFI_DEVICE_PATH_PROTOCOL
*OriginalVariable
;
1039 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1040 EFI_DEVICE_PATH_PROTOCOL
*SavedNewVariable
;
1041 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1047 // Get global variable and its size according to the name given.
1049 Variable
= TerminalGetVariableAndSize (
1051 &gEfiGlobalVariableGuid
,
1054 if (Variable
== NULL
) {
1059 OriginalVariable
= Variable
;
1063 // Get first device path instance from Variable
1065 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1066 if (Instance
== NULL
) {
1067 FreePool (OriginalVariable
);
1071 // Loop through all the device path instances of Variable
1075 // Loop through all the terminal types that this driver supports
1078 for (TerminalType
= PcAnsiType
; TerminalType
<= VTUTF8Type
; TerminalType
++) {
1080 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1083 // Compare the genterated device path to the current device path instance
1085 if (TempDevicePath
!= NULL
) {
1086 if (CompareMem (Instance
, TempDevicePath
, InstanceSize
) == 0) {
1091 FreePool (TempDevicePath
);
1095 // If a match was not found, then keep the current device path instance
1098 SavedNewVariable
= NewVariable
;
1099 NewVariable
= AppendDevicePathInstance (NewVariable
, Instance
);
1100 if (SavedNewVariable
!= NULL
) {
1101 FreePool (SavedNewVariable
);
1105 // Get next device path instance from Variable
1107 FreePool (Instance
);
1108 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1109 } while (Instance
!= NULL
);
1111 FreePool (OriginalVariable
);
1114 VariableSize
= GetDevicePathSize (NewVariable
);
1116 Status
= gRT
->SetVariable (
1118 &gEfiGlobalVariableGuid
,
1119 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1123 ASSERT_EFI_ERROR (Status
);
1126 if (NewVariable
!= NULL
) {
1127 FreePool (NewVariable
);
1134 TerminalGetVariableAndSize (
1136 IN EFI_GUID
*VendorGuid
,
1137 OUT UINTN
*VariableSize
1141 Routine Description:
1142 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
1143 buffer, and the size of the buffer. On failure return NULL.
1146 Name - String part of EFI variable name
1148 VendorGuid - GUID part of EFI variable name
1150 VariableSize - Returns the size of the EFI variable that was read
1153 Dynamically allocated memory that contains a copy of the EFI variable.
1154 Caller is repsoncible freeing the buffer.
1156 NULL - Variable was not read
1167 // Pass in a small size buffer to find the actual variable size.
1170 Buffer
= AllocatePool (BufferSize
);
1171 if (Buffer
== NULL
) {
1176 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1178 if (Status
== EFI_SUCCESS
) {
1179 *VariableSize
= BufferSize
;
1182 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
1184 // Allocate the buffer to return
1187 Buffer
= AllocatePool (BufferSize
);
1188 if (Buffer
== NULL
) {
1193 // Read variable into the allocated buffer.
1195 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1196 if (EFI_ERROR (Status
)) {
1203 // Variable not found or other errors met.
1210 *VariableSize
= BufferSize
;
1215 SetTerminalDevicePath (
1216 IN UINT8 TerminalType
,
1217 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
1218 OUT EFI_DEVICE_PATH_PROTOCOL
**TerminalDevicePath
1221 VENDOR_DEVICE_PATH Node
;
1223 *TerminalDevicePath
= NULL
;
1224 Node
.Header
.Type
= MESSAGING_DEVICE_PATH
;
1225 Node
.Header
.SubType
= MSG_VENDOR_DP
;
1228 // generate terminal device path node according to terminal type.
1230 switch (TerminalType
) {
1265 return EFI_UNSUPPORTED
;
1269 SetDevicePathNodeLength (
1271 sizeof (VENDOR_DEVICE_PATH
)
1274 // append the terminal node onto parent device path
1275 // to generate a complete terminal device path.
1277 *TerminalDevicePath
= AppendDevicePathNode (
1279 (EFI_DEVICE_PATH_PROTOCOL
*) &Node
1281 if (*TerminalDevicePath
== NULL
) {
1282 return EFI_OUT_OF_RESOURCES
;
1290 IN TERMINAL_DEV
*TerminalDevice
1294 // Make the raw fifo empty.
1296 TerminalDevice
->RawFiFo
.Head
= TerminalDevice
->RawFiFo
.Tail
;
1300 InitializeUnicodeFiFo (
1301 IN TERMINAL_DEV
*TerminalDevice
1305 // Make the unicode fifo empty
1307 TerminalDevice
->UnicodeFiFo
.Head
= TerminalDevice
->UnicodeFiFo
.Tail
;
1311 InitializeEfiKeyFiFo (
1312 IN TERMINAL_DEV
*TerminalDevice
1316 // Make the efi key fifo empty
1318 TerminalDevice
->EfiKeyFiFo
.Head
= TerminalDevice
->EfiKeyFiFo
.Tail
;
1323 The user Entry Point for module Terminal. The user code starts with this function.
1325 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1326 @param[in] SystemTable A pointer to the EFI System Table.
1328 @retval EFI_SUCCESS The entry point is executed successfully.
1329 @retval other Some error occurs when executing this entry point.
1335 IN EFI_HANDLE ImageHandle
,
1336 IN EFI_SYSTEM_TABLE
*SystemTable
1342 // Install driver model protocol(s).
1344 Status
= EfiLibInstallDriverBindingComponentName2 (
1347 &gTerminalDriverBinding
,
1349 &gTerminalComponentName
,
1350 &gTerminalComponentName2
1352 ASSERT_EFI_ERROR (Status
);