3 Copyright (c) 2006 - 2007, 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.
20 #include "ConPlatform.h"
22 EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextInDriverBinding
= {
23 ConPlatformTextInDriverBindingSupported
,
24 ConPlatformTextInDriverBindingStart
,
25 ConPlatformTextInDriverBindingStop
,
31 EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextOutDriverBinding
= {
32 ConPlatformTextOutDriverBindingSupported
,
33 ConPlatformTextOutDriverBindingStart
,
34 ConPlatformTextOutDriverBindingStop
,
42 ConPlatformTextInDriverBindingSupported (
43 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
44 IN EFI_HANDLE ControllerHandle
,
45 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
53 (Standard DriverBinding Protocol Supported() function)
61 return ConPlatformDriverBindingSupported (
65 &gEfiSimpleTextInProtocolGuid
71 ConPlatformTextOutDriverBindingSupported (
72 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
73 IN EFI_HANDLE ControllerHandle
,
74 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
82 (Standard DriverBinding Protocol Supported() function)
90 return ConPlatformDriverBindingSupported (
94 &gEfiSimpleTextOutProtocolGuid
99 ConPlatformDriverBindingSupported (
100 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
101 IN EFI_HANDLE ControllerHandle
,
102 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
103 IN EFI_GUID
*ProtocolGuid
111 (Standard DriverBinding Protocol Supported() function)
123 // Test to see if this is a physical device by checking to see if
124 // it has a Device Path Protocol
126 Status
= gBS
->OpenProtocol (
128 &gEfiDevicePathProtocolGuid
,
130 This
->DriverBindingHandle
,
132 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
134 if (EFI_ERROR (Status
)) {
138 // Test to see if this device supports the Simple Text Output Protocol
140 Status
= gBS
->OpenProtocol (
143 (VOID
**) &Interface
,
144 This
->DriverBindingHandle
,
146 EFI_OPEN_PROTOCOL_BY_DRIVER
148 if (EFI_ERROR (Status
)) {
155 This
->DriverBindingHandle
,
164 ConPlatformTextInDriverBindingStart (
165 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
166 IN EFI_HANDLE ControllerHandle
,
167 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
175 (Standard DriverBinding Protocol Start() function)
183 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
184 EFI_SIMPLE_TEXT_IN_PROTOCOL
*TextIn
;
187 // Get the Device Path Protocol so the environment variables can be updated
189 Status
= gBS
->OpenProtocol (
191 &gEfiDevicePathProtocolGuid
,
192 (VOID
**) &DevicePath
,
193 This
->DriverBindingHandle
,
195 EFI_OPEN_PROTOCOL_GET_PROTOCOL
197 if (EFI_ERROR (Status
)) {
201 // Open the Simple Input Protocol BY_DRIVER
203 Status
= gBS
->OpenProtocol (
205 &gEfiSimpleTextInProtocolGuid
,
207 This
->DriverBindingHandle
,
209 EFI_OPEN_PROTOCOL_BY_DRIVER
211 if (EFI_ERROR (Status
)) {
215 // Check the device handle, if it is a hot plug device,
216 // do not put the device path into ConInDev, and install
217 // gEfiConsoleInDeviceGuid to the device handle directly.
218 // The policy is, make hot plug device plug in and play immediately.
220 if (IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
221 gBS
->InstallMultipleProtocolInterfaces (
223 &gEfiConsoleInDeviceGuid
,
229 // Append the device path to the ConInDev environment variable
231 ConPlatformUpdateDeviceVariable (
238 // If the device path is an instance in the ConIn environment variable,
239 // then install EfiConsoleInDeviceGuid onto ControllerHandle
241 Status
= ConPlatformUpdateDeviceVariable (
247 if (!EFI_ERROR (Status
)) {
248 gBS
->InstallMultipleProtocolInterfaces (
250 &gEfiConsoleInDeviceGuid
,
257 &gEfiSimpleTextInProtocolGuid
,
258 This
->DriverBindingHandle
,
269 ConPlatformTextOutDriverBindingStart (
270 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
271 IN EFI_HANDLE ControllerHandle
,
272 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
280 (Standard DriverBinding Protocol Start() function)
288 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
289 EFI_SIMPLE_TEXT_OUT_PROTOCOL
*TextOut
;
295 // Get the Device Path Protocol so the environment variables can be updated
297 Status
= gBS
->OpenProtocol (
299 &gEfiDevicePathProtocolGuid
,
300 (VOID
**) &DevicePath
,
301 This
->DriverBindingHandle
,
303 EFI_OPEN_PROTOCOL_GET_PROTOCOL
305 if (EFI_ERROR (Status
)) {
309 // Open the Simple Text Output Protocol BY_DRIVER
311 Status
= gBS
->OpenProtocol (
313 &gEfiSimpleTextOutProtocolGuid
,
315 This
->DriverBindingHandle
,
317 EFI_OPEN_PROTOCOL_BY_DRIVER
319 if (EFI_ERROR (Status
)) {
323 // Check the device handle, if it is a hot plug device,
324 // do not put the device path into ConOutDev and StdErrDev,
325 // and install gEfiConsoleOutDeviceGuid to the device handle directly.
326 // The policy is, make hot plug device plug in and play immediately.
328 if (IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
329 gBS
->InstallMultipleProtocolInterfaces (
331 &gEfiConsoleOutDeviceGuid
,
337 // Append the device path to the ConOutDev environment variable
339 ConPlatformUpdateDeviceVariable (
345 // Append the device path to the StdErrDev environment variable
347 ConPlatformUpdateDeviceVariable (
354 // If the device path is an instance in the ConOut environment variable,
355 // then install EfiConsoleOutDeviceGuid onto ControllerHandle
357 Status
= ConPlatformUpdateDeviceVariable (
363 if (!EFI_ERROR (Status
)) {
365 Status
= gBS
->InstallMultipleProtocolInterfaces (
367 &gEfiConsoleOutDeviceGuid
,
373 // If the device path is an instance in the StdErr environment variable,
374 // then install EfiStandardErrorDeviceGuid onto ControllerHandle
376 Status
= ConPlatformUpdateDeviceVariable (
381 if (!EFI_ERROR (Status
)) {
383 gBS
->InstallMultipleProtocolInterfaces (
385 &gEfiStandardErrorDeviceGuid
,
394 &gEfiSimpleTextOutProtocolGuid
,
395 This
->DriverBindingHandle
,
406 ConPlatformTextInDriverBindingStop (
407 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
408 IN EFI_HANDLE ControllerHandle
,
409 IN UINTN NumberOfChildren
,
410 IN EFI_HANDLE
*ChildHandleBuffer
417 (Standard DriverBinding Protocol Stop() function)
426 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
429 // hot plug device is not included into the console associated variables,
430 // so no need to check variable for those hot plug devices.
432 if (!IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
434 // Get the Device Path Protocol so the environment variables can be updated
436 Status
= gBS
->OpenProtocol (
438 &gEfiDevicePathProtocolGuid
,
439 (VOID
**) &DevicePath
,
440 This
->DriverBindingHandle
,
442 EFI_OPEN_PROTOCOL_GET_PROTOCOL
444 if (!EFI_ERROR (Status
)) {
446 // Remove DevicePath from ConInDev
448 ConPlatformUpdateDeviceVariable (
456 // Uninstall the Console Device GUIDs from Controller Handle
458 ConPlatformUnInstallProtocol (
461 &gEfiConsoleInDeviceGuid
465 // Close the Simple Input Protocol
469 &gEfiSimpleTextInProtocolGuid
,
470 This
->DriverBindingHandle
,
479 ConPlatformTextOutDriverBindingStop (
480 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
481 IN EFI_HANDLE ControllerHandle
,
482 IN UINTN NumberOfChildren
,
483 IN EFI_HANDLE
*ChildHandleBuffer
490 (Standard DriverBinding Protocol Stop() function)
499 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
502 // hot plug device is not included into the console associated variables,
503 // so no need to check variable for those hot plug devices.
505 if (!IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
507 // Get the Device Path Protocol so the environment variables can be updated
509 Status
= gBS
->OpenProtocol (
511 &gEfiDevicePathProtocolGuid
,
512 (VOID
**) &DevicePath
,
513 This
->DriverBindingHandle
,
515 EFI_OPEN_PROTOCOL_GET_PROTOCOL
517 if (!EFI_ERROR (Status
)) {
519 // Remove DevicePath from ConOutDev, and StdErrDev
521 ConPlatformUpdateDeviceVariable (
526 ConPlatformUpdateDeviceVariable (
534 // Uninstall the Console Device GUIDs from Controller Handle
536 ConPlatformUnInstallProtocol (
539 &gEfiConsoleOutDeviceGuid
542 ConPlatformUnInstallProtocol (
545 &gEfiStandardErrorDeviceGuid
549 // Close the Simple Text Output Protocol
553 &gEfiSimpleTextOutProtocolGuid
,
554 This
->DriverBindingHandle
,
563 ConPlatformUnInstallProtocol (
564 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
565 IN EFI_HANDLE Handle
,
566 IN EFI_GUID
*ProtocolGuid
571 Status
= gBS
->OpenProtocol (
575 This
->DriverBindingHandle
,
577 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
580 if (!EFI_ERROR (Status
)) {
581 gBS
->UninstallMultipleProtocolInterfaces (
593 ConPlatformGetVariable (
599 Read the EFI variable (Name) and return a dynamically allocated
600 buffer, and the size of the buffer. On failure return NULL.
603 Name - String part of EFI variable name
606 Dynamically allocated memory that contains a copy of the EFI variable.
607 Caller is repsoncible freeing the buffer.
609 NULL - Variable was not read
621 // Test to see if the variable exists. If it doesn't reuturn NULL
623 Status
= gRT
->GetVariable (
625 &gEfiGlobalVariableGuid
,
631 if (Status
== EFI_BUFFER_TOO_SMALL
) {
633 // Allocate the buffer to return
635 Buffer
= AllocatePool (BufferSize
);
636 if (Buffer
== NULL
) {
640 // Read variable into the allocated buffer.
642 Status
= gRT
->GetVariable (
644 &gEfiGlobalVariableGuid
,
649 if (EFI_ERROR (Status
)) {
659 ConPlatformMatchDevicePaths (
660 IN EFI_DEVICE_PATH_PROTOCOL
* Multi
,
661 IN EFI_DEVICE_PATH_PROTOCOL
* Single
,
662 IN EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath OPTIONAL
,
668 Function compares a device path data structure to that of all the nodes of a
669 second device path instance.
672 Multi - A pointer to a multi-instance device path data structure.
674 Single - A pointer to a single-instance device path data structure.
676 NewDevicePath - If Delete is TRUE, this parameter must not be null, and it
677 points to the remaining device path data structure.
678 (remaining device path = Multi - Single.)
680 Delete - If TRUE, means removing Single from Multi.
681 If FALSE, the routine just check whether Single matches
682 with any instance in Multi.
686 The function returns EFI_SUCCESS if the Single is contained within Multi.
687 Otherwise, EFI_NOT_FOUND is returned.
691 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
692 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath1
;
693 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath2
;
694 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
698 // The passed in DevicePath should not be NULL
700 if ((!Multi
) || (!Single
)) {
701 return EFI_NOT_FOUND
;
704 // if performing Delete operation, the NewDevicePath must not be NULL.
706 TempDevicePath1
= NULL
;
709 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
712 // search for the match of 'Single' in 'Multi'
714 while (DevicePathInst
) {
715 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
717 FreePool (DevicePathInst
);
722 TempDevicePath2
= AppendDevicePathInstance (
726 if (TempDevicePath1
!= NULL
) {
727 FreePool (TempDevicePath1
);
729 TempDevicePath1
= TempDevicePath2
;
733 FreePool (DevicePathInst
);
734 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
738 *NewDevicePath
= TempDevicePath1
;
742 return EFI_NOT_FOUND
;
746 ConPlatformUpdateDeviceVariable (
747 IN CHAR16
*VariableName
,
748 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
749 IN CONPLATFORM_VAR_OPERATION Operation
765 EFI_DEVICE_PATH_PROTOCOL
*VariableDevicePath
;
766 EFI_DEVICE_PATH_PROTOCOL
*NewVariableDevicePath
;
768 VariableDevicePath
= NULL
;
769 NewVariableDevicePath
= NULL
;
772 // Get Variable according to variable name.
773 // The memory for Variable is allocated within ConPlatformGetVarible(),
774 // it is the caller's responsibility to free the memory before return.
776 VariableDevicePath
= ConPlatformGetVariable (VariableName
);
778 if (Operation
!= DELETE
) {
780 Status
= ConPlatformMatchDevicePaths (
787 if ((Operation
== CHECK
) || (!EFI_ERROR (Status
))) {
789 // The device path is already in the variable
791 if (VariableDevicePath
!= NULL
) {
792 FreePool (VariableDevicePath
);
798 // The device path is not in variable. Append DevicePath to the
799 // environment variable that is a multi-instance device path.
801 Status
= EFI_SUCCESS
;
802 NewVariableDevicePath
= AppendDevicePathInstance (
806 if (NewVariableDevicePath
== NULL
) {
807 Status
= EFI_OUT_OF_RESOURCES
;
812 // Remove DevicePath from the environment variable that
813 // is a multi-instance device path.
815 Status
= ConPlatformMatchDevicePaths (
818 &NewVariableDevicePath
,
823 if (VariableDevicePath
!= NULL
) {
824 FreePool (VariableDevicePath
);
827 if (EFI_ERROR (Status
)) {
831 Status
= gRT
->SetVariable (
833 &gEfiGlobalVariableGuid
,
834 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
835 GetDevicePathSize (NewVariableDevicePath
),
836 NewVariableDevicePath
839 FreePool (NewVariableDevicePath
);
846 EFI_HANDLE DriverBindingHandle
,
847 EFI_HANDLE ControllerHandle
853 // HotPlugDeviceGuid indicates ControllerHandle stands for a hot plug device.
855 Status
= gBS
->OpenProtocol (
857 &gEfiHotPlugDeviceGuid
,
861 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
863 if (EFI_ERROR (Status
)) {