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
,
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
;
296 // Get the Device Path Protocol so the environment variables can be updated
298 Status
= gBS
->OpenProtocol (
300 &gEfiDevicePathProtocolGuid
,
301 (VOID
**) &DevicePath
,
302 This
->DriverBindingHandle
,
304 EFI_OPEN_PROTOCOL_GET_PROTOCOL
306 if (EFI_ERROR (Status
)) {
310 // Open the Simple Text Output Protocol BY_DRIVER
312 Status
= gBS
->OpenProtocol (
314 &gEfiSimpleTextOutProtocolGuid
,
316 This
->DriverBindingHandle
,
318 EFI_OPEN_PROTOCOL_BY_DRIVER
320 if (EFI_ERROR (Status
)) {
324 // Check the device handle, if it is a hot plug device,
325 // do not put the device path into ConOutDev and StdErrDev,
326 // and install gEfiConsoleOutDeviceGuid to the device handle directly.
327 // The policy is, make hot plug device plug in and play immediately.
329 if (IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
330 gBS
->InstallMultipleProtocolInterfaces (
332 &gEfiConsoleOutDeviceGuid
,
338 // Append the device path to the ConOutDev environment variable
340 ConPlatformUpdateDeviceVariable (
346 // Append the device path to the StdErrDev environment variable
348 ConPlatformUpdateDeviceVariable (
355 // If the device path is an instance in the ConOut environment variable,
356 // then install EfiConsoleOutDeviceGuid onto ControllerHandle
358 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 ConPlatformDriverBindingStop (
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, ConOutDev, and StdErrDev
448 ConPlatformUpdateDeviceVariable (
453 ConPlatformUpdateDeviceVariable (
458 ConPlatformUpdateDeviceVariable (
466 // Uninstall the Console Device GUIDs from Controller Handle
468 ConPlatformUnInstallProtocol (
471 &gEfiConsoleInDeviceGuid
474 ConPlatformUnInstallProtocol (
477 &gEfiConsoleOutDeviceGuid
480 ConPlatformUnInstallProtocol (
483 &gEfiStandardErrorDeviceGuid
487 // Close the Simple Input and Simple Text Output Protocols
491 &gEfiSimpleTextInProtocolGuid
,
492 This
->DriverBindingHandle
,
498 &gEfiSimpleTextOutProtocolGuid
,
499 This
->DriverBindingHandle
,
507 ConPlatformUnInstallProtocol (
508 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
509 IN EFI_HANDLE Handle
,
510 IN EFI_GUID
*ProtocolGuid
515 Status
= gBS
->OpenProtocol (
519 This
->DriverBindingHandle
,
521 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
524 if (!EFI_ERROR (Status
)) {
525 gBS
->UninstallMultipleProtocolInterfaces (
537 ConPlatformGetVariable (
543 Read the EFI variable (Name) and return a dynamically allocated
544 buffer, and the size of the buffer. On failure return NULL.
547 Name - String part of EFI variable name
550 Dynamically allocated memory that contains a copy of the EFI variable.
551 Caller is repsoncible freeing the buffer.
553 NULL - Variable was not read
565 // Test to see if the variable exists. If it doesn't reuturn NULL
567 Status
= gRT
->GetVariable (
569 &gEfiGlobalVariableGuid
,
575 if (Status
== EFI_BUFFER_TOO_SMALL
) {
577 // Allocate the buffer to return
579 Status
= gBS
->AllocatePool (EfiBootServicesData
, BufferSize
, &Buffer
);
580 if (EFI_ERROR (Status
)) {
584 // Read variable into the allocated buffer.
586 Status
= gRT
->GetVariable (
588 &gEfiGlobalVariableGuid
,
593 if (EFI_ERROR (Status
)) {
594 gBS
->FreePool (Buffer
);
603 ConPlatformMatchDevicePaths (
604 IN EFI_DEVICE_PATH_PROTOCOL
* Multi
,
605 IN EFI_DEVICE_PATH_PROTOCOL
* Single
,
606 IN EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath OPTIONAL
,
612 Function compares a device path data structure to that of all the nodes of a
613 second device path instance.
616 Multi - A pointer to a multi-instance device path data structure.
618 Single - A pointer to a single-instance device path data structure.
620 NewDevicePath - If Delete is TRUE, this parameter must not be null, and it
621 points to the remaining device path data structure.
622 (remaining device path = Multi - Single.)
624 Delete - If TRUE, means removing Single from Multi.
625 If FALSE, the routine just check whether Single matches
626 with any instance in Multi.
630 The function returns EFI_SUCCESS if the Single is contained within Multi.
631 Otherwise, EFI_NOT_FOUND is returned.
635 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
636 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath1
;
637 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath2
;
638 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
642 // The passed in DevicePath should not be NULL
644 if ((!Multi
) || (!Single
)) {
645 return EFI_NOT_FOUND
;
648 // if performing Delete operation, the NewDevicePath must not be NULL.
650 TempDevicePath1
= NULL
;
653 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
656 // search for the match of 'Single' in 'Multi'
658 while (DevicePathInst
) {
659 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
661 gBS
->FreePool (DevicePathInst
);
666 TempDevicePath2
= AppendDevicePathInstance (
670 gBS
->FreePool (TempDevicePath1
);
671 TempDevicePath1
= TempDevicePath2
;
675 gBS
->FreePool (DevicePathInst
);
676 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
680 *NewDevicePath
= TempDevicePath1
;
684 return EFI_NOT_FOUND
;
688 ConPlatformUpdateDeviceVariable (
689 IN CHAR16
*VariableName
,
690 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
691 IN CONPLATFORM_VAR_OPERATION Operation
707 EFI_DEVICE_PATH_PROTOCOL
*VariableDevicePath
;
708 EFI_DEVICE_PATH_PROTOCOL
*NewVariableDevicePath
;
710 VariableDevicePath
= NULL
;
711 NewVariableDevicePath
= NULL
;
714 // Get Variable according to variable name.
715 // The memory for Variable is allocated within ConPlatformGetVarible(),
716 // it is the caller's responsibility to free the memory before return.
718 VariableDevicePath
= ConPlatformGetVariable (VariableName
);
720 if (Operation
!= DELETE
) {
722 Status
= ConPlatformMatchDevicePaths (
729 if ((Operation
== CHECK
) || (!EFI_ERROR (Status
))) {
731 // The device path is already in the variable
733 gBS
->FreePool (VariableDevicePath
);
738 // The device path is not in variable. Append DevicePath to the
739 // environment variable that is a multi-instance device path.
741 Status
= EFI_SUCCESS
;
742 NewVariableDevicePath
= AppendDevicePathInstance (
746 if (NewVariableDevicePath
== NULL
) {
747 Status
= EFI_OUT_OF_RESOURCES
;
752 // Remove DevicePath from the environment variable that
753 // is a multi-instance device path.
755 Status
= ConPlatformMatchDevicePaths (
758 &NewVariableDevicePath
,
763 gBS
->FreePool (VariableDevicePath
);
765 if (EFI_ERROR (Status
)) {
769 Status
= gRT
->SetVariable (
771 &gEfiGlobalVariableGuid
,
772 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
773 GetDevicePathSize (NewVariableDevicePath
),
774 NewVariableDevicePath
777 gBS
->FreePool (NewVariableDevicePath
);
784 EFI_HANDLE DriverBindingHandle
,
785 EFI_HANDLE ControllerHandle
791 // HotPlugDeviceGuid indicates ControllerHandle stands for a hot plug device.
793 Status
= gBS
->OpenProtocol (
795 &gEfiHotPlugDeviceGuid
,
799 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
801 if (EFI_ERROR (Status
)) {