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.
20 #include "ConPlatform.h"
22 EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextInDriverBinding
= {
23 ConPlatformTextInDriverBindingSupported
,
24 ConPlatformTextInDriverBindingStart
,
25 ConPlatformDriverBindingStop
,
31 EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextOutDriverBinding
= {
32 ConPlatformTextOutDriverBindingSupported
,
33 ConPlatformTextOutDriverBindingStart
,
34 ConPlatformDriverBindingStop
,
43 ConPlatformTextInDriverBindingSupported (
44 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
45 IN EFI_HANDLE ControllerHandle
,
46 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
54 (Standard DriverBinding Protocol Supported() function)
62 return ConPlatformDriverBindingSupported (
66 &gEfiSimpleTextInProtocolGuid
73 ConPlatformTextOutDriverBindingSupported (
74 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
75 IN EFI_HANDLE ControllerHandle
,
76 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
84 (Standard DriverBinding Protocol Supported() function)
92 return ConPlatformDriverBindingSupported (
96 &gEfiSimpleTextOutProtocolGuid
101 ConPlatformDriverBindingSupported (
102 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
103 IN EFI_HANDLE ControllerHandle
,
104 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
105 IN EFI_GUID
*ProtocolGuid
113 (Standard DriverBinding Protocol Supported() function)
125 // Test to see if this is a physical device by checking to see if
126 // it has a Device Path Protocol
128 Status
= gBS
->OpenProtocol (
130 &gEfiDevicePathProtocolGuid
,
132 This
->DriverBindingHandle
,
134 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
136 if (EFI_ERROR (Status
)) {
140 // Test to see if this device supports the Simple Text Output Protocol
142 Status
= gBS
->OpenProtocol (
145 (VOID
**) &Interface
,
146 This
->DriverBindingHandle
,
148 EFI_OPEN_PROTOCOL_BY_DRIVER
150 if (EFI_ERROR (Status
)) {
157 This
->DriverBindingHandle
,
167 ConPlatformTextInDriverBindingStart (
168 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
169 IN EFI_HANDLE ControllerHandle
,
170 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
178 (Standard DriverBinding Protocol Start() function)
186 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
187 EFI_SIMPLE_TEXT_IN_PROTOCOL
*TextIn
;
190 // Get the Device Path Protocol so the environment variables can be updated
192 Status
= gBS
->OpenProtocol (
194 &gEfiDevicePathProtocolGuid
,
195 (VOID
**) &DevicePath
,
196 This
->DriverBindingHandle
,
198 EFI_OPEN_PROTOCOL_GET_PROTOCOL
200 if (EFI_ERROR (Status
)) {
204 // Open the Simple Input Protocol BY_DRIVER
206 Status
= gBS
->OpenProtocol (
208 &gEfiSimpleTextInProtocolGuid
,
210 This
->DriverBindingHandle
,
212 EFI_OPEN_PROTOCOL_BY_DRIVER
214 if (EFI_ERROR (Status
)) {
218 // Check the device handle, if it is a hot plug device,
219 // do not put the device path into ConInDev, and install
220 // gEfiConsoleInDeviceGuid to the device handle directly.
221 // The policy is, make hot plug device plug in and play immediately.
223 if (IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
224 gBS
->InstallMultipleProtocolInterfaces (
226 &gEfiConsoleInDeviceGuid
,
232 // Append the device path to the ConInDev environment variable
234 ConPlatformUpdateDeviceVariable (
241 // If the device path is an instance in the ConIn environment variable,
242 // then install EfiConsoleInDeviceGuid onto ControllerHandle
244 Status
= ConPlatformUpdateDeviceVariable (
250 if (!EFI_ERROR (Status
)) {
251 gBS
->InstallMultipleProtocolInterfaces (
253 &gEfiConsoleInDeviceGuid
,
260 &gEfiSimpleTextInProtocolGuid
,
261 This
->DriverBindingHandle
,
273 ConPlatformTextOutDriverBindingStart (
274 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
275 IN EFI_HANDLE ControllerHandle
,
276 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
284 (Standard DriverBinding Protocol Start() function)
292 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
293 EFI_SIMPLE_TEXT_OUT_PROTOCOL
*TextOut
;
300 // Get the Device Path Protocol so the environment variables can be updated
302 Status
= gBS
->OpenProtocol (
304 &gEfiDevicePathProtocolGuid
,
305 (VOID
**) &DevicePath
,
306 This
->DriverBindingHandle
,
308 EFI_OPEN_PROTOCOL_GET_PROTOCOL
310 if (EFI_ERROR (Status
)) {
314 // Open the Simple Text Output Protocol BY_DRIVER
316 Status
= gBS
->OpenProtocol (
318 &gEfiSimpleTextOutProtocolGuid
,
320 This
->DriverBindingHandle
,
322 EFI_OPEN_PROTOCOL_BY_DRIVER
324 if (EFI_ERROR (Status
)) {
328 // Check the device handle, if it is a hot plug device,
329 // do not put the device path into ConOutDev and StdErrDev,
330 // and install gEfiConsoleOutDeviceGuid to the device handle directly.
331 // The policy is, make hot plug device plug in and play immediately.
333 if (IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
334 gBS
->InstallMultipleProtocolInterfaces (
336 &gEfiConsoleOutDeviceGuid
,
342 // Append the device path to the ConOutDev environment variable
344 ConPlatformUpdateDeviceVariable (
350 // Append the device path to the StdErrDev environment variable
352 ConPlatformUpdateDeviceVariable (
359 // If the device path is an instance in the ConOut environment variable,
360 // then install EfiConsoleOutDeviceGuid onto ControllerHandle
362 Status
= ConPlatformUpdateDeviceVariable (
367 if (!EFI_ERROR (Status
)) {
369 Status
= gBS
->InstallMultipleProtocolInterfaces (
371 &gEfiConsoleOutDeviceGuid
,
377 // If the device path is an instance in the StdErr environment variable,
378 // then install EfiStandardErrorDeviceGuid onto ControllerHandle
380 Status
= ConPlatformUpdateDeviceVariable (
385 if (!EFI_ERROR (Status
)) {
387 gBS
->InstallMultipleProtocolInterfaces (
389 &gEfiStandardErrorDeviceGuid
,
398 &gEfiSimpleTextOutProtocolGuid
,
399 This
->DriverBindingHandle
,
411 ConPlatformDriverBindingStop (
412 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
413 IN EFI_HANDLE ControllerHandle
,
414 IN UINTN NumberOfChildren
,
415 IN EFI_HANDLE
*ChildHandleBuffer
422 (Standard DriverBinding Protocol Stop() function)
431 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
434 // hot plug device is not included into the console associated variables,
435 // so no need to check variable for those hot plug devices.
437 if (!IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
439 // Get the Device Path Protocol so the environment variables can be updated
441 Status
= gBS
->OpenProtocol (
443 &gEfiDevicePathProtocolGuid
,
444 (VOID
**) &DevicePath
,
445 This
->DriverBindingHandle
,
447 EFI_OPEN_PROTOCOL_GET_PROTOCOL
449 if (!EFI_ERROR (Status
)) {
451 // Remove DevicePath from ConInDev, ConOutDev, and StdErrDev
453 ConPlatformUpdateDeviceVariable (
458 ConPlatformUpdateDeviceVariable (
463 ConPlatformUpdateDeviceVariable (
471 // Uninstall the Console Device GUIDs from Controller Handle
473 ConPlatformUnInstallProtocol (
476 &gEfiConsoleInDeviceGuid
479 ConPlatformUnInstallProtocol (
482 &gEfiConsoleOutDeviceGuid
485 ConPlatformUnInstallProtocol (
488 &gEfiStandardErrorDeviceGuid
492 // Close the Simple Input and Simple Text Output Protocols
496 &gEfiSimpleTextInProtocolGuid
,
497 This
->DriverBindingHandle
,
503 &gEfiSimpleTextOutProtocolGuid
,
504 This
->DriverBindingHandle
,
512 ConPlatformUnInstallProtocol (
513 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
514 IN EFI_HANDLE Handle
,
515 IN EFI_GUID
*ProtocolGuid
520 Status
= gBS
->OpenProtocol (
524 This
->DriverBindingHandle
,
526 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
529 if (!EFI_ERROR (Status
)) {
530 gBS
->UninstallMultipleProtocolInterfaces (
542 ConPlatformGetVariable (
548 Read the EFI variable (Name) and return a dynamically allocated
549 buffer, and the size of the buffer. On failure return NULL.
552 Name - String part of EFI variable name
555 Dynamically allocated memory that contains a copy of the EFI variable.
556 Caller is repsoncible freeing the buffer.
558 NULL - Variable was not read
570 // Test to see if the variable exists. If it doesn't reuturn NULL
572 Status
= gRT
->GetVariable (
574 &gEfiGlobalVariableGuid
,
580 if (Status
== EFI_BUFFER_TOO_SMALL
) {
582 // Allocate the buffer to return
584 Status
= gBS
->AllocatePool (EfiBootServicesData
, BufferSize
, &Buffer
);
585 if (EFI_ERROR (Status
)) {
589 // Read variable into the allocated buffer.
591 Status
= gRT
->GetVariable (
593 &gEfiGlobalVariableGuid
,
598 if (EFI_ERROR (Status
)) {
599 gBS
->FreePool (Buffer
);
608 ConPlatformMatchDevicePaths (
609 IN EFI_DEVICE_PATH_PROTOCOL
* Multi
,
610 IN EFI_DEVICE_PATH_PROTOCOL
* Single
,
611 IN EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath OPTIONAL
,
617 Function compares a device path data structure to that of all the nodes of a
618 second device path instance.
621 Multi - A pointer to a multi-instance device path data structure.
623 Single - A pointer to a single-instance device path data structure.
625 NewDevicePath - If Delete is TRUE, this parameter must not be null, and it
626 points to the remaining device path data structure.
627 (remaining device path = Multi - Single.)
629 Delete - If TRUE, means removing Single from Multi.
630 If FALSE, the routine just check whether Single matches
631 with any instance in Multi.
635 The function returns EFI_SUCCESS if the Single is contained within Multi.
636 Otherwise, EFI_NOT_FOUND is returned.
640 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
641 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath1
;
642 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath2
;
643 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
647 // The passed in DevicePath should not be NULL
649 if ((!Multi
) || (!Single
)) {
650 return EFI_NOT_FOUND
;
653 // if performing Delete operation, the NewDevicePath must not be NULL.
655 TempDevicePath1
= NULL
;
658 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
661 // search for the match of 'Single' in 'Multi'
663 while (DevicePathInst
) {
664 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
666 gBS
->FreePool (DevicePathInst
);
671 TempDevicePath2
= AppendDevicePathInstance (
675 gBS
->FreePool (TempDevicePath1
);
676 TempDevicePath1
= TempDevicePath2
;
680 gBS
->FreePool (DevicePathInst
);
681 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
685 *NewDevicePath
= TempDevicePath1
;
689 return EFI_NOT_FOUND
;
693 ConPlatformUpdateDeviceVariable (
694 IN CHAR16
*VariableName
,
695 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
696 IN CONPLATFORM_VAR_OPERATION Operation
712 EFI_DEVICE_PATH_PROTOCOL
*VariableDevicePath
;
713 EFI_DEVICE_PATH_PROTOCOL
*NewVariableDevicePath
;
715 VariableDevicePath
= NULL
;
716 NewVariableDevicePath
= NULL
;
719 // Get Variable according to variable name.
720 // The memory for Variable is allocated within ConPlatformGetVarible(),
721 // it is the caller's responsibility to free the memory before return.
723 VariableDevicePath
= ConPlatformGetVariable (VariableName
);
725 if (Operation
!= DELETE
) {
727 Status
= ConPlatformMatchDevicePaths (
734 if ((Operation
== CHECK
) || (!EFI_ERROR (Status
))) {
736 // The device path is already in the variable
738 gBS
->FreePool (VariableDevicePath
);
743 // The device path is not in variable. Append DevicePath to the
744 // environment variable that is a multi-instance device path.
746 Status
= EFI_SUCCESS
;
747 NewVariableDevicePath
= AppendDevicePathInstance (
751 if (NewVariableDevicePath
== NULL
) {
752 Status
= EFI_OUT_OF_RESOURCES
;
757 // Remove DevicePath from the environment variable that
758 // is a multi-instance device path.
760 Status
= ConPlatformMatchDevicePaths (
763 &NewVariableDevicePath
,
768 gBS
->FreePool (VariableDevicePath
);
770 if (EFI_ERROR (Status
)) {
774 Status
= gRT
->SetVariable (
776 &gEfiGlobalVariableGuid
,
777 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
778 GetDevicePathSize (NewVariableDevicePath
),
779 NewVariableDevicePath
782 gBS
->FreePool (NewVariableDevicePath
);
789 EFI_HANDLE DriverBindingHandle
,
790 EFI_HANDLE ControllerHandle
796 // HotPlugDeviceGuid indicates ControllerHandle stands for a hot plug device.
798 Status
= gBS
->OpenProtocol (
800 &gEfiHotPlugDeviceGuid
,
804 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
806 if (EFI_ERROR (Status
)) {