ArmPlatformPkg: add support for FV embedded device tree blobs

This adds support to the ArmVExpressPkg platforms to load their
device tree binary from a Firmware Volume if one is found that
matches the current platform. If none is found, the existing
logic to find a FDT by name from a file system is retained as
a fallback.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17359 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Ard Biesheuvel 2015-05-07 15:39:23 +00:00 committed by oliviermartin
parent 5af5259c43
commit 35eabda773
2 changed files with 118 additions and 6 deletions

View File

@ -14,9 +14,14 @@
#include "ArmVExpressInternal.h"
#include <PiDxe.h>
#include <Library/BaseMemoryLib.h>
#include <Library/VirtioMmioDeviceLib.h>
#include <Library/ArmShellCmdLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DevicePathLib.h>
#include <Protocol/FirmwareVolume2.h>
#define ARM_FVP_BASE_VIRTIO_BLOCK_BASE 0x1c130000
@ -50,6 +55,95 @@ VIRTIO_BLK_DEVICE_PATH mVirtioBlockDevicePath =
}
};
STATIC
EFI_STATUS
InternalFindFdtByGuid (
IN OUT EFI_DEVICE_PATH **FdtDevicePath,
IN CONST EFI_GUID *FdtGuid
)
{
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileDevicePath;
EFI_HANDLE *HandleBuffer;
UINTN HandleCount;
UINTN Index;
EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
EFI_GUID NameGuid;
UINTN Size;
VOID *Key;
EFI_FV_FILETYPE FileType;
EFI_FV_FILE_ATTRIBUTES Attributes;
EFI_DEVICE_PATH *FvDevicePath;
EFI_STATUS Status;
if (FdtGuid == NULL) {
return EFI_NOT_FOUND;
}
EfiInitializeFwVolDevicepathNode (&FileDevicePath, FdtGuid);
HandleBuffer = NULL;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiFirmwareVolume2ProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return Status;
}
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiFirmwareVolume2ProtocolGuid,
(VOID **) &FvProtocol
);
if (EFI_ERROR (Status)) {
return Status;
}
// Allocate Key
Key = AllocatePool (FvProtocol->KeySize);
ASSERT (Key != NULL);
ZeroMem (Key, FvProtocol->KeySize);
do {
FileType = EFI_FV_FILETYPE_RAW;
Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);
if (Status == EFI_NOT_FOUND) {
break;
}
if (EFI_ERROR (Status)) {
return Status;
}
//
// Check whether this file is the one we are looking for. If so,
// create a device path for it and return it to the caller.
//
if (CompareGuid (&NameGuid, FdtGuid)) {
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
if (!EFI_ERROR (Status)) {
*FdtDevicePath = AppendDevicePathNode (FvDevicePath,
(EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);
}
goto Done;
}
} while (TRUE);
FreePool (Key);
}
if (Index == HandleCount) {
Status = EFI_NOT_FOUND;
}
return Status;
Done:
FreePool (Key);
return Status;
}
/**
* Generic UEFI Entrypoint for 'ArmFvpDxe' driver
* See UEFI specification for the details of the parameters
@ -66,6 +160,7 @@ ArmFvpInitialise (
CHAR16 *TextDevicePath;
UINTN TextDevicePathSize;
VOID *Buffer;
EFI_DEVICE_PATH *FdtDevicePath;
Status = gBS->InstallProtocolInterface (&ImageHandle,
&gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,
@ -76,13 +171,25 @@ ArmFvpInitialise (
Status = ArmVExpressGetPlatform (&Platform);
if (!EFI_ERROR (Status)) {
TextDevicePathSize = StrSize ((CHAR16*)PcdGetPtr (PcdFvpFdtDevicePathsBase)) - sizeof (CHAR16);
TextDevicePathSize += StrSize (Platform->FdtName);
TextDevicePath = AllocatePool (TextDevicePathSize);
FdtDevicePath = NULL;
Status = InternalFindFdtByGuid (&FdtDevicePath, Platform->FdtGuid);
if (!EFI_ERROR (Status)) {
TextDevicePath = ConvertDevicePathToText (FdtDevicePath, FALSE, FALSE);
if (TextDevicePath != NULL) {
TextDevicePathSize = StrSize (TextDevicePath);
}
FreePool (FdtDevicePath);
} else {
TextDevicePathSize = StrSize ((CHAR16*)PcdGetPtr (PcdFvpFdtDevicePathsBase)) - sizeof (CHAR16);
TextDevicePathSize += StrSize (Platform->FdtName);
TextDevicePath = AllocatePool (TextDevicePathSize);
if (TextDevicePath != NULL) {
StrCpy (TextDevicePath, ((CHAR16*)PcdGetPtr (PcdFvpFdtDevicePathsBase)));
StrCat (TextDevicePath, Platform->FdtName);
}
}
if (TextDevicePath != NULL) {
StrCpy (TextDevicePath, ((CHAR16*)PcdGetPtr (PcdFvpFdtDevicePathsBase)));
StrCat (TextDevicePath, Platform->FdtName);
Buffer = PcdSetPtr (PcdFdtDevicePaths, &TextDevicePathSize, TextDevicePath);
if (Buffer == NULL) {
DEBUG ((

View File

@ -49,10 +49,15 @@
UefiDriverEntryPoint
UefiBootServicesTableLib
VirtioMmioDeviceLib
DevicePathLib
[LibraryClasses.AARCH64]
ArmGicLib
[Protocols]
gEfiFirmwareVolume2ProtocolGuid
gEfiDevicePathProtocolGuid
[FixedPcd]
gArmVExpressTokenSpaceGuid.PcdFvpFdtDevicePathsBase