mirror of https://github.com/acidanthera/audk.git
EmbeddedPkg/FdtPlatformDxe: Run FDT installation process at TPL_APPLICATION level
The current mechanism relies on EndOfDxe event that runs at TPL_CALLBACK level. It prevents some protocols to run as excepted because they require TPL_CALLBACK (eg: TFTP transfer). This change moves FDT installation in the driver entrypoint (that is called at TPL_APPLICATION level). Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <olivier.martin@arm.com> Reviewed-by: Ronald Cron <Ronald.Cron@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17298 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
cc053ee6da
commit
cd66c5a2f1
|
@ -30,7 +30,6 @@
|
||||||
#include <Protocol/EfiShell.h>
|
#include <Protocol/EfiShell.h>
|
||||||
#include <Protocol/EfiShellDynamicCommand.h>
|
#include <Protocol/EfiShellDynamicCommand.h>
|
||||||
|
|
||||||
#include <Guid/EventGroup.h>
|
|
||||||
#include <Guid/Fdt.h>
|
#include <Guid/Fdt.h>
|
||||||
|
|
||||||
#include <libfdt.h>
|
#include <libfdt.h>
|
||||||
|
@ -39,17 +38,6 @@
|
||||||
// Internal types
|
// 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
|
|
||||||
);
|
|
||||||
|
|
||||||
STATIC SHELL_STATUS EFIAPI ShellDynCmdSetFdtHandler (
|
STATIC SHELL_STATUS EFIAPI ShellDynCmdSetFdtHandler (
|
||||||
IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
|
IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable,
|
IN EFI_SYSTEM_TABLE *SystemTable,
|
||||||
|
@ -92,6 +80,105 @@ STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
|
||||||
|
|
||||||
STATIC EFI_HANDLE mFdtPlatformDxeHiiHandle;
|
STATIC EFI_HANDLE mFdtPlatformDxeHiiHandle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 NumPages;
|
||||||
|
EFI_PHYSICAL_ADDRESS FdtConfigurationTableBase;
|
||||||
|
|
||||||
|
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;
|
||||||
|
NumPages = 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.
|
||||||
|
//
|
||||||
|
NumPages = EFI_SIZE_TO_PAGES (FdtBlobSize);
|
||||||
|
Status = gBS->AllocatePages (
|
||||||
|
AllocateAnyPages, EfiRuntimeServicesData,
|
||||||
|
NumPages, &FdtConfigurationTableBase
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error:
|
||||||
|
if (FdtBlobBase != 0) {
|
||||||
|
gBS->FreePages (FdtBlobBase, NumPages);
|
||||||
|
}
|
||||||
|
FreePool (DevicePath);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Main entry point of the FDT platform driver.
|
Main entry point of the FDT platform driver.
|
||||||
|
|
||||||
|
@ -113,23 +200,11 @@ FdtPlatformEntryPoint (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_EVENT EndOfDxeEvent;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group.
|
// Install the Device Tree from its expected location
|
||||||
// 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 (
|
Status = RunFdtInstallation (NULL);
|
||||||
EVT_NOTIFY_SIGNAL,
|
|
||||||
TPL_CALLBACK,
|
|
||||||
OnEndOfDxe,
|
|
||||||
NULL,
|
|
||||||
&gEfiEndOfDxeEventGroupGuid,
|
|
||||||
&EndOfDxeEvent
|
|
||||||
);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -184,32 +259,6 @@ FdtPlatformEntryPoint (
|
||||||
return Status;
|
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.
|
Run the FDT installation process.
|
||||||
|
|
||||||
|
@ -353,106 +402,6 @@ RunFdtInstallation (
|
||||||
return 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
|
This is the shell command "setfdt" handler function. This function handles
|
||||||
the command when it is invoked in the shell.
|
the command when it is invoked in the shell.
|
||||||
|
@ -612,7 +561,6 @@ ShellDynCmdSetFdtHandler (
|
||||||
}
|
}
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
|
|
||||||
gBS->UninstallMultipleProtocolInterfaces (
|
gBS->UninstallMultipleProtocolInterfaces (
|
||||||
gImageHandle,
|
gImageHandle,
|
||||||
&gEfiShellProtocolGuid, Shell,
|
&gEfiShellProtocolGuid, Shell,
|
||||||
|
|
Loading…
Reference in New Issue