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.
28 EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding
= {
29 TerminalDriverBindingSupported
,
30 TerminalDriverBindingStart
,
31 TerminalDriverBindingStop
,
38 EFI_GUID
*gTerminalType
[] = {
46 TERMINAL_DEV gTerminalDevTemplate
= {
47 TERMINAL_DEV_SIGNATURE
,
54 TerminalConInReadKeyStroke
,
59 TerminalConOutOutputString
,
60 TerminalConOutTestString
,
61 TerminalConOutQueryMode
,
62 TerminalConOutSetMode
,
63 TerminalConOutSetAttribute
,
64 TerminalConOutClearScreen
,
65 TerminalConOutSetCursorPosition
,
66 TerminalConOutEnableCursor
,
69 { // SimpleTextOutputMode
72 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
), // Attribute
93 NULL
, // ControllerNameTable
104 TerminalDriverBindingSupported (
105 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
106 IN EFI_HANDLE Controller
,
107 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
111 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
112 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
113 VENDOR_DEVICE_PATH
*Node
;
116 // If remaining device path is not NULL, then make sure it is a
117 // device path that describes a terminal communications protocol.
119 if (RemainingDevicePath
!= NULL
) {
121 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
123 if (Node
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
124 Node
->Header
.SubType
!= MSG_VENDOR_DP
||
125 DevicePathNodeLength(&Node
->Header
) != sizeof(VENDOR_DEVICE_PATH
)) {
127 return EFI_UNSUPPORTED
;
131 // only supports PC ANSI, VT100, VT100+ and VT-UTF8 terminal types
133 if (!CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
) &&
134 !CompareGuid (&Node
->Guid
, &gEfiVT100Guid
) &&
135 !CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
) &&
136 !CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
138 return EFI_UNSUPPORTED
;
142 // Open the IO Abstraction(s) needed to perform the supported test
144 Status
= gBS
->OpenProtocol (
146 &gEfiDevicePathProtocolGuid
,
147 (VOID
**) &ParentDevicePath
,
148 This
->DriverBindingHandle
,
150 EFI_OPEN_PROTOCOL_BY_DRIVER
152 if (Status
== EFI_ALREADY_STARTED
) {
156 if (EFI_ERROR (Status
)) {
162 &gEfiDevicePathProtocolGuid
,
163 This
->DriverBindingHandle
,
168 // The Controller must support the Serial I/O Protocol.
169 // This driver is a bus driver with at most 1 child device, so it is
170 // ok for it to be already started.
172 Status
= gBS
->OpenProtocol (
174 &gEfiSerialIoProtocolGuid
,
176 This
->DriverBindingHandle
,
178 EFI_OPEN_PROTOCOL_BY_DRIVER
180 if (Status
== EFI_ALREADY_STARTED
) {
184 if (EFI_ERROR (Status
)) {
188 // Close the I/O Abstraction(s) used to perform the supported test
192 &gEfiSerialIoProtocolGuid
,
193 This
->DriverBindingHandle
,
202 TerminalDriverBindingStart (
203 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
204 IN EFI_HANDLE Controller
,
205 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
211 Start the controller.
215 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
216 Controller - The handle of the controller to start.
217 RemainingDevicePath - A pointer to the remaining portion of a devcie path.
226 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
227 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
228 VENDOR_DEVICE_PATH
*Node
;
229 VENDOR_DEVICE_PATH
*DefaultNode
;
230 EFI_SERIAL_IO_MODE
*Mode
;
231 UINTN SerialInTimeOut
;
232 TERMINAL_DEV
*TerminalDevice
;
234 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
237 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
239 TerminalDevice
= NULL
;
242 // Get the Device Path Protocol to build the device path of the child device
244 Status
= gBS
->OpenProtocol (
246 &gEfiDevicePathProtocolGuid
,
247 (VOID
**) &ParentDevicePath
,
248 This
->DriverBindingHandle
,
250 EFI_OPEN_PROTOCOL_BY_DRIVER
252 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
257 // Open the Serial I/O Protocol BY_DRIVER. It might already be started.
259 Status
= gBS
->OpenProtocol (
261 &gEfiSerialIoProtocolGuid
,
263 This
->DriverBindingHandle
,
265 EFI_OPEN_PROTOCOL_BY_DRIVER
267 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
271 if (Status
!= EFI_ALREADY_STARTED
) {
273 // If Serial I/O is not already open by this driver, then tag the handle
274 // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and
275 // StdErrDev variables with the list of possible terminal types on this
278 Status
= gBS
->OpenProtocol (
282 This
->DriverBindingHandle
,
284 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
286 if (EFI_ERROR (Status
)) {
287 Status
= gBS
->InstallMultipleProtocolInterfaces (
290 DuplicateDevicePath (ParentDevicePath
),
293 if (EFI_ERROR (Status
)) {
297 // if the serial device is a hot plug device, do not update the
298 // ConInDev, ConOutDev, and StdErrDev variables.
300 Status
= gBS
->OpenProtocol (
302 &gEfiHotPlugDeviceGuid
,
304 This
->DriverBindingHandle
,
306 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
308 if (EFI_ERROR (Status
)) {
309 TerminalUpdateConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
310 TerminalUpdateConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
311 TerminalUpdateConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
316 // Make sure a child handle does not already exist. This driver can only
317 // produce one child per serial port.
319 Status
= gBS
->OpenProtocolInformation (
321 &gEfiSerialIoProtocolGuid
,
325 if (!EFI_ERROR (Status
)) {
326 Status
= EFI_SUCCESS
;
327 for (Index
= 0; Index
< EntryCount
; Index
++) {
328 if (OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
329 Status
= EFI_ALREADY_STARTED
;
333 FreePool (OpenInfoBuffer
);
334 if (EFI_ERROR (Status
)) {
339 // If RemainingDevicePath is NULL, then create default device path node
341 if (RemainingDevicePath
== NULL
) {
342 DefaultNode
= AllocateZeroPool (sizeof (VENDOR_DEVICE_PATH
));
343 if (DefaultNode
== NULL
) {
344 Status
= EFI_OUT_OF_RESOURCES
;
348 TerminalType
= FixedPcdGet8 (PcdDefaultTerminalType
);
349 // must be between PcAnsiType (0) and VTUTF8Type (3)
350 ASSERT (TerminalType
<= VTUTF8Type
);
352 CopyMem (&DefaultNode
->Guid
, gTerminalType
[TerminalType
], sizeof (EFI_GUID
));
353 RemainingDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*)DefaultNode
;
356 // Use the RemainingDevicePath to determine the terminal type
358 Node
= (VENDOR_DEVICE_PATH
*)RemainingDevicePath
;
359 if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
360 TerminalType
= PcAnsiType
;
361 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
362 TerminalType
= VT100Type
;
363 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
364 TerminalType
= VT100PlusType
;
365 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
366 TerminalType
= VTUTF8Type
;
373 // Initialize the Terminal Dev
375 TerminalDevice
= AllocateCopyPool (sizeof (TERMINAL_DEV
), &gTerminalDevTemplate
);
376 if (TerminalDevice
== NULL
) {
377 Status
= EFI_OUT_OF_RESOURCES
;
381 TerminalDevice
->TerminalType
= TerminalType
;
382 TerminalDevice
->SerialIo
= SerialIo
;
384 Status
= gBS
->CreateEvent (
387 TerminalConInWaitForKey
,
388 &TerminalDevice
->SimpleInput
,
389 &TerminalDevice
->SimpleInput
.WaitForKey
391 if (EFI_ERROR (Status
)) {
396 // initialize the FIFO buffer used for accommodating
397 // the pre-read pending characters
399 InitializeRawFiFo (TerminalDevice
);
400 InitializeUnicodeFiFo (TerminalDevice
);
401 InitializeEfiKeyFiFo (TerminalDevice
);
404 // Set the timeout value of serial buffer for
405 // keystroke response performance issue
407 Mode
= TerminalDevice
->SerialIo
->Mode
;
409 if (Mode
->BaudRate
!= 0) {
410 SerialInTimeOut
= (1 + Mode
->DataBits
+ Mode
->StopBits
) * 2 * 1000000 / (UINTN
) Mode
->BaudRate
;
413 Status
= TerminalDevice
->SerialIo
->SetAttributes (
414 TerminalDevice
->SerialIo
,
416 Mode
->ReceiveFifoDepth
,
417 (UINT32
) SerialInTimeOut
,
418 (EFI_PARITY_TYPE
) (Mode
->Parity
),
419 (UINT8
) Mode
->DataBits
,
420 (EFI_STOP_BITS_TYPE
) (Mode
->StopBits
)
422 if (EFI_ERROR (Status
)) {
424 // if set attributes operation fails, invalidate
425 // the value of SerialInTimeOut,thus make it
426 // inconsistent with the default timeout value
427 // of serial buffer. This will invoke the recalculation
428 // in the readkeystroke routine.
430 TerminalDevice
->SerialInTimeOut
= 0;
432 TerminalDevice
->SerialInTimeOut
= SerialInTimeOut
;
435 // Build the device path for the child device
437 Status
= SetTerminalDevicePath (
438 TerminalDevice
->TerminalType
,
440 &TerminalDevice
->DevicePath
442 if (EFI_ERROR (Status
)) {
446 DevicePath
= TerminalDevice
->DevicePath
;
448 Status
= TerminalDevice
->SimpleInput
.Reset (
449 &TerminalDevice
->SimpleInput
,
452 if (EFI_ERROR (Status
)) {
454 // Need to report Error Code first
459 // Simple Text Output Protocol
461 TerminalDevice
->SimpleTextOutput
.Mode
= &TerminalDevice
->SimpleTextOutputMode
;
463 Status
= TerminalDevice
->SimpleTextOutput
.Reset (
464 &TerminalDevice
->SimpleTextOutput
,
467 if (EFI_ERROR (Status
)) {
471 Status
= TerminalDevice
->SimpleTextOutput
.SetMode (
472 &TerminalDevice
->SimpleTextOutput
,
475 if (EFI_ERROR (Status
)) {
479 Status
= TerminalDevice
->SimpleTextOutput
.EnableCursor (
480 &TerminalDevice
->SimpleTextOutput
,
483 if (EFI_ERROR (Status
)) {
487 Status
= gBS
->CreateEvent (
492 &TerminalDevice
->TwoSecondTimeOut
496 // Build the component name for the child device
498 TerminalDevice
->ControllerNameTable
= NULL
;
499 switch (TerminalDevice
->TerminalType
) {
503 gTerminalComponentName
.SupportedLanguages
,
504 &TerminalDevice
->ControllerNameTable
,
505 (CHAR16
*)L
"PC-ANSI Serial Console"
512 gTerminalComponentName
.SupportedLanguages
,
513 &TerminalDevice
->ControllerNameTable
,
514 (CHAR16
*)L
"VT-100 Serial Console"
521 gTerminalComponentName
.SupportedLanguages
,
522 &TerminalDevice
->ControllerNameTable
,
523 (CHAR16
*)L
"VT-100+ Serial Console"
530 gTerminalComponentName
.SupportedLanguages
,
531 &TerminalDevice
->ControllerNameTable
,
532 (CHAR16
*)L
"VT-UTF8 Serial Console"
537 // Install protocol interfaces for the serial device.
539 Status
= gBS
->InstallMultipleProtocolInterfaces (
540 &TerminalDevice
->Handle
,
541 &gEfiDevicePathProtocolGuid
,
542 TerminalDevice
->DevicePath
,
543 &gEfiSimpleTextInProtocolGuid
,
544 &TerminalDevice
->SimpleInput
,
545 &gEfiSimpleTextOutProtocolGuid
,
546 &TerminalDevice
->SimpleTextOutput
,
549 if (EFI_ERROR (Status
)) {
553 // if the serial device is a hot plug device, attaches the HotPlugGuid
554 // onto the terminal device handle.
556 Status
= gBS
->OpenProtocol (
558 &gEfiHotPlugDeviceGuid
,
560 This
->DriverBindingHandle
,
562 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
564 if (!EFI_ERROR (Status
)) {
565 Status
= gBS
->InstallMultipleProtocolInterfaces (
566 &TerminalDevice
->Handle
,
567 &gEfiHotPlugDeviceGuid
,
573 // Register the Parent-Child relationship via
574 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
576 Status
= gBS
->OpenProtocol (
578 &gEfiSerialIoProtocolGuid
,
579 (VOID
**) &TerminalDevice
->SerialIo
,
580 This
->DriverBindingHandle
,
581 TerminalDevice
->Handle
,
582 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
584 if (EFI_ERROR (Status
)) {
588 if (DefaultNode
!= NULL
) {
589 FreePool (DefaultNode
);
596 // Report error code before exiting
598 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
599 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
600 PcdGet32 (PcdStatusCodeValueRemoteConsoleError
),
606 // Use the Stop() function to free all resources allocated in Start()
608 if (TerminalDevice
!= NULL
) {
610 if (TerminalDevice
->Handle
!= NULL
) {
611 This
->Stop (This
, Controller
, 1, &TerminalDevice
->Handle
);
614 if (TerminalDevice
->TwoSecondTimeOut
!= NULL
) {
615 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
618 if (TerminalDevice
->SimpleInput
.WaitForKey
!= NULL
) {
619 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
622 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
623 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
626 if (TerminalDevice
->DevicePath
!= NULL
) {
627 FreePool (TerminalDevice
->DevicePath
);
630 FreePool (TerminalDevice
);
634 if (DefaultNode
!= NULL
) {
635 FreePool (DefaultNode
);
638 This
->Stop (This
, Controller
, 0, NULL
);
645 TerminalDriverBindingStop (
646 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
647 IN EFI_HANDLE Controller
,
648 IN UINTN NumberOfChildren
,
649 IN EFI_HANDLE
*ChildHandleBuffer
655 Stop a device controller.
659 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
660 Controller - A handle to the device being stopped.
661 NumberOfChildren - The number of child device handles in ChildHandleBuffer.
662 ChildHandleBuffer - An array of child handles to be freed.
666 EFI_SUCCESS - Operation successful.
667 EFI_DEVICE_ERROR - Devices error.
673 BOOLEAN AllChildrenStopped
;
674 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
675 TERMINAL_DEV
*TerminalDevice
;
676 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
677 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
678 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
680 Status
= gBS
->HandleProtocol (
682 &gEfiDevicePathProtocolGuid
,
683 (VOID
**) &DevicePath
685 if (EFI_ERROR (Status
)) {
690 // Complete all outstanding transactions to Controller.
691 // Don't allow any new transaction to Controller to be started.
693 if (NumberOfChildren
== 0) {
695 // Close the bus driver
697 Status
= gBS
->OpenProtocol (
700 (VOID
**) &ParentDevicePath
,
701 This
->DriverBindingHandle
,
703 EFI_OPEN_PROTOCOL_GET_PROTOCOL
705 if (!EFI_ERROR (Status
)) {
707 // Remove Parent Device Path from
708 // the Console Device Environment Variables
710 TerminalRemoveConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
711 TerminalRemoveConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
712 TerminalRemoveConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
715 // Uninstall the Terminal Driver's GUID Tag from the Serial controller
717 Status
= gBS
->UninstallMultipleProtocolInterfaces (
725 // Free the ParentDevicePath that was duplicated in Start()
727 if (!EFI_ERROR (Status
)) {
728 FreePool (ParentDevicePath
);
734 &gEfiSerialIoProtocolGuid
,
735 This
->DriverBindingHandle
,
741 &gEfiDevicePathProtocolGuid
,
742 This
->DriverBindingHandle
,
749 AllChildrenStopped
= TRUE
;
751 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
753 Status
= gBS
->OpenProtocol (
754 ChildHandleBuffer
[Index
],
755 &gEfiSimpleTextOutProtocolGuid
,
756 (VOID
**) &SimpleTextOutput
,
757 This
->DriverBindingHandle
,
758 ChildHandleBuffer
[Index
],
759 EFI_OPEN_PROTOCOL_GET_PROTOCOL
761 if (!EFI_ERROR (Status
)) {
763 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
767 &gEfiSerialIoProtocolGuid
,
768 This
->DriverBindingHandle
,
769 ChildHandleBuffer
[Index
]
772 Status
= gBS
->UninstallMultipleProtocolInterfaces (
773 ChildHandleBuffer
[Index
],
774 &gEfiSimpleTextInProtocolGuid
,
775 &TerminalDevice
->SimpleInput
,
776 &gEfiSimpleTextOutProtocolGuid
,
777 &TerminalDevice
->SimpleTextOutput
,
778 &gEfiDevicePathProtocolGuid
,
779 TerminalDevice
->DevicePath
,
782 if (EFI_ERROR (Status
)) {
785 &gEfiSerialIoProtocolGuid
,
787 This
->DriverBindingHandle
,
788 ChildHandleBuffer
[Index
],
789 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
793 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
794 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
797 Status
= gBS
->OpenProtocol (
798 ChildHandleBuffer
[Index
],
799 &gEfiHotPlugDeviceGuid
,
801 This
->DriverBindingHandle
,
803 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
805 if (!EFI_ERROR (Status
)) {
806 Status
= gBS
->UninstallMultipleProtocolInterfaces (
807 ChildHandleBuffer
[Index
],
808 &gEfiHotPlugDeviceGuid
,
813 Status
= EFI_SUCCESS
;
816 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
817 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
818 FreePool (TerminalDevice
->DevicePath
);
819 FreePool (TerminalDevice
);
823 if (EFI_ERROR (Status
)) {
824 AllChildrenStopped
= FALSE
;
828 if (!AllChildrenStopped
) {
829 return EFI_DEVICE_ERROR
;
836 TerminalUpdateConsoleDevVariable (
837 IN CHAR16
*VariableName
,
838 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
844 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
845 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
846 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
851 // Get global variable and its size according to the name given.
853 Variable
= TerminalGetVariableAndSize (
855 &gEfiGlobalVariableGuid
,
859 // Append terminal device path onto the variable.
861 for (TerminalType
= PcAnsiType
; TerminalType
<= VTUTF8Type
; TerminalType
++) {
862 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
863 NewVariable
= AppendDevicePathInstance (Variable
, TempDevicePath
);
864 if (Variable
!= NULL
) {
868 if (TempDevicePath
!= NULL
) {
869 FreePool (TempDevicePath
);
872 Variable
= NewVariable
;
875 VariableSize
= GetDevicePathSize (Variable
);
877 Status
= gRT
->SetVariable (
879 &gEfiGlobalVariableGuid
,
880 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
884 ASSERT_EFI_ERROR (Status
);
891 TerminalRemoveConsoleDevVariable (
892 IN CHAR16
*VariableName
,
893 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
899 Remove console device variable.
903 VariableName - A pointer to the variable name.
904 ParentDevicePath - A pointer to the parent device path.
916 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
917 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
918 EFI_DEVICE_PATH_PROTOCOL
*OriginalVariable
;
919 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
920 EFI_DEVICE_PATH_PROTOCOL
*SavedNewVariable
;
921 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
927 // Get global variable and its size according to the name given.
929 Variable
= TerminalGetVariableAndSize (
931 &gEfiGlobalVariableGuid
,
934 if (Variable
== NULL
) {
939 OriginalVariable
= Variable
;
943 // Get first device path instance from Variable
945 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
946 if (Instance
== NULL
) {
947 FreePool (OriginalVariable
);
951 // Loop through all the device path instances of Variable
955 // Loop through all the terminal types that this driver supports
958 for (TerminalType
= PcAnsiType
; TerminalType
<= VTUTF8Type
; TerminalType
++) {
960 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
963 // Compare the genterated device path to the current device path instance
965 if (TempDevicePath
!= NULL
) {
966 if (CompareMem (Instance
, TempDevicePath
, InstanceSize
) == 0) {
971 FreePool (TempDevicePath
);
975 // If a match was not found, then keep the current device path instance
978 SavedNewVariable
= NewVariable
;
979 NewVariable
= AppendDevicePathInstance (NewVariable
, Instance
);
980 if (SavedNewVariable
!= NULL
) {
981 FreePool (SavedNewVariable
);
985 // Get next device path instance from Variable
988 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
989 } while (Instance
!= NULL
);
991 FreePool (OriginalVariable
);
994 VariableSize
= GetDevicePathSize (NewVariable
);
996 Status
= gRT
->SetVariable (
998 &gEfiGlobalVariableGuid
,
999 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1003 ASSERT_EFI_ERROR (Status
);
1006 if (NewVariable
!= NULL
) {
1007 FreePool (NewVariable
);
1014 TerminalGetVariableAndSize (
1016 IN EFI_GUID
*VendorGuid
,
1017 OUT UINTN
*VariableSize
1021 Routine Description:
1022 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
1023 buffer, and the size of the buffer. On failure return NULL.
1026 Name - String part of EFI variable name
1028 VendorGuid - GUID part of EFI variable name
1030 VariableSize - Returns the size of the EFI variable that was read
1033 Dynamically allocated memory that contains a copy of the EFI variable.
1034 Caller is repsoncible freeing the buffer.
1036 NULL - Variable was not read
1047 // Pass in a small size buffer to find the actual variable size.
1050 Buffer
= AllocatePool (BufferSize
);
1051 if (Buffer
== NULL
) {
1056 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1058 if (Status
== EFI_SUCCESS
) {
1059 *VariableSize
= BufferSize
;
1062 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
1064 // Allocate the buffer to return
1067 Buffer
= AllocatePool (BufferSize
);
1068 if (Buffer
== NULL
) {
1073 // Read variable into the allocated buffer.
1075 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1076 if (EFI_ERROR (Status
)) {
1083 // Variable not found or other errors met.
1090 *VariableSize
= BufferSize
;
1095 SetTerminalDevicePath (
1096 IN UINT8 TerminalType
,
1097 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
1098 OUT EFI_DEVICE_PATH_PROTOCOL
**TerminalDevicePath
1101 VENDOR_DEVICE_PATH Node
;
1103 *TerminalDevicePath
= NULL
;
1104 Node
.Header
.Type
= MESSAGING_DEVICE_PATH
;
1105 Node
.Header
.SubType
= MSG_VENDOR_DP
;
1108 // generate terminal device path node according to terminal type.
1110 switch (TerminalType
) {
1145 return EFI_UNSUPPORTED
;
1149 SetDevicePathNodeLength (
1151 sizeof (VENDOR_DEVICE_PATH
)
1154 // append the terminal node onto parent device path
1155 // to generate a complete terminal device path.
1157 *TerminalDevicePath
= AppendDevicePathNode (
1159 (EFI_DEVICE_PATH_PROTOCOL
*) &Node
1161 if (*TerminalDevicePath
== NULL
) {
1162 return EFI_OUT_OF_RESOURCES
;
1170 IN TERMINAL_DEV
*TerminalDevice
1174 // Make the raw fifo empty.
1176 TerminalDevice
->RawFiFo
.Head
= TerminalDevice
->RawFiFo
.Tail
;
1180 InitializeUnicodeFiFo (
1181 IN TERMINAL_DEV
*TerminalDevice
1185 // Make the unicode fifo empty
1187 TerminalDevice
->UnicodeFiFo
.Head
= TerminalDevice
->UnicodeFiFo
.Tail
;
1191 InitializeEfiKeyFiFo (
1192 IN TERMINAL_DEV
*TerminalDevice
1196 // Make the efi key fifo empty
1198 TerminalDevice
->EfiKeyFiFo
.Head
= TerminalDevice
->EfiKeyFiFo
.Tail
;
1203 The user Entry Point for module Terminal. The user code starts with this function.
1205 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1206 @param[in] SystemTable A pointer to the EFI System Table.
1208 @retval EFI_SUCCESS The entry point is executed successfully.
1209 @retval other Some error occurs when executing this entry point.
1215 IN EFI_HANDLE ImageHandle
,
1216 IN EFI_SYSTEM_TABLE
*SystemTable
1222 // Install driver model protocol(s).
1224 Status
= EfiLibInstallAllDriverProtocols (
1227 &gTerminalDriverBinding
,
1229 &gTerminalComponentName
,
1233 ASSERT_EFI_ERROR (Status
);