3 Copyright (c) 2006 - 2007, Intel Corporation
\r
4 All rights reserved. This program and the accompanying materials
\r
5 are licensed and made available under the terms and conditions of the BSD License
\r
6 which accompanies this distribution. The full text of the license may be found at
\r
7 http://opensource.org/licenses/bsd-license.php
\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
20 #include <ConPlatform.h>
\r
23 EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextInDriverBinding = {
\r
24 ConPlatformTextInDriverBindingSupported,
\r
25 ConPlatformTextInDriverBindingStart,
\r
26 ConPlatformTextInDriverBindingStop,
\r
32 EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextOutDriverBinding = {
\r
33 ConPlatformTextOutDriverBindingSupported,
\r
34 ConPlatformTextOutDriverBindingStart,
\r
35 ConPlatformTextOutDriverBindingStop,
\r
42 The user Entry Point for module ConPlatform. The user code starts with this function.
\r
44 @param[in] ImageHandle The firmware allocated handle for the EFI image.
\r
45 @param[in] SystemTable A pointer to the EFI System Table.
\r
47 @retval EFI_SUCCESS The entry point is executed successfully.
\r
48 @retval other Some error occurs when executing this entry point.
\r
53 InitializeConPlatform(
\r
54 IN EFI_HANDLE ImageHandle,
\r
55 IN EFI_SYSTEM_TABLE *SystemTable
\r
61 // Install driver model protocol(s).
\r
63 Status = EfiLibInstallAllDriverProtocols (
\r
66 &gConPlatformTextInDriverBinding,
\r
68 &gConPlatformComponentName,
\r
72 ASSERT_EFI_ERROR (Status);
\r
74 Status = EfiLibInstallAllDriverProtocols (
\r
77 &gConPlatformTextOutDriverBinding,
\r
79 &gConPlatformComponentName,
\r
83 ASSERT_EFI_ERROR (Status);
\r
92 ConPlatformTextInDriverBindingSupported (
\r
93 IN EFI_DRIVER_BINDING_PROTOCOL *This,
\r
94 IN EFI_HANDLE ControllerHandle,
\r
95 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
\r
99 Routine Description:
\r
103 (Standard DriverBinding Protocol Supported() function)
\r
111 return ConPlatformDriverBindingSupported (
\r
114 RemainingDevicePath,
\r
115 &gEfiSimpleTextInProtocolGuid
\r
121 ConPlatformTextOutDriverBindingSupported (
\r
122 IN EFI_DRIVER_BINDING_PROTOCOL *This,
\r
123 IN EFI_HANDLE ControllerHandle,
\r
124 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
\r
128 Routine Description:
\r
132 (Standard DriverBinding Protocol Supported() function)
\r
140 return ConPlatformDriverBindingSupported (
\r
143 RemainingDevicePath,
\r
144 &gEfiSimpleTextOutProtocolGuid
\r
149 ConPlatformDriverBindingSupported (
\r
150 IN EFI_DRIVER_BINDING_PROTOCOL *This,
\r
151 IN EFI_HANDLE ControllerHandle,
\r
152 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
\r
153 IN EFI_GUID *ProtocolGuid
\r
157 Routine Description:
\r
161 (Standard DriverBinding Protocol Supported() function)
\r
173 // Test to see if this is a physical device by checking to see if
\r
174 // it has a Device Path Protocol
\r
176 Status = gBS->OpenProtocol (
\r
178 &gEfiDevicePathProtocolGuid,
\r
180 This->DriverBindingHandle,
\r
182 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
\r
184 if (EFI_ERROR (Status)) {
\r
188 // Test to see if this device supports the Simple Text Output Protocol
\r
190 Status = gBS->OpenProtocol (
\r
193 (VOID **) &Interface,
\r
194 This->DriverBindingHandle,
\r
196 EFI_OPEN_PROTOCOL_BY_DRIVER
\r
198 if (EFI_ERROR (Status)) {
\r
202 gBS->CloseProtocol (
\r
205 This->DriverBindingHandle,
\r
209 return EFI_SUCCESS;
\r
214 ConPlatformTextInDriverBindingStart (
\r
215 IN EFI_DRIVER_BINDING_PROTOCOL *This,
\r
216 IN EFI_HANDLE ControllerHandle,
\r
217 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
\r
221 Routine Description:
\r
225 (Standard DriverBinding Protocol Start() function)
\r
233 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
\r
234 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;
\r
237 // Get the Device Path Protocol so the environment variables can be updated
\r
239 Status = gBS->OpenProtocol (
\r
241 &gEfiDevicePathProtocolGuid,
\r
242 (VOID **) &DevicePath,
\r
243 This->DriverBindingHandle,
\r
245 EFI_OPEN_PROTOCOL_GET_PROTOCOL
\r
247 if (EFI_ERROR (Status)) {
\r
251 // Open the Simple Input Protocol BY_DRIVER
\r
253 Status = gBS->OpenProtocol (
\r
255 &gEfiSimpleTextInProtocolGuid,
\r
257 This->DriverBindingHandle,
\r
259 EFI_OPEN_PROTOCOL_BY_DRIVER
\r
261 if (EFI_ERROR (Status)) {
\r
265 // Check the device handle, if it is a hot plug device,
\r
266 // do not put the device path into ConInDev, and install
\r
267 // gEfiConsoleInDeviceGuid to the device handle directly.
\r
268 // The policy is, make hot plug device plug in and play immediately.
\r
270 if (IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {
\r
271 gBS->InstallMultipleProtocolInterfaces (
\r
273 &gEfiConsoleInDeviceGuid,
\r
279 // Append the device path to the ConInDev environment variable
\r
281 ConPlatformUpdateDeviceVariable (
\r
288 // If the device path is an instance in the ConIn environment variable,
\r
289 // then install EfiConsoleInDeviceGuid onto ControllerHandle
\r
291 Status = ConPlatformUpdateDeviceVariable (
\r
297 if (!EFI_ERROR (Status)) {
\r
298 gBS->InstallMultipleProtocolInterfaces (
\r
300 &gEfiConsoleInDeviceGuid,
\r
305 gBS->CloseProtocol (
\r
307 &gEfiSimpleTextInProtocolGuid,
\r
308 This->DriverBindingHandle,
\r
314 return EFI_SUCCESS;
\r
319 ConPlatformTextOutDriverBindingStart (
\r
320 IN EFI_DRIVER_BINDING_PROTOCOL *This,
\r
321 IN EFI_HANDLE ControllerHandle,
\r
322 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
\r
326 Routine Description:
\r
330 (Standard DriverBinding Protocol Start() function)
\r
338 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
\r
339 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;
\r
345 // Get the Device Path Protocol so the environment variables can be updated
\r
347 Status = gBS->OpenProtocol (
\r
349 &gEfiDevicePathProtocolGuid,
\r
350 (VOID **) &DevicePath,
\r
351 This->DriverBindingHandle,
\r
353 EFI_OPEN_PROTOCOL_GET_PROTOCOL
\r
355 if (EFI_ERROR (Status)) {
\r
359 // Open the Simple Text Output Protocol BY_DRIVER
\r
361 Status = gBS->OpenProtocol (
\r
363 &gEfiSimpleTextOutProtocolGuid,
\r
364 (VOID **) &TextOut,
\r
365 This->DriverBindingHandle,
\r
367 EFI_OPEN_PROTOCOL_BY_DRIVER
\r
369 if (EFI_ERROR (Status)) {
\r
373 // Check the device handle, if it is a hot plug device,
\r
374 // do not put the device path into ConOutDev and StdErrDev,
\r
375 // and install gEfiConsoleOutDeviceGuid to the device handle directly.
\r
376 // The policy is, make hot plug device plug in and play immediately.
\r
378 if (IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {
\r
379 gBS->InstallMultipleProtocolInterfaces (
\r
381 &gEfiConsoleOutDeviceGuid,
\r
387 // Append the device path to the ConOutDev environment variable
\r
389 ConPlatformUpdateDeviceVariable (
\r
395 // Append the device path to the StdErrDev environment variable
\r
397 ConPlatformUpdateDeviceVariable (
\r
404 // If the device path is an instance in the ConOut environment variable,
\r
405 // then install EfiConsoleOutDeviceGuid onto ControllerHandle
\r
407 Status = ConPlatformUpdateDeviceVariable (
\r
413 if (!EFI_ERROR (Status)) {
\r
415 Status = gBS->InstallMultipleProtocolInterfaces (
\r
417 &gEfiConsoleOutDeviceGuid,
\r
423 // If the device path is an instance in the StdErr environment variable,
\r
424 // then install EfiStandardErrorDeviceGuid onto ControllerHandle
\r
426 Status = ConPlatformUpdateDeviceVariable (
\r
431 if (!EFI_ERROR (Status)) {
\r
433 gBS->InstallMultipleProtocolInterfaces (
\r
435 &gEfiStandardErrorDeviceGuid,
\r
442 gBS->CloseProtocol (
\r
444 &gEfiSimpleTextOutProtocolGuid,
\r
445 This->DriverBindingHandle,
\r
451 return EFI_SUCCESS;
\r
456 ConPlatformTextInDriverBindingStop (
\r
457 IN EFI_DRIVER_BINDING_PROTOCOL *This,
\r
458 IN EFI_HANDLE ControllerHandle,
\r
459 IN UINTN NumberOfChildren,
\r
460 IN EFI_HANDLE *ChildHandleBuffer
\r
464 Routine Description:
\r
467 (Standard DriverBinding Protocol Stop() function)
\r
476 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
\r
479 // hot plug device is not included into the console associated variables,
\r
480 // so no need to check variable for those hot plug devices.
\r
482 if (!IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {
\r
484 // Get the Device Path Protocol so the environment variables can be updated
\r
486 Status = gBS->OpenProtocol (
\r
488 &gEfiDevicePathProtocolGuid,
\r
489 (VOID **) &DevicePath,
\r
490 This->DriverBindingHandle,
\r
492 EFI_OPEN_PROTOCOL_GET_PROTOCOL
\r
494 if (!EFI_ERROR (Status)) {
\r
496 // Remove DevicePath from ConInDev
\r
498 ConPlatformUpdateDeviceVariable (
\r
506 // Uninstall the Console Device GUIDs from Controller Handle
\r
508 ConPlatformUnInstallProtocol (
\r
511 &gEfiConsoleInDeviceGuid
\r
515 // Close the Simple Input Protocol
\r
517 gBS->CloseProtocol (
\r
519 &gEfiSimpleTextInProtocolGuid,
\r
520 This->DriverBindingHandle,
\r
524 return EFI_SUCCESS;
\r
529 ConPlatformTextOutDriverBindingStop (
\r
530 IN EFI_DRIVER_BINDING_PROTOCOL *This,
\r
531 IN EFI_HANDLE ControllerHandle,
\r
532 IN UINTN NumberOfChildren,
\r
533 IN EFI_HANDLE *ChildHandleBuffer
\r
537 Routine Description:
\r
540 (Standard DriverBinding Protocol Stop() function)
\r
549 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
\r
552 // hot plug device is not included into the console associated variables,
\r
553 // so no need to check variable for those hot plug devices.
\r
555 if (!IsHotPlugDevice (This->DriverBindingHandle, ControllerHandle)) {
\r
557 // Get the Device Path Protocol so the environment variables can be updated
\r
559 Status = gBS->OpenProtocol (
\r
561 &gEfiDevicePathProtocolGuid,
\r
562 (VOID **) &DevicePath,
\r
563 This->DriverBindingHandle,
\r
565 EFI_OPEN_PROTOCOL_GET_PROTOCOL
\r
567 if (!EFI_ERROR (Status)) {
\r
569 // Remove DevicePath from ConOutDev, and StdErrDev
\r
571 ConPlatformUpdateDeviceVariable (
\r
576 ConPlatformUpdateDeviceVariable (
\r
584 // Uninstall the Console Device GUIDs from Controller Handle
\r
586 ConPlatformUnInstallProtocol (
\r
589 &gEfiConsoleOutDeviceGuid
\r
592 ConPlatformUnInstallProtocol (
\r
595 &gEfiStandardErrorDeviceGuid
\r
599 // Close the Simple Text Output Protocol
\r
601 gBS->CloseProtocol (
\r
603 &gEfiSimpleTextOutProtocolGuid,
\r
604 This->DriverBindingHandle,
\r
608 return EFI_SUCCESS;
\r
613 ConPlatformUnInstallProtocol (
\r
614 IN EFI_DRIVER_BINDING_PROTOCOL *This,
\r
615 IN EFI_HANDLE Handle,
\r
616 IN EFI_GUID *ProtocolGuid
\r
621 Status = gBS->OpenProtocol (
\r
625 This->DriverBindingHandle,
\r
627 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
\r
630 if (!EFI_ERROR (Status)) {
\r
631 gBS->UninstallMultipleProtocolInterfaces (
\r
643 ConPlatformGetVariable (
\r
648 Routine Description:
\r
649 Read the EFI variable (Name) and return a dynamically allocated
\r
650 buffer, and the size of the buffer. On failure return NULL.
\r
653 Name - String part of EFI variable name
\r
656 Dynamically allocated memory that contains a copy of the EFI variable.
\r
657 Caller is repsoncible freeing the buffer.
\r
659 NULL - Variable was not read
\r
671 // Test to see if the variable exists. If it doesn't reuturn NULL
\r
673 Status = gRT->GetVariable (
\r
675 &gEfiGlobalVariableGuid,
\r
681 if (Status == EFI_BUFFER_TOO_SMALL) {
\r
683 // Allocate the buffer to return
\r
685 Buffer = AllocatePool (BufferSize);
\r
686 if (Buffer == NULL) {
\r
690 // Read variable into the allocated buffer.
\r
692 Status = gRT->GetVariable (
\r
694 &gEfiGlobalVariableGuid,
\r
699 if (EFI_ERROR (Status)) {
\r
709 ConPlatformMatchDevicePaths (
\r
710 IN EFI_DEVICE_PATH_PROTOCOL * Multi,
\r
711 IN EFI_DEVICE_PATH_PROTOCOL * Single,
\r
712 IN EFI_DEVICE_PATH_PROTOCOL **NewDevicePath OPTIONAL,
\r
717 Routine Description:
\r
718 Function compares a device path data structure to that of all the nodes of a
\r
719 second device path instance.
\r
722 Multi - A pointer to a multi-instance device path data structure.
\r
724 Single - A pointer to a single-instance device path data structure.
\r
726 NewDevicePath - If Delete is TRUE, this parameter must not be null, and it
\r
727 points to the remaining device path data structure.
\r
728 (remaining device path = Multi - Single.)
\r
730 Delete - If TRUE, means removing Single from Multi.
\r
731 If FALSE, the routine just check whether Single matches
\r
732 with any instance in Multi.
\r
736 The function returns EFI_SUCCESS if the Single is contained within Multi.
\r
737 Otherwise, EFI_NOT_FOUND is returned.
\r
741 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
\r
742 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
\r
743 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
\r
747 // The passed in DevicePath should not be NULL
\r
749 if ((!Multi) || (!Single)) {
\r
750 return EFI_NOT_FOUND;
\r
753 // if performing Delete operation, the NewDevicePath must not be NULL.
\r
755 TempDevicePath = NULL;
\r
757 DevicePath = Multi;
\r
758 DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
\r
761 // search for the match of 'Single' in 'Multi'
\r
763 while (DevicePathInst) {
\r
764 if (CompareMem (Single, DevicePathInst, Size) == 0) {
\r
766 FreePool (DevicePathInst);
\r
767 return EFI_SUCCESS;
\r
771 TempDevicePath = AppendDevicePathInstance (
\r
778 FreePool (DevicePathInst);
\r
779 DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
\r
783 *NewDevicePath = TempDevicePath;
\r
784 return EFI_SUCCESS;
\r
787 return EFI_NOT_FOUND;
\r
791 ConPlatformUpdateDeviceVariable (
\r
792 IN CHAR16 *VariableName,
\r
793 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
\r
794 IN CONPLATFORM_VAR_OPERATION Operation
\r
798 Routine Description:
\r
810 EFI_DEVICE_PATH_PROTOCOL *VariableDevicePath;
\r
811 EFI_DEVICE_PATH_PROTOCOL *NewVariableDevicePath;
\r
813 VariableDevicePath = NULL;
\r
814 NewVariableDevicePath = NULL;
\r
817 // Get Variable according to variable name.
\r
818 // The memory for Variable is allocated within ConPlatformGetVarible(),
\r
819 // it is the caller's responsibility to free the memory before return.
\r
821 VariableDevicePath = ConPlatformGetVariable (VariableName);
\r
823 if (Operation != DELETE) {
\r
825 Status = ConPlatformMatchDevicePaths (
\r
826 VariableDevicePath,
\r
832 if ((Operation == CHECK) || (!EFI_ERROR (Status))) {
\r
834 // The device path is already in the variable
\r
836 if (VariableDevicePath != NULL) {
\r
837 FreePool (VariableDevicePath);
\r
843 // The device path is not in variable. Append DevicePath to the
\r
844 // environment variable that is a multi-instance device path.
\r
846 Status = EFI_SUCCESS;
\r
847 NewVariableDevicePath = AppendDevicePathInstance (
\r
848 VariableDevicePath,
\r
851 if (NewVariableDevicePath == NULL) {
\r
852 Status = EFI_OUT_OF_RESOURCES;
\r
857 // Remove DevicePath from the environment variable that
\r
858 // is a multi-instance device path.
\r
860 Status = ConPlatformMatchDevicePaths (
\r
861 VariableDevicePath,
\r
863 &NewVariableDevicePath,
\r
868 if (VariableDevicePath != NULL) {
\r
869 FreePool (VariableDevicePath);
\r
872 if (EFI_ERROR (Status)) {
\r
876 if (NewVariableDevicePath != NULL) {
\r
877 Status = gRT->SetVariable (
\r
879 &gEfiGlobalVariableGuid,
\r
880 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
\r
881 GetDevicePathSize (NewVariableDevicePath),
\r
882 NewVariableDevicePath
\r
885 FreePool (NewVariableDevicePath);
\r
893 EFI_HANDLE DriverBindingHandle,
\r
894 EFI_HANDLE ControllerHandle
\r
900 // HotPlugDeviceGuid indicates ControllerHandle stands for a hot plug device.
\r
902 Status = gBS->OpenProtocol (
\r
904 &gEfiHotPlugDeviceGuid,
\r
906 DriverBindingHandle,
\r
908 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
\r
910 if (EFI_ERROR (Status)) {
\r