summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c742
-rw-r--r--EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf55
-rw-r--r--EmbeddedPkg/Drivers/FdtPlatformDxe/README.txt50
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dec6
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dsc3
-rw-r--r--EmbeddedPkg/Include/Guid/Fdt.h11
6 files changed, 863 insertions, 4 deletions
diff --git a/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c
new file mode 100644
index 0000000000..8608fcf5ba
--- /dev/null
+++ b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c
@@ -0,0 +1,742 @@
+/** @file
+
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+ 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 <Uefi.h>
+
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Library/BdsLib.h>
+
+#include <Protocol/DevicePathFromText.h>
+#include <Protocol/DevicePath.h>
+
+#include <Guid/EventGroup.h>
+#include <Guid/Fdt.h>
+
+#include <libfdt.h>
+
+//
+// Internal types
+//
+STATIC VOID OnEndOfDxe (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+STATIC EFI_STATUS RunFdtInstallation (
+ VOID
+ );
+STATIC EFI_STATUS InstallFdt (
+ IN CONST CHAR16* TextDevicePath
+ );
+
+/**
+ Main entry point of the FDT platform driver.
+
+ @param[in] ImageHandle The firmware allocated handle for the present driver
+ UEFI image.
+ @param[in] *SystemTable A pointer to the EFI System table.
+
+ @retval EFI_SUCCESS The driver was initialized.
+ @retval EFI_OUT_OF_RESOURCES The "End of DXE" event could not be allocated.
+
+**/
+EFI_STATUS
+FdtPlatformEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT EndOfDxeEvent;
+
+ //
+ // Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group.
+ // The "OnEndOfDxe()" function is declared as the call back function.
+ // It will be called at the end of the DXE phase when an event of the
+ // same group is signalled to inform about the end of the DXE phase.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ OnEndOfDxe,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+
+ return Status;
+}
+
+/**
+ Notification function of the event defined as belonging to the
+ EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in
+ the entry point of the driver.
+
+ This function is called when an event belonging to the
+ EFI_END_OF_DXE_EVENT_GROUP_GUID event group is signalled. Such an
+ event is signalled once at the end of the dispatching of all
+ drivers (end of the so called DXE phase).
+
+ @param[in] Event Event declared in the entry point of the driver whose
+ notification function is being invoked.
+ @param[in] Context NULL
+
+**/
+STATIC
+VOID
+OnEndOfDxe (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ RunFdtInstallation ();
+ gBS->CloseEvent (Event);
+}
+
+/**
+ Run the FDT installation process.
+
+ Loop in priority order over the device paths from which the FDT has
+ been asked to be retrieved for. For each device path, try to install
+ the FDT. Stop as soon as an installation succeeds.
+
+ @retval EFI_SUCCESS The FDT was installed.
+ @retval EFI_NOT_FOUND Failed to locate a protocol or a file.
+ @retval EFI_INVALID_PARAMETER Invalid device path.
+ @retval EFI_UNSUPPORTED Device path not supported.
+ @retval EFI_OUT_OF_RESOURCES An allocation failed.
+
+**/
+STATIC
+EFI_STATUS
+RunFdtInstallation (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ VOID *Data;
+ CHAR16 *TextDevicePathStart;
+ CHAR16 *TextDevicePathSeparator;
+ UINTN TextDevicePathLen;
+ CHAR16 *TextDevicePath;
+
+ //
+ // For development purpose, if enabled through the "PcdOverridePlatformFdt"
+ // feature PCD, try first to install the FDT specified by the device path in
+ // text form stored in the "Fdt" UEFI variable.
+ //
+ if (FeaturePcdGet (PcdOverridePlatformFdt)) {
+ Data = NULL;
+ DataSize = 0;
+ Status = gRT->GetVariable (
+ L"Fdt",
+ &gFdtVariableGuid,
+ NULL,
+ &DataSize,
+ Data
+ );
+
+ //
+ // Keep going only if the "Fdt" variable is defined.
+ //
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Data = AllocatePool (DataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ Status = gRT->GetVariable (
+ L"Fdt",
+ &gFdtVariableGuid,
+ NULL,
+ &DataSize,
+ Data
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = InstallFdt ((CHAR16*)Data);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((
+ EFI_D_WARN,
+ "Installation of the FDT using the device path <%s> completed.\n",
+ (CHAR16*)Data
+ ));
+ }
+ }
+ FreePool (Data);
+ }
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ EFI_D_ERROR,
+ "Installation of the FDT specified by the \"Fdt\" UEFI variable failed - %r\n",
+ Status
+ ));
+ } else {
+ return Status;
+ }
+ }
+ }
+
+ //
+ // Loop over the device path list provided by "PcdFdtDevicePaths". The device
+ // paths are in text form and separated by a semi-colon.
+ //
+
+ Status = EFI_SUCCESS;
+ for (TextDevicePathStart = (CHAR16*)PcdGetPtr (PcdFdtDevicePaths);
+ *TextDevicePathStart != L'\0' ; ) {
+ TextDevicePathSeparator = StrStr (TextDevicePathStart, L";");
+
+ //
+ // Last device path of the list
+ //
+ if (TextDevicePathSeparator == NULL) {
+ TextDevicePath = TextDevicePathStart;
+ } else {
+ TextDevicePathLen = (UINTN)(TextDevicePathSeparator - TextDevicePathStart);
+ TextDevicePath = AllocateCopyPool (
+ (TextDevicePathLen + 1) * sizeof (CHAR16),
+ TextDevicePathStart
+ );
+ if (TextDevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((EFI_D_ERROR, "Memory allocation error during FDT installation process.\n"));
+ break;
+ }
+ TextDevicePath[TextDevicePathLen] = L'\0';
+ }
+
+ Status = InstallFdt (TextDevicePath);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_WARN, "Installation of the FDT using the device path <%s> failed - %r.\n",
+ TextDevicePath, Status
+ ));
+ } else {
+ DEBUG ((EFI_D_WARN, "Installation of the FDT using the device path <%s> completed.\n",
+ TextDevicePath
+ ));
+ }
+
+ if (TextDevicePathSeparator == NULL) {
+ break;
+ } else {
+ FreePool (TextDevicePath);
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+ TextDevicePathStart = TextDevicePathSeparator + 1;
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Failed to install the FDT - %r.\n", Status));
+ }
+
+ return Status;
+}
+
+/**
+ Install the FDT specified by its device path in text form.
+
+ @param[in] TextDevicePath Device path of the FDT to install in text form
+
+ @retval EFI_SUCCESS The FDT was installed.
+ @retval EFI_NOT_FOUND Failed to locate a protocol or a file.
+ @retval EFI_INVALID_PARAMETER Invalid device path.
+ @retval EFI_UNSUPPORTED Device path not supported.
+ @retval EFI_OUT_OF_RESOURCES An allocation failed.
+**/
+STATIC
+EFI_STATUS
+InstallFdt (
+ IN CONST CHAR16* TextDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
+ EFI_DEVICE_PATH *DevicePath;
+ EFI_PHYSICAL_ADDRESS FdtBlobBase;
+ UINTN FdtBlobSize;
+ UINTN NbPages;
+ EFI_PHYSICAL_ADDRESS RsFdtBlobBase;
+
+ Status = gBS->LocateProtocol (
+ &gEfiDevicePathFromTextProtocolGuid,
+ NULL,
+ (VOID **)&EfiDevicePathFromTextProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "InstallFdt() - Failed to locate EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol\n"));
+ return Status;
+ }
+
+ DevicePath = (EFI_DEVICE_PATH*)EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (TextDevicePath);
+ if (DevicePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Load the FDT given its device path.
+ // This operation may fail if the device path is not supported.
+ //
+ FdtBlobBase = 0;
+ NbPages = 0;
+ Status = BdsLoadImage (DevicePath, AllocateAnyPages, &FdtBlobBase, &FdtBlobSize);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ // 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.
+ //
+ NbPages = EFI_SIZE_TO_PAGES (FdtBlobSize);
+ Status = gBS->AllocatePages (
+ AllocateAnyPages, EfiRuntimeServicesData,
+ NbPages, &RsFdtBlobBase
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ CopyMem (
+ (VOID*)((UINTN)RsFdtBlobBase),
+ (VOID*)((UINTN)FdtBlobBase),
+ FdtBlobSize
+ );
+
+ //
+ // Install the FDT into the Configuration Table
+ //
+ Status = gBS->InstallConfigurationTable (
+ &gFdtTableGuid,
+ (VOID*)((UINTN)RsFdtBlobBase)
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePages (RsFdtBlobBase, NbPages);
+ }
+
+Error :
+
+ if (FdtBlobBase != 0) {
+ gBS->FreePages (FdtBlobBase, NbPages);
+ }
+ FreePool (DevicePath);
+
+ return Status;
+}
+
+=======
+
+/**
+ This is the shell command "setfdt" handler function. This function handles
+ the command when it is invoked in the shell.
+
+ @param[in] This The instance of the
+ EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+ @param[in] SystemTable The pointer to the UEFI system table.
+ @param[in] ShellParameters The parameters associated with the command.
+ @param[in] Shell The instance of the shell protocol used in the
+ context of processing this command.
+
+ @return SHELL_SUCCESS The operation was successful.
+ @return SHELL_ABORTED Operation aborted due to internal error.
+ @return SHELL_INVALID_PARAMETER The parameters of the command are not valid.
+ @return SHELL_INVALID_PARAMETER The EFI Shell file path is not valid.
+ @return SHELL_NOT_FOUND Failed to locate a protocol or a file.
+ @return SHELL_UNSUPPORTED Device path not supported.
+ @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
+ @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.
+
+**/
+STATIC
+SHELL_STATUS
+EFIAPI
+ShellDynCmdSetFdtHandler (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
+ IN EFI_SHELL_PROTOCOL *Shell
+ )
+{
+ SHELL_STATUS ShellStatus;
+ EFI_STATUS Status;
+ LIST_ENTRY *ParamPackage;
+ BOOLEAN FilePath;
+ CONST CHAR16 *ValueStr;
+
+ ShellStatus = SHELL_SUCCESS;
+ ParamPackage = NULL;
+ FilePath = FALSE;
+
+ //
+ // Install the Shell and Shell Parameters Protocols on the driver
+ // image. This is necessary for the initialisation of the Shell
+ // Library to succeed in the next step.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &gImageHandle,
+ &gEfiShellProtocolGuid, Shell,
+ &gEfiShellParametersProtocolGuid, ShellParameters,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return SHELL_ABORTED;
+ }
+
+ //
+ // Initialise the Shell Library as we are going to use it.
+ // Assert that the return code is EFI_SUCCESS as it should.
+ // To anticipate any change is the codes returned by
+ // ShellInitialize(), leave in case of error.
+ //
+ Status = ShellInitialize ();
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return SHELL_ABORTED;
+ }
+
+ Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);
+ if (!EFI_ERROR (Status)) {
+ switch (ShellCommandLineGetCount (ParamPackage)) {
+ case 1:
+ //
+ // Case "setfdt -i"
+ //
+ if (!ShellCommandLineGetFlag (ParamPackage, L"-i")) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+ break;
+
+ case 2:
+ //
+ // Case "setfdt file_path" or
+ // "setfdt -i file_path" or
+ // "setfdt file_path -i"
+ //
+ FilePath = TRUE;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ }
+ }
+ if (EFI_ERROR (Status)) {
+ ShellStatus = EfiCodeToShellCode (Status);
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_ERROR),
+ mFdtPlatformDxeHiiHandle,
+ Status
+ );
+ goto Error;
+ }
+
+ //
+ // Update the preferred device path for the FDT if asked for.
+ //
+ if (FilePath) {
+ ValueStr = ShellCommandLineGetRawValue (ParamPackage, 1);
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_UPDATING),
+ mFdtPlatformDxeHiiHandle
+ );
+ ShellStatus = UpdateFdtTextDevicePath (Shell, ValueStr);
+ if (ShellStatus != SHELL_SUCCESS) {
+ goto Error;
+ }
+ }
+
+ //
+ // Run the FDT installation process if asked for.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_INSTALLING),
+ mFdtPlatformDxeHiiHandle
+ );
+ Status = RunFdtInstallation ();
+ ShellStatus = EfiCodeToShellCode (Status);
+ if (!EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_INSTALL_SUCCEEDED),
+ mFdtPlatformDxeHiiHandle
+ );
+ } else {
+ if (Status == EFI_INVALID_PARAMETER) {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_INVALID_DEVICE_PATH),
+ mFdtPlatformDxeHiiHandle
+ );
+ } else {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_ERROR),
+ mFdtPlatformDxeHiiHandle,
+ Status
+ );
+ }
+ }
+ }
+
+Error:
+
+ gBS->UninstallMultipleProtocolInterfaces (
+ gImageHandle,
+ &gEfiShellProtocolGuid, Shell,
+ &gEfiShellParametersProtocolGuid, ShellParameters,
+ NULL
+ );
+ ShellCommandLineFreeVarList (ParamPackage);
+
+ return ShellStatus;
+}
+
+/**
+ This is the shell command "setfdt" help handler function. This
+ function returns the formatted help for the "setfdt" command.
+ The format matchs that in Appendix B of the revision 2.1 of the
+ UEFI Shell Specification.
+
+ @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+ @param[in] Language The pointer to the language string to use.
+
+ @return CHAR16* Pool allocated help string, must be freed by caller.
+**/
+STATIC
+CHAR16*
+EFIAPI
+ShellDynCmdSetFdtGetHelp (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN CONST CHAR8 *Language
+ )
+{
+ //
+ // This allocates memory. The caller has to free the allocated memory.
+ //
+ return HiiGetString (
+ mFdtPlatformDxeHiiHandle,
+ STRING_TOKEN (STR_GET_HELP_SETFDT),
+ Language
+ );
+}
+
+/**
+ Update the text device path stored in the "Fdt" UEFI variable given
+ an EFI Shell file path or a text device path.
+
+ This function is a subroutine of the ShellDynCmdSetFdtHandler() function
+ to make its code easier to read.
+
+ @param[in] Shell The instance of the shell protocol used in the
+ context of processing the "setfdt" command.
+ @param[in] FilePath EFI Shell path or the device path to the FDT file.
+
+ @return SHELL_SUCCESS The text device path was succesfully updated.
+ @return SHELL_INVALID_PARAMETER The Shell file path is not valid.
+ @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
+ @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.
+ @return SHELL_NOT_FOUND Device path to text protocol not found.
+ @return SHELL_ABORTED Operation aborted.
+
+**/
+STATIC
+SHELL_STATUS
+UpdateFdtTextDevicePath (
+ IN EFI_SHELL_PROTOCOL *Shell,
+ IN CONST CHAR16 *FilePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH *DevicePath;
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *EfiDevicePathToTextProtocol;
+ CHAR16 *TextDevicePath;
+ CHAR16 *FdtVariableValue;
+ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
+ SHELL_STATUS ShellStatus;
+
+ ASSERT (FilePath != NULL);
+ TextDevicePath = NULL;
+ FdtVariableValue = NULL;
+
+ DevicePath = Shell->GetDevicePathFromFilePath (FilePath);
+ if (DevicePath != NULL) {
+ Status = gBS->LocateProtocol (
+ &gEfiDevicePathToTextProtocolGuid,
+ NULL,
+ (VOID **)&EfiDevicePathToTextProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ TextDevicePath = EfiDevicePathToTextProtocol->ConvertDevicePathToText (
+ DevicePath,
+ FALSE,
+ FALSE
+ );
+ if (TextDevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+ FdtVariableValue = TextDevicePath;
+ } else {
+ //
+ // Try to convert back the EFI Device Path String into a EFI device Path
+ // to ensure the format is valid
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiDevicePathFromTextProtocolGuid,
+ NULL,
+ (VOID **)&EfiDevicePathFromTextProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ DevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (
+ FilePath
+ );
+ if (DevicePath == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Error;
+ }
+ FdtVariableValue = (CHAR16*)FilePath;
+ }
+
+ Status = gRT->SetVariable (
+ (CHAR16*)L"Fdt",
+ &gFdtVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS ,
+ StrSize (FdtVariableValue),
+ FdtVariableValue
+ );
+
+Error:
+ ShellStatus = EfiCodeToShellCode (Status);
+ if (!EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_UPDATE_SUCCEEDED),
+ mFdtPlatformDxeHiiHandle,
+ FdtVariableValue
+ );
+ } else {
+ if (Status == EFI_INVALID_PARAMETER) {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_INVALID_PATH),
+ mFdtPlatformDxeHiiHandle,
+ FilePath
+ );
+ } else {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_ERROR),
+ mFdtPlatformDxeHiiHandle,
+ Status
+ );
+ }
+ }
+
+ if (DevicePath != NULL) {
+ FreePool (DevicePath);
+ }
+ if (TextDevicePath != NULL) {
+ FreePool (TextDevicePath);
+ }
+
+ return ShellStatus;
+}
+
+/**
+ Transcode one of the EFI return code used by the model into an EFI Shell return code.
+
+ @param[in] Status EFI return code.
+
+ @return Transcoded EFI Shell return code.
+
+**/
+STATIC
+SHELL_STATUS
+EfiCodeToShellCode (
+ IN EFI_STATUS Status
+ )
+{
+ SHELL_STATUS ShellStatus;
+
+ switch (Status) {
+ case EFI_SUCCESS :
+ ShellStatus = SHELL_SUCCESS;
+ break;
+
+ case EFI_INVALID_PARAMETER :
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ break;
+
+ case EFI_UNSUPPORTED :
+ ShellStatus = SHELL_UNSUPPORTED;
+ break;
+
+ case EFI_DEVICE_ERROR :
+ ShellStatus = SHELL_DEVICE_ERROR;
+ break;
+
+ case EFI_WRITE_PROTECTED :
+ case EFI_SECURITY_VIOLATION :
+ ShellStatus = SHELL_ACCESS_DENIED;
+ break;
+
+ case EFI_OUT_OF_RESOURCES :
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ break;
+
+ case EFI_NOT_FOUND :
+ ShellStatus = SHELL_NOT_FOUND;
+ break;
+
+ default :
+ ShellStatus = SHELL_ABORTED;
+ }
+
+ return ShellStatus;
+}
+>>>>>>> 4ac4fed... EmbeddedPkg/FdtPlatformDxe: Fix typo issue
diff --git a/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf
new file mode 100644
index 0000000000..ea45baa2e3
--- /dev/null
+++ b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf
@@ -0,0 +1,55 @@
+#/** @file
+#
+# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+#
+# 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 = 0x00010006
+ BASE_NAME = FdtPlatformDxe
+ FILE_GUID = 6e9a4c69-57c6-4fcd-b083-4f2c3bdb6051
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 0.1
+ ENTRY_POINT = FdtPlatformEntryPoint
+
+[Sources.common]
+ FdtPlatform.c
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BdsLib
+ DxeServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+
+[Protocols]
+ gEfiDevicePathFromTextProtocolGuid
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid
+ gFdtTableGuid
+ gFdtVariableGuid
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdOverridePlatformFdt
+
+[Pcd]
+ gEmbeddedTokenSpaceGuid.PcdFdtDevicePaths
+
+[Depex]
+ TRUE
diff --git a/EmbeddedPkg/Drivers/FdtPlatformDxe/README.txt b/EmbeddedPkg/Drivers/FdtPlatformDxe/README.txt
new file mode 100644
index 0000000000..bf61e661af
--- /dev/null
+++ b/EmbeddedPkg/Drivers/FdtPlatformDxe/README.txt
@@ -0,0 +1,50 @@
+/** @file
+
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+ 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.
+
+**/
+
+The purpose of the FdtPlatformDxe UEFI driver is to install the Flat Device
+Tree (FDT) of the platform the UEFI frimware is running on into the UEFI
+Configuration Table. The FDT is identified within the UEFI Configuration
+Table by the "gFdtTableGuid" GUID defined in EmbeddedPkg.dec.
+
+Once installed, an UEFI application or OS boot loader can get from the UEFI
+Configuration Table the FDT of the platform from the "gFdtTableGuid" GUID.
+
+The installation is done after each boot at the end of the DXE phase,
+just before the BDS phase. It is done at the end of the DXE phase to be sure
+that all drivers have been dispatched. That way, all UEFI protocols that may
+be needed to retrieve the FDT can be made available. It is done before the BDS
+phase to be able to provide the FDT during that phase.
+
+The present driver tries to retrieve the FDT from the device paths defined in the
+"gEmbeddedTokenSpaceGuid.PcdFdtDevicePaths" PCD. The "PcdFdtDevicePaths" PCD
+contains a list a device paths. The device paths are in the text form and
+separated by semi-colons. The present driver tries the device paths in the order
+it finds them in the "PcdFdtDevicePaths" PCD as long as he did not install
+succesfully a FDT.
+
+The "PcdFdtDevicePaths" PCD is a dynamic PCD that can be modified during the
+DXE phase. This allows for exemple to select the right FDT when a binary is
+intended to run on several platforms and/or variants of a platform.
+
+If the driver manages to download a FDT from one of the device paths mentioned
+above then it installs it in the UEFI Configuration table and the run over the
+device paths is stopped.
+
+For development purposes only, if the feature PCD "gEmbeddedTokenSpaceGuid.
+PcdOverridePlatformFdt" is equal to TRUE, then before to try to install the
+FDT from the device paths listed in the "PcdFdtDevicePaths" PCD, the present
+driver tries to install it using the device path defined by the UEFI variable
+"Fdt". If the variable does not exist or the installation using the device path
+defined by the UEFI variable fails then the installation proceeds as described
+above.
diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
index 600d0e54c4..1a498d2446 100644
--- a/EmbeddedPkg/EmbeddedPkg.dec
+++ b/EmbeddedPkg/EmbeddedPkg.dec
@@ -52,6 +52,7 @@
## FDT Configuration Table
# Include/Guid/Fdt.h
gFdtTableGuid = { 0xb1b621d5, 0xf19c, 0x41a5, { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } }
+ gFdtVariableGuid = { 0x25a4fd4a, 0x9703, 0x4ba9, { 0xa1, 0x90, 0xb7, 0xc8, 0x4e, 0xfb, 0x3e, 0x57 } }
[Protocols.common]
gHardwareInterruptProtocolGuid = { 0x2890B3EA, 0x053D, 0x1643, { 0xAD, 0x0C, 0xD6, 0x48, 0x08, 0xDA, 0x3F, 0xF1 } }
@@ -79,6 +80,7 @@
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|FALSE|BOOLEAN|0x0000001b
gEmbeddedTokenSpaceGuid.PcdCacheEnable|FALSE|BOOLEAN|0x00000042
gEmbeddedTokenSpaceGuid.PcdGdbSerial|FALSE|BOOLEAN|0x00000053
+ gEmbeddedTokenSpaceGuid.PcdOverridePlatformFdt|TRUE|BOOLEAN|0x00000054
[PcdsFixedAtBuild.common]
@@ -148,6 +150,7 @@
gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbProductId|0xbeef|UINT32|0x00000023
gEmbeddedTokenSpaceGuid.PcdAndroidFastbootTcpPort|1234|UINT32|0x00000024
+
[PcdsFixedAtBuild.ARM]
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32|UINT8|0x00000010
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00000011
@@ -169,3 +172,6 @@
[PcdsFixedAtBuild.X64]
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|52|UINT8|0x00000010
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16|UINT8|0x00000011
+
+[PcdsFixedAtBuild.common, PcdsDynamic.common]
+ gEmbeddedTokenSpaceGuid.PcdFdtDevicePaths|L""|VOID*|0x00000055
diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc
index a3a136da32..8a58b9b121 100644
--- a/EmbeddedPkg/EmbeddedPkg.dsc
+++ b/EmbeddedPkg/EmbeddedPkg.dsc
@@ -264,8 +264,9 @@
EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
- # FDT Support
+ # FDT installation
EmbeddedPkg/Library/FdtLoadLib/FdtLoadLib.inf
+ EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf
EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
diff --git a/EmbeddedPkg/Include/Guid/Fdt.h b/EmbeddedPkg/Include/Guid/Fdt.h
index f2397ff22a..74c85dc30b 100644
--- a/EmbeddedPkg/Include/Guid/Fdt.h
+++ b/EmbeddedPkg/Include/Guid/Fdt.h
@@ -12,12 +12,17 @@
*
**/
-#ifndef __FDT_GUID_H__
-#define __FDT_GUID_H__
+#ifndef __FDT_H__
+#define __FDT_H__
#define FDT_TABLE_GUID \
{ 0xb1b621d5, 0xf19c, 0x41a5, { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } }
extern EFI_GUID gFdtTableGuid;
-#endif /* __FDT_GUID_H__ */
+#define FDT_VARIABLE_GUID \
+ { 0x25a4fd4a, 0x9703, 0x4ba9, { 0xa1, 0x90, 0xb7, 0xc8, 0x4e, 0xfb, 0x3e, 0x57 } }
+
+extern EFI_GUID gFdtVariableGuid;
+
+#endif /* __FDT_H__ */