summaryrefslogtreecommitdiff
path: root/EdkUnixPkg/Library/EdkGenericBdsLib
diff options
context:
space:
mode:
Diffstat (limited to 'EdkUnixPkg/Library/EdkGenericBdsLib')
-rw-r--r--EdkUnixPkg/Library/EdkGenericBdsLib/BdsConsole.c157
-rw-r--r--EdkUnixPkg/Library/EdkGenericBdsLib/BdsMisc.c89
2 files changed, 176 insertions, 70 deletions
diff --git a/EdkUnixPkg/Library/EdkGenericBdsLib/BdsConsole.c b/EdkUnixPkg/Library/EdkGenericBdsLib/BdsConsole.c
index 721d74363a..6c9097f142 100644
--- a/EdkUnixPkg/Library/EdkGenericBdsLib/BdsConsole.c
+++ b/EdkUnixPkg/Library/EdkGenericBdsLib/BdsConsole.c
@@ -19,6 +19,30 @@ Abstract:
--*/
+BOOLEAN
+IsNvNeed (
+ IN CHAR16 *ConVarName
+ )
+{
+ CHAR16 *Ptr;
+
+ Ptr = ConVarName;
+
+ //
+ // If the variable includes "Dev" at last, we consider
+ // it does not support NV attribute.
+ //
+ while (*Ptr) {
+ Ptr++;
+ }
+
+ if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
EFI_STATUS
BdsLibUpdateConsoleVariable (
IN CHAR16 *ConVarName,
@@ -56,12 +80,12 @@ Returns:
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *VarConsole;
UINTN DevicePathSize;
- EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
+ UINT32 Attributes;
VarConsole = NULL;
DevicePathSize = 0;
- NewDevicePath = NULL;
Status = EFI_UNSUPPORTED;
//
@@ -79,73 +103,70 @@ Returns:
&gEfiGlobalVariableGuid,
&DevicePathSize
);
-
+
+ //
+ // Initialize NewDevicePath
+ //
+ NewDevicePath = VarConsole;
+
+ //
+ // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.
+ // In the end, NewDevicePath is the final device path.
+ //
if (ExclusiveDevicePath != NULL && VarConsole != NULL) {
- if (BdsLibMatchDevicePaths (VarConsole, ExclusiveDevicePath)) {
-
- Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
-
- while (VarConsole != NULL) {
- if (CompareMem (
- Instance,
- ExclusiveDevicePath,
- DevicePathSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)
- ) == 0) {
- //
- // Remove the match part
- //
- NewDevicePath = AppendDevicePathInstance (NewDevicePath, VarConsole);
- break;
- } else {
- //
- // Continue the next instance
- //
- NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);
- }
-
- Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
- }
- //
- // Reset the console variable with new device path
- //
- gRT->SetVariable (
- ConVarName,
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
- GetDevicePathSize (NewDevicePath),
- NewDevicePath
- );
- }
+ NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);
}
//
- // Try to append customized device path
+ // Try to append customized device path to NewDevicePath.
//
- VarConsole = BdsLibGetVariableAndSize (
- ConVarName,
- &gEfiGlobalVariableGuid,
- &DevicePathSize
- );
-
if (CustomizedConDevicePath != NULL) {
- if (!BdsLibMatchDevicePaths (VarConsole, CustomizedConDevicePath)) {
+ if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {
//
- // In the first check, the default console variable will be null,
- // just append current customized device path
+ // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
//
- VarConsole = AppendDevicePathInstance (VarConsole, CustomizedConDevicePath);
-
+ NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);
//
- // Update the variable of the default console
+ // In the first check, the default console variable will be null,
+ // just append current customized device path
//
- gRT->SetVariable (
- ConVarName,
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
- GetDevicePathSize (VarConsole),
- VarConsole
- );
+ TempNewDevicePath = NewDevicePath;
+ NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);
+ BdsLibSafeFreePool(TempNewDevicePath);
}
}
+
+ //
+ // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.
+ //
+ if (IsNvNeed(ConVarName)) {
+ //
+ // ConVarName has NV attribute.
+ //
+ Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
+ } else {
+ //
+ // ConVarName does not have NV attribute.
+ //
+ Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
+ }
+
+ //
+ // Finally, Update the variable of the default console by NewDevicePath
+ //
+ gRT->SetVariable (
+ ConVarName,
+ &gEfiGlobalVariableGuid,
+ Attributes,
+ GetDevicePathSize (NewDevicePath),
+ NewDevicePath
+ );
+
+ if (VarConsole == NewDevicePath) {
+ BdsLibSafeFreePool(VarConsole);
+ } else {
+ BdsLibSafeFreePool(VarConsole);
+ BdsLibSafeFreePool(NewDevicePath);
+ }
return EFI_SUCCESS;
@@ -201,7 +222,7 @@ Returns:
return EFI_UNSUPPORTED;
}
- CopyOfDevicePath = DuplicateDevicePath (StartDevicePath);
+ CopyOfDevicePath = StartDevicePath;
do {
//
// Check every instance of the console variable
@@ -226,7 +247,7 @@ Returns:
} else {
DeviceExist = TRUE;
}
-
+ BdsLibSafeFreePool(Instance);
} while (CopyOfDevicePath != NULL);
gBS->FreePool (StartDevicePath);
@@ -289,6 +310,8 @@ Returns:
BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
}
+ BdsLibSafeFreePool(HandleBuffer);
+
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleTextOutProtocolGuid,
@@ -305,6 +328,9 @@ Returns:
BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
}
+
+ BdsLibSafeFreePool(HandleBuffer);
+
//
// Connect all console variables
//
@@ -337,8 +363,6 @@ Returns:
--*/
{
EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *VarErrout;
- UINTN DevicePathSize;
//
// Connect all default console variables
@@ -356,14 +380,7 @@ Returns:
// Special treat the err out device, becaues the null
// err out var is legal.
//
- VarErrout = BdsLibGetVariableAndSize (
- L"ErrOut",
- &gEfiGlobalVariableGuid,
- &DevicePathSize
- );
- if (VarErrout != NULL) {
- BdsLibConnectConsoleVariable (L"ErrOut");
- }
+ BdsLibConnectConsoleVariable (L"ErrOut");
return EFI_SUCCESS;
diff --git a/EdkUnixPkg/Library/EdkGenericBdsLib/BdsMisc.c b/EdkUnixPkg/Library/EdkGenericBdsLib/BdsMisc.c
index 6b4d1aa149..2662ba7297 100644
--- a/EdkUnixPkg/Library/EdkGenericBdsLib/BdsMisc.c
+++ b/EdkUnixPkg/Library/EdkGenericBdsLib/BdsMisc.c
@@ -652,6 +652,95 @@ Returns:
return Buffer;
}
+VOID
+BdsLibSafeFreePool (
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Free pool safely.
+
+Arguments:
+
+ Buffer - The allocated pool entry to free
+
+Returns:
+
+ Pointer of the buffer allocated.
+
+--*/
+{
+ if (Buffer != NULL) {
+ gBS->FreePool (Buffer);
+ Buffer = NULL;
+ }
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+BdsLibDelPartMatchInstance (
+ IN EFI_DEVICE_PATH_PROTOCOL *Multi,
+ IN EFI_DEVICE_PATH_PROTOCOL *Single
+ )
+/*++
+
+Routine Description:
+
+ Delete the instance in Multi which matches partly with Single instance
+
+Arguments:
+
+ Multi - A pointer to a multi-instance device path data structure.
+
+ Single - A pointer to a single-instance device path data structure.
+
+Returns:
+
+ This function will remove the device path instances in Multi which partly
+ match with the Single, and return the result device path. If there is no
+ remaining device path as a result, this function will return NULL.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Instance;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
+ UINTN InstanceSize;
+ UINTN SingleDpSize;
+ UINTN Size;
+
+ NewDevicePath = NULL;
+ TempNewDevicePath = NULL;
+
+ if (Multi == NULL || Single == NULL) {
+ return Multi;
+ }
+
+ Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
+ SingleDpSize = GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;
+ InstanceSize -= END_DEVICE_PATH_LENGTH;
+
+ while (Instance != NULL) {
+
+ Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize;
+
+ if ((CompareMem (Instance, Single, Size) != 0)) {
+ //
+ // Append the device path instance which does not match with Single
+ //
+ TempNewDevicePath = NewDevicePath;
+ NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);
+ BdsLibSafeFreePool(TempNewDevicePath);
+ }
+ BdsLibSafeFreePool(Instance);
+ Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
+ InstanceSize -= END_DEVICE_PATH_LENGTH;
+ }
+
+ return NewDevicePath;
+}
+
BOOLEAN
BdsLibMatchDevicePaths (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,