From 6bab33c7b677dea7a67df512ef1a058daeebef57 Mon Sep 17 00:00:00 2001 From: oliviermartin Date: Wed, 15 Jun 2011 19:56:50 +0000 Subject: [PATCH] ArmPlatformPkg/Bds: Fix various bugs in the new BDS The errors were: - uncaught returned error - used of uninitialized variables ArmPlatformPkg/Bds: Implement the update of MemMap Boot Device git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11830 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/Include/Library/BdsLib.h | 38 ++++++++++++++++++++++++- ArmPkg/Library/BdsLib/BdsFilePath.c | 28 +++++++++++++++++- ArmPkg/Library/BdsLib/BdsInternal.h | 1 + ArmPlatformPkg/Bds/BootOption.c | 15 ++++++---- ArmPlatformPkg/Bds/BootOptionSupport.c | 39 +++++++++++++++++++++++--- 5 files changed, 110 insertions(+), 11 deletions(-) diff --git a/ArmPkg/Include/Library/BdsLib.h b/ArmPkg/Include/Library/BdsLib.h index a6ae2f108b..75d01505fd 100644 --- a/ArmPkg/Include/Library/BdsLib.h +++ b/ArmPkg/Include/Library/BdsLib.h @@ -15,6 +15,25 @@ #ifndef __BDS_ENTRY_H__ #define __BDS_ENTRY_H__ +/** + Connect a Device Path and return the handle of the driver that support this DevicePath + + @param DevicePath Device Path of the File to connect + @param Handle Handle of the driver that support this DevicePath + @param RemainingDevicePath Remaining DevicePath nodes that do not match the driver DevicePath + + @retval EFI_SUCCESS A driver that matches the Device Path has been found + @retval EFI_NOT_FOUND No handles match the search. + @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL + +**/ +EFI_STATUS +BdsConnectDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, + OUT EFI_HANDLE *Handle, + OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath + ); + /** Connect all DXE drivers @@ -32,7 +51,7 @@ BdsConnectAllDrivers ( Start a Linux kernel from a Device Path @param LinuxKernel Device Path to the Linux Kernel - @param Parameters Linux kernel agruments + @param Parameters Linux kernel arguments @param Fdt Device Path to the Flat Device Tree @retval EFI_SUCCESS All drivers have been connected @@ -47,6 +66,23 @@ BdsBootLinux ( IN EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath ); +/** + Start an EFI Application from a Device Path + + @param ParentImageHandle Handle of the calling image + @param DevicePath Location of the EFI Application + + @retval EFI_SUCCESS All drivers have been connected + @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found + @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results. + +**/ +EFI_STATUS +BdsStartEfiApplication ( + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + /** Start an EFI Application from any Firmware Volume diff --git a/ArmPkg/Library/BdsLib/BdsFilePath.c b/ArmPkg/Library/BdsLib/BdsFilePath.c index be1a824d50..69aa25561c 100644 --- a/ArmPkg/Library/BdsLib/BdsFilePath.c +++ b/ArmPkg/Library/BdsLib/BdsFilePath.c @@ -298,6 +298,18 @@ TryRemovableDevice ( return Status; } +/** + Connect a Device Path and return the handle of the driver that support this DevicePath + + @param DevicePath Device Path of the File to connect + @param Handle Handle of the driver that support this DevicePath + @param RemainingDevicePath Remaining DevicePath nodes that do not match the driver DevicePath + + @retval EFI_SUCCESS A driver that matches the Device Path has been found + @retval EFI_NOT_FOUND No handles match the search. + @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL + +**/ EFI_STATUS BdsConnectDevicePath ( IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, @@ -335,7 +347,7 @@ BdsConnectDevicePath ( // Now, we have got the whole Device Path connected, call again ConnectController to ensure all the supported Driver // Binding Protocol are connected (such as DiskIo and SimpleFileSystem) Remaining = DevicePath; - Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid,&Remaining,Handle); + Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid,&Remaining,Handle); if (!EFI_ERROR (Status)) { Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE); if (EFI_ERROR (Status)) { @@ -420,6 +432,9 @@ BdsFileSystemLoadImage ( File = NULL; Status = Fs->Open(Fs, &File, FilePathDevicePath->PathName, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR(Status)) { + return Status; + } Size = 0; File->GetInfo(File, &gEfiFileInfoGuid, &Size, NULL); @@ -811,6 +826,17 @@ BdsLoadImage ( return EFI_UNSUPPORTED; } +/** + Start an EFI Application from a Device Path + + @param ParentImageHandle Handle of the calling image + @param DevicePath Location of the EFI Application + + @retval EFI_SUCCESS All drivers have been connected + @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found + @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results. + +**/ EFI_STATUS BdsStartEfiApplication ( IN EFI_HANDLE ParentImageHandle, diff --git a/ArmPkg/Library/BdsLib/BdsInternal.h b/ArmPkg/Library/BdsLib/BdsInternal.h index a497df03ea..dd961c816b 100644 --- a/ArmPkg/Library/BdsLib/BdsInternal.h +++ b/ArmPkg/Library/BdsLib/BdsInternal.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/ArmPlatformPkg/Bds/BootOption.c b/ArmPlatformPkg/Bds/BootOption.c index a8ba23fe73..d3c7445fae 100644 --- a/ArmPlatformPkg/Bds/BootOption.c +++ b/ArmPlatformPkg/Bds/BootOption.c @@ -258,8 +258,13 @@ BootOptionSetFields ( CopyMem (&((BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments, BootArguments, AsciiStrSize(BootArguments)); BootOption->OptionalData = (BDS_LOADER_OPTIONAL_DATA *)EfiLoadOptionPtr; + // 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->LoadOptionIndex = BootOptionAllocateBootIndex(); BootOption->LoadOption = EfiLoadOption; BootOption->LoadOptionSize = EfiLoadOptionSize; @@ -341,20 +346,20 @@ BootOptionUpdate ( ) { EFI_STATUS Status; - BDS_LOAD_OPTION *BootOption; CHAR16 BootVariableName[9]; // Update the BDS Load Option structure BootOptionSetFields (BdsLoadOption, Attributes, BootDescription, DevicePath, BootType, BootArguments); // Update the related environment variables - UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex); + 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, - BootOption->LoadOptionSize, - BootOption->LoadOption + BdsLoadOption->LoadOptionSize, + BdsLoadOption->LoadOption ); return Status; diff --git a/ArmPlatformPkg/Bds/BootOptionSupport.c b/ArmPlatformPkg/Bds/BootOptionSupport.c index 7de2df4825..a4396b5109 100644 --- a/ArmPlatformPkg/Bds/BootOptionSupport.c +++ b/ArmPlatformPkg/Bds/BootOptionSupport.c @@ -386,7 +386,7 @@ BdsLoadOptionFileSystemUpdateDevicePath ( Print(L"File path of the EFI Application or the kernel: "); UnicodeStrToAsciiStr (EndingDevicePath->PathName,AsciiBootFilePath); - Status = EditHIInputAscii(AsciiBootFilePath,BOOT_DEVICE_FILEPATH_MAX); + Status = EditHIInputAscii (AsciiBootFilePath,BOOT_DEVICE_FILEPATH_MAX); if (EFI_ERROR(Status)) { return Status; } @@ -567,9 +567,40 @@ BdsLoadOptionMemMapUpdateDevicePath ( OUT UINT32 *Attributes ) { - ASSERT(0); - //TODO: Implement me - return EFI_SUCCESS; + EFI_STATUS Status; + CHAR8 AsciiStartingAddress[BOOT_DEVICE_ADDRESS_MAX]; + CHAR8 AsciiEndingAddress[BOOT_DEVICE_ADDRESS_MAX]; + MEMMAP_DEVICE_PATH* EndingDevicePath; + EFI_DEVICE_PATH* DevicePath; + + DevicePath = DuplicateDevicePath (BootOption->FilePathList); + EndingDevicePath = (MEMMAP_DEVICE_PATH*)GetLastDevicePathNode (DevicePath); + + Print(L"Starting Address of the binary: "); + AsciiSPrint (AsciiStartingAddress,BOOT_DEVICE_ADDRESS_MAX,"0x%X",(UINTN)EndingDevicePath->StartingAddress); + Status = EditHIInputAscii (AsciiStartingAddress,BOOT_DEVICE_ADDRESS_MAX); + if (EFI_ERROR(Status)) { + return EFI_ABORTED; + } + + Print(L"Ending Address of the binary: "); + AsciiSPrint (AsciiEndingAddress,BOOT_DEVICE_ADDRESS_MAX,"0x%X",(UINTN)EndingDevicePath->EndingAddress); + Status = EditHIInputAscii (AsciiEndingAddress,BOOT_DEVICE_ADDRESS_MAX); + if (EFI_ERROR(Status)) { + return EFI_ABORTED; + } + + EndingDevicePath->StartingAddress = AsciiStrHexToUint64 (AsciiStartingAddress); + EndingDevicePath->EndingAddress = AsciiStrHexToUint64 (AsciiEndingAddress); + + Status = BootDeviceGetType (NULL, BootType, Attributes); + if (EFI_ERROR(Status)) { + FreePool(DevicePath); + } else { + *NewDevicePath = DevicePath; + } + + return Status; } BOOLEAN