--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ BdsConsole.c\r
+\r
+Abstract:\r
+\r
+ BDS Lib functions which contain all the code to connect console device\r
+\r
+--*/\r
+\r
+EFI_STATUS\r
+BdsLibUpdateConsoleVariable (\r
+ IN CHAR16 *ConVarName,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function update console variable based on ConVarName, it can \r
+ add or remove one specific console device path from the variable\r
+\r
+Arguments:\r
+\r
+ ConVarName - Console related variable name, ConIn, ConOut, ErrOut.\r
+\r
+ CustomizedConDevicePath - The console device path which will be added to\r
+ the console variable ConVarName, this parameter\r
+ can not be multi-instance.\r
+\r
+ ExclusiveDevicePath - The console device path which will be removed\r
+ from the console variable ConVarName, this\r
+ parameter can not be multi-instance.\r
+\r
+Returns:\r
+\r
+ EFI_UNSUPPORTED - Add or remove the same device path.\r
+ \r
+ EFI_SUCCESS - Success add or remove the device path from \r
+ the console variable.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
+ UINTN DevicePathSize;\r
+ EFI_DEVICE_PATH_PROTOCOL *Instance;\r
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
+\r
+ VarConsole = NULL;\r
+ DevicePathSize = 0;\r
+ NewDevicePath = NULL;\r
+ Status = EFI_UNSUPPORTED;\r
+\r
+ //\r
+ // Notes: check the device path point, here should check\r
+ // with compare memory\r
+ //\r
+ if (CustomizedConDevicePath == ExclusiveDevicePath) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ //\r
+ // Delete the ExclusiveDevicePath from current default console\r
+ //\r
+ VarConsole = BdsLibGetVariableAndSize (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ &DevicePathSize\r
+ );\r
+\r
+ if (ExclusiveDevicePath != NULL && VarConsole != NULL) {\r
+ if (BdsLibMatchDevicePaths (VarConsole, ExclusiveDevicePath)) {\r
+\r
+ Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);\r
+\r
+ while (VarConsole != NULL) {\r
+ if (CompareMem (\r
+ Instance,\r
+ ExclusiveDevicePath,\r
+ DevicePathSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)\r
+ ) == 0) {\r
+ //\r
+ // Remove the match part\r
+ //\r
+ NewDevicePath = AppendDevicePathInstance (NewDevicePath, VarConsole);\r
+ break;\r
+ } else {\r
+ //\r
+ // Continue the next instance\r
+ //\r
+ NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);\r
+ }\r
+\r
+ Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);\r
+ }\r
+ //\r
+ // Reset the console variable with new device path\r
+ //\r
+ gRT->SetVariable (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ GetDevicePathSize (NewDevicePath),\r
+ NewDevicePath\r
+ );\r
+ }\r
+ }\r
+ //\r
+ // Try to append customized device path\r
+ //\r
+ VarConsole = BdsLibGetVariableAndSize (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ &DevicePathSize\r
+ );\r
+\r
+ if (CustomizedConDevicePath != NULL) {\r
+ if (!BdsLibMatchDevicePaths (VarConsole, CustomizedConDevicePath)) {\r
+ //\r
+ // In the first check, the default console variable will be null,\r
+ // just append current customized device path\r
+ //\r
+ VarConsole = AppendDevicePathInstance (VarConsole, CustomizedConDevicePath);\r
+\r
+ //\r
+ // Update the variable of the default console\r
+ //\r
+ gRT->SetVariable (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ GetDevicePathSize (VarConsole),\r
+ VarConsole\r
+ );\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+BdsLibConnectConsoleVariable (\r
+ IN CHAR16 *ConVarName\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Connect the console device base on the variable ConVarName, if\r
+ device path of the ConVarName is multi-instance device path, if\r
+ anyone of the instances is connected success, then this function\r
+ will return success.\r
+\r
+Arguments:\r
+\r
+ ConVarName - Console related variable name, ConIn, ConOut, ErrOut.\r
+\r
+Returns:\r
+\r
+ EFI_NOT_FOUND - There is not any console devices connected success\r
+ \r
+ EFI_SUCCESS - Success connect any one instance of the console\r
+ device path base on the variable ConVarName.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *StartDevicePath;\r
+ UINTN VariableSize;\r
+ EFI_DEVICE_PATH_PROTOCOL *Instance;\r
+ EFI_DEVICE_PATH_PROTOCOL *Next;\r
+ EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;\r
+ UINTN Size;\r
+ BOOLEAN DeviceExist;\r
+\r
+ Status = EFI_SUCCESS;\r
+ DeviceExist = FALSE;\r
+\r
+ //\r
+ // Check if the console variable exist\r
+ //\r
+ StartDevicePath = BdsLibGetVariableAndSize (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ &VariableSize\r
+ );\r
+ if (StartDevicePath == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ CopyOfDevicePath = DuplicateDevicePath (StartDevicePath);\r
+ do {\r
+ //\r
+ // Check every instance of the console variable\r
+ //\r
+ Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);\r
+ Next = Instance;\r
+ while (!IsDevicePathEndType (Next)) {\r
+ Next = NextDevicePathNode (Next);\r
+ }\r
+\r
+ SetDevicePathEndNode (Next);\r
+\r
+ //\r
+ // Connect the instance device path\r
+ //\r
+ Status = BdsLibConnectDevicePath (Instance);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Delete the instance from the console varialbe\r
+ //\r
+ BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);\r
+ } else {\r
+ DeviceExist = TRUE;\r
+ }\r
+\r
+ } while (CopyOfDevicePath != NULL);\r
+\r
+ gBS->FreePool (StartDevicePath);\r
+\r
+ if (DeviceExist == FALSE) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+VOID\r
+BdsLibConnectAllConsoles (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function will search every simpletxt devive in current system,\r
+ and make every simpletxt device as pertantial console device.\r
+\r
+Arguments:\r
+\r
+ None\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;\r
+ UINTN HandleCount;\r
+ EFI_HANDLE *HandleBuffer;\r
+\r
+ Index = 0;\r
+ HandleCount = 0;\r
+ HandleBuffer = NULL;\r
+ ConDevicePath = NULL;\r
+\r
+ //\r
+ // Update all the console varables\r
+ //\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiSimpleTextInProtocolGuid,\r
+ NULL,\r
+ &HandleCount,\r
+ &HandleBuffer\r
+ );\r
+ for (Index = 0; Index < HandleCount; Index++) {\r
+ Status = gBS->HandleProtocol (\r
+ HandleBuffer[Index],\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ConDevicePath\r
+ );\r
+ BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);\r
+ }\r
+\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiSimpleTextOutProtocolGuid,\r
+ NULL,\r
+ &HandleCount,\r
+ &HandleBuffer\r
+ );\r
+ for (Index = 0; Index < HandleCount; Index++) {\r
+ Status = gBS->HandleProtocol (\r
+ HandleBuffer[Index],\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ConDevicePath\r
+ );\r
+ BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);\r
+ BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);\r
+ }\r
+ //\r
+ // Connect all console variables\r
+ //\r
+ BdsLibConnectAllDefaultConsoles ();\r
+\r
+}\r
+\r
+EFI_STATUS\r
+BdsLibConnectAllDefaultConsoles (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This function will connect console device base on the console \r
+ device variable ConIn, ConOut and ErrOut.\r
+\r
+Arguments:\r
+\r
+ None\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - At least one of the ConIn and ConOut device have\r
+ been connected success.\r
+ \r
+ EFI_STATUS - Return the status of BdsLibConnectConsoleVariable ().\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *VarErrout;\r
+ UINTN DevicePathSize;\r
+\r
+ //\r
+ // Connect all default console variables\r
+ //\r
+ Status = BdsLibConnectConsoleVariable (L"ConIn");\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = BdsLibConnectConsoleVariable (L"ConOut");\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Special treat the err out device, becaues the null\r
+ // err out var is legal.\r
+ //\r
+ VarErrout = BdsLibGetVariableAndSize (\r
+ L"ErrOut",\r
+ &gEfiGlobalVariableGuid,\r
+ &DevicePathSize\r
+ );\r
+ if (VarErrout != NULL) {\r
+ BdsLibConnectConsoleVariable (L"ErrOut");\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r