]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkUnixPkg/Library/EdkGenericBdsLib/BdsConsole.c
Unix version of EFI emulator
[mirror_edk2.git] / EdkUnixPkg / Library / EdkGenericBdsLib / BdsConsole.c
diff --git a/EdkUnixPkg/Library/EdkGenericBdsLib/BdsConsole.c b/EdkUnixPkg/Library/EdkGenericBdsLib/BdsConsole.c
new file mode 100644 (file)
index 0000000..721d743
--- /dev/null
@@ -0,0 +1,370 @@
+/*++\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