From patchwork Tue Oct 25 17:16:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 79253 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp3230176qge; Tue, 25 Oct 2016 10:17:17 -0700 (PDT) X-Received: by 10.98.211.147 with SMTP id z19mr41348275pfk.149.1477415837649; Tue, 25 Oct 2016 10:17:17 -0700 (PDT) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id l3si21674350pgn.2.2016.10.25.10.17.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 25 Oct 2016 10:17:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 32C9E1A1E6B; Tue, 25 Oct 2016 10:17:17 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x233.google.com (mail-wm0-x233.google.com [IPv6:2a00:1450:400c:c09::233]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 295E61A1E57 for ; Tue, 25 Oct 2016 10:17:15 -0700 (PDT) Received: by mail-wm0-x233.google.com with SMTP id c78so175139734wme.0 for ; Tue, 25 Oct 2016 10:17:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=1m3W/DLlXM0HcQWVIFak/2LWbrJU8wYl3tZn34OqRx4=; b=F3QwwPn642Gm1bXGYNW+HNOb7NaajeZan/PiGcqsj8qVnpytvBc86JiCxf9R8KoQzM ehoMFHdDVIPwjYPgkYfUYW8ftXbAxFIUFpSK6QoSDbdKmep3UH+L5Rkppf33N0z60DM2 XNGkz4LPH2388ggjXuKLcQ2ONQLx/Zx69ZFlo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=1m3W/DLlXM0HcQWVIFak/2LWbrJU8wYl3tZn34OqRx4=; b=k0YLjTdd2KDvhdKwaHVFbDzgO4rxCnrVcyTdTOnS/TGP58QuDVJ0qoJSJx220TEv1P jZhv5ZysWAwl9p5TVxzRm+HN0MHzJq7TWk6ywnu+ec58G9+xp1LDUe3hjWLl1uhjRqYf GVeNQQEFkZCTBLYTQUUIKOT/lnOHnTFFt7k5qvkw/nv6h8QzD8oyINxgW7pLuQX3uEMw 9nTa9qVpahvR3iXiv0Pu1zcb1cYXIIheCvRhK9iRFuT22Eegoq+HWKCfkTBzPpR3Y10W ScEcyuz6gWTzfxJi75T7PnnicqMYcL8s0HmN2a7BMcGI2YrADI9rO5vrqaTwhwHABAr/ ITeQ== X-Gm-Message-State: ABUngvfn53SR2nBXSPi4fg8aqhoGe9hPM8A2yQ+ePEvfY/rOpBCMsUWSjsXhJH11STGM0Rvg X-Received: by 10.194.78.195 with SMTP id d3mr3884533wjx.96.1477415832102; Tue, 25 Oct 2016 10:17:12 -0700 (PDT) Received: from localhost.localdomain ([105.129.136.43]) by smtp.gmail.com with ESMTPSA id jt8sm26216669wjc.33.2016.10.25.10.17.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 25 Oct 2016 10:17:11 -0700 (PDT) From: Ard Biesheuvel To: edk2-devel@lists.01.org, leif.lindholm@linaro.org Date: Tue, 25 Oct 2016 18:16:58 +0100 Message-Id: <1477415818-11404-1-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 Subject: [edk2] [PATCH] ArmPlatformPkg: remove ARM BDS X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ryan.harkin@linaro.org, Ard Biesheuvel MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" This is no longer used, and does not belong in a reference code base, so remove it. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- Note that the OpenPlatformPkg version of Beagle will still need to be brought in line with the EDK2 version (after switching to the generic BDS) ArmPlatformPkg/Bds/Bds.c | 561 --------- ArmPlatformPkg/Bds/Bds.inf | 90 -- ArmPlatformPkg/Bds/BdsHelper.c | 465 -------- ArmPlatformPkg/Bds/BdsInternal.h | 277 ----- ArmPlatformPkg/Bds/BootLinux.c | 124 -- ArmPlatformPkg/Bds/BootMenu.c | 1101 ------------------ ArmPlatformPkg/Bds/BootOption.c | 316 ------ ArmPlatformPkg/Bds/BootOptionSupport.c | 1195 -------------------- 8 files changed, 4129 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel Reviewed-by: Leif Lindholm Tested-by: Ryan Harkin Reviewed-by: Ryan Harkin diff --git a/ArmPlatformPkg/Bds/Bds.c b/ArmPlatformPkg/Bds/Bds.c deleted file mode 100644 index 4cea3cd531bb..000000000000 --- a/ArmPlatformPkg/Bds/Bds.c +++ /dev/null @@ -1,561 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2015, 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" - -#include -#include - -#include - -#include - -#define EFI_SET_TIMER_TO_SECOND 10000000 - -STATIC -EFI_STATUS -GetConsoleDevicePathFromVariable ( - IN CHAR16* ConsoleVarName, - IN CHAR16* DefaultConsolePaths, - OUT EFI_DEVICE_PATH** DevicePaths - ) -{ - EFI_STATUS Status; - UINTN Size; - EFI_DEVICE_PATH_PROTOCOL* DevicePathInstances; - EFI_DEVICE_PATH_PROTOCOL* DevicePathInstance; - CHAR16* DevicePathStr; - CHAR16* NextDevicePathStr; - EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol; - - Status = GetGlobalEnvironmentVariable (ConsoleVarName, NULL, NULL, (VOID**)&DevicePathInstances); - if (EFI_ERROR(Status)) { - // In case no default console device path has been defined we assume a driver handles the console (eg: SimpleTextInOutSerial) - if ((DefaultConsolePaths == NULL) || (DefaultConsolePaths[0] == L'\0')) { - *DevicePaths = NULL; - return EFI_SUCCESS; - } - - Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); - ASSERT_EFI_ERROR(Status); - - DevicePathInstances = NULL; - - // Extract the Device Path instances from the multi-device path string - while ((DefaultConsolePaths != NULL) && (DefaultConsolePaths[0] != L'\0')) { - NextDevicePathStr = StrStr (DefaultConsolePaths, L";"); - if (NextDevicePathStr == NULL) { - DevicePathStr = DefaultConsolePaths; - DefaultConsolePaths = NULL; - } else { - DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DefaultConsolePaths + 1) * sizeof(CHAR16), DefaultConsolePaths); - *(DevicePathStr + (NextDevicePathStr - DefaultConsolePaths)) = L'\0'; - DefaultConsolePaths = NextDevicePathStr; - if (DefaultConsolePaths[0] == L';') { - DefaultConsolePaths++; - } - } - - DevicePathInstance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr); - ASSERT(DevicePathInstance != NULL); - DevicePathInstances = AppendDevicePathInstance (DevicePathInstances, DevicePathInstance); - - if (NextDevicePathStr != NULL) { - FreePool (DevicePathStr); - } - FreePool (DevicePathInstance); - } - - // Set the environment variable with this device path multi-instances - Size = GetDevicePathSize (DevicePathInstances); - if (Size > 0) { - gRT->SetVariable ( - ConsoleVarName, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - Size, - DevicePathInstances - ); - } else { - Status = EFI_INVALID_PARAMETER; - } - } - - if (!EFI_ERROR(Status)) { - *DevicePaths = DevicePathInstances; - } - return Status; -} - -STATIC -EFI_STATUS -InitializeConsolePipe ( - IN EFI_DEVICE_PATH *ConsoleDevicePaths, - IN EFI_GUID *Protocol, - OUT EFI_HANDLE *Handle, - OUT VOID* *Interface - ) -{ - EFI_STATUS Status; - UINTN Size; - UINTN NoHandles; - EFI_HANDLE *Buffer; - EFI_DEVICE_PATH_PROTOCOL* DevicePath; - - // Connect all the Device Path Consoles - while (ConsoleDevicePaths != NULL) { - DevicePath = GetNextDevicePathInstance (&ConsoleDevicePaths, &Size); - - Status = BdsConnectDevicePath (DevicePath, Handle, NULL); - DEBUG_CODE_BEGIN(); - if (EFI_ERROR(Status)) { - // We convert back to the text representation of the device Path - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; - CHAR16* DevicePathTxt; - EFI_STATUS Status; - - Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); - if (!EFI_ERROR(Status)) { - DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePath, TRUE, TRUE); - - DEBUG((EFI_D_ERROR,"Fail to start the console with the Device Path '%s'. (Error '%r')\n", DevicePathTxt, Status)); - - FreePool (DevicePathTxt); - } - } - DEBUG_CODE_END(); - - // If the console splitter driver is not supported by the platform then use the first Device Path - // instance for the console interface. - if (!EFI_ERROR(Status) && (*Interface == NULL)) { - Status = gBS->HandleProtocol (*Handle, Protocol, Interface); - } - } - - // No Device Path has been defined for this console interface. We take the first protocol implementation - if (*Interface == NULL) { - Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer); - if (EFI_ERROR (Status)) { - BdsConnectAllDrivers(); - Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer); - } - - if (!EFI_ERROR(Status)) { - *Handle = Buffer[0]; - Status = gBS->HandleProtocol (*Handle, Protocol, Interface); - ASSERT_EFI_ERROR(Status); - FreePool (Buffer); - } - } else { - Status = EFI_SUCCESS; - } - - return Status; -} - -EFI_STATUS -InitializeConsole ( - VOID - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH* ConOutDevicePaths; - EFI_DEVICE_PATH* ConInDevicePaths; - EFI_DEVICE_PATH* ConErrDevicePaths; - - // By getting the Console Device Paths from the environment variables before initializing the console pipe, we - // create the 3 environment variables (ConIn, ConOut, ConErr) that allows to initialize all the console interface - // of newly installed console drivers - Status = GetConsoleDevicePathFromVariable (L"ConOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConOutDevicePaths); - ASSERT_EFI_ERROR (Status); - Status = GetConsoleDevicePathFromVariable (L"ConIn", (CHAR16*)PcdGetPtr(PcdDefaultConInPaths), &ConInDevicePaths); - ASSERT_EFI_ERROR (Status); - Status = GetConsoleDevicePathFromVariable (L"ErrOut", (CHAR16*)PcdGetPtr(PcdDefaultConOutPaths), &ConErrDevicePaths); - ASSERT_EFI_ERROR (Status); - - // Initialize the Consoles - Status = InitializeConsolePipe (ConOutDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)&gST->ConOut); - ASSERT_EFI_ERROR (Status); - Status = InitializeConsolePipe (ConInDevicePaths, &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **)&gST->ConIn); - ASSERT_EFI_ERROR (Status); - Status = InitializeConsolePipe (ConErrDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)&gST->StdErr); - if (EFI_ERROR(Status)) { - // In case of error, we reuse the console output for the error output - gST->StandardErrorHandle = gST->ConsoleOutHandle; - gST->StdErr = gST->ConOut; - } - - // Free Memory allocated for reading the UEFI Variables - if (ConOutDevicePaths) { - FreePool (ConOutDevicePaths); - } - if (ConInDevicePaths) { - FreePool (ConInDevicePaths); - } - if (ConErrDevicePaths) { - FreePool (ConErrDevicePaths); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -DefineDefaultBootEntries ( - VOID - ) -{ - BDS_LOAD_OPTION* BdsLoadOption; - UINTN Size; - EFI_STATUS Status; - EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; - EFI_DEVICE_PATH* BootDevicePath; - UINTN CmdLineSize; - UINTN CmdLineAsciiSize; - CHAR16* DefaultBootArgument; - CHAR8* AsciiDefaultBootArgument; - - // - // If Boot Order does not exist then create a default entry - // - Size = 0; - Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL); - if (Status == EFI_NOT_FOUND) { - if ((PcdGetPtr(PcdDefaultBootDevicePath) == NULL) || (StrLen ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)) == 0)) { - return EFI_UNSUPPORTED; - } - - Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); - if (EFI_ERROR(Status)) { - // You must provide an implementation of DevicePathFromTextProtocol in your firmware (eg: DevicePathDxe) - DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathFromTextProtocol\n")); - return Status; - } - BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)); - - DEBUG_CODE_BEGIN(); - // We convert back to the text representation of the device Path to see if the initial text is correct - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; - CHAR16* DevicePathTxt; - - Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); - ASSERT_EFI_ERROR(Status); - DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootDevicePath, TRUE, TRUE); - - if (StrCmp ((CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath), DevicePathTxt) != 0) { - DEBUG ((EFI_D_ERROR, "Device Path given: '%s' Device Path expected: '%s'\n", - (CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath), DevicePathTxt)); - ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); - } - - FreePool (DevicePathTxt); - DEBUG_CODE_END(); - - // Create the entry is the Default values are correct - if (BootDevicePath != NULL) { - // We do not support NULL pointer - ASSERT (PcdGetPtr (PcdDefaultBootArgument) != NULL); - - // - // Logic to handle ASCII or Unicode default parameters - // - if (*(CHAR8*)PcdGetPtr (PcdDefaultBootArgument) == '\0') { - CmdLineSize = 0; - CmdLineAsciiSize = 0; - DefaultBootArgument = NULL; - AsciiDefaultBootArgument = NULL; - } else if (IsUnicodeString ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument))) { - // The command line is a Unicode string - DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument); - CmdLineSize = StrSize (DefaultBootArgument); - - // Initialize ASCII variables - CmdLineAsciiSize = CmdLineSize / 2; - AsciiDefaultBootArgument = AllocatePool (CmdLineAsciiSize); - if (AsciiDefaultBootArgument == NULL) { - return EFI_OUT_OF_RESOURCES; - } - UnicodeStrToAsciiStr ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument), AsciiDefaultBootArgument); - } else { - // The command line is a ASCII string - AsciiDefaultBootArgument = (CHAR8*)PcdGetPtr (PcdDefaultBootArgument); - CmdLineAsciiSize = AsciiStrSize (AsciiDefaultBootArgument); - - // Initialize ASCII variables - CmdLineSize = CmdLineAsciiSize * 2; - DefaultBootArgument = AllocatePool (CmdLineSize); - if (DefaultBootArgument == NULL) { - return EFI_OUT_OF_RESOURCES; - } - AsciiStrToUnicodeStr (AsciiDefaultBootArgument, DefaultBootArgument); - } - - BootOptionCreate (LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT, - (CHAR16*)PcdGetPtr (PcdDefaultBootDescription), - BootDevicePath, - (UINT8 *)DefaultBootArgument, // OptionalData - CmdLineSize, // OptionalDataSize - &BdsLoadOption - ); - FreePool (BdsLoadOption); - - if (DefaultBootArgument == (CHAR16*)PcdGetPtr (PcdDefaultBootArgument)) { - FreePool (AsciiDefaultBootArgument); - } else if (DefaultBootArgument != NULL) { - FreePool (DefaultBootArgument); - } - } else { - Status = EFI_UNSUPPORTED; - } - } - - return Status; -} - -EFI_STATUS -StartDefaultBootOnTimeout ( - VOID - ) -{ - UINTN Size; - UINT16 Timeout; - UINT16 *TimeoutPtr; - EFI_EVENT WaitList[2]; - UINTN WaitIndex; - UINT16 *BootOrder; - UINTN BootOrderSize; - UINTN Index; - CHAR16 BootVariableName[9]; - EFI_STATUS Status; - EFI_INPUT_KEY Key; - - Size = sizeof(UINT16); - Timeout = (UINT16)PcdGet16 (PcdPlatformBootTimeOut); - Status = GetGlobalEnvironmentVariable (L"Timeout", &Timeout, &Size, (VOID**)&TimeoutPtr); - if (!EFI_ERROR (Status)) { - Timeout = *TimeoutPtr; - FreePool (TimeoutPtr); - } - - if (Timeout != 0xFFFF) { - if (Timeout > 0) { - // Create the waiting events (keystroke and 1sec timer) - gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &WaitList[0]); - gBS->SetTimer (WaitList[0], TimerPeriodic, EFI_SET_TIMER_TO_SECOND); - WaitList[1] = gST->ConIn->WaitForKey; - - // Start the timer - WaitIndex = 0; - Print(L"The default boot selection will start in "); - while ((Timeout > 0) && (WaitIndex == 0)) { - Print(L"%3d seconds",Timeout); - gBS->WaitForEvent (2, WaitList, &WaitIndex); - if (WaitIndex == 0) { - Print(L"\b\b\b\b\b\b\b\b\b\b\b"); - Timeout--; - } - } - // Discard key in the buffer - do { - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); - } while(!EFI_ERROR(Status)); - gBS->CloseEvent (WaitList[0]); - Print(L"\n\r"); - } - - // In case of Timeout we start the default boot selection - if (Timeout == 0) { - // Get the Boot Option Order from the environment variable (a default value should have been created) - GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); - - for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) { - UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOrder[Index]); - Status = BdsStartBootOption (BootVariableName); - if(!EFI_ERROR(Status)){ - // Boot option returned successfully, hence don't need to start next boot option - break; - } - // In case of success, we should not return from this call. - } - FreePool (BootOrder); - } - } - return EFI_SUCCESS; -} - -/** - An empty function to pass error checking of CreateEventEx (). - - @param Event Event whose notification function is being invoked. - @param Context Pointer to the notification function's context, - which is implementation-dependent. - -**/ -VOID -EFIAPI -EmptyCallbackFunction ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - return; -} - -/** - This function uses policy data from the platform to determine what operating - system or system utility should be loaded and invoked. This function call - also optionally make the use of user input to determine the operating system - or system utility to be loaded and invoked. When the DXE Core has dispatched - all the drivers on the dispatch queue, this function is called. This - function will attempt to connect the boot devices required to load and invoke - the selected operating system or system utility. During this process, - additional firmware volumes may be discovered that may contain addition DXE - drivers that can be dispatched by the DXE Core. If a boot device cannot be - fully connected, this function calls the DXE Service Dispatch() to allow the - DXE drivers from any newly discovered firmware volumes to be dispatched. - Then the boot device connection can be attempted again. If the same boot - device connection operation fails twice in a row, then that boot device has - failed, and should be skipped. This function should never return. - - @param This The EFI_BDS_ARCH_PROTOCOL instance. - - @return None. - -**/ -VOID -EFIAPI -BdsEntry ( - IN EFI_BDS_ARCH_PROTOCOL *This - ) -{ - UINTN Size; - EFI_STATUS Status; - UINT16 *BootNext; - UINTN BootNextSize; - CHAR16 BootVariableName[9]; - EFI_EVENT EndOfDxeEvent; - - // - // Signal EndOfDxe PI Event - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - EmptyCallbackFunction, - NULL, - &gEfiEndOfDxeEventGroupGuid, - &EndOfDxeEvent - ); - if (!EFI_ERROR (Status)) { - gBS->SignalEvent (EndOfDxeEvent); - } - - PERF_END (NULL, "DXE", NULL, 0); - - // - // Declare the Firmware Vendor - // - if (FixedPcdGetPtr(PcdFirmwareVendor) != NULL) { - Size = 0x100; - gST->FirmwareVendor = AllocateRuntimePool (Size); - ASSERT (gST->FirmwareVendor != NULL); - UnicodeSPrint (gST->FirmwareVendor, Size, L"%a EFI %a %a", PcdGetPtr(PcdFirmwareVendor), __DATE__, __TIME__); - } - - // - // Fixup Table CRC after we updated Firmware Vendor - // - gST->Hdr.CRC32 = 0; - Status = gBS->CalculateCrc32 ((VOID*)gST, gST->Hdr.HeaderSize, &gST->Hdr.CRC32); - ASSERT_EFI_ERROR (Status); - - // Now we need to setup the EFI System Table with information about the console devices. - InitializeConsole (); - - // If BootNext environment variable is defined then we just load it ! - BootNextSize = sizeof(UINT16); - Status = GetGlobalEnvironmentVariable (L"BootNext", NULL, &BootNextSize, (VOID**)&BootNext); - if (!EFI_ERROR(Status)) { - ASSERT(BootNextSize == sizeof(UINT16)); - - // Generate the requested Boot Entry variable name - UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", *BootNext); - - // Set BootCurrent variable - gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - BootNextSize, BootNext); - - FreePool (BootNext); - - // Start the requested Boot Entry - Status = BdsStartBootOption (BootVariableName); - if (Status != EFI_NOT_FOUND) { - // BootNext has not been succeeded launched - if (EFI_ERROR(Status)) { - Print(L"Fail to start BootNext.\n"); - } - - // Delete the BootNext environment variable - gRT->SetVariable (L"BootNext", &gEfiGlobalVariableGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - 0, NULL); - } - - // Clear BootCurrent variable - gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - 0, NULL); - } - - // If Boot Order does not exist then create a default entry - DefineDefaultBootEntries (); - - // - // Update the CRC32 in the EFI System Table header - // - gST->Hdr.CRC32 = 0; - Status = gBS->CalculateCrc32 ((VOID*)gST, gST->Hdr.HeaderSize, &gST->Hdr.CRC32); - ASSERT_EFI_ERROR (Status); - - // Timer before initiating the default boot selection - StartDefaultBootOnTimeout (); - - // Start the Boot Menu - Status = BootMenuMain (); - ASSERT_EFI_ERROR (Status); - -} - -EFI_BDS_ARCH_PROTOCOL gBdsProtocol = { - BdsEntry, -}; - -EFI_STATUS -EFIAPI -BdsInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = gBS->InstallMultipleProtocolInterfaces ( - &ImageHandle, - &gEfiBdsArchProtocolGuid, &gBdsProtocol, - NULL - ); - ASSERT_EFI_ERROR (Status); - - return Status; -} diff --git a/ArmPlatformPkg/Bds/Bds.inf b/ArmPlatformPkg/Bds/Bds.inf deleted file mode 100644 index 96bec16f0a2e..000000000000 --- a/ArmPlatformPkg/Bds/Bds.inf +++ /dev/null @@ -1,90 +0,0 @@ -#/** @file -# -# Component description file for Bds module -# -# Copyright (c) 2011-2015, ARM Ltd. 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. -# -#**/ - - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = ArmPlatformBds - FILE_GUID = 5a50aa81-c3ae-4608-a0e3-41a2e69baf94 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - - ENTRY_POINT = BdsInitialize - -[Sources] - Bds.c - BdsHelper.c - BootLinux.c - BootMenu.c - BootOption.c - BootOptionSupport.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - ArmPkg/ArmPkg.dec - ArmPlatformPkg/ArmPlatformPkg.dec - EmbeddedPkg/EmbeddedPkg.dec - IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec - -[Guids] - gFdtTableGuid - -[LibraryClasses] - BdsLib - UefiBootServicesTableLib - DxeServicesTableLib - UefiDriverEntryPoint - DebugLib - PerformanceLib - PrintLib - BaseLib - FdtLib - NetLib - -[Guids] - gEfiEndOfDxeEventGroupGuid - gEfiFileSystemInfoGuid - gFdtVariableGuid - -[Protocols] - gEfiBdsArchProtocolGuid - gEfiBlockIoProtocolGuid - gEfiSimpleTextInProtocolGuid - gEfiPxeBaseCodeProtocolGuid - gEfiSimpleNetworkProtocolGuid - gEfiDevicePathToTextProtocolGuid - gEfiFirmwareVolumeBlockProtocolGuid - gEfiFirmwareVolumeBlock2ProtocolGuid - gEfiDhcp4ServiceBindingProtocolGuid - gEfiMtftp4ServiceBindingProtocolGuid - -[FeaturePcd] - gArmPlatformTokenSpaceGuid.PcdBdsLinuxSupport - -[Pcd] - gArmPlatformTokenSpaceGuid.PcdFirmwareVendor - gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription - gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath - gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument - gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut - gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths - gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths - - gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile - -[Depex] - TRUE diff --git a/ArmPlatformPkg/Bds/BdsHelper.c b/ArmPlatformPkg/Bds/BdsHelper.c deleted file mode 100644 index 732292cdb94a..000000000000 --- a/ArmPlatformPkg/Bds/BdsHelper.c +++ /dev/null @@ -1,465 +0,0 @@ -/** @file -* -* Copyright (c) 2011 - 2014, 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 -#include "BdsInternal.h" - -EFI_STATUS -EditHIInputStr ( - IN OUT CHAR16 *CmdLine, - IN UINTN MaxCmdLine - ) -{ - UINTN CmdLineIndex; - UINTN WaitIndex; - CHAR8 Char; - EFI_INPUT_KEY Key; - EFI_STATUS Status; - - // The command line must be at least one character long - ASSERT (MaxCmdLine > 0); - - // Ensure the last character of the buffer is the NULL character - CmdLine[MaxCmdLine - 1] = '\0'; - - Print (CmdLine); - - // To prevent a buffer overflow, we only allow to enter (MaxCmdLine-1) characters - for (CmdLineIndex = StrLen (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'; - Print (L"\r\n"); - - return EFI_SUCCESS; - } else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){ - if (CmdLineIndex != 0) { - CmdLineIndex--; - Print (L"\b \b"); - } - } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) { - return EFI_INVALID_PARAMETER; - } else if (CmdLineIndex < (MaxCmdLine-1)) { - CmdLine[CmdLineIndex++] = Key.UnicodeChar; - Print (L"%c", Key.UnicodeChar); - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -GetHIInputStr ( - IN OUT CHAR16 *CmdLine, - IN UINTN MaxCmdLine - ) -{ - EFI_STATUS Status; - - // For a new input just passed an empty string - CmdLine[0] = L'\0'; - - Status = EditHIInputStr (CmdLine, MaxCmdLine); - - return Status; -} - -EFI_STATUS -EditHIInputAscii ( - IN OUT CHAR8 *CmdLine, - IN UINTN MaxCmdLine - ) -{ - CHAR16* Str; - EFI_STATUS Status; - - Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16)); - AsciiStrToUnicodeStr (CmdLine, Str); - - Status = EditHIInputStr (Str, MaxCmdLine); - if (!EFI_ERROR(Status)) { - UnicodeStrToAsciiStr (Str, CmdLine); - } - FreePool (Str); - - return Status; -} - -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 - ) -{ - CHAR16 CmdLine[255]; - EFI_STATUS Status; - - CmdLine[0] = '\0'; - Status = EditHIInputStr (CmdLine, 255); - if (!EFI_ERROR(Status)) { - *Integer = StrDecimalToUintn (CmdLine); - } - - return Status; -} - -/** - Get an IPv4 address - - The function asks the user for an IPv4 address. If the input - string defines a valid IPv4 address, the four bytes of the - corresponding IPv4 address are extracted from the string and returned by - the function. As long as the user does not define a valid IP - address, he is asked for one. He can always escape by - pressing ESC. - - @param[out] EFI_IP_ADDRESS OutIpAddr Returned IPv4 address. Valid if - and only if the returned value - is equal to EFI_SUCCESS - - @retval EFI_SUCCESS Input completed - @retval EFI_ABORTED Editing aborted by the user - @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to - lack of resource -**/ -EFI_STATUS -GetHIInputIP ( - OUT EFI_IP_ADDRESS *OutIpAddr - ) -{ - EFI_STATUS Status; - CHAR16 CmdLine[48]; - - while (TRUE) { - CmdLine[0] = '\0'; - Status = EditHIInputStr (CmdLine, 48); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - - Status = NetLibStrToIp4 (CmdLine, &OutIpAddr->v4); - if (Status == EFI_INVALID_PARAMETER) { - Print (L"Invalid address\n"); - } else { - return Status; - } - } -} - -/** - Edit an IPv4 address - - The function displays as a string following the "%d.%d.%d.%d" format the - IPv4 address that is passed in and asks the user to modify it. If the - resulting string defines a valid IPv4 address, the four bytes of the - corresponding IPv4 address are extracted from the string and returned by - the function. As long as the user does not define a valid IP - address, he is asked for one. He can always escape by - pressing ESC. - - @param[in ] EFI_IP_ADDRESS InIpAddr Input IPv4 address - @param[out] EFI_IP_ADDRESS OutIpAddr Returned IPv4 address. Valid if - and only if the returned value - is equal to EFI_SUCCESS - - @retval EFI_SUCCESS Update completed - @retval EFI_ABORTED Editing aborted by the user - @retval EFI_INVALID_PARAMETER The string returned by the user is - mal-formated - @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to - lack of resource -**/ -EFI_STATUS -EditHIInputIP ( - IN EFI_IP_ADDRESS *InIpAddr, - OUT EFI_IP_ADDRESS *OutIpAddr - ) -{ - EFI_STATUS Status; - CHAR16 CmdLine[48]; - - while (TRUE) { - UnicodeSPrint ( - CmdLine, 48, L"%d.%d.%d.%d", - InIpAddr->v4.Addr[0], InIpAddr->v4.Addr[1], - InIpAddr->v4.Addr[2], InIpAddr->v4.Addr[3] - ); - - Status = EditHIInputStr (CmdLine, 48); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - Status = NetLibStrToIp4 (CmdLine, &OutIpAddr->v4); - if (Status == EFI_INVALID_PARAMETER) { - Print (L"Invalid address\n"); - } else { - return Status; - } - } -} - -EFI_STATUS -GetHIInputBoolean ( - OUT BOOLEAN *Value - ) -{ - CHAR16 CmdBoolean[2]; - EFI_STATUS Status; - - while(1) { - Print (L"[y/n] "); - Status = GetHIInputStr (CmdBoolean, 2); - if (EFI_ERROR(Status)) { - return Status; - } else if ((CmdBoolean[0] == L'y') || (CmdBoolean[0] == L'Y')) { - if (Value) *Value = TRUE; - return EFI_SUCCESS; - } else if ((CmdBoolean[0] == L'n') || (CmdBoolean[0] == L'N')) { - if (Value) *Value = FALSE; - return EFI_SUCCESS; - } - } -} - -// 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; - BDS_LOAD_OPTION *BdsLoadOption; - - Status = BootOptionFromLoadOptionVariable (BootOption, &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; -} - -UINTN -GetUnalignedDevicePathSize ( - IN EFI_DEVICE_PATH* DevicePath - ) -{ - UINTN Size; - EFI_DEVICE_PATH* AlignedDevicePath; - - if ((UINTN)DevicePath & 0x1) { - AlignedDevicePath = DuplicateDevicePath (DevicePath); - Size = GetDevicePathSize (AlignedDevicePath); - FreePool (AlignedDevicePath); - } else { - Size = GetDevicePathSize (DevicePath); - } - return Size; -} - -EFI_DEVICE_PATH* -GetAlignedDevicePath ( - IN EFI_DEVICE_PATH* DevicePath - ) -{ - if ((UINTN)DevicePath & 0x1) { - return DuplicateDevicePath (DevicePath); - } else { - return DevicePath; - } -} - -BOOLEAN -IsUnicodeString ( - IN VOID* String - ) -{ - // We do not support NULL pointer - ASSERT (String != NULL); - - if (*(CHAR16*)String < 0x100) { - //Note: We could get issue if the string is an empty Ascii string... - return TRUE; - } else { - return FALSE; - } -} - -/* - * Try to detect if the given string is an ASCII or Unicode string - * - * There are actually few limitation to this function but it is mainly to give - * a user friendly output. - * - * Some limitations: - * - it only supports unicode string that use ASCII character (< 0x100) - * - single character ASCII strings are interpreted as Unicode string - * - string cannot be longer than BOOT_DEVICE_OPTION_MAX characters and - * thus (BOOT_DEVICE_OPTION_MAX*2) bytes for an Unicode string and - * BOOT_DEVICE_OPTION_MAX bytes for an ASCII string. - * - * @param String Buffer that might contain a Unicode or Ascii string - * @param IsUnicode If not NULL this boolean value returns if the string is an - * ASCII or Unicode string. - */ -BOOLEAN -IsPrintableString ( - IN VOID* String, - OUT BOOLEAN *IsUnicode - ) -{ - BOOLEAN UnicodeDetected; - BOOLEAN IsPrintable; - UINTN Index; - CHAR16 Character; - - // We do not support NULL pointer - ASSERT (String != NULL); - - // Test empty string - if (*(CHAR16*)String == L'\0') { - if (IsUnicode) { - *IsUnicode = TRUE; - } - return TRUE; - } else if (*(CHAR16*)String == '\0') { - if (IsUnicode) { - *IsUnicode = FALSE; - } - return TRUE; - } - - // Limitation: if the string is an ASCII single character string. This comparison - // will assume it is a Unicode string. - if (*(CHAR16*)String < 0x100) { - UnicodeDetected = TRUE; - } else { - UnicodeDetected = FALSE; - } - - IsPrintable = FALSE; - for (Index = 0; Index < BOOT_DEVICE_OPTION_MAX; Index++) { - if (UnicodeDetected) { - Character = ((CHAR16*)String)[Index]; - } else { - Character = ((CHAR8*)String)[Index]; - } - - if (Character == '\0') { - // End of the string - IsPrintable = TRUE; - break; - } else if ((Character < 0x20) || (Character > 0x7f)) { - // We only support the range of printable ASCII character - IsPrintable = FALSE; - break; - } - } - - if (IsPrintable && IsUnicode) { - *IsUnicode = UnicodeDetected; - } - - return IsPrintable; -} diff --git a/ArmPlatformPkg/Bds/BdsInternal.h b/ArmPlatformPkg/Bds/BdsInternal.h deleted file mode 100644 index ddf5308e8b23..000000000000 --- a/ArmPlatformPkg/Bds/BdsInternal.h +++ /dev/null @@ -1,277 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2015, 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. -* -**/ - -#ifndef _BDSINTERNAL_H_ -#define _BDSINTERNAL_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define BOOT_DEVICE_DESCRIPTION_MAX 100 -#define BOOT_DEVICE_FILEPATH_MAX 100 -#define BOOT_DEVICE_OPTION_MAX 300 -#define BOOT_DEVICE_ADDRESS_MAX (sizeof(L"0x0000000000000000")) - -#define UPDATE_BOOT_ENTRY L"Update entry: " -#define DELETE_BOOT_ENTRY L"Delete entry: " -#define MOVE_BOOT_ENTRY L"Move entry: " - -typedef struct { - LIST_ENTRY Link; - BDS_LOAD_OPTION* BdsLoadOption; -} BDS_LOAD_OPTION_ENTRY; - -typedef enum { - BDS_DEVICE_FILESYSTEM = 0, - BDS_DEVICE_MEMMAP, - BDS_DEVICE_PXE, - BDS_DEVICE_TFTP, - BDS_DEVICE_MAX -} BDS_SUPPORTED_DEVICE_TYPE; - -typedef struct { - LIST_ENTRY Link; - CHAR16 Description[BOOT_DEVICE_DESCRIPTION_MAX]; - EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; - struct _BDS_LOAD_OPTION_SUPPORT* Support; -} BDS_SUPPORTED_DEVICE; - -#define SUPPORTED_BOOT_DEVICE_FROM_LINK(a) BASE_CR(a, BDS_SUPPORTED_DEVICE, Link) - -typedef struct _BDS_LOAD_OPTION_SUPPORT { - BDS_SUPPORTED_DEVICE_TYPE Type; - EFI_STATUS (*ListDevices)(IN OUT LIST_ENTRY* BdsLoadOptionList); - BOOLEAN (*IsSupported)(IN EFI_DEVICE_PATH *DevicePath); - EFI_STATUS (*CreateDevicePathNode)(IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes); - EFI_STATUS (*UpdateDevicePathNode)(IN EFI_DEVICE_PATH *OldDevicePath, IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath); - - /// Define if the boot menu should request if the file is a EFI binary or a Linux kernel - /// Example: PXE boot always deliver a UEFI application. - BOOLEAN RequestBootType; -} BDS_LOAD_OPTION_SUPPORT; - -#define LOAD_OPTION_ENTRY_FROM_LINK(a) BASE_CR(a, BDS_LOAD_OPTION_ENTRY, Link) -#define LOAD_OPTION_FROM_LINK(a) ((BDS_LOAD_OPTION_ENTRY*)BASE_CR(a, BDS_LOAD_OPTION_ENTRY, Link))->BdsLoadOption - -// GUID of the EFI Linux Loader -extern CONST EFI_GUID mLinuxLoaderAppGuid; - -// Device path of the EFI Linux Loader in the Firmware Volume -extern EFI_DEVICE_PATH* mLinuxLoaderDevicePath; - -EFI_STATUS -BootDeviceListSupportedInit ( - IN OUT LIST_ENTRY *SupportedDeviceList - ); - -EFI_STATUS -BootDeviceListSupportedFree ( - IN LIST_ENTRY *SupportedDeviceList, - IN BDS_SUPPORTED_DEVICE *Except - ); - -EFI_STATUS -BootDeviceGetDeviceSupport ( - IN EFI_DEVICE_PATH *DevicePath, - OUT BDS_LOAD_OPTION_SUPPORT **DeviceSupport - ); - -EFI_STATUS -GetHIInputStr ( - IN OUT CHAR16 *CmdLine, - IN UINTN MaxCmdLine - ); - -EFI_STATUS -EditHIInputStr ( - IN OUT CHAR16 *CmdLine, - IN UINTN MaxCmdLine - ); - -EFI_STATUS -GetHIInputAscii ( - IN OUT CHAR8 *CmdLine, - IN UINTN MaxCmdLine - ); - -EFI_STATUS -EditHIInputAscii ( - IN OUT CHAR8 *CmdLine, - IN UINTN MaxCmdLine - ); - -EFI_STATUS -GetHIInputInteger ( - IN OUT UINTN *Integer - ); - -EFI_STATUS -GetHIInputIP ( - OUT EFI_IP_ADDRESS *Ip - ); - -EFI_STATUS -EditHIInputIP ( - IN EFI_IP_ADDRESS *InIpAddr, - OUT EFI_IP_ADDRESS *OutIpAddr - ); - -EFI_STATUS -GetHIInputBoolean ( - OUT BOOLEAN *Value - ); - -EFI_DEVICE_PATH* -GetLastDevicePathNode ( - IN EFI_DEVICE_PATH* DevicePath - ); - -EFI_STATUS -BdsStartBootOption ( - IN CHAR16* BootOption - ); - -UINTN -GetUnalignedDevicePathSize ( - IN EFI_DEVICE_PATH* DevicePath - ); - -EFI_DEVICE_PATH* -GetAlignedDevicePath ( - IN EFI_DEVICE_PATH* DevicePath - ); - -EFI_STATUS -GenerateDeviceDescriptionName ( - IN EFI_HANDLE Handle, - IN OUT CHAR16* Description - ); - -EFI_STATUS -BootOptionList ( - IN OUT LIST_ENTRY *BootOptionList - ); - -EFI_STATUS -BootOptionParseLoadOption ( - IN EFI_LOAD_OPTION EfiLoadOption, - IN UINTN EfiLoadOptionSize, - OUT BDS_LOAD_OPTION **BdsLoadOption - ); - -EFI_STATUS -BootOptionStart ( - IN BDS_LOAD_OPTION *BootOption - ); - -EFI_STATUS -BootOptionCreate ( - IN UINT32 Attributes, - IN CHAR16* BootDescription, - IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, - IN UINT8* OptionalData, - IN UINTN OptionalDataSize, - OUT BDS_LOAD_OPTION** BdsLoadOption - ); - -EFI_STATUS -BootOptionUpdate ( - IN BDS_LOAD_OPTION* BdsLoadOption, - IN UINT32 Attributes, - IN CHAR16* BootDescription, - IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, - IN UINT8* OptionalData, - IN UINTN OptionalDataSize - ); - -EFI_STATUS -BootOptionDelete ( - IN BDS_LOAD_OPTION *BootOption - ); - -EFI_STATUS -BootMenuMain ( - VOID - ); - -BOOLEAN -IsUnicodeString ( - IN VOID* String - ); - -/* - * Try to detect if the given string is an ASCII or Unicode string - * - * There are actually few limitation to this function but it is mainly to give - * a user friendly output. - * - * Some limitations: - * - it only supports unicode string that use ASCII character (< 0x100) - * - single character ASCII strings are interpreted as Unicode string - * - string cannot be longer than 2 x BOOT_DEVICE_OPTION_MAX (600 bytes) - * - * @param String Buffer that might contain a Unicode or Ascii string - * @param IsUnicode If not NULL this boolean value returns if the string is an - * ASCII or Unicode string. - */ -BOOLEAN -IsPrintableString ( - IN VOID* String, - OUT BOOLEAN *IsUnicode - ); - -/** - An empty function to pass error checking of CreateEventEx (). - - @param Event Event whose notification function is being invoked. - @param Context Pointer to the notification function's context, - which is implementation-dependent. - -**/ -VOID -EFIAPI -EmptyCallbackFunction ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - * This function check if the DevicePath defines an EFI binary - * - * This function is used when the BDS support Linux loader to - * detect if the binary is an EFI application or potentially a - * Linux kernel. - */ -EFI_STATUS -IsEfiBinary ( - IN EFI_DEVICE_PATH* DevicePath, - OUT BOOLEAN *EfiBinary - ); - -#endif /* _BDSINTERNAL_H_ */ diff --git a/ArmPlatformPkg/Bds/BootLinux.c b/ArmPlatformPkg/Bds/BootLinux.c deleted file mode 100644 index 0445e894e153..000000000000 --- a/ArmPlatformPkg/Bds/BootLinux.c +++ /dev/null @@ -1,124 +0,0 @@ -/** @file -* -* Copyright (c) 2011 - 2015, 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" - -// This GUID is defined in the INGF file of ArmPkg/Application/LinuxLoader -CONST EFI_GUID mLinuxLoaderAppGuid = { 0x701f54f2, 0x0d70, 0x4b89, { 0xbc, 0x0a, 0xd9, 0xca, 0x25, 0x37, 0x90, 0x59 }}; - -// Device path of the EFI Linux Loader in the Firmware Volume -EFI_DEVICE_PATH* mLinuxLoaderDevicePath = NULL; - -STATIC -BOOLEAN -HasFilePathEfiExtension ( - IN CHAR16* FilePath - ) -{ - return (StrCmp (FilePath + (StrSize (FilePath) / sizeof (CHAR16)) - 5, L".EFI") == 0) || - (StrCmp (FilePath + (StrSize (FilePath) / sizeof (CHAR16)) - 5, L".efi") == 0); -} - -/** - * This function check if the DevicePath defines an EFI binary - * - * This function is used when the BDS support Linux loader to - * detect if the binary is an EFI application or potentially a - * Linux kernel. - */ -EFI_STATUS -IsEfiBinary ( - IN EFI_DEVICE_PATH* DevicePath, - OUT BOOLEAN *EfiBinary - ) -{ - EFI_STATUS Status; - CHAR16* FileName; - EFI_DEVICE_PATH* PrevDevicePathNode; - EFI_DEVICE_PATH* DevicePathNode; - EFI_PHYSICAL_ADDRESS Image; - UINTN FileSize; - EFI_IMAGE_DOS_HEADER* DosHeader; - UINTN PeCoffHeaderOffset; - EFI_IMAGE_NT_HEADERS32* NtHeader; - - ASSERT (EfiBinary != NULL); - - // - // Check if the last node of the device path is a FilePath node - // - PrevDevicePathNode = NULL; - DevicePathNode = DevicePath; - while ((DevicePathNode != NULL) && !IsDevicePathEnd (DevicePathNode)) { - PrevDevicePathNode = DevicePathNode; - DevicePathNode = NextDevicePathNode (DevicePathNode); - } - - if ((PrevDevicePathNode != NULL) && - (PrevDevicePathNode->Type == MEDIA_DEVICE_PATH) && - (PrevDevicePathNode->SubType == MEDIA_FILEPATH_DP)) - { - FileName = ((FILEPATH_DEVICE_PATH*)PrevDevicePathNode)->PathName; - } else { - FileName = NULL; - } - - if (FileName == NULL) { - Print (L"Is an EFI Application? "); - Status = GetHIInputBoolean (EfiBinary); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - } else if (HasFilePathEfiExtension (FileName)) { - *EfiBinary = TRUE; - } else { - // Check if the file exist - Status = BdsLoadImage (DevicePath, AllocateAnyPages, &Image, &FileSize); - if (!EFI_ERROR (Status)) { - - DosHeader = (EFI_IMAGE_DOS_HEADER *)(UINTN) Image; - if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, - // so read the PE header after the DOS image header. - // - PeCoffHeaderOffset = DosHeader->e_lfanew; - } else { - PeCoffHeaderOffset = 0; - } - - // - // Check PE/COFF image. - // - NtHeader = (EFI_IMAGE_NT_HEADERS32 *)(UINTN) (Image + PeCoffHeaderOffset); - if (NtHeader->Signature != EFI_IMAGE_NT_SIGNATURE) { - *EfiBinary = FALSE; - } else { - *EfiBinary = TRUE; - } - - // Free memory - gBS->FreePages (Image, EFI_SIZE_TO_PAGES (FileSize)); - } else { - // If we did not manage to open it then ask for the type - Print (L"Is an EFI Application? "); - Status = GetHIInputBoolean (EfiBinary); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - } - } - - return EFI_SUCCESS; -} diff --git a/ArmPlatformPkg/Bds/BootMenu.c b/ArmPlatformPkg/Bds/BootMenu.c deleted file mode 100644 index 5cbac1d2dc1a..000000000000 --- a/ArmPlatformPkg/Bds/BootMenu.c +++ /dev/null @@ -1,1101 +0,0 @@ -/** @file -* -* Copyright (c) 2011 - 2015, 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" - -#include - -/** - Worker function that displays the list of boot options that is passed in. - - The function loops over the entries of the list of boot options that is passed - in. For each entry, the boot option description is displayed on a single line - along with the position of the option in the list. In debug mode, the UEFI - device path and the arguments of the boot option are displayed as well in - subsequent lines. - - @param[in] BootOptionsList List of the boot options - -**/ -STATIC -VOID -DisplayBootOptions ( - IN LIST_ENTRY* BootOptionsList - ) -{ - EFI_STATUS Status; - UINTN BootOptionCount; - LIST_ENTRY *Entry; - BDS_LOAD_OPTION *BdsLoadOption; - BOOLEAN IsUnicode; - - BootOptionCount = 0 ; - for (Entry = GetFirstNode (BootOptionsList); - !IsNull (BootOptionsList, Entry); - Entry = GetNextNode (BootOptionsList, Entry) - ) { - - BdsLoadOption = LOAD_OPTION_FROM_LINK (Entry); - Print (L"[%d] %s\n", ++BootOptionCount, BdsLoadOption->Description); - - DEBUG_CODE_BEGIN (); - CHAR16* DevicePathTxt; - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; - - Status = gBS->LocateProtocol ( - &gEfiDevicePathToTextProtocolGuid, - NULL, - (VOID **)&DevicePathToTextProtocol - ); - ASSERT_EFI_ERROR (Status); - DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText ( - BdsLoadOption->FilePathList, - TRUE, - TRUE - ); - Print (L"\t- %s\n", DevicePathTxt); - - if (IsPrintableString (BdsLoadOption->OptionalData, &IsUnicode)) { - if (IsUnicode) { - Print (L"\t- Arguments: %s\n", BdsLoadOption->OptionalData); - } else { - AsciiPrint ("\t- Arguments: %a\n", BdsLoadOption->OptionalData); - } - } - - FreePool (DevicePathTxt); - DEBUG_CODE_END (); - } -} - -/** - Worker function that asks for a boot option to be selected and returns a - pointer to the structure describing the selected boot option. - - @param[in] BootOptionsList List of the boot options - - @retval EFI_SUCCESS Selection succeeded - @retval !EFI_SUCCESS Input error or input cancelled - -**/ -STATIC -EFI_STATUS -SelectBootOption ( - IN LIST_ENTRY* BootOptionsList, - IN CONST CHAR16* InputStatement, - OUT BDS_LOAD_OPTION_ENTRY** BdsLoadOptionEntry - ) -{ - EFI_STATUS Status; - UINTN BootOptionCount; - UINT16 *BootOrder; - LIST_ENTRY* Entry; - UINTN BootOptionSelected; - UINTN Index; - - // Get the number of boot options - Status = GetGlobalEnvironmentVariable ( - L"BootOrder", NULL, &BootOptionCount, (VOID**)&BootOrder - ); - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - FreePool (BootOrder); - BootOptionCount /= sizeof (UINT16); - - // Check if a valid boot option(s) is found - if (BootOptionCount == 0) { - if (StrCmp (InputStatement, DELETE_BOOT_ENTRY) == 0) { - Print (L"Nothing to remove!\n"); - } else if (StrCmp (InputStatement, UPDATE_BOOT_ENTRY) == 0) { - Print (L"Nothing to update!\n"); - } else if (StrCmp (InputStatement, MOVE_BOOT_ENTRY) == 0) { - Print (L"Nothing to move!\n"); - } else { - Print (L"No supported Boot Entry.\n"); - } - return EFI_NOT_FOUND; - } - - // Get the index of the boot device to delete - BootOptionSelected = 0; - while (BootOptionSelected == 0) { - Print (InputStatement); - Status = GetHIInputInteger (&BootOptionSelected); - if (EFI_ERROR (Status)) { - Print (L"\n"); - goto ErrorExit; - } else if ((BootOptionSelected == 0) || (BootOptionSelected > BootOptionCount)) { - Print (L"Invalid input (max %d)\n", BootOptionCount); - BootOptionSelected = 0; - } - } - - // Get the structure of the Boot device to delete - Index = 1; - for (Entry = GetFirstNode (BootOptionsList); - !IsNull (BootOptionsList, Entry); - Entry = GetNextNode (BootOptionsList,Entry) - ) - { - if (Index == BootOptionSelected) { - *BdsLoadOptionEntry = LOAD_OPTION_ENTRY_FROM_LINK (Entry); - break; - } - Index++; - } - -ErrorExit: - return Status; -} - -STATIC -EFI_STATUS -SelectBootDevice ( - OUT BDS_SUPPORTED_DEVICE** SupportedBootDevice - ) -{ - EFI_STATUS Status; - LIST_ENTRY SupportedDeviceList; - UINTN SupportedDeviceCount; - LIST_ENTRY* Entry; - UINTN SupportedDeviceSelected; - UINTN Index; - - // - // List the Boot Devices supported - // - - // Start all the drivers first - BdsConnectAllDrivers (); - - // List the supported devices - Status = BootDeviceListSupportedInit (&SupportedDeviceList); - ASSERT_EFI_ERROR(Status); - - SupportedDeviceCount = 0; - for (Entry = GetFirstNode (&SupportedDeviceList); - !IsNull (&SupportedDeviceList,Entry); - Entry = GetNextNode (&SupportedDeviceList,Entry) - ) - { - *SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry); - Print(L"[%d] %s\n",SupportedDeviceCount+1,(*SupportedBootDevice)->Description); - - DEBUG_CODE_BEGIN(); - CHAR16* DevicePathTxt; - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; - - Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); - ASSERT_EFI_ERROR(Status); - DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText ((*SupportedBootDevice)->DevicePathProtocol,TRUE,TRUE); - - Print(L"\t- %s\n",DevicePathTxt); - - FreePool(DevicePathTxt); - DEBUG_CODE_END(); - - SupportedDeviceCount++; - } - - if (SupportedDeviceCount == 0) { - Print(L"There is no supported device.\n"); - Status = EFI_ABORTED; - goto EXIT; - } - - // - // Select the Boot Device - // - SupportedDeviceSelected = 0; - while (SupportedDeviceSelected == 0) { - Print(L"Select the Boot Device: "); - Status = GetHIInputInteger (&SupportedDeviceSelected); - if (EFI_ERROR(Status)) { - Status = EFI_ABORTED; - goto EXIT; - } else if ((SupportedDeviceSelected == 0) || (SupportedDeviceSelected > SupportedDeviceCount)) { - Print(L"Invalid input (max %d)\n",SupportedDeviceCount); - SupportedDeviceSelected = 0; - } - } - - // - // Get the Device Path for the selected boot device - // - Index = 1; - for (Entry = GetFirstNode (&SupportedDeviceList); - !IsNull (&SupportedDeviceList,Entry); - Entry = GetNextNode (&SupportedDeviceList,Entry) - ) - { - if (Index == SupportedDeviceSelected) { - *SupportedBootDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry); - break; - } - Index++; - } - -EXIT: - BootDeviceListSupportedFree (&SupportedDeviceList, *SupportedBootDevice); - return Status; -} - -EFI_STATUS -BootMenuAddBootOption ( - IN LIST_ENTRY *BootOptionsList - ) -{ - EFI_STATUS Status; - BDS_SUPPORTED_DEVICE* SupportedBootDevice; - CHAR16 BootDescription[BOOT_DEVICE_DESCRIPTION_MAX]; - CHAR16 CmdLine[BOOT_DEVICE_OPTION_MAX]; - UINT32 Attributes; - BDS_LOAD_OPTION_ENTRY *BdsLoadOptionEntry; - EFI_DEVICE_PATH *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePathNodes; - UINT8* OptionalData; - UINTN OptionalDataSize; - BOOLEAN EfiBinary; - CHAR16 *LinuxDevicePath; - - Attributes = 0; - SupportedBootDevice = NULL; - - // List the Boot Devices supported - Status = SelectBootDevice (&SupportedBootDevice); - if (EFI_ERROR(Status)) { - Status = EFI_ABORTED; - goto EXIT; - } - - // Create the specific device path node - if (FeaturePcdGet (PcdBdsLinuxSupport) && mLinuxLoaderDevicePath) { - Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application or the kernel", &DevicePathNodes); - } else { - Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application", &DevicePathNodes); - } - if (EFI_ERROR (Status)) { - Status = EFI_ABORTED; - goto EXIT; - } - // Append the Device Path to the selected device path - DevicePath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)DevicePathNodes); - if (DevicePath == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto EXIT; - } - - // Is it an EFI application? - if (FeaturePcdGet (PcdBdsLinuxSupport) && mLinuxLoaderDevicePath) { - Status = IsEfiBinary (DevicePath, &EfiBinary); - if (EFI_ERROR (Status)) { - Status = EFI_ABORTED; - goto EXIT; - } - - if (EfiBinary == FALSE) { - Print (L"It is assumed the binary is a Linux kernel and the embedded Linux Loader is going to be used.\n"); - Print (L"Supported command line formats by the embedded Linux Loader:\n"); - Print (L"- -c \"\"\n"); - Print (L"- -c \"\" -f \n"); - Print (L"- -c \"\" -a \n"); - - // Copy the Linux path into the command line - LinuxDevicePath = ConvertDevicePathToText (DevicePath, FALSE, FALSE); - CopyMem (CmdLine, LinuxDevicePath, MAX (sizeof (CmdLine), StrSize (LinuxDevicePath))); - FreePool (LinuxDevicePath); - - // Free the generated Device Path - FreePool (DevicePath); - // and use the embedded Linux Loader as the EFI application - DevicePath = mLinuxLoaderDevicePath; - } else { - CmdLine[0] = L'\0'; - } - } else { - CmdLine[0] = L'\0'; - } - - Print (L"Arguments to pass to the EFI Application: "); - Status = EditHIInputStr (CmdLine, BOOT_DEVICE_OPTION_MAX); - if (EFI_ERROR (Status)) { - Status = EFI_ABORTED; - goto EXIT; - } - - OptionalData = (UINT8*)CmdLine; - OptionalDataSize = StrSize (CmdLine); - - Print(L"Description for this new Entry: "); - Status = GetHIInputStr (BootDescription, BOOT_DEVICE_DESCRIPTION_MAX); - if (EFI_ERROR(Status)) { - Status = EFI_ABORTED; - goto FREE_DEVICE_PATH; - } - - // Create new entry - BdsLoadOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool (sizeof(BDS_LOAD_OPTION_ENTRY)); - Status = BootOptionCreate (Attributes, BootDescription, DevicePath, OptionalData, OptionalDataSize, &BdsLoadOptionEntry->BdsLoadOption); - if (!EFI_ERROR(Status)) { - InsertTailList (BootOptionsList, &BdsLoadOptionEntry->Link); - } - -FREE_DEVICE_PATH: - FreePool (DevicePath); - -EXIT: - if (Status == EFI_ABORTED) { - Print(L"\n"); - } - FreePool(SupportedBootDevice); - return Status; -} - -EFI_STATUS -BootMenuRemoveBootOption ( - IN LIST_ENTRY *BootOptionsList - ) -{ - EFI_STATUS Status; - BDS_LOAD_OPTION_ENTRY* BootOptionEntry; - - DisplayBootOptions (BootOptionsList); - Status = SelectBootOption (BootOptionsList, DELETE_BOOT_ENTRY, &BootOptionEntry); - if (EFI_ERROR (Status)) { - return Status; - } - - // If the Boot Option was attached to a list remove it - if (!IsListEmpty (&BootOptionEntry->Link)) { - // Remove the entry from the list - RemoveEntryList (&BootOptionEntry->Link); - } - - // Delete the BDS Load option structures - BootOptionDelete (BootOptionEntry->BdsLoadOption); - - return EFI_SUCCESS; -} - -EFI_STATUS -BootMenuUpdateBootOption ( - IN LIST_ENTRY *BootOptionsList - ) -{ - EFI_STATUS Status; - BDS_LOAD_OPTION_ENTRY *BootOptionEntry; - BDS_LOAD_OPTION *BootOption; - BDS_LOAD_OPTION_SUPPORT* DeviceSupport; - CHAR16 BootDescription[BOOT_DEVICE_DESCRIPTION_MAX]; - CHAR8 CmdLine[BOOT_DEVICE_OPTION_MAX]; - CHAR16 UnicodeCmdLine[BOOT_DEVICE_OPTION_MAX]; - CHAR16 *LinuxDevicePath; - EFI_DEVICE_PATH *DevicePath; - UINT8* OptionalData; - UINTN OptionalDataSize; - BOOLEAN IsPrintable; - BOOLEAN IsUnicode; - BOOLEAN EfiBinary; - - DisplayBootOptions (BootOptionsList); - Status = SelectBootOption (BootOptionsList, UPDATE_BOOT_ENTRY, &BootOptionEntry); - if (EFI_ERROR (Status)) { - return Status; - } - BootOption = BootOptionEntry->BdsLoadOption; - - // Get the device support for this Boot Option - Status = BootDeviceGetDeviceSupport (BootOption->FilePathList, &DeviceSupport); - if (EFI_ERROR(Status)) { - Print(L"Not possible to retrieve the supported device for the update\n"); - return EFI_UNSUPPORTED; - } - - EfiBinary = TRUE; - if (FeaturePcdGet (PcdBdsLinuxSupport) && mLinuxLoaderDevicePath) { - Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application or the kernel", &DevicePath); - if (EFI_ERROR (Status)) { - Status = EFI_ABORTED; - goto EXIT; - } - - // Is it an EFI application? - Status = IsEfiBinary (DevicePath, &EfiBinary); - if (EFI_ERROR (Status)) { - Status = EFI_ABORTED; - goto EXIT; - } - - if (EfiBinary == FALSE) { - Print (L"It is assumed the binary is a Linux kernel and the embedded Linux Loader is going to be used.\n"); - Print (L"Supported command line formats by the embedded Linux Loader:\n"); - Print (L"- -c \"\"\n"); - Print (L"- -c \"\" -f \n"); - Print (L"- -c \"\" -a \n"); - - // Copy the Linux path into the command line - LinuxDevicePath = ConvertDevicePathToText (DevicePath, FALSE, FALSE); - CopyMem (UnicodeCmdLine, LinuxDevicePath, MAX (sizeof (UnicodeCmdLine), StrSize (LinuxDevicePath))); - FreePool (LinuxDevicePath); - - // Free the generated Device Path - FreePool (DevicePath); - // and use the embedded Linux Loader as the EFI application - DevicePath = mLinuxLoaderDevicePath; - - // The command line is a unicode printable string - IsPrintable = TRUE; - IsUnicode = TRUE; - } - } else { - Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application", &DevicePath); - if (EFI_ERROR (Status)) { - Status = EFI_ABORTED; - goto EXIT; - } - } - - Print (L"Arguments to pass to the EFI Application: "); - - // When the command line has not been initialized by the embedded Linux loader earlier - if (EfiBinary) { - if (BootOption->OptionalDataSize > 0) { - IsPrintable = IsPrintableString (BootOption->OptionalData, &IsUnicode); - if (IsPrintable) { - // - // The size in bytes of the string, final zero included, should - // be equal to or at least lower than "BootOption->OptionalDataSize" - // and the "IsPrintableString()" has already tested that the length - // in number of characters is smaller than BOOT_DEVICE_OPTION_MAX, - // final '\0' included. We can thus copy the string for editing - // using "CopyMem()". Furthermore, note that in the case of an Unicode - // string "StrnCpy()" and "StrCpy()" can not be used to copy the - // string because the data pointed to by "BootOption->OptionalData" - // is not necessarily 2-byte aligned. - // - if (IsUnicode) { - CopyMem ( - UnicodeCmdLine, BootOption->OptionalData, - MIN (sizeof (UnicodeCmdLine), - BootOption->OptionalDataSize) - ); - } else { - CopyMem ( - CmdLine, BootOption->OptionalData, - MIN (sizeof (CmdLine), - BootOption->OptionalDataSize) - ); - } - } - } else { - UnicodeCmdLine[0] = L'\0'; - IsPrintable = TRUE; - IsUnicode = TRUE; - } - } - - // We do not request arguments for OptionalData that cannot be printed - if (IsPrintable) { - if (IsUnicode) { - Status = EditHIInputStr (UnicodeCmdLine, BOOT_DEVICE_OPTION_MAX); - if (EFI_ERROR (Status)) { - Status = EFI_ABORTED; - goto FREE_DEVICE_PATH; - } - - OptionalData = (UINT8*)UnicodeCmdLine; - OptionalDataSize = StrSize (UnicodeCmdLine); - } else { - Status = EditHIInputAscii (CmdLine, BOOT_DEVICE_OPTION_MAX); - if (EFI_ERROR (Status)) { - Status = EFI_ABORTED; - goto FREE_DEVICE_PATH; - } - - OptionalData = (UINT8*)CmdLine; - OptionalDataSize = AsciiStrSize (CmdLine); - } - } else { - // We keep the former OptionalData - OptionalData = BootOption->OptionalData; - OptionalDataSize = BootOption->OptionalDataSize; - } - - Print(L"Description for this new Entry: "); - StrnCpy (BootDescription, BootOption->Description, BOOT_DEVICE_DESCRIPTION_MAX); - Status = EditHIInputStr (BootDescription, BOOT_DEVICE_DESCRIPTION_MAX); - if (EFI_ERROR(Status)) { - Status = EFI_ABORTED; - goto FREE_DEVICE_PATH; - } - - // Update the entry - Status = BootOptionUpdate (BootOption, BootOption->Attributes, BootDescription, DevicePath, OptionalData, OptionalDataSize); - -FREE_DEVICE_PATH: - FreePool (DevicePath); - -EXIT: - if (Status == EFI_ABORTED) { - Print(L"\n"); - } - return Status; -} - -/** - Reorder boot options - - Ask for the boot option to move and then move it when up or down arrows - are pressed. This function is called when the user selects the "Reorder Boot - Device Entries" entry in the boot manager menu. - The order of the boot options in BootOptionList and in the UEFI BootOrder - global variable are kept coherent until the user confirm his reordering (ie: - he does not exit by pressing escape). - - @param[in] BootOptionsList List of the boot devices constructed in - BootMenuMain() - - @retval EFI_SUCCESS No error encountered. - @retval !EFI_SUCCESS An error has occured either in the selection of the - boot option to move or while interacting with the user. - -**/ -STATIC -EFI_STATUS -BootMenuReorderBootOptions ( - IN LIST_ENTRY *BootOptionsList - ) -{ - EFI_STATUS Status; - BDS_LOAD_OPTION_ENTRY *BootOptionEntry; - LIST_ENTRY *SelectedEntry; - LIST_ENTRY *PrevEntry; - BOOLEAN Move; - BOOLEAN Save; - BOOLEAN Cancel; - UINTN WaitIndex; - EFI_INPUT_KEY Key; - LIST_ENTRY *SecondEntry; - UINTN BootOrderSize; - UINT16 *BootOrder; - LIST_ENTRY *Entry; - UINTN Index; - - DisplayBootOptions (BootOptionsList); - - // Ask to select the boot option to move - while (TRUE) { - Status = SelectBootOption (BootOptionsList, MOVE_BOOT_ENTRY, &BootOptionEntry); - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - - SelectedEntry = &BootOptionEntry->Link; - SecondEntry = NULL; - // Note down the previous entry in the list to be able to cancel changes - PrevEntry = GetPreviousNode (BootOptionsList, SelectedEntry); - - // Start of interaction - while (TRUE) { - Print ( - L"* Use up/down arrows to move the entry '%s'", - BootOptionEntry->BdsLoadOption->Description - ); - - // Wait for a move, save or cancel request - Move = FALSE; - Save = FALSE; - Cancel = FALSE; - do { - Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex); - if (!EFI_ERROR (Status)) { - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); - } - if (EFI_ERROR (Status)) { - Print (L"\n"); - goto ErrorExit; - } - - switch (Key.ScanCode) { - case SCAN_NULL: - Save = (Key.UnicodeChar == CHAR_LINEFEED) || - (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) || - (Key.UnicodeChar == 0x7f); - break; - - case SCAN_UP: - SecondEntry = GetPreviousNode (BootOptionsList, SelectedEntry); - Move = SecondEntry != BootOptionsList; - break; - - case SCAN_DOWN: - SecondEntry = GetNextNode (BootOptionsList, SelectedEntry); - Move = SecondEntry != BootOptionsList; - break; - - case SCAN_ESC: - Cancel = TRUE; - break; - } - } while ((!Move) && (!Save) && (!Cancel)); - - if (Move) { - if ((SelectedEntry != NULL) && (SecondEntry != NULL)) { - SwapListEntries (SelectedEntry, SecondEntry); - } - } else { - if (Save) { - Status = GetGlobalEnvironmentVariable ( - L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder - ); - BootOrderSize /= sizeof (UINT16); - - if (!EFI_ERROR (Status)) { - // The order of the boot options in the 'BootOptionsList' is the - // new order that has been just defined by the user. Save this new - // order in "BootOrder" UEFI global variable. - Entry = GetFirstNode (BootOptionsList); - for (Index = 0; Index < BootOrderSize; Index++) { - BootOrder[Index] = (LOAD_OPTION_FROM_LINK (Entry))->LoadOptionIndex; - Entry = GetNextNode (BootOptionsList, Entry); - } - Status = gRT->SetVariable ( - (CHAR16*)L"BootOrder", - &gEfiGlobalVariableGuid, - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - BootOrderSize * sizeof (UINT16), - BootOrder - ); - FreePool (BootOrder); - } - - if (EFI_ERROR (Status)) { - Print (L"\nAn error occurred, move not completed!\n"); - Cancel = TRUE; - } - } - - if (Cancel) { - // - // Restore initial position of the selected boot option - // - RemoveEntryList (SelectedEntry); - InsertHeadList (PrevEntry, SelectedEntry); - } - } - - Print (L"\n"); - DisplayBootOptions (BootOptionsList); - // Saved or cancelled, back to the choice of boot option to move - if (!Move) { - break; - } - } - } - -ErrorExit: - return Status ; -} - -EFI_STATUS -UpdateFdtPath ( - IN LIST_ENTRY *BootOptionsList - ) -{ - EFI_STATUS Status; - BDS_SUPPORTED_DEVICE *SupportedBootDevice; - EFI_DEVICE_PATH_PROTOCOL *FdtDevicePathNodes; - EFI_DEVICE_PATH_PROTOCOL *FdtDevicePath; - CHAR16 *FdtTextDevicePath; - EFI_PHYSICAL_ADDRESS FdtBlobBase; - UINTN FdtBlobSize; - UINTN NumPages; - EFI_PHYSICAL_ADDRESS FdtConfigurationTableBase; - - SupportedBootDevice = NULL; - - Status = SelectBootDevice (&SupportedBootDevice); - if (EFI_ERROR (Status)) { - Status = EFI_ABORTED; - goto EXIT; - } - - // Create the specific device path node - Status = SupportedBootDevice->Support->CreateDevicePathNode (L"FDT blob", &FdtDevicePathNodes); - if (EFI_ERROR (Status)) { - Status = EFI_ABORTED; - goto EXIT; - } - - if (FdtDevicePathNodes != NULL) { - Status = EFI_OUT_OF_RESOURCES; - - FdtDevicePath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, FdtDevicePathNodes); - FreePool (FdtDevicePathNodes); - if (FdtDevicePath == NULL) { - goto EXIT; - } - - FdtTextDevicePath = ConvertDevicePathToText (FdtDevicePath, TRUE, TRUE); - if (FdtTextDevicePath == NULL) { - goto EXIT; - } - - Status = gRT->SetVariable ( - (CHAR16*)L"Fdt", - &gFdtVariableGuid, - EFI_VARIABLE_RUNTIME_ACCESS | - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS, - StrSize (FdtTextDevicePath), - FdtTextDevicePath - ); - ASSERT_EFI_ERROR (Status); - FreePool (FdtTextDevicePath); - } else { - Status = gRT->SetVariable ( - (CHAR16*)L"Fdt", - &gFdtVariableGuid, - EFI_VARIABLE_RUNTIME_ACCESS | - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS, - 0, - NULL - ); - ASSERT_EFI_ERROR (Status); - return Status; - } - - // - // Try to load FDT from the new EFI Device Path - // - - // - // Load the FDT given its device path. - // This operation may fail if the device path is not supported. - // - FdtBlobBase = 0; - NumPages = 0; - Status = BdsLoadImage (FdtDevicePath, AllocateAnyPages, &FdtBlobBase, &FdtBlobSize); - FreePool (FdtDevicePath); - - if (EFI_ERROR (Status)) { - goto EXIT_LOAD_FDT; - } - - // Check the FDT header is valid. We only make this check in DEBUG mode in - // case the FDT header change on production device and this ASSERT() becomes - // not valid. - ASSERT (fdt_check_header ((VOID*)(UINTN)FdtBlobBase) == 0); - - // - // Ensure the Size of the Device Tree is smaller than the size of the read file - // - ASSERT ((UINTN)fdt_totalsize ((VOID*)(UINTN)FdtBlobBase) <= FdtBlobSize); - - // - // Store the FDT as Runtime Service Data to prevent the Kernel from - // overwritting its data. - // - NumPages = EFI_SIZE_TO_PAGES (FdtBlobSize); - Status = gBS->AllocatePages ( - AllocateAnyPages, EfiRuntimeServicesData, - NumPages, &FdtConfigurationTableBase - ); - if (EFI_ERROR (Status)) { - goto EXIT_LOAD_FDT; - } - gBS->CopyMem ( - (VOID*)(UINTN)FdtConfigurationTableBase, - (VOID*)(UINTN)FdtBlobBase, - FdtBlobSize - ); - - // - // Install the FDT into the Configuration Table - // - Status = gBS->InstallConfigurationTable ( - &gFdtTableGuid, - (VOID*)(UINTN)FdtConfigurationTableBase - ); - if (EFI_ERROR (Status)) { - gBS->FreePages (FdtConfigurationTableBase, NumPages); - } - -EXIT_LOAD_FDT: - if (EFI_ERROR (Status)) { - Print (L"\nWarning: Did not manage to install the new device tree. Try to restart the platform.\n"); - } - - if (FdtBlobBase != 0) { - gBS->FreePages (FdtBlobBase, NumPages); - } - -EXIT: - if (Status == EFI_ABORTED) { - Print (L"\n"); - } - - if (SupportedBootDevice != NULL) { - FreePool (SupportedBootDevice); - } - - return Status; -} - -/** - Set boot timeout - - Ask for the boot timeout in seconds and if the input succeeds assign the - input value to the UEFI global variable "Timeout". This function is called - when the user selects the "Set Boot Timeout" of the boot manager menu. - - @param[in] BootOptionsList List of the boot devices, not used here - - @retval EFI_SUCCESS Boot timeout in second retrieved from the standard - input and assigned to the UEFI "Timeout" global - variable - @retval !EFI_SUCCESS Either the input or the setting of the UEFI global - variable "Timeout" has failed. -**/ -EFI_STATUS -STATIC -BootMenuSetBootTimeout ( - IN LIST_ENTRY *BootOptionsList - ) -{ - EFI_STATUS Status; - UINTN Input; - UINT16 Timeout; - - Print (L"Timeout duration (in seconds): "); - Status = GetHIInputInteger (&Input); - if (EFI_ERROR (Status)) { - Print (L"\n"); - goto ErrorExit; - } - - Timeout = Input; - Status = gRT->SetVariable ( - (CHAR16*)L"Timeout", - &gEfiGlobalVariableGuid, - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, - sizeof (UINT16), - &Timeout - ); - ASSERT_EFI_ERROR (Status); - -ErrorExit: - return Status; -} - -struct BOOT_MANAGER_ENTRY { - CONST CHAR16* Description; - EFI_STATUS (*Callback) (IN LIST_ENTRY *BootOptionsList); -} BootManagerEntries[] = { - { L"Add Boot Device Entry", BootMenuAddBootOption }, - { L"Update Boot Device Entry", BootMenuUpdateBootOption }, - { L"Remove Boot Device Entry", BootMenuRemoveBootOption }, - { L"Reorder Boot Device Entries", BootMenuReorderBootOptions }, - { L"Update FDT path", UpdateFdtPath }, - { L"Set Boot Timeout", BootMenuSetBootTimeout }, -}; - -EFI_STATUS -BootMenuManager ( - IN LIST_ENTRY *BootOptionsList - ) -{ - UINTN Index; - UINTN OptionSelected; - UINTN BootManagerEntryCount; - EFI_STATUS Status; - - BootManagerEntryCount = sizeof(BootManagerEntries) / sizeof(struct BOOT_MANAGER_ENTRY); - - while (TRUE) { - // Display Boot Manager menu - for (Index = 0; Index < BootManagerEntryCount; Index++) { - Print(L"[%d] %s\n",Index+1,BootManagerEntries[Index]); - } - Print(L"[%d] Return to main menu\n",Index+1); - - // Select which entry to call - Print(L"Choice: "); - Status = GetHIInputInteger (&OptionSelected); - if (EFI_ERROR(Status) || (OptionSelected == (BootManagerEntryCount+1))) { - if (EFI_ERROR(Status)) { - Print(L"\n"); - } - return EFI_SUCCESS; - } else if ((OptionSelected > 0) && (OptionSelected <= BootManagerEntryCount)) { - BootManagerEntries[OptionSelected-1].Callback (BootOptionsList); - } - } - // Should never go here -} - -EFI_STATUS -BootShell ( - IN LIST_ENTRY *BootOptionsList - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH* EfiShellDevicePath; - - // Find the EFI Shell - Status = LocateEfiApplicationInFvByName (L"Shell", &EfiShellDevicePath); - if (Status == EFI_NOT_FOUND) { - Print (L"Error: EFI Application not found.\n"); - return Status; - } else if (EFI_ERROR (Status)) { - Print (L"Error: Status Code: 0x%X\n", (UINT32)Status); - return Status; - } else { - // Need to connect every drivers to ensure no dependencies are missing for the application - Status = BdsConnectAllDrivers (); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n")); - return Status; - } - - return BdsStartEfiApplication (gImageHandle, EfiShellDevicePath, 0, NULL); - } -} - -struct BOOT_MAIN_ENTRY { - CONST CHAR16* Description; - EFI_STATUS (*Callback) (IN LIST_ENTRY *BootOptionsList); -} BootMainEntries[] = { - { L"Shell", BootShell }, - { L"Boot Manager", BootMenuManager }, -}; - -EFI_STATUS -BootMenuMain ( - VOID - ) -{ - LIST_ENTRY BootOptionsList; - UINTN OptionCount; - UINTN BootOptionCount; - EFI_STATUS Status; - LIST_ENTRY* Entry; - BDS_LOAD_OPTION* BootOption; - UINTN BootOptionSelected; - UINTN Index; - UINTN BootMainEntryCount; - BOOLEAN IsUnicode; - - BootOption = NULL; - BootMainEntryCount = sizeof(BootMainEntries) / sizeof(struct BOOT_MAIN_ENTRY); - - if (FeaturePcdGet (PcdBdsLinuxSupport)) { - // Check Linux Loader is present - Status = LocateEfiApplicationInFvByGuid (&mLinuxLoaderAppGuid, &mLinuxLoaderDevicePath); - ASSERT_EFI_ERROR (Status); - } - - while (TRUE) { - // Get Boot#### list - BootOptionList (&BootOptionsList); - - OptionCount = 1; - - // Display the Boot options - for (Entry = GetFirstNode (&BootOptionsList); - !IsNull (&BootOptionsList,Entry); - Entry = GetNextNode (&BootOptionsList,Entry) - ) - { - BootOption = LOAD_OPTION_FROM_LINK(Entry); - - Print(L"[%d] %s\n", OptionCount, BootOption->Description); - - DEBUG_CODE_BEGIN(); - CHAR16* DevicePathTxt; - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; - - Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); - if (EFI_ERROR(Status)) { - // You must provide an implementation of DevicePathToTextProtocol in your firmware (eg: DevicePathDxe) - DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathToTextProtocol\n")); - return Status; - } - DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootOption->FilePathList, TRUE, TRUE); - - Print(L"\t- %s\n",DevicePathTxt); - - if (BootOption->OptionalData != NULL) { - if (IsPrintableString (BootOption->OptionalData, &IsUnicode)) { - if (IsUnicode) { - Print (L"\t- Arguments: %s\n", BootOption->OptionalData); - } else { - AsciiPrint ("\t- Arguments: %a\n", BootOption->OptionalData); - } - } - } - FreePool(DevicePathTxt); - DEBUG_CODE_END(); - - OptionCount++; - } - BootOptionCount = OptionCount-1; - - // Display the hardcoded Boot entries - for (Index = 0; Index < BootMainEntryCount; Index++) { - Print(L"[%d] %s\n",OptionCount,BootMainEntries[Index]); - OptionCount++; - } - - // Request the boot entry from the user - BootOptionSelected = 0; - while (BootOptionSelected == 0) { - Print(L"Start: "); - Status = GetHIInputInteger (&BootOptionSelected); - if (EFI_ERROR(Status) || (BootOptionSelected == 0) || (BootOptionSelected > OptionCount)) { - Print(L"Invalid input (max %d)\n",(OptionCount-1)); - BootOptionSelected = 0; - } - } - - // Start the selected entry - if (BootOptionSelected > BootOptionCount) { - // Start the hardcoded entry - Status = BootMainEntries[BootOptionSelected - BootOptionCount - 1].Callback (&BootOptionsList); - } else { - // Find the selected entry from the Boot#### list - Index = 1; - for (Entry = GetFirstNode (&BootOptionsList); - !IsNull (&BootOptionsList,Entry); - Entry = GetNextNode (&BootOptionsList,Entry) - ) - { - if (Index == BootOptionSelected) { - BootOption = LOAD_OPTION_FROM_LINK(Entry); - break; - } - Index++; - } - - Status = BootOptionStart (BootOption); - } - } - // Should never go here -} diff --git a/ArmPlatformPkg/Bds/BootOption.c b/ArmPlatformPkg/Bds/BootOption.c deleted file mode 100644 index 32a5679762f9..000000000000 --- a/ArmPlatformPkg/Bds/BootOption.c +++ /dev/null @@ -1,316 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2015, 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 -BootOptionStart ( - IN BDS_LOAD_OPTION *BootOption - ) -{ - EFI_STATUS Status; - UINT16 LoadOptionIndexSize; - - // Connect all the drivers if the EFI Application is not a EFI OS Loader - if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) { - BdsConnectAllDrivers (); - } - - // Set BootCurrent variable - LoadOptionIndexSize = sizeof (UINT16); - gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - LoadOptionIndexSize, &(BootOption->LoadOptionIndex)); - - Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData); - - // Clear BootCurrent variable - LoadOptionIndexSize = sizeof (UINT16); - gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - 0, NULL); - - return Status; -} - -EFI_STATUS -BootOptionList ( - IN OUT LIST_ENTRY *BootOptionList - ) -{ - EFI_STATUS Status; - UINTN Index; - UINT16* BootOrder; - UINTN BootOrderSize; - BDS_LOAD_OPTION* BdsLoadOption; - BDS_LOAD_OPTION_ENTRY* BdsLoadOptionEntry; - - InitializeListHead (BootOptionList); - - // Get the Boot Option Order from the environment variable - Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); - if (EFI_ERROR(Status)) { - return Status; - } - - for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) { - Status = BootOptionFromLoadOptionIndex (BootOrder[Index], &BdsLoadOption); - if (!EFI_ERROR(Status)) { - BdsLoadOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool(sizeof(BDS_LOAD_OPTION_ENTRY)); - BdsLoadOptionEntry->BdsLoadOption = BdsLoadOption; - InsertTailList (BootOptionList,&BdsLoadOptionEntry->Link); - } - } - - FreePool (BootOrder); - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -BootOptionSetFields ( - IN BDS_LOAD_OPTION* BootOption, - IN UINT32 Attributes, - IN CHAR16* BootDescription, - IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, - IN UINT8* OptionalData, - IN UINTN OptionalDataSize - ) -{ - EFI_LOAD_OPTION *EfiLoadOption; - UINTN EfiLoadOptionSize; - UINTN BootDescriptionSize; - UINT16 FilePathListLength; - UINT8* EfiLoadOptionPtr; - - // If we are overwriting an existent Boot Option then we have to free previously allocated memory - if (BootOption->LoadOption) { - FreePool (BootOption->LoadOption); - } - - BootDescriptionSize = StrSize (BootDescription); - - // Compute the size of the FilePath list - FilePathListLength = GetUnalignedDevicePathSize (DevicePath); - - // Allocate the memory for the EFI Load Option - EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + OptionalDataSize; - EfiLoadOption = (EFI_LOAD_OPTION *)AllocatePool(EfiLoadOptionSize); - EfiLoadOptionPtr = (UINT8 *)EfiLoadOption; - - // - // Populate the EFI Load Option and BDS Boot Option structures - // - - // Attributes fields - BootOption->Attributes = Attributes; - *(UINT32*)EfiLoadOptionPtr = Attributes; - EfiLoadOptionPtr += sizeof(UINT32); - - // FilePath List fields - BootOption->FilePathListLength = FilePathListLength; - *(UINT16*)EfiLoadOptionPtr = FilePathListLength; - EfiLoadOptionPtr += sizeof(UINT16); - - // Boot description fields - BootOption->Description = (CHAR16*)EfiLoadOptionPtr; - CopyMem (EfiLoadOptionPtr, BootDescription, BootDescriptionSize); - EfiLoadOptionPtr += BootDescriptionSize; - - // File path fields - BootOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)EfiLoadOptionPtr; - CopyMem (EfiLoadOptionPtr, DevicePath, FilePathListLength); - EfiLoadOptionPtr += FilePathListLength; - - // Optional Data fields, Do unaligned writes - BootOption->OptionalData = EfiLoadOptionPtr; - - if (OptionalData != NULL) { - CopyMem (BootOption->OptionalData, OptionalData, OptionalDataSize); - } - - BootOption->OptionalDataSize = OptionalDataSize; - - // If this function is called at the creation of the Boot Device entry (not at the update) the - // BootOption->LoadOptionSize must be zero then we get a new BootIndex for this entry - if (BootOption->LoadOptionSize == 0) { - BootOption->LoadOptionIndex = BootOptionAllocateBootIndex (); - } - - // Fill the EFI Load option fields - BootOption->LoadOption = EfiLoadOption; - BootOption->LoadOptionSize = EfiLoadOptionSize; - - return EFI_SUCCESS; -} - -EFI_STATUS -BootOptionCreate ( - IN UINT32 Attributes, - IN CHAR16* BootDescription, - IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, - IN UINT8* OptionalData, - IN UINTN OptionalDataSize, - OUT BDS_LOAD_OPTION** BdsLoadOption - ) -{ - EFI_STATUS Status; - BDS_LOAD_OPTION_ENTRY* BootOptionEntry; - BDS_LOAD_OPTION* BootOption; - CHAR16 BootVariableName[9]; - UINT16* BootOrder; - UINTN BootOrderSize; - - // - // Allocate and fill the memory for the BDS Load Option structure - // - BootOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool (sizeof (BDS_LOAD_OPTION_ENTRY)); - InitializeListHead (&BootOptionEntry->Link); - BootOptionEntry->BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION)); - - BootOption = BootOptionEntry->BdsLoadOption; - BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, OptionalData, OptionalDataSize); - - // - // Set the related environment variables - // - - // Create Boot#### environment variable - UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex); - Status = gRT->SetVariable ( - BootVariableName, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - BootOption->LoadOptionSize, - BootOption->LoadOption - ); - - // Add the new Boot Index to the list - Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); - if (!EFI_ERROR(Status)) { - BootOrder = ReallocatePool (BootOrderSize, BootOrderSize + sizeof(UINT16), BootOrder); - // Add the new index at the end - BootOrder[BootOrderSize / sizeof(UINT16)] = BootOption->LoadOptionIndex; - BootOrderSize += sizeof(UINT16); - } else { - // BootOrder does not exist. Create it - BootOrderSize = sizeof(UINT16); - BootOrder = &(BootOption->LoadOptionIndex); - } - - // Update (or Create) the BootOrder environment variable - Status = gRT->SetVariable ( - L"BootOrder", - &gEfiGlobalVariableGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - BootOrderSize, - BootOrder - ); - - // We only free it if the UEFI Variable 'BootOrder' was already existing - if (BootOrderSize > sizeof(UINT16)) { - FreePool (BootOrder); - } - - *BdsLoadOption = BootOption; - return Status; -} - -EFI_STATUS -BootOptionUpdate ( - IN BDS_LOAD_OPTION* BdsLoadOption, - IN UINT32 Attributes, - IN CHAR16* BootDescription, - IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, - IN UINT8* OptionalData, - IN UINTN OptionalDataSize - ) -{ - EFI_STATUS Status; - CHAR16 BootVariableName[9]; - - // Update the BDS Load Option structure - BootOptionSetFields (BdsLoadOption, Attributes, BootDescription, DevicePath, OptionalData, OptionalDataSize); - - // Update the related environment variables - UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BdsLoadOption->LoadOptionIndex); - - Status = gRT->SetVariable ( - BootVariableName, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - BdsLoadOption->LoadOptionSize, - BdsLoadOption->LoadOption - ); - - return Status; -} - -EFI_STATUS -BootOptionDelete ( - IN BDS_LOAD_OPTION *BootOption - ) -{ - UINTN Index; - UINTN BootOrderSize; - UINT16* BootOrder; - UINTN BootOrderCount; - CHAR16 BootVariableName[9]; - EFI_STATUS Status; - - // Remove the entry from the BootOrder environment variable - Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); - if (!EFI_ERROR(Status)) { - BootOrderCount = BootOrderSize / sizeof(UINT16); - - // Find the index of the removed entry - for (Index = 0; Index < BootOrderCount; Index++) { - if (BootOrder[Index] == BootOption->LoadOptionIndex) { - // If it the last entry we do not need to rearrange the BootOrder list - if (Index + 1 != BootOrderCount) { - CopyMem ( - &BootOrder[Index], - &BootOrder[Index + 1], - (BootOrderCount - (Index + 1)) * sizeof(UINT16) - ); - } - break; - } - } - - // Update the BootOrder environment variable - Status = gRT->SetVariable ( - L"BootOrder", - &gEfiGlobalVariableGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - BootOrderSize - sizeof(UINT16), - BootOrder - ); - } - - // Delete Boot#### environment variable - UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex); - Status = gRT->SetVariable ( - BootVariableName, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - 0, - NULL - ); - - FreePool (BootOrder); - - return Status; -} diff --git a/ArmPlatformPkg/Bds/BootOptionSupport.c b/ArmPlatformPkg/Bds/BootOptionSupport.c deleted file mode 100644 index 27faf003c69e..000000000000 --- a/ArmPlatformPkg/Bds/BootOptionSupport.c +++ /dev/null @@ -1,1195 +0,0 @@ -/** @file -* -* Copyright (c) 2011-2014, 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" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype))) - -EFI_STATUS -BdsLoadOptionFileSystemList ( - IN OUT LIST_ENTRY* BdsLoadOptionList - ); - -EFI_STATUS -BdsLoadOptionFileSystemCreateDevicePath ( - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes - ); - -EFI_STATUS -BdsLoadOptionFileSystemUpdateDevicePath ( - IN EFI_DEVICE_PATH *OldDevicePath, - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath - ); - -BOOLEAN -BdsLoadOptionFileSystemIsSupported ( - IN EFI_DEVICE_PATH *DevicePath - ); - -EFI_STATUS -BdsLoadOptionMemMapList ( - IN OUT LIST_ENTRY* BdsLoadOptionList - ); - -EFI_STATUS -BdsLoadOptionMemMapCreateDevicePath ( - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes - ); - -EFI_STATUS -BdsLoadOptionMemMapUpdateDevicePath ( - IN EFI_DEVICE_PATH *OldDevicePath, - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath - ); - -BOOLEAN -BdsLoadOptionMemMapIsSupported ( - IN EFI_DEVICE_PATH *DevicePath - ); - -EFI_STATUS -BdsLoadOptionPxeList ( - IN OUT LIST_ENTRY* BdsLoadOptionList - ); - -EFI_STATUS -BdsLoadOptionPxeCreateDevicePath ( - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes - ); - -EFI_STATUS -BdsLoadOptionPxeUpdateDevicePath ( - IN EFI_DEVICE_PATH *OldDevicePath, - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath - ); - -BOOLEAN -BdsLoadOptionPxeIsSupported ( - IN EFI_DEVICE_PATH *DevicePath - ); - -EFI_STATUS -BdsLoadOptionTftpList ( - IN OUT LIST_ENTRY* BdsLoadOptionList - ); - -EFI_STATUS -BdsLoadOptionTftpCreateDevicePath ( - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes - ); - -EFI_STATUS -BdsLoadOptionTftpUpdateDevicePath ( - IN EFI_DEVICE_PATH *OldDevicePath, - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath - ); - -BOOLEAN -BdsLoadOptionTftpIsSupported ( - IN EFI_DEVICE_PATH *DevicePath - ); - -BDS_LOAD_OPTION_SUPPORT BdsLoadOptionSupportList[] = { - { - BDS_DEVICE_FILESYSTEM, - BdsLoadOptionFileSystemList, - BdsLoadOptionFileSystemIsSupported, - BdsLoadOptionFileSystemCreateDevicePath, - BdsLoadOptionFileSystemUpdateDevicePath, - TRUE - }, - { - BDS_DEVICE_MEMMAP, - BdsLoadOptionMemMapList, - BdsLoadOptionMemMapIsSupported, - BdsLoadOptionMemMapCreateDevicePath, - BdsLoadOptionMemMapUpdateDevicePath, - TRUE - }, - { - BDS_DEVICE_PXE, - BdsLoadOptionPxeList, - BdsLoadOptionPxeIsSupported, - BdsLoadOptionPxeCreateDevicePath, - BdsLoadOptionPxeUpdateDevicePath, - FALSE - }, - { - BDS_DEVICE_TFTP, - BdsLoadOptionTftpList, - BdsLoadOptionTftpIsSupported, - BdsLoadOptionTftpCreateDevicePath, - BdsLoadOptionTftpUpdateDevicePath, - TRUE - } -}; - -EFI_STATUS -BootDeviceListSupportedInit ( - IN OUT LIST_ENTRY *SupportedDeviceList - ) -{ - UINTN Index; - - // Initialize list of supported devices - InitializeListHead (SupportedDeviceList); - - for (Index = 0; Index < BDS_DEVICE_MAX; Index++) { - BdsLoadOptionSupportList[Index].ListDevices (SupportedDeviceList); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -BootDeviceListSupportedFree ( - IN LIST_ENTRY *SupportedDeviceList, - IN BDS_SUPPORTED_DEVICE *Except - ) -{ - LIST_ENTRY *Entry; - BDS_SUPPORTED_DEVICE* SupportedDevice; - - Entry = GetFirstNode (SupportedDeviceList); - while (Entry != SupportedDeviceList) { - SupportedDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry); - Entry = RemoveEntryList (Entry); - if (SupportedDevice != Except) { - FreePool (SupportedDevice); - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -BootDeviceGetDeviceSupport ( - IN EFI_DEVICE_PATH *DevicePath, - OUT BDS_LOAD_OPTION_SUPPORT **DeviceSupport - ) -{ - UINTN Index; - - // Find which supported device is the most appropriate - for (Index = 0; Index < BDS_DEVICE_MAX; Index++) { - if (BdsLoadOptionSupportList[Index].IsSupported (DevicePath)) { - *DeviceSupport = &BdsLoadOptionSupportList[Index]; - return EFI_SUCCESS; - } - } - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -BdsLoadOptionFileSystemList ( - IN OUT LIST_ENTRY* BdsLoadOptionList - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - BDS_SUPPORTED_DEVICE *SupportedDevice; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* FileProtocol; - EFI_FILE_HANDLE Fs; - UINTN Size; - EFI_FILE_SYSTEM_INFO* FsInfo; - EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; - - // List all the Simple File System Protocols - Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &HandleBuffer); - if (EFI_ERROR (Status)) { - return Status; - } - - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); - if (!EFI_ERROR(Status)) { - // Allocate BDS Supported Device structure - SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof(BDS_SUPPORTED_DEVICE)); - - FileProtocol = NULL; - Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&FileProtocol); - ASSERT_EFI_ERROR(Status); - - FileProtocol->OpenVolume (FileProtocol, &Fs); - - // Generate a Description from the file system - Size = 0; - FsInfo = NULL; - Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo); - if (Status == EFI_BUFFER_TOO_SMALL) { - FsInfo = AllocatePool (Size); - Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo); - } - UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"%s (%d MB)",FsInfo->VolumeLabel,(UINT32)(FsInfo->VolumeSize / (1024 * 1024))); - FreePool(FsInfo); - Fs->Close (Fs); - - SupportedDevice->DevicePathProtocol = DevicePathProtocol; - SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_FILESYSTEM]; - - InsertTailList (BdsLoadOptionList,&SupportedDevice->Link); - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -BdsLoadOptionFileSystemCreateDevicePath ( - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes - ) -{ - EFI_STATUS Status; - FILEPATH_DEVICE_PATH* FilePathDevicePath; - CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; - UINTN BootFilePathSize; - - Print(L"File path of the %s: ", FileName); - Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); - if (EFI_ERROR(Status)) { - return EFI_ABORTED; - } - - BootFilePathSize = StrSize (BootFilePath); - if (BootFilePathSize == 2) { - *DevicePathNodes = NULL; - return EFI_NOT_FOUND; - } - - // Create the FilePath Device Path node - FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH); - FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH; - FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP; - SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); - CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize); - SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize)); - *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)FilePathDevicePath; - - return Status; -} - -EFI_STATUS -BdsLoadOptionFileSystemUpdateDevicePath ( - IN EFI_DEVICE_PATH *OldDevicePath, - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath - ) -{ - EFI_STATUS Status; - CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; - UINTN BootFilePathSize; - FILEPATH_DEVICE_PATH* EndingDevicePath; - FILEPATH_DEVICE_PATH* FilePathDevicePath; - EFI_DEVICE_PATH* DevicePath; - - DevicePath = DuplicateDevicePath (OldDevicePath); - - EndingDevicePath = (FILEPATH_DEVICE_PATH*)GetLastDevicePathNode (DevicePath); - - Print(L"File path of the %s: ", FileName); - StrnCpy (BootFilePath, EndingDevicePath->PathName, BOOT_DEVICE_FILEPATH_MAX); - Status = EditHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); - if (EFI_ERROR(Status)) { - return Status; - } - - BootFilePathSize = StrSize(BootFilePath); - if (BootFilePathSize == 2) { - *NewDevicePath = NULL; - return EFI_NOT_FOUND; - } - - // Create the FilePath Device Path node - FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); - FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH; - FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP; - SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); - CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize); - - // Generate the new Device Path by replacing the last node by the updated node - SetDevicePathEndNode (EndingDevicePath); - *NewDevicePath = AppendDevicePathNode (DevicePath, (CONST EFI_DEVICE_PATH_PROTOCOL *)FilePathDevicePath); - FreePool(DevicePath); - - return EFI_SUCCESS; -} - -/** - Check if a boot option path is a file system boot option path or not. - - The device specified by the beginning of the path has to support the Simple File - System protocol. Furthermore, the remaining part of the path has to be composed of - a single node of type MEDIA_DEVICE_PATH and sub-type MEDIA_FILEPATH_DP. - - @param[in] DevicePath Complete device path of a boot option. - - @retval FALSE The boot option path has not been identified as that of a - file system boot option. - @retval TRUE The boot option path is a file system boot option. -**/ -BOOLEAN -BdsLoadOptionFileSystemIsSupported ( - IN EFI_DEVICE_PATH *DevicePath - ) -{ - EFI_STATUS Status; - EFI_HANDLE Handle; - EFI_DEVICE_PATH *RemainingDevicePath; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileProtocol; - - Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath); - if (EFI_ERROR (Status)) { - return FALSE; - } - - Status = gBS->HandleProtocol ( - Handle, - &gEfiSimpleFileSystemProtocolGuid, - (VOID **)(&FileProtocol) - ); - if (EFI_ERROR (Status)) { - return FALSE; - } - - if (!IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP)) - return FALSE; - - return TRUE; -} - -STATIC -BOOLEAN -IsParentDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath - ) -{ - UINTN ParentSize; - UINTN ChildSize; - - ParentSize = GetDevicePathSize (ParentDevicePath); - ChildSize = GetDevicePathSize (ChildDevicePath); - - if (ParentSize > ChildSize) { - return FALSE; - } - - if (CompareMem (ParentDevicePath, ChildDevicePath, ParentSize - END_DEVICE_PATH_LENGTH) != 0) { - return FALSE; - } - - return TRUE; -} - -EFI_STATUS -BdsLoadOptionMemMapList ( - IN OUT LIST_ENTRY* BdsLoadOptionList - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN DevicePathHandleCount; - EFI_HANDLE *DevicePathHandleBuffer; - BOOLEAN IsParent; - UINTN Index; - UINTN Index2; - BDS_SUPPORTED_DEVICE *SupportedDevice; - EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; - EFI_DEVICE_PATH* DevicePath; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileProtocol; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol; - - // List all the BlockIo Protocols - Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &HandleBuffer); - if (EFI_ERROR (Status)) { - return Status; - } - - for (Index = 0; Index < HandleCount; Index++) { - // We only select handles WITH a Device Path AND not part of Media (to - // avoid duplication with HardDisk, CDROM, etc). Skip handles used by - // Simple Filesystem or used for Variable Storage. - - - Status = gBS->HandleProtocol (HandleBuffer[Index], - &gEfiSimpleFileSystemProtocolGuid, - (VOID *)&FileProtocol); - if (!EFI_ERROR(Status)) { - // SimpleFilesystem supported on this handle, skip - continue; - } - - Status = gBS->HandleProtocol (HandleBuffer[Index], - &gEfiFirmwareVolumeBlockProtocolGuid, - (VOID *)&FvbProtocol); - if (!EFI_ERROR(Status)) { - // Firmware Volme Block / Variable storage supported on this handle, skip - continue; - } - - Status = gBS->HandleProtocol (HandleBuffer[Index], - &gEfiFirmwareVolumeBlock2ProtocolGuid, - (VOID *)&FvbProtocol); - if (!EFI_ERROR(Status)) { - // Firmware Volme Block / Variable storage supported on this handle, skip - continue; - } - - Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); - if (!EFI_ERROR(Status)) { - // BlockIo is not part of Media Device Path - DevicePath = DevicePathProtocol; - while (!IsDevicePathEndType (DevicePath) && (DevicePathType (DevicePath) != MEDIA_DEVICE_PATH)) { - DevicePath = NextDevicePathNode (DevicePath); - } - if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) { - continue; - } - - // Open all the handle supporting the DevicePath protocol and verify this handle has not got any child - Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &DevicePathHandleCount, &DevicePathHandleBuffer); - ASSERT_EFI_ERROR (Status); - IsParent = FALSE; - for (Index2 = 0; (Index2 < DevicePathHandleCount) && !IsParent; Index2++) { - if (HandleBuffer[Index] != DevicePathHandleBuffer[Index2]) { - gBS->HandleProtocol (DevicePathHandleBuffer[Index2], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); - if (IsParentDevicePath (DevicePathProtocol, DevicePath)) { - IsParent = TRUE; - } - } - } - if (IsParent) { - continue; - } - - // Allocate BDS Supported Device structure - SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE)); - - Status = GenerateDeviceDescriptionName (HandleBuffer[Index], SupportedDevice->Description); - ASSERT_EFI_ERROR (Status); - - SupportedDevice->DevicePathProtocol = DevicePathProtocol; - SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_MEMMAP]; - - InsertTailList (BdsLoadOptionList,&SupportedDevice->Link); - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -BdsLoadOptionMemMapCreateDevicePath ( - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes - ) -{ - EFI_STATUS Status; - MEMMAP_DEVICE_PATH *MemMapDevicePath; - CHAR16 StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX]; - CHAR16 StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX]; - - Print(L"Starting Address of the %s: ", FileName); - Status = GetHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX); - if (EFI_ERROR(Status)) { - return EFI_ABORTED; - } - - Print(L"Ending Address of the %s: ", FileName); - Status = GetHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX); - if (EFI_ERROR(Status)) { - return EFI_ABORTED; - } - - // Create the MemMap Device Path Node - MemMapDevicePath = (MEMMAP_DEVICE_PATH*)AllocatePool (sizeof(MEMMAP_DEVICE_PATH) + END_DEVICE_PATH_LENGTH); - MemMapDevicePath->Header.Type = HARDWARE_DEVICE_PATH; - MemMapDevicePath->Header.SubType = HW_MEMMAP_DP; - SetDevicePathNodeLength (MemMapDevicePath, sizeof(MEMMAP_DEVICE_PATH)); - MemMapDevicePath->MemoryType = EfiBootServicesData; - MemMapDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress); - MemMapDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress); - - // Set a Device Path End Node after the Memory Map Device Path Node - SetDevicePathEndNode (MemMapDevicePath + 1); - *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)MemMapDevicePath; - - return Status; -} - -EFI_STATUS -BdsLoadOptionMemMapUpdateDevicePath ( - IN EFI_DEVICE_PATH *OldDevicePath, - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath - ) -{ - EFI_STATUS Status; - CHAR16 StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX]; - CHAR16 StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX]; - MEMMAP_DEVICE_PATH* EndingDevicePath; - EFI_DEVICE_PATH* DevicePath; - - DevicePath = DuplicateDevicePath (OldDevicePath); - EndingDevicePath = (MEMMAP_DEVICE_PATH*)GetLastDevicePathNode (DevicePath); - - Print(L"Starting Address of the %s: ", FileName); - UnicodeSPrint (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->StartingAddress); - Status = EditHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX); - if (EFI_ERROR(Status)) { - return EFI_ABORTED; - } - - Print(L"Ending Address of the %s: ", FileName); - UnicodeSPrint (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->EndingAddress); - Status = EditHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX); - if (EFI_ERROR(Status)) { - return EFI_ABORTED; - } - - EndingDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress); - EndingDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress); - - if (EFI_ERROR(Status)) { - FreePool(DevicePath); - } else { - *NewDevicePath = DevicePath; - } - - return Status; -} - -/** - Check if a boot option path is a memory map boot option path or not. - - The device specified by the beginning of the path has to support the BlockIo - protocol. Furthermore, the remaining part of the path has to be composed of - a single node of type HARDWARE_DEVICE_PATH and sub-type HW_MEMMAP_DP. - - @param[in] DevicePath Complete device path of a boot option. - - @retval FALSE The boot option path has not been identified as that of a - memory map boot option. - @retval TRUE The boot option path is a a memory map boot option. -**/ -BOOLEAN -BdsLoadOptionMemMapIsSupported ( - IN EFI_DEVICE_PATH *DevicePath - ) -{ - EFI_STATUS Status; - EFI_HANDLE Handle; - EFI_DEVICE_PATH *RemainingDevicePath; - EFI_BLOCK_IO_PROTOCOL *BlockIoProtocol; - - Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath); - if (EFI_ERROR (Status)) { - return FALSE; - } - - Status = gBS->HandleProtocol ( - Handle, - &gEfiBlockIoProtocolGuid, - (VOID **)(&BlockIoProtocol) - ); - if (EFI_ERROR (Status)) { - return FALSE; - } - - if (!IS_DEVICE_PATH_NODE (RemainingDevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP)) - return FALSE; - - return TRUE; -} - -EFI_STATUS -BdsLoadOptionPxeList ( - IN OUT LIST_ENTRY* BdsLoadOptionList - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - BDS_SUPPORTED_DEVICE *SupportedDevice; - EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; - EFI_SIMPLE_NETWORK_PROTOCOL* SimpleNet; - CHAR16 DeviceDescription[BOOT_DEVICE_DESCRIPTION_MAX]; - EFI_MAC_ADDRESS *Mac; - - // List all the PXE Protocols - Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPxeBaseCodeProtocolGuid, NULL, &HandleCount, &HandleBuffer); - if (EFI_ERROR (Status)) { - return Status; - } - - for (Index = 0; Index < HandleCount; Index++) { - // We only select the handle WITH a Device Path AND the PXE Protocol - Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); - if (!EFI_ERROR(Status)) { - // Allocate BDS Supported Device structure - SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE)); - - Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleNetworkProtocolGuid, (VOID **)&SimpleNet); - if (!EFI_ERROR(Status)) { - Mac = &SimpleNet->Mode->CurrentAddress; - UnicodeSPrint (DeviceDescription,BOOT_DEVICE_DESCRIPTION_MAX,L"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac->Addr[0], Mac->Addr[1], Mac->Addr[2], Mac->Addr[3], Mac->Addr[4], Mac->Addr[5]); - } else { - Status = GenerateDeviceDescriptionName (HandleBuffer[Index], DeviceDescription); - ASSERT_EFI_ERROR (Status); - } - UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"PXE on %s",DeviceDescription); - - SupportedDevice->DevicePathProtocol = DevicePathProtocol; - SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_PXE]; - - InsertTailList (BdsLoadOptionList,&SupportedDevice->Link); - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -BdsLoadOptionPxeCreateDevicePath ( - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes - ) -{ - *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH); - SetDevicePathEndNode (*DevicePathNodes); - - return EFI_SUCCESS; -} - -/** - Update the parameters of a Pxe boot option - - @param[in] OldDevicePath Current complete device path of the Pxe boot option. - This has to be a valid complete Pxe boot option path. - @param[in] FileName Description of the file the path is asked for - @param[out] NewDevicePath Pointer to the new complete device path. - - @retval EFI_SUCCESS Update completed - @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource -**/ -EFI_STATUS -BdsLoadOptionPxeUpdateDevicePath ( - IN EFI_DEVICE_PATH *OldDevicePath, - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath - ) -{ - // - // Make a copy of the complete device path that is made of : - // the device path of the device supporting the Pxe base code protocol - // followed by an end node. - // - *NewDevicePath = DuplicateDevicePath (OldDevicePath); - if (*NewDevicePath == NULL) { - return EFI_OUT_OF_RESOURCES; - } else { - return EFI_SUCCESS; - } -} - -BOOLEAN -BdsLoadOptionPxeIsSupported ( - IN EFI_DEVICE_PATH *DevicePath - ) -{ - EFI_STATUS Status; - EFI_HANDLE Handle; - EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; - EFI_PXE_BASE_CODE_PROTOCOL *PxeBcProtocol; - - Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath); - if (EFI_ERROR(Status)) { - return FALSE; - } - - if (!IsDevicePathEnd(RemainingDevicePath)) { - return FALSE; - } - - Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol); - if (EFI_ERROR (Status)) { - return FALSE; - } else { - return TRUE; - } -} - -/** - Add to the list of boot devices the devices allowing a TFTP boot - - @param[in] BdsLoadOptionList List of devices to boot from - - @retval EFI_SUCCESS Update completed - @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource -**/ -EFI_STATUS -BdsLoadOptionTftpList ( - IN OUT LIST_ENTRY* BdsLoadOptionList - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - EFI_HANDLE Handle; - UINTN Index; - EFI_DEVICE_PATH_PROTOCOL *DevicePathProtocol; - VOID *Interface; - EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetworkProtocol; - BDS_SUPPORTED_DEVICE *SupportedDevice; - EFI_MAC_ADDRESS *Mac; - - // - // List all the handles on which the Simple Network Protocol is installed. - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleNetworkProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return Status; - } - - for (Index = 0; Index < HandleCount; Index++) { - Handle = HandleBuffer[Index]; - // - // We select the handles that support : - // . the Device Path Protocol - // . the MTFTP4 Protocol - // - Status = gBS->HandleProtocol ( - Handle, - &gEfiDevicePathProtocolGuid, - (VOID **)&DevicePathProtocol - ); - if (EFI_ERROR (Status)) { - continue; - } - - Status = gBS->HandleProtocol ( - Handle, - &gEfiMtftp4ServiceBindingProtocolGuid, - &Interface - ); - if (EFI_ERROR (Status)) { - continue; - } - - Status = gBS->HandleProtocol ( - Handle, - &gEfiSimpleNetworkProtocolGuid, - (VOID **)&SimpleNetworkProtocol - ); - if (EFI_ERROR (Status)) { - continue; - } - - // Allocate BDS Supported Device structure - SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof (BDS_SUPPORTED_DEVICE)); - if (SupportedDevice == NULL) { - continue; - } - - Mac = &SimpleNetworkProtocol->Mode->CurrentAddress; - UnicodeSPrint ( - SupportedDevice->Description, - BOOT_DEVICE_DESCRIPTION_MAX, - L"TFTP on MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", - Mac->Addr[0], Mac->Addr[1], Mac->Addr[2], Mac->Addr[3], Mac->Addr[4], Mac->Addr[5] - ); - - SupportedDevice->DevicePathProtocol = DevicePathProtocol; - SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_TFTP]; - - InsertTailList (BdsLoadOptionList, &SupportedDevice->Link); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -BdsLoadOptionTftpCreateDevicePath ( - IN CHAR16* FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes - ) -{ - EFI_STATUS Status; - BOOLEAN IsDHCP; - EFI_IP_ADDRESS LocalIp; - EFI_IP_ADDRESS SubnetMask; - EFI_IP_ADDRESS GatewayIp; - EFI_IP_ADDRESS RemoteIp; - IPv4_DEVICE_PATH *IPv4DevicePathNode; - FILEPATH_DEVICE_PATH *FilePathDevicePath; - CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; - UINTN BootFilePathSize; - - Print (L"Get the IP address from DHCP: "); - Status = GetHIInputBoolean (&IsDHCP); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - - if (!IsDHCP) { - Print (L"Local static IP address: "); - Status = GetHIInputIP (&LocalIp); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - Print (L"Get the network mask: "); - Status = GetHIInputIP (&SubnetMask); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - Print (L"Get the gateway IP address: "); - Status = GetHIInputIP (&GatewayIp); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - } - - Print (L"Get the TFTP server IP address: "); - Status = GetHIInputIP (&RemoteIp); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - - Print (L"File path of the %s : ", FileName); - Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - - BootFilePathSize = StrSize(BootFilePath); - if (BootFilePathSize == 2) { - return EFI_NOT_FOUND; - } - - // Allocate the memory for the IPv4 + File Path Device Path Nodes - IPv4DevicePathNode = (IPv4_DEVICE_PATH*)AllocatePool(sizeof(IPv4_DEVICE_PATH) + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH); - - // Create the IPv4 Device Path - IPv4DevicePathNode->Header.Type = MESSAGING_DEVICE_PATH; - IPv4DevicePathNode->Header.SubType = MSG_IPv4_DP; - SetDevicePathNodeLength (&IPv4DevicePathNode->Header, sizeof(IPv4_DEVICE_PATH)); - - if (!IsDHCP) { - CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS)); - CopyMem (&IPv4DevicePathNode->SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS)); - CopyMem (&IPv4DevicePathNode->GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS)); - } - - CopyMem (&IPv4DevicePathNode->RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS)); - IPv4DevicePathNode->LocalPort = 0; - IPv4DevicePathNode->RemotePort = 0; - IPv4DevicePathNode->Protocol = EFI_IP_PROTO_TCP; - IPv4DevicePathNode->StaticIpAddress = (IsDHCP != TRUE); - - // Create the FilePath Device Path node - FilePathDevicePath = (FILEPATH_DEVICE_PATH*)(IPv4DevicePathNode + 1); - FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH; - FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP; - SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize); - CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize); - - // Set the End Device Path Node - SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize)); - *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)IPv4DevicePathNode; - - return Status; -} - -/** - Update the parameters of a TFTP boot option - - The function asks sequentially to update the IPv4 parameters as well as the boot file path, - providing the previously set value if any. - - @param[in] OldDevicePath Current complete device path of the Tftp boot option. - This has to be a valid complete Tftp boot option path. - By complete, we mean that it is not only the Tftp - specific end part built by the - "BdsLoadOptionTftpCreateDevicePath()" function. - This path is handled as read only. - @param[in] FileName Description of the file the path is asked for - @param[out] NewDevicePath Pointer to the new complete device path. - - @retval EFI_SUCCESS Update completed - @retval EFI_ABORTED Update aborted by the user - @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource -**/ -EFI_STATUS -BdsLoadOptionTftpUpdateDevicePath ( - IN EFI_DEVICE_PATH *OldDevicePath, - IN CHAR16 *FileName, - OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH *DevicePath; - EFI_DEVICE_PATH *DevicePathNode; - UINT8 *Ipv4NodePtr; - IPv4_DEVICE_PATH Ipv4Node; - BOOLEAN IsDHCP; - EFI_IP_ADDRESS OldIp; - EFI_IP_ADDRESS OldSubnetMask; - EFI_IP_ADDRESS OldGatewayIp; - EFI_IP_ADDRESS LocalIp; - EFI_IP_ADDRESS SubnetMask; - EFI_IP_ADDRESS GatewayIp; - EFI_IP_ADDRESS RemoteIp; - UINT8 *FileNodePtr; - CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX]; - UINTN PathSize; - UINTN BootFilePathSize; - FILEPATH_DEVICE_PATH *NewFilePathNode; - - Ipv4NodePtr = NULL; - - // - // Make a copy of the complete device path that is made of : - // the device path of the device that support the Simple Network protocol - // followed by an IPv4 node (type IPv4_DEVICE_PATH), - // followed by a file path node (type FILEPATH_DEVICE_PATH) and ended up - // by an end node. The IPv6 case is not handled yet. - // - - DevicePath = DuplicateDevicePath (OldDevicePath); - if (DevicePath == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } - - // - // Because of the check done by "BdsLoadOptionTftpIsSupported()" prior to the - // call to this function, we know that the device path ends with an IPv4 node - // followed by a file path node and finally an end node. To get the address of - // the last IPv4 node, we loop over the whole device path, noting down the - // address of each encountered IPv4 node. - // - - for (DevicePathNode = DevicePath; - !IsDevicePathEnd (DevicePathNode); - DevicePathNode = NextDevicePathNode (DevicePathNode)) - { - if (IS_DEVICE_PATH_NODE (DevicePathNode, MESSAGING_DEVICE_PATH, MSG_IPv4_DP)) { - Ipv4NodePtr = (UINT8*)DevicePathNode; - } - } - - // Copy for alignment of the IPv4 node data - CopyMem (&Ipv4Node, Ipv4NodePtr, sizeof (IPv4_DEVICE_PATH)); - - Print (L"Get the IP address from DHCP: "); - Status = GetHIInputBoolean (&IsDHCP); - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - - if (!IsDHCP) { - Print (L"Local static IP address: "); - if (Ipv4Node.StaticIpAddress) { - CopyMem (&OldIp.v4, &Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS)); - Status = EditHIInputIP (&OldIp, &LocalIp); - } else { - Status = GetHIInputIP (&LocalIp); - } - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - - Print (L"Get the network mask: "); - if (Ipv4Node.StaticIpAddress) { - CopyMem (&OldSubnetMask.v4, &Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS)); - Status = EditHIInputIP (&OldSubnetMask, &SubnetMask); - } else { - Status = GetHIInputIP (&SubnetMask); - } - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - - Print (L"Get the gateway IP address: "); - if (Ipv4Node.StaticIpAddress) { - CopyMem (&OldGatewayIp.v4, &Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS)); - Status = EditHIInputIP (&OldGatewayIp, &GatewayIp); - } else { - Status = GetHIInputIP (&GatewayIp); - } - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - } - - Print (L"TFTP server IP address: "); - // Copy remote IPv4 address into IPv4 or IPv6 union - CopyMem (&OldIp.v4, &Ipv4Node.RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS)); - - Status = EditHIInputIP (&OldIp, &RemoteIp); - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - - // Get the path of the boot file and its size in number of bytes - FileNodePtr = Ipv4NodePtr + sizeof (IPv4_DEVICE_PATH); - BootFilePathSize = DevicePathNodeLength (FileNodePtr) - SIZE_OF_FILEPATH_DEVICE_PATH; - - // - // Ask for update of the boot file path - // - do { - // Copy for 2-byte alignment of the Unicode string - CopyMem ( - BootFilePath, FileNodePtr + SIZE_OF_FILEPATH_DEVICE_PATH, - MIN (BootFilePathSize, BOOT_DEVICE_FILEPATH_MAX) - ); - BootFilePath[BOOT_DEVICE_FILEPATH_MAX - 1] = L'\0'; - - Print (L"File path of the %s: ", FileName); - Status = EditHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX); - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - PathSize = StrSize (BootFilePath); - if (PathSize > 2) { - break; - } - // Empty string, give the user another try - Print (L"Empty string - Invalid path\n"); - } while (PathSize <= 2) ; - - // - // Update the IPv4 node. IPv6 case not handled yet. - // - if (IsDHCP) { - Ipv4Node.StaticIpAddress = FALSE; - ZeroMem (&Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS)); - ZeroMem (&Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS)); - ZeroMem (&Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS)); - } else { - Ipv4Node.StaticIpAddress = TRUE; - CopyMem (&Ipv4Node.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS)); - CopyMem (&Ipv4Node.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS)); - CopyMem (&Ipv4Node.GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS)); - } - - CopyMem (&Ipv4Node.RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS)); - CopyMem (Ipv4NodePtr, &Ipv4Node, sizeof (IPv4_DEVICE_PATH)); - - // - // Create the new file path node - // - NewFilePathNode = (FILEPATH_DEVICE_PATH*)AllocatePool ( - SIZE_OF_FILEPATH_DEVICE_PATH + - PathSize - ); - NewFilePathNode->Header.Type = MEDIA_DEVICE_PATH; - NewFilePathNode->Header.SubType = MEDIA_FILEPATH_DP; - SetDevicePathNodeLength ( - NewFilePathNode, - SIZE_OF_FILEPATH_DEVICE_PATH + PathSize - ); - CopyMem (NewFilePathNode->PathName, BootFilePath, PathSize); - - // - // Generate the new Device Path by replacing the file path node at address - // "FileNodePtr" by the new one "NewFilePathNode" and return its address. - // - SetDevicePathEndNode (FileNodePtr); - *NewDevicePath = AppendDevicePathNode ( - DevicePath, - (CONST EFI_DEVICE_PATH_PROTOCOL*)NewFilePathNode - ); - -ErrorExit: - if (DevicePath != NULL) { - FreePool (DevicePath) ; - } - - return Status; -} - -BOOLEAN -BdsLoadOptionTftpIsSupported ( - IN EFI_DEVICE_PATH *DevicePath - ) -{ - EFI_STATUS Status; - EFI_HANDLE Handle; - EFI_DEVICE_PATH *RemainingDevicePath; - EFI_DEVICE_PATH *NextDevicePath; - EFI_PXE_BASE_CODE_PROTOCOL *PxeBcProtocol; - - Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath); - if (EFI_ERROR(Status)) { - return FALSE; - } - - // Validate the Remaining Device Path - if (IsDevicePathEnd(RemainingDevicePath)) { - return FALSE; - } - if (!IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv4_DP) && - !IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv6_DP)) { - return FALSE; - } - NextDevicePath = NextDevicePathNode (RemainingDevicePath); - if (IsDevicePathEnd(NextDevicePath)) { - return FALSE; - } - if (!IS_DEVICE_PATH_NODE(NextDevicePath,MEDIA_DEVICE_PATH,MEDIA_FILEPATH_DP)) { - return FALSE; - } - - Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol); - if (EFI_ERROR (Status)) { - return FALSE; - } else { - return TRUE; - } -}