mirror of https://github.com/acidanthera/audk.git
EmbeddedPkg: add DT platform driver to select between DT and ACPI
As a follow up to the changes proposed by Laszlo to make ACPI and DT mutually exclusive on ArmVirtQemu, this patch proposes a DT platform DXE driver that either installs the NULL protocol PlatformHasAcpiGuid, or installs the FV embedded DTB binary as a configuration table under the appropriate GUID, depending on a preference setting recorded as a UEFI variable, and configurable via a HII screen. The DTB binary can be embedded in the firmware image by adding the following to the platform .fdf file: FILE FREEFORM = 25462CDA-221F-47DF-AC1D-259CFAA4E326 { SECTION RAW = SomePkg/path/to/foo.dtb } Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
parent
89ad870fbf
commit
779cc439e8
|
@ -0,0 +1,213 @@
|
|||
/** @file
|
||||
*
|
||||
* Copyright (c) 2017, Linaro, 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.
|
||||
*
|
||||
**/
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/DxeServicesLib.h>
|
||||
#include <Library/HiiLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
|
||||
#include "DtPlatformDxe.h"
|
||||
|
||||
extern UINT8 DtPlatformHiiBin[];
|
||||
extern UINT8 DtPlatformDxeStrings[];
|
||||
|
||||
typedef struct {
|
||||
VENDOR_DEVICE_PATH VendorDevicePath;
|
||||
EFI_DEVICE_PATH_PROTOCOL End;
|
||||
} HII_VENDOR_DEVICE_PATH;
|
||||
|
||||
STATIC HII_VENDOR_DEVICE_PATH mDtPlatformDxeVendorDevicePath = {
|
||||
{
|
||||
{
|
||||
HARDWARE_DEVICE_PATH,
|
||||
HW_VENDOR_DP,
|
||||
{
|
||||
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
|
||||
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
|
||||
}
|
||||
},
|
||||
DT_PLATFORM_FORMSET_GUID
|
||||
},
|
||||
{
|
||||
END_DEVICE_PATH_TYPE,
|
||||
END_ENTIRE_DEVICE_PATH_SUBTYPE,
|
||||
{
|
||||
(UINT8) (END_DEVICE_PATH_LENGTH),
|
||||
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
InstallHiiPages (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HII_HANDLE HiiHandle;
|
||||
EFI_HANDLE DriverHandle;
|
||||
|
||||
DriverHandle = NULL;
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (&DriverHandle,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
&mDtPlatformDxeVendorDevicePath,
|
||||
NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
HiiHandle = HiiAddPackages (&gDtPlatformFormSetGuid,
|
||||
DriverHandle,
|
||||
DtPlatformDxeStrings,
|
||||
DtPlatformHiiBin,
|
||||
NULL);
|
||||
|
||||
if (HiiHandle == NULL) {
|
||||
gBS->UninstallMultipleProtocolInterfaces (DriverHandle,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
&mDtPlatformDxeVendorDevicePath,
|
||||
NULL);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
The entry point for DtPlatformDxe driver.
|
||||
|
||||
@param[in] ImageHandle The image handle of the driver.
|
||||
@param[in] SystemTable The system table.
|
||||
|
||||
@retval EFI_ALREADY_STARTED The driver already exists in system.
|
||||
@retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of
|
||||
resources.
|
||||
@retval EFI_SUCCES All the related protocols are installed on
|
||||
the driver.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DtPlatformDxeEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DT_ACPI_VARSTORE_DATA DtAcpiPref;
|
||||
UINTN BufferSize;
|
||||
VOID *Dtb;
|
||||
UINTN DtbSize;
|
||||
VOID *DtbCopy;
|
||||
|
||||
//
|
||||
// Check whether a DTB blob is included in the firmware image.
|
||||
//
|
||||
Dtb = NULL;
|
||||
Status = GetSectionFromAnyFv (&gDtPlatformDefaultDtbFileGuid,
|
||||
EFI_SECTION_RAW, 0, &Dtb, &DtbSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN, "%a: no DTB blob found, defaulting to ACPI\n",
|
||||
__FUNCTION__));
|
||||
DtAcpiPref.Pref = DT_ACPI_SELECT_ACPI;
|
||||
} else {
|
||||
//
|
||||
// Get the current DT/ACPI preference from the DtAcpiPref variable.
|
||||
//
|
||||
BufferSize = sizeof (DtAcpiPref);
|
||||
Status = gRT->GetVariable(DT_ACPI_VARIABLE_NAME, &gDtPlatformFormSetGuid,
|
||||
NULL, &BufferSize, &DtAcpiPref);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN, "%a: no DT/ACPI preference found, defaulting to DT\n",
|
||||
__FUNCTION__));
|
||||
DtAcpiPref.Pref = DT_ACPI_SELECT_DT;
|
||||
}
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status) &&
|
||||
DtAcpiPref.Pref != DT_ACPI_SELECT_ACPI &&
|
||||
DtAcpiPref.Pref != DT_ACPI_SELECT_DT) {
|
||||
DEBUG ((DEBUG_WARN, "%a: invalid value for %s, defaulting to DT\n",
|
||||
__FUNCTION__, DT_ACPI_VARIABLE_NAME));
|
||||
DtAcpiPref.Pref = DT_ACPI_SELECT_DT;
|
||||
Status = EFI_INVALID_PARAMETER; // trigger setvar below
|
||||
}
|
||||
|
||||
//
|
||||
// Write the newly selected default value back to the variable store.
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = gRT->SetVariable(DT_ACPI_VARIABLE_NAME, &gDtPlatformFormSetGuid,
|
||||
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
||||
sizeof (DtAcpiPref), &DtAcpiPref);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
if (DtAcpiPref.Pref == DT_ACPI_SELECT_ACPI) {
|
||||
//
|
||||
// ACPI was selected: install the gEdkiiPlatformHasAcpiGuid GUID as a
|
||||
// NULL protocol to unlock dispatch of ACPI related drivers.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
|
||||
&gEdkiiPlatformHasAcpiGuid, NULL, NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR,
|
||||
"%a: failed to install gEdkiiPlatformHasAcpiGuid as a protocol\n",
|
||||
__FUNCTION__));
|
||||
return Status;
|
||||
}
|
||||
} else if (DtAcpiPref.Pref == DT_ACPI_SELECT_DT) {
|
||||
//
|
||||
// DT was selected: copy the blob into newly allocated memory and install
|
||||
// a reference to it as the FDT configuration table.
|
||||
//
|
||||
DtbCopy = AllocateCopyPool (DtbSize, Dtb);
|
||||
if (DtbCopy == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
Status = gBS->InstallConfigurationTable (&gFdtTableGuid, DtbCopy);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "%a: failed to install FDT configuration table\n",
|
||||
__FUNCTION__));
|
||||
FreePool (DtbCopy);
|
||||
return Status;
|
||||
}
|
||||
} else {
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
// No point in installing the HII pages if ACPI is the only description
|
||||
// we have
|
||||
//
|
||||
if (Dtb == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Note that we don't uninstall the gEdkiiPlatformHasAcpiGuid protocol nor
|
||||
// the FDT configuration table if the following call fails. While that will
|
||||
// cause loading of this driver to fail, proceeding with ACPI and DT both
|
||||
// disabled will guarantee a failed boot, and so it is better to leave them
|
||||
// installed in that case.
|
||||
//
|
||||
return InstallHiiPages ();
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/** @file
|
||||
*
|
||||
* Copyright (c) 2017, Linaro 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 __DT_PLATFORM_DXE_H__
|
||||
#define __DT_PLATFORM_DXE_H__
|
||||
|
||||
#include <Guid/HiiPlatformSetupFormset.h>
|
||||
#include <Guid/DtPlatformFormSet.h>
|
||||
|
||||
#define DT_ACPI_SELECT_DT 0x0
|
||||
#define DT_ACPI_SELECT_ACPI 0x1
|
||||
|
||||
#define DT_ACPI_VARIABLE_NAME L"DtAcpiPref"
|
||||
|
||||
typedef struct {
|
||||
UINT8 Pref;
|
||||
UINT8 Reserved[3];
|
||||
} DT_ACPI_VARSTORE_DATA;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
## @file
|
||||
#
|
||||
# Copyright (c) 2017, Linaro, 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 = 0x00010019
|
||||
BASE_NAME = DtPlatformDxe
|
||||
FILE_GUID = FC097B3C-2EBD-4A75-A3DA-121DCAB365CC
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = DtPlatformDxeEntryPoint
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
DtPlatformDxe.c
|
||||
DtPlatformHii.vfr
|
||||
DtPlatformHii.uni
|
||||
|
||||
[Packages]
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
DebugLib
|
||||
DxeServicesLib
|
||||
HiiLib
|
||||
MemoryAllocationLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
UefiRuntimeServicesTableLib
|
||||
|
||||
[Guids]
|
||||
gDtPlatformFormSetGuid
|
||||
gDtPlatformDefaultDtbFileGuid
|
||||
gEdkiiPlatformHasAcpiGuid
|
||||
gFdtTableGuid
|
||||
|
||||
[Depex]
|
||||
gEfiVariableArchProtocolGuid AND
|
||||
gEfiVariableWriteArchProtocolGuid
|
|
@ -0,0 +1,27 @@
|
|||
/** @file
|
||||
*
|
||||
* Copyright (c) 2017, Linaro, 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.
|
||||
*
|
||||
**/
|
||||
|
||||
#langdef en-US "English"
|
||||
|
||||
#string STR_FORM_SET_TITLE #language en-US "O/S Hardware Description Selection"
|
||||
#string STR_FORM_SET_TITLE_HELP #language en-US "Press <Enter> to choose between ACPI and DT hardware descriptions."
|
||||
|
||||
#string STR_MAIN_FORM_TITLE #language en-US "O/S Hardware Description Selection"
|
||||
#string STR_NULL_STRING #language en-US ""
|
||||
|
||||
#string STR_DT_ACPI_SELECT_PROMPT #language en-US "O/S Hardware Description"
|
||||
#string STR_DT_ACPI_SELECT_HELP #language en-US "Select the hardware description that will be exposed to the O/S."
|
||||
|
||||
#string STR_DT_ACPI_SELECT_DT #language en-US "Device Tree"
|
||||
#string STR_DT_ACPI_SELECT_ACPI #language en-US "ACPI"
|
|
@ -0,0 +1,51 @@
|
|||
/** @file
|
||||
*
|
||||
* Copyright (c) 2017, Linaro, 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.
|
||||
*
|
||||
**/
|
||||
|
||||
#include "DtPlatformDxe.h"
|
||||
|
||||
//
|
||||
// EFI Variable attributes
|
||||
//
|
||||
#define EFI_VARIABLE_NON_VOLATILE 0x00000001
|
||||
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
|
||||
#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
|
||||
#define EFI_VARIABLE_READ_ONLY 0x00000008
|
||||
|
||||
formset
|
||||
guid = DT_PLATFORM_FORMSET_GUID,
|
||||
title = STRING_TOKEN(STR_FORM_SET_TITLE),
|
||||
help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP),
|
||||
classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
|
||||
|
||||
efivarstore DT_ACPI_VARSTORE_DATA,
|
||||
attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, // EFI variable attributes
|
||||
name = DtAcpiPref,
|
||||
guid = DT_PLATFORM_FORMSET_GUID;
|
||||
|
||||
form formid = 0x1000,
|
||||
title = STRING_TOKEN(STR_MAIN_FORM_TITLE);
|
||||
|
||||
oneof varid = DtAcpiPref.Pref,
|
||||
prompt = STRING_TOKEN(STR_DT_ACPI_SELECT_PROMPT),
|
||||
help = STRING_TOKEN(STR_DT_ACPI_SELECT_HELP),
|
||||
flags = NUMERIC_SIZE_1 | INTERACTIVE | RESET_REQUIRED,
|
||||
option text = STRING_TOKEN(STR_DT_ACPI_SELECT_DT), value = DT_ACPI_SELECT_DT, flags = DEFAULT;
|
||||
option text = STRING_TOKEN(STR_DT_ACPI_SELECT_ACPI), value = DT_ACPI_SELECT_ACPI, flags = 0;
|
||||
endoneof;
|
||||
|
||||
subtitle text = STRING_TOKEN(STR_NULL_STRING);
|
||||
|
||||
endform;
|
||||
|
||||
endformset;
|
|
@ -62,6 +62,12 @@
|
|||
## Include/Guid/PlatformHasDeviceTree.h
|
||||
gEdkiiPlatformHasDeviceTreeGuid = { 0x7ebb920d, 0x1aaf, 0x46d9, { 0xb2, 0xaf, 0x54, 0x1e, 0x1d, 0xce, 0x14, 0x8b } }
|
||||
|
||||
# HII form set GUID for DtPlatformDxe driver
|
||||
gDtPlatformFormSetGuid = { 0x2b7a240d, 0xd5ad, 0x4fd6, { 0xbe, 0x1c, 0xdf, 0xa4, 0x41, 0x5f, 0x55, 0x26 } }
|
||||
|
||||
# File GUID for default DTB image embedded in the firmware volume
|
||||
gDtPlatformDefaultDtbFileGuid = { 0x25462cda, 0x221f, 0x47df, { 0xac, 0x1d, 0x25, 0x9c, 0xfa, 0xa4, 0xe3, 0x26 } }
|
||||
|
||||
[Protocols.common]
|
||||
gHardwareInterruptProtocolGuid = { 0x2890B3EA, 0x053D, 0x1643, { 0xAD, 0x0C, 0xD6, 0x48, 0x08, 0xDA, 0x3F, 0xF1 } }
|
||||
gEfiDebugSupportPeriodicCallbackProtocolGuid = { 0x9546e07c, 0x2cbb, 0x4c88, { 0x98, 0x6c, 0xcd, 0x34, 0x10, 0x86, 0xf0, 0x44 } }
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/** @file
|
||||
*
|
||||
* Copyright (c) 2017, Linaro 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 __DT_PLATFORM_DEFAULT_DTB_FILE_H__
|
||||
#define __DT_PLATFORM_DEFAULT_DTB_FILE_H__
|
||||
|
||||
#define DT_PLATFORM_DEFAULT_DTB_FILE_GUID \
|
||||
{ 0x25462cda, 0x221f, 0x47df, { 0xac, 0x1d, 0x25, 0x9c, 0xfa, 0xa4, 0xe3, 0x26 } }
|
||||
|
||||
extern EFI_GUID gDtPlatformDefaultDtbFileGuid;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
/** @file
|
||||
*
|
||||
* Copyright (c) 2017, Linaro 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 __DT_PLATFORM_FORMSET_H__
|
||||
#define __DT_PLATFORM_FORMSET_H__
|
||||
|
||||
#define DT_PLATFORM_FORMSET_GUID \
|
||||
{ 0x2b7a240d, 0xd5ad, 0x4fd6, { 0xbe, 0x1c, 0xdf, 0xa4, 0x41, 0x5f, 0x55, 0x26 } }
|
||||
|
||||
extern EFI_GUID gDtPlatformFormSetGuid;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue