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>
23 EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextInDriverBinding
= {
24 ConPlatformTextInDriverBindingSupported
,
25 ConPlatformTextInDriverBindingStart
,
26 ConPlatformTextInDriverBindingStop
,
32 EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextOutDriverBinding
= {
33 ConPlatformTextOutDriverBindingSupported
,
34 ConPlatformTextOutDriverBindingStart
,
35 ConPlatformTextOutDriverBindingStop
,
42 The user Entry Point for module ConPlatform. The user code starts with this function.
44 @param[in] ImageHandle The firmware allocated handle for the EFI image.
45 @param[in] SystemTable A pointer to the EFI System Table.
47 @retval EFI_SUCCESS The entry point is executed successfully.
48 @retval other Some error occurs when executing this entry point.
53 InitializeConPlatform(
54 IN EFI_HANDLE ImageHandle
,
55 IN EFI_SYSTEM_TABLE
*SystemTable
61 // Install driver model protocol(s).
63 Status
= EfiLibInstallDriverBindingComponentName2 (
66 &gConPlatformTextInDriverBinding
,
68 &gConPlatformComponentName
,
69 &gConPlatformComponentName2
71 ASSERT_EFI_ERROR (Status
);
73 Status
= EfiLibInstallDriverBindingComponentName2 (
76 &gConPlatformTextOutDriverBinding
,
78 &gConPlatformComponentName
,
79 &gConPlatformComponentName2
81 ASSERT_EFI_ERROR (Status
);
90 ConPlatformTextInDriverBindingSupported (
91 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
92 IN EFI_HANDLE ControllerHandle
,
93 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
101 (Standard DriverBinding Protocol Supported() function)
109 return ConPlatformDriverBindingSupported (
113 &gEfiSimpleTextInProtocolGuid
119 ConPlatformTextOutDriverBindingSupported (
120 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
121 IN EFI_HANDLE ControllerHandle
,
122 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
130 (Standard DriverBinding Protocol Supported() function)
138 return ConPlatformDriverBindingSupported (
142 &gEfiSimpleTextOutProtocolGuid
147 ConPlatformDriverBindingSupported (
148 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
149 IN EFI_HANDLE ControllerHandle
,
150 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
151 IN EFI_GUID
*ProtocolGuid
159 (Standard DriverBinding Protocol Supported() function)
171 // Test to see if this is a physical device by checking to see if
172 // it has a Device Path Protocol
174 Status
= gBS
->OpenProtocol (
176 &gEfiDevicePathProtocolGuid
,
178 This
->DriverBindingHandle
,
180 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
182 if (EFI_ERROR (Status
)) {
186 // Test to see if this device supports the Simple Text Output Protocol
188 Status
= gBS
->OpenProtocol (
191 (VOID
**) &Interface
,
192 This
->DriverBindingHandle
,
194 EFI_OPEN_PROTOCOL_BY_DRIVER
196 if (EFI_ERROR (Status
)) {
203 This
->DriverBindingHandle
,
212 ConPlatformTextInDriverBindingStart (
213 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
214 IN EFI_HANDLE ControllerHandle
,
215 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
223 (Standard DriverBinding Protocol Start() function)
231 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
232 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
235 // Get the Device Path Protocol so the environment variables can be updated
237 Status
= gBS
->OpenProtocol (
239 &gEfiDevicePathProtocolGuid
,
240 (VOID
**) &DevicePath
,
241 This
->DriverBindingHandle
,
243 EFI_OPEN_PROTOCOL_GET_PROTOCOL
245 if (EFI_ERROR (Status
)) {
249 // Open the Simple Input Protocol BY_DRIVER
251 Status
= gBS
->OpenProtocol (
253 &gEfiSimpleTextInProtocolGuid
,
255 This
->DriverBindingHandle
,
257 EFI_OPEN_PROTOCOL_BY_DRIVER
259 if (EFI_ERROR (Status
)) {
263 // Check the device handle, if it is a hot plug device,
264 // do not put the device path into ConInDev, and install
265 // gEfiConsoleInDeviceGuid to the device handle directly.
266 // The policy is, make hot plug device plug in and play immediately.
268 if (IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
269 gBS
->InstallMultipleProtocolInterfaces (
271 &gEfiConsoleInDeviceGuid
,
277 // Append the device path to the ConInDev environment variable
279 ConPlatformUpdateDeviceVariable (
286 // If the device path is an instance in the ConIn environment variable,
287 // then install EfiConsoleInDeviceGuid onto ControllerHandle
289 Status
= ConPlatformUpdateDeviceVariable (
295 if (!EFI_ERROR (Status
)) {
296 gBS
->InstallMultipleProtocolInterfaces (
298 &gEfiConsoleInDeviceGuid
,
305 &gEfiSimpleTextInProtocolGuid
,
306 This
->DriverBindingHandle
,
317 ConPlatformTextOutDriverBindingStart (
318 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
319 IN EFI_HANDLE ControllerHandle
,
320 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
328 (Standard DriverBinding Protocol Start() function)
336 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
337 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
343 // Get the Device Path Protocol so the environment variables can be updated
345 Status
= gBS
->OpenProtocol (
347 &gEfiDevicePathProtocolGuid
,
348 (VOID
**) &DevicePath
,
349 This
->DriverBindingHandle
,
351 EFI_OPEN_PROTOCOL_GET_PROTOCOL
353 if (EFI_ERROR (Status
)) {
357 // Open the Simple Text Output Protocol BY_DRIVER
359 Status
= gBS
->OpenProtocol (
361 &gEfiSimpleTextOutProtocolGuid
,
363 This
->DriverBindingHandle
,
365 EFI_OPEN_PROTOCOL_BY_DRIVER
367 if (EFI_ERROR (Status
)) {
371 // Check the device handle, if it is a hot plug device,
372 // do not put the device path into ConOutDev and StdErrDev,
373 // and install gEfiConsoleOutDeviceGuid to the device handle directly.
374 // The policy is, make hot plug device plug in and play immediately.
376 if (IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
377 gBS
->InstallMultipleProtocolInterfaces (
379 &gEfiConsoleOutDeviceGuid
,
385 // Append the device path to the ConOutDev environment variable
387 ConPlatformUpdateDeviceVariable (
393 // Append the device path to the StdErrDev environment variable
395 ConPlatformUpdateDeviceVariable (
402 // If the device path is an instance in the ConOut environment variable,
403 // then install EfiConsoleOutDeviceGuid onto ControllerHandle
405 Status
= ConPlatformUpdateDeviceVariable (
411 if (!EFI_ERROR (Status
)) {
413 Status
= gBS
->InstallMultipleProtocolInterfaces (
415 &gEfiConsoleOutDeviceGuid
,
421 // If the device path is an instance in the StdErr environment variable,
422 // then install EfiStandardErrorDeviceGuid onto ControllerHandle
424 Status
= ConPlatformUpdateDeviceVariable (
429 if (!EFI_ERROR (Status
)) {
431 gBS
->InstallMultipleProtocolInterfaces (
433 &gEfiStandardErrorDeviceGuid
,
442 &gEfiSimpleTextOutProtocolGuid
,
443 This
->DriverBindingHandle
,
454 ConPlatformTextInDriverBindingStop (
455 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
456 IN EFI_HANDLE ControllerHandle
,
457 IN UINTN NumberOfChildren
,
458 IN EFI_HANDLE
*ChildHandleBuffer
465 (Standard DriverBinding Protocol Stop() function)
474 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
477 // hot plug device is not included into the console associated variables,
478 // so no need to check variable for those hot plug devices.
480 if (!IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
482 // Get the Device Path Protocol so the environment variables can be updated
484 Status
= gBS
->OpenProtocol (
486 &gEfiDevicePathProtocolGuid
,
487 (VOID
**) &DevicePath
,
488 This
->DriverBindingHandle
,
490 EFI_OPEN_PROTOCOL_GET_PROTOCOL
492 if (!EFI_ERROR (Status
)) {
494 // Remove DevicePath from ConInDev
496 ConPlatformUpdateDeviceVariable (
504 // Uninstall the Console Device GUIDs from Controller Handle
506 ConPlatformUnInstallProtocol (
509 &gEfiConsoleInDeviceGuid
513 // Close the Simple Input Protocol
517 &gEfiSimpleTextInProtocolGuid
,
518 This
->DriverBindingHandle
,
527 ConPlatformTextOutDriverBindingStop (
528 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
529 IN EFI_HANDLE ControllerHandle
,
530 IN UINTN NumberOfChildren
,
531 IN EFI_HANDLE
*ChildHandleBuffer
538 (Standard DriverBinding Protocol Stop() function)
547 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
550 // hot plug device is not included into the console associated variables,
551 // so no need to check variable for those hot plug devices.
553 if (!IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
555 // Get the Device Path Protocol so the environment variables can be updated
557 Status
= gBS
->OpenProtocol (
559 &gEfiDevicePathProtocolGuid
,
560 (VOID
**) &DevicePath
,
561 This
->DriverBindingHandle
,
563 EFI_OPEN_PROTOCOL_GET_PROTOCOL
565 if (!EFI_ERROR (Status
)) {
567 // Remove DevicePath from ConOutDev, and StdErrDev
569 ConPlatformUpdateDeviceVariable (
574 ConPlatformUpdateDeviceVariable (
582 // Uninstall the Console Device GUIDs from Controller Handle
584 ConPlatformUnInstallProtocol (
587 &gEfiConsoleOutDeviceGuid
590 ConPlatformUnInstallProtocol (
593 &gEfiStandardErrorDeviceGuid
597 // Close the Simple Text Output Protocol
601 &gEfiSimpleTextOutProtocolGuid
,
602 This
->DriverBindingHandle
,
611 ConPlatformUnInstallProtocol (
612 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
613 IN EFI_HANDLE Handle
,
614 IN EFI_GUID
*ProtocolGuid
619 Status
= gBS
->OpenProtocol (
623 This
->DriverBindingHandle
,
625 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
628 if (!EFI_ERROR (Status
)) {
629 gBS
->UninstallMultipleProtocolInterfaces (
641 ConPlatformGetVariable (
647 Read the EFI variable (Name) and return a dynamically allocated
648 buffer, and the size of the buffer. On failure return NULL.
651 Name - String part of EFI variable name
654 Dynamically allocated memory that contains a copy of the EFI variable.
655 Caller is repsoncible freeing the buffer.
657 NULL - Variable was not read
669 // Test to see if the variable exists. If it doesn't reuturn NULL
671 Status
= gRT
->GetVariable (
673 &gEfiGlobalVariableGuid
,
679 if (Status
== EFI_BUFFER_TOO_SMALL
) {
681 // Allocate the buffer to return
683 Buffer
= AllocatePool (BufferSize
);
684 if (Buffer
== NULL
) {
688 // Read variable into the allocated buffer.
690 Status
= gRT
->GetVariable (
692 &gEfiGlobalVariableGuid
,
697 if (EFI_ERROR (Status
)) {
707 ConPlatformMatchDevicePaths (
708 IN EFI_DEVICE_PATH_PROTOCOL
* Multi
,
709 IN EFI_DEVICE_PATH_PROTOCOL
* Single
,
710 IN EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath OPTIONAL
,
716 Function compares a device path data structure to that of all the nodes of a
717 second device path instance.
720 Multi - A pointer to a multi-instance device path data structure.
722 Single - A pointer to a single-instance device path data structure.
724 NewDevicePath - If Delete is TRUE, this parameter must not be null, and it
725 points to the remaining device path data structure.
726 (remaining device path = Multi - Single.)
728 Delete - If TRUE, means removing Single from Multi.
729 If FALSE, the routine just check whether Single matches
730 with any instance in Multi.
734 The function returns EFI_SUCCESS if the Single is contained within Multi.
735 Otherwise, EFI_NOT_FOUND is returned.
739 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
740 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
741 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
745 // The passed in DevicePath should not be NULL
747 if ((!Multi
) || (!Single
)) {
748 return EFI_NOT_FOUND
;
751 // if performing Delete operation, the NewDevicePath must not be NULL.
753 TempDevicePath
= NULL
;
756 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
759 // search for the match of 'Single' in 'Multi'
761 while (DevicePathInst
) {
762 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
764 FreePool (DevicePathInst
);
769 TempDevicePath
= AppendDevicePathInstance (
776 FreePool (DevicePathInst
);
777 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
781 *NewDevicePath
= TempDevicePath
;
785 return EFI_NOT_FOUND
;
789 ConPlatformUpdateDeviceVariable (
790 IN CHAR16
*VariableName
,
791 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
792 IN CONPLATFORM_VAR_OPERATION Operation
808 EFI_DEVICE_PATH_PROTOCOL
*VariableDevicePath
;
809 EFI_DEVICE_PATH_PROTOCOL
*NewVariableDevicePath
;
811 VariableDevicePath
= NULL
;
812 NewVariableDevicePath
= NULL
;
815 // Get Variable according to variable name.
816 // The memory for Variable is allocated within ConPlatformGetVarible(),
817 // it is the caller's responsibility to free the memory before return.
819 VariableDevicePath
= ConPlatformGetVariable (VariableName
);
821 if (Operation
!= DELETE
) {
823 Status
= ConPlatformMatchDevicePaths (
830 if ((Operation
== CHECK
) || (!EFI_ERROR (Status
))) {
832 // The device path is already in the variable
834 if (VariableDevicePath
!= NULL
) {
835 FreePool (VariableDevicePath
);
841 // The device path is not in variable. Append DevicePath to the
842 // environment variable that is a multi-instance device path.
844 Status
= EFI_SUCCESS
;
845 NewVariableDevicePath
= AppendDevicePathInstance (
849 if (NewVariableDevicePath
== NULL
) {
850 Status
= EFI_OUT_OF_RESOURCES
;
855 // Remove DevicePath from the environment variable that
856 // is a multi-instance device path.
858 Status
= ConPlatformMatchDevicePaths (
861 &NewVariableDevicePath
,
866 if (VariableDevicePath
!= NULL
) {
867 FreePool (VariableDevicePath
);
870 if (EFI_ERROR (Status
)) {
874 if (NewVariableDevicePath
!= NULL
) {
875 Status
= gRT
->SetVariable (
877 &gEfiGlobalVariableGuid
,
878 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
879 GetDevicePathSize (NewVariableDevicePath
),
880 NewVariableDevicePath
883 FreePool (NewVariableDevicePath
);
891 EFI_HANDLE DriverBindingHandle
,
892 EFI_HANDLE ControllerHandle
898 // HotPlugDeviceGuid indicates ControllerHandle stands for a hot plug device.
900 Status
= gBS
->OpenProtocol (
902 &gEfiHotPlugDeviceGuid
,
906 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
908 if (EFI_ERROR (Status
)) {