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
= EfiLibInstallAllDriverProtocols (
66 &gConPlatformTextInDriverBinding
,
68 &gConPlatformComponentName
,
72 ASSERT_EFI_ERROR (Status
);
74 Status
= EfiLibInstallAllDriverProtocols (
77 &gConPlatformTextOutDriverBinding
,
79 &gConPlatformComponentName
,
83 ASSERT_EFI_ERROR (Status
);
92 ConPlatformTextInDriverBindingSupported (
93 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
94 IN EFI_HANDLE ControllerHandle
,
95 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
103 (Standard DriverBinding Protocol Supported() function)
111 return ConPlatformDriverBindingSupported (
115 &gEfiSimpleTextInProtocolGuid
121 ConPlatformTextOutDriverBindingSupported (
122 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
123 IN EFI_HANDLE ControllerHandle
,
124 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
132 (Standard DriverBinding Protocol Supported() function)
140 return ConPlatformDriverBindingSupported (
144 &gEfiSimpleTextOutProtocolGuid
149 ConPlatformDriverBindingSupported (
150 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
151 IN EFI_HANDLE ControllerHandle
,
152 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
153 IN EFI_GUID
*ProtocolGuid
161 (Standard DriverBinding Protocol Supported() function)
173 // Test to see if this is a physical device by checking to see if
174 // it has a Device Path Protocol
176 Status
= gBS
->OpenProtocol (
178 &gEfiDevicePathProtocolGuid
,
180 This
->DriverBindingHandle
,
182 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
184 if (EFI_ERROR (Status
)) {
188 // Test to see if this device supports the Simple Text Output Protocol
190 Status
= gBS
->OpenProtocol (
193 (VOID
**) &Interface
,
194 This
->DriverBindingHandle
,
196 EFI_OPEN_PROTOCOL_BY_DRIVER
198 if (EFI_ERROR (Status
)) {
205 This
->DriverBindingHandle
,
214 ConPlatformTextInDriverBindingStart (
215 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
216 IN EFI_HANDLE ControllerHandle
,
217 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
225 (Standard DriverBinding Protocol Start() function)
233 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
234 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*TextIn
;
237 // Get the Device Path Protocol so the environment variables can be updated
239 Status
= gBS
->OpenProtocol (
241 &gEfiDevicePathProtocolGuid
,
242 (VOID
**) &DevicePath
,
243 This
->DriverBindingHandle
,
245 EFI_OPEN_PROTOCOL_GET_PROTOCOL
247 if (EFI_ERROR (Status
)) {
251 // Open the Simple Input Protocol BY_DRIVER
253 Status
= gBS
->OpenProtocol (
255 &gEfiSimpleTextInProtocolGuid
,
257 This
->DriverBindingHandle
,
259 EFI_OPEN_PROTOCOL_BY_DRIVER
261 if (EFI_ERROR (Status
)) {
265 // Check the device handle, if it is a hot plug device,
266 // do not put the device path into ConInDev, and install
267 // gEfiConsoleInDeviceGuid to the device handle directly.
268 // The policy is, make hot plug device plug in and play immediately.
270 if (IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
271 gBS
->InstallMultipleProtocolInterfaces (
273 &gEfiConsoleInDeviceGuid
,
279 // Append the device path to the ConInDev environment variable
281 ConPlatformUpdateDeviceVariable (
288 // If the device path is an instance in the ConIn environment variable,
289 // then install EfiConsoleInDeviceGuid onto ControllerHandle
291 Status
= ConPlatformUpdateDeviceVariable (
297 if (!EFI_ERROR (Status
)) {
298 gBS
->InstallMultipleProtocolInterfaces (
300 &gEfiConsoleInDeviceGuid
,
307 &gEfiSimpleTextInProtocolGuid
,
308 This
->DriverBindingHandle
,
319 ConPlatformTextOutDriverBindingStart (
320 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
321 IN EFI_HANDLE ControllerHandle
,
322 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
330 (Standard DriverBinding Protocol Start() function)
338 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
339 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*TextOut
;
345 // Get the Device Path Protocol so the environment variables can be updated
347 Status
= gBS
->OpenProtocol (
349 &gEfiDevicePathProtocolGuid
,
350 (VOID
**) &DevicePath
,
351 This
->DriverBindingHandle
,
353 EFI_OPEN_PROTOCOL_GET_PROTOCOL
355 if (EFI_ERROR (Status
)) {
359 // Open the Simple Text Output Protocol BY_DRIVER
361 Status
= gBS
->OpenProtocol (
363 &gEfiSimpleTextOutProtocolGuid
,
365 This
->DriverBindingHandle
,
367 EFI_OPEN_PROTOCOL_BY_DRIVER
369 if (EFI_ERROR (Status
)) {
373 // Check the device handle, if it is a hot plug device,
374 // do not put the device path into ConOutDev and StdErrDev,
375 // and install gEfiConsoleOutDeviceGuid to the device handle directly.
376 // The policy is, make hot plug device plug in and play immediately.
378 if (IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
379 gBS
->InstallMultipleProtocolInterfaces (
381 &gEfiConsoleOutDeviceGuid
,
387 // Append the device path to the ConOutDev environment variable
389 ConPlatformUpdateDeviceVariable (
395 // Append the device path to the StdErrDev environment variable
397 ConPlatformUpdateDeviceVariable (
404 // If the device path is an instance in the ConOut environment variable,
405 // then install EfiConsoleOutDeviceGuid onto ControllerHandle
407 Status
= ConPlatformUpdateDeviceVariable (
413 if (!EFI_ERROR (Status
)) {
415 Status
= gBS
->InstallMultipleProtocolInterfaces (
417 &gEfiConsoleOutDeviceGuid
,
423 // If the device path is an instance in the StdErr environment variable,
424 // then install EfiStandardErrorDeviceGuid onto ControllerHandle
426 Status
= ConPlatformUpdateDeviceVariable (
431 if (!EFI_ERROR (Status
)) {
433 gBS
->InstallMultipleProtocolInterfaces (
435 &gEfiStandardErrorDeviceGuid
,
444 &gEfiSimpleTextOutProtocolGuid
,
445 This
->DriverBindingHandle
,
456 ConPlatformTextInDriverBindingStop (
457 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
458 IN EFI_HANDLE ControllerHandle
,
459 IN UINTN NumberOfChildren
,
460 IN EFI_HANDLE
*ChildHandleBuffer
467 (Standard DriverBinding Protocol Stop() function)
476 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
479 // hot plug device is not included into the console associated variables,
480 // so no need to check variable for those hot plug devices.
482 if (!IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
484 // Get the Device Path Protocol so the environment variables can be updated
486 Status
= gBS
->OpenProtocol (
488 &gEfiDevicePathProtocolGuid
,
489 (VOID
**) &DevicePath
,
490 This
->DriverBindingHandle
,
492 EFI_OPEN_PROTOCOL_GET_PROTOCOL
494 if (!EFI_ERROR (Status
)) {
496 // Remove DevicePath from ConInDev
498 ConPlatformUpdateDeviceVariable (
506 // Uninstall the Console Device GUIDs from Controller Handle
508 ConPlatformUnInstallProtocol (
511 &gEfiConsoleInDeviceGuid
515 // Close the Simple Input Protocol
519 &gEfiSimpleTextInProtocolGuid
,
520 This
->DriverBindingHandle
,
529 ConPlatformTextOutDriverBindingStop (
530 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
531 IN EFI_HANDLE ControllerHandle
,
532 IN UINTN NumberOfChildren
,
533 IN EFI_HANDLE
*ChildHandleBuffer
540 (Standard DriverBinding Protocol Stop() function)
549 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
552 // hot plug device is not included into the console associated variables,
553 // so no need to check variable for those hot plug devices.
555 if (!IsHotPlugDevice (This
->DriverBindingHandle
, ControllerHandle
)) {
557 // Get the Device Path Protocol so the environment variables can be updated
559 Status
= gBS
->OpenProtocol (
561 &gEfiDevicePathProtocolGuid
,
562 (VOID
**) &DevicePath
,
563 This
->DriverBindingHandle
,
565 EFI_OPEN_PROTOCOL_GET_PROTOCOL
567 if (!EFI_ERROR (Status
)) {
569 // Remove DevicePath from ConOutDev, and StdErrDev
571 ConPlatformUpdateDeviceVariable (
576 ConPlatformUpdateDeviceVariable (
584 // Uninstall the Console Device GUIDs from Controller Handle
586 ConPlatformUnInstallProtocol (
589 &gEfiConsoleOutDeviceGuid
592 ConPlatformUnInstallProtocol (
595 &gEfiStandardErrorDeviceGuid
599 // Close the Simple Text Output Protocol
603 &gEfiSimpleTextOutProtocolGuid
,
604 This
->DriverBindingHandle
,
613 ConPlatformUnInstallProtocol (
614 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
615 IN EFI_HANDLE Handle
,
616 IN EFI_GUID
*ProtocolGuid
621 Status
= gBS
->OpenProtocol (
625 This
->DriverBindingHandle
,
627 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
630 if (!EFI_ERROR (Status
)) {
631 gBS
->UninstallMultipleProtocolInterfaces (
643 ConPlatformGetVariable (
649 Read the EFI variable (Name) and return a dynamically allocated
650 buffer, and the size of the buffer. On failure return NULL.
653 Name - String part of EFI variable name
656 Dynamically allocated memory that contains a copy of the EFI variable.
657 Caller is repsoncible freeing the buffer.
659 NULL - Variable was not read
671 // Test to see if the variable exists. If it doesn't reuturn NULL
673 Status
= gRT
->GetVariable (
675 &gEfiGlobalVariableGuid
,
681 if (Status
== EFI_BUFFER_TOO_SMALL
) {
683 // Allocate the buffer to return
685 Buffer
= AllocatePool (BufferSize
);
686 if (Buffer
== NULL
) {
690 // Read variable into the allocated buffer.
692 Status
= gRT
->GetVariable (
694 &gEfiGlobalVariableGuid
,
699 if (EFI_ERROR (Status
)) {
709 ConPlatformMatchDevicePaths (
710 IN EFI_DEVICE_PATH_PROTOCOL
* Multi
,
711 IN EFI_DEVICE_PATH_PROTOCOL
* Single
,
712 IN EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath OPTIONAL
,
718 Function compares a device path data structure to that of all the nodes of a
719 second device path instance.
722 Multi - A pointer to a multi-instance device path data structure.
724 Single - A pointer to a single-instance device path data structure.
726 NewDevicePath - If Delete is TRUE, this parameter must not be null, and it
727 points to the remaining device path data structure.
728 (remaining device path = Multi - Single.)
730 Delete - If TRUE, means removing Single from Multi.
731 If FALSE, the routine just check whether Single matches
732 with any instance in Multi.
736 The function returns EFI_SUCCESS if the Single is contained within Multi.
737 Otherwise, EFI_NOT_FOUND is returned.
741 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
742 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath1
;
743 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath2
;
744 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
748 // The passed in DevicePath should not be NULL
750 if ((!Multi
) || (!Single
)) {
751 return EFI_NOT_FOUND
;
754 // if performing Delete operation, the NewDevicePath must not be NULL.
756 TempDevicePath1
= NULL
;
759 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
762 // search for the match of 'Single' in 'Multi'
764 while (DevicePathInst
) {
765 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
767 FreePool (DevicePathInst
);
772 TempDevicePath2
= AppendDevicePathInstance (
776 if (TempDevicePath1
!= NULL
) {
777 FreePool (TempDevicePath1
);
779 TempDevicePath1
= TempDevicePath2
;
783 FreePool (DevicePathInst
);
784 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
788 *NewDevicePath
= TempDevicePath1
;
792 return EFI_NOT_FOUND
;
796 ConPlatformUpdateDeviceVariable (
797 IN CHAR16
*VariableName
,
798 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
799 IN CONPLATFORM_VAR_OPERATION Operation
815 EFI_DEVICE_PATH_PROTOCOL
*VariableDevicePath
;
816 EFI_DEVICE_PATH_PROTOCOL
*NewVariableDevicePath
;
818 VariableDevicePath
= NULL
;
819 NewVariableDevicePath
= NULL
;
822 // Get Variable according to variable name.
823 // The memory for Variable is allocated within ConPlatformGetVarible(),
824 // it is the caller's responsibility to free the memory before return.
826 VariableDevicePath
= ConPlatformGetVariable (VariableName
);
828 if (Operation
!= DELETE
) {
830 Status
= ConPlatformMatchDevicePaths (
837 if ((Operation
== CHECK
) || (!EFI_ERROR (Status
))) {
839 // The device path is already in the variable
841 if (VariableDevicePath
!= NULL
) {
842 FreePool (VariableDevicePath
);
848 // The device path is not in variable. Append DevicePath to the
849 // environment variable that is a multi-instance device path.
851 Status
= EFI_SUCCESS
;
852 NewVariableDevicePath
= AppendDevicePathInstance (
856 if (NewVariableDevicePath
== NULL
) {
857 Status
= EFI_OUT_OF_RESOURCES
;
862 // Remove DevicePath from the environment variable that
863 // is a multi-instance device path.
865 Status
= ConPlatformMatchDevicePaths (
868 &NewVariableDevicePath
,
873 if (VariableDevicePath
!= NULL
) {
874 FreePool (VariableDevicePath
);
877 if (EFI_ERROR (Status
)) {
881 Status
= gRT
->SetVariable (
883 &gEfiGlobalVariableGuid
,
884 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
885 GetDevicePathSize (NewVariableDevicePath
),
886 NewVariableDevicePath
889 FreePool (NewVariableDevicePath
);
896 EFI_HANDLE DriverBindingHandle
,
897 EFI_HANDLE ControllerHandle
903 // HotPlugDeviceGuid indicates ControllerHandle stands for a hot plug device.
905 Status
= gBS
->OpenProtocol (
907 &gEfiHotPlugDeviceGuid
,
911 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
913 if (EFI_ERROR (Status
)) {