diff options
Diffstat (limited to 'ArmPlatformPkg/Bds/BdsHelper.c')
-rw-r--r-- | ArmPlatformPkg/Bds/BdsHelper.c | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/ArmPlatformPkg/Bds/BdsHelper.c b/ArmPlatformPkg/Bds/BdsHelper.c new file mode 100644 index 0000000000..2f0cb31d39 --- /dev/null +++ b/ArmPlatformPkg/Bds/BdsHelper.c @@ -0,0 +1,307 @@ +/** @file +* +* Copyright (c) 2011, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include "BdsInternal.h" + +EFI_STATUS +GetEnvironmentVariable ( + IN CONST CHAR16* VariableName, + IN VOID* DefaultValue, + IN OUT UINTN* Size, + OUT VOID** Value + ) +{ + EFI_STATUS Status; + UINTN VariableSize; + + // Try to get the variable size. + *Value = NULL; + VariableSize = 0; + Status = gRT->GetVariable ((CHAR16 *) VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value); + if (Status == EFI_NOT_FOUND) { + if ((DefaultValue != NULL) && (Size != NULL) && (*Size != 0)) { + // If the environment variable does not exist yet then set it with the default value + Status = gRT->SetVariable ( + (CHAR16*)VariableName, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + *Size, + DefaultValue + ); + *Value = DefaultValue; + } else { + return EFI_NOT_FOUND; + } + } else if (Status == EFI_BUFFER_TOO_SMALL) { + // Get the environment variable value + *Value = AllocatePool (VariableSize); + if (*Value == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &VariableSize, *Value); + if (EFI_ERROR (Status)) { + FreePool(*Value); + return EFI_INVALID_PARAMETER; + } + + if (Size) { + *Size = VariableSize; + } + } else { + *Value = DefaultValue; + return Status; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EditHIInputAscii ( + IN OUT CHAR8 *CmdLine, + IN UINTN MaxCmdLine + ) +{ + UINTN CmdLineIndex; + UINTN WaitIndex; + CHAR8 Char; + EFI_INPUT_KEY Key; + EFI_STATUS Status; + + AsciiPrint (CmdLine); + + for (CmdLineIndex = AsciiStrLen(CmdLine); CmdLineIndex < MaxCmdLine; ) { + Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex); + ASSERT_EFI_ERROR (Status); + + Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + ASSERT_EFI_ERROR (Status); + + // Unicode character is valid when Scancode is NUll + if (Key.ScanCode == SCAN_NULL) { + // Scan code is NUll, hence read Unicode character + Char = (CHAR8)Key.UnicodeChar; + } else { + Char = CHAR_NULL; + } + + if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) { + CmdLine[CmdLineIndex] = '\0'; + AsciiPrint ("\n\r"); + + return EFI_SUCCESS; + } else if ((Char == '\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){ + if (CmdLineIndex != 0) { + CmdLineIndex--; + AsciiPrint ("\b \b"); + } + } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) { + return EFI_INVALID_PARAMETER; + } else { + CmdLine[CmdLineIndex++] = Char; + AsciiPrint ("%c", Char); + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +GetHIInputAscii ( + IN OUT CHAR8 *CmdLine, + IN UINTN MaxCmdLine + ) +{ + // For a new input just passed an empty string + CmdLine[0] = '\0'; + + return EditHIInputAscii (CmdLine,MaxCmdLine); +} + +EFI_STATUS +GetHIInputInteger ( + OUT UINTN *Integer + ) +{ + CHAR8 CmdLine[255]; + EFI_STATUS Status; + + CmdLine[0] = '\0'; + Status = EditHIInputAscii (CmdLine,255); + if (!EFI_ERROR(Status)) { + *Integer = AsciiStrDecimalToUintn (CmdLine); + } + + return Status; +} + +EFI_STATUS +GetHIInputIP ( + OUT EFI_IP_ADDRESS *Ip + ) +{ + CHAR8 CmdLine[255]; + CHAR8 *Str; + EFI_STATUS Status; + + CmdLine[0] = '\0'; + Status = EditHIInputAscii (CmdLine,255); + if (!EFI_ERROR(Status)) { + Str = CmdLine; + Ip->v4.Addr[0] = (UINT8)AsciiStrDecimalToUintn (Str); + + Str = AsciiStrStr (Str, "."); + if (Str == NULL) { + return EFI_INVALID_PARAMETER; + } + + Ip->v4.Addr[1] = (UINT8)AsciiStrDecimalToUintn (++Str); + + Str = AsciiStrStr (Str, "."); + if (Str == NULL) { + return EFI_INVALID_PARAMETER; + } + + Ip->v4.Addr[2] = (UINT8)AsciiStrDecimalToUintn (++Str); + + Str = AsciiStrStr (Str, "."); + if (Str == NULL) { + return EFI_INVALID_PARAMETER; + } + + Ip->v4.Addr[3] = (UINT8)AsciiStrDecimalToUintn (++Str); + } + + return Status; +} + +EFI_STATUS +GetHIInputBoolean ( + OUT BOOLEAN *Value + ) +{ + CHAR8 CmdBoolean[2]; + EFI_STATUS Status; + + while(1) { + Print (L"[y/n] "); + Status = GetHIInputAscii (CmdBoolean,2); + if (EFI_ERROR(Status)) { + return Status; + } else if ((CmdBoolean[0] == 'y') || (CmdBoolean[0] == 'Y')) { + if (Value) *Value = TRUE; + return EFI_SUCCESS; + } else if ((CmdBoolean[0] == 'n') || (CmdBoolean[0] == 'N')) { + if (Value) *Value = FALSE; + return EFI_SUCCESS; + } + } +} + +BOOLEAN +HasFilePathEfiExtension ( + IN CHAR16* FilePath + ) +{ + return (StrCmp (FilePath + (StrSize(FilePath)/sizeof(CHAR16)) - 5, L".efi") == 0); +} + +// Return the last non end-type Device Path Node from a Device Path +EFI_DEVICE_PATH* +GetLastDevicePathNode ( + IN EFI_DEVICE_PATH* DevicePath + ) +{ + EFI_DEVICE_PATH* PrevDevicePathNode; + + PrevDevicePathNode = DevicePath; + while (!IsDevicePathEndType (DevicePath)) { + PrevDevicePathNode = DevicePath; + DevicePath = NextDevicePathNode (DevicePath); + } + + return PrevDevicePathNode; +} + +EFI_STATUS +GenerateDeviceDescriptionName ( + IN EFI_HANDLE Handle, + IN OUT CHAR16* Description + ) +{ + EFI_STATUS Status; + EFI_COMPONENT_NAME_PROTOCOL* ComponentName2Protocol; + EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; + EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; + CHAR16* DriverName; + CHAR16* DevicePathTxt; + EFI_DEVICE_PATH* DevicePathNode; + + ComponentName2Protocol = NULL; + Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol); + if (!EFI_ERROR(Status)) { + //TODO: Fixme. we must find the best langague + Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName); + if (!EFI_ERROR(Status)) { + StrnCpy (Description,DriverName,BOOT_DEVICE_DESCRIPTION_MAX); + } + } + + if (EFI_ERROR(Status)) { + // Use the lastest non null entry of the Device path as a description + Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); + if (EFI_ERROR(Status)) { + return Status; + } + + // Convert the last non end-type Device Path Node in text for the description + DevicePathNode = GetLastDevicePathNode (DevicePathProtocol); + Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); + ASSERT_EFI_ERROR(Status); + DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathNode,TRUE,TRUE); + StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX); + FreePool (DevicePathTxt); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +BdsStartBootOption ( + IN CHAR16* BootOption + ) +{ + EFI_STATUS Status; + EFI_LOAD_OPTION EfiLoadOption; + UINTN EfiLoadOptionSize; + BDS_LOAD_OPTION *BdsLoadOption; + + Status = GetEnvironmentVariable (BootOption, NULL, &EfiLoadOptionSize, (VOID**)&EfiLoadOption); + if (!EFI_ERROR(Status)) { + Status = BootOptionParseLoadOption (EfiLoadOption, EfiLoadOptionSize, &BdsLoadOption); + if (!EFI_ERROR(Status)) { + Status = BootOptionStart (BdsLoadOption); + FreePool (BdsLoadOption); + } + + if (!EFI_ERROR(Status)) { + Status = EFI_SUCCESS; + } else { + Status = EFI_NOT_STARTED; + } + } else { + Status = EFI_NOT_FOUND; + } + return Status; +} |