From d2998af2117119d3db4a41f7907d0e6f22548cc2 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Tue, 7 Apr 2020 11:00:28 -0700 Subject: [PATCH] PrmPkg: Add package and include headers REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3812 Adds a new package to maintain Platform Runtime Mechanism (PRM) support. This package is intended to include generic code that provides a common infrastructure to support PRM in firmware and a collection of sample PRM modules that demonstrate how to use the interfaces and other package resources to author a PRM module. The following initial headers are included in this commit: * Prm.h - Includes common content for PRM with no dependencies on other PRM header files. * PrmContextBuffer.h - Includes definitions for PRM context buffers. Context buffers are standardized structures that point to various resources available to a PRM handler during its execution. * PrmDataBuffer.h - Includes definitions for PRM data buffers. Within the context of PRM, these data buffers are composed of a generic header followed by a variable length blob of arbitrary data. * PrmExportDescriptor.h - Includes definitions for creating PRM export descriptors. A PRM export descriptor is a structure referenced in the export table of PRM module that contains PRM-specific metadata about the module. * PrmMmio.h - Includes definitions for describing MMIO ranges uses by PRM modules. * PrmModule.h - Includes definitions commonly used by PRM module authors. This file is provided to serve as a convenient include for PRM module authors. * PrmOsServices.h - Includes content specific to PRM OS services. OS Services will not planned to be present in the final version of PRM. The OS Services have been reduced to a simple debug print function. So this is currently planned to be a temporary file to support debugging during PRM development. Note: Modules built for the UEFI environment can be built by Visual Studio and non-Visual Studio toolchains. However, PRM modules are currently only supported on Visual Studio toolchain due to usage of export tables. Cc: Andrew Fish Cc: Kang Gao Cc: Michael D Kinney Cc: Michael Kubacki Cc: Leif Lindholm Cc: Benjamin You Cc: Liu Yun Cc: Ankit Sinha Cc: Nate DeSimone Signed-off-by: Michael Kubacki Acked-by: Michael D Kinney Acked-by: Liming Gao Acked-by: Leif Lindholm Reviewed-by: Ankit Sinha --- PrmPkg/Include/Prm.h | 46 ++++++++++ PrmPkg/Include/PrmContextBuffer.h | 131 +++++++++++++++++++++++++++ PrmPkg/Include/PrmDataBuffer.h | 50 ++++++++++ PrmPkg/Include/PrmExportDescriptor.h | 87 ++++++++++++++++++ PrmPkg/Include/PrmMmio.h | 45 +++++++++ PrmPkg/Include/PrmModule.h | 68 ++++++++++++++ PrmPkg/Include/PrmModuleUpdate.h | 46 ++++++++++ PrmPkg/Include/PrmOsServices.h | 45 +++++++++ PrmPkg/PrmPkg.dec | 49 ++++++++++ PrmPkg/PrmPkg.uni | 10 ++ 10 files changed, 577 insertions(+) create mode 100644 PrmPkg/Include/Prm.h create mode 100644 PrmPkg/Include/PrmContextBuffer.h create mode 100644 PrmPkg/Include/PrmDataBuffer.h create mode 100644 PrmPkg/Include/PrmExportDescriptor.h create mode 100644 PrmPkg/Include/PrmMmio.h create mode 100644 PrmPkg/Include/PrmModule.h create mode 100644 PrmPkg/Include/PrmModuleUpdate.h create mode 100644 PrmPkg/Include/PrmOsServices.h create mode 100644 PrmPkg/PrmPkg.dec create mode 100644 PrmPkg/PrmPkg.uni diff --git a/PrmPkg/Include/Prm.h b/PrmPkg/Include/Prm.h new file mode 100644 index 0000000000..0e3ccfffa3 --- /dev/null +++ b/PrmPkg/Include/Prm.h @@ -0,0 +1,46 @@ +/** @file + + Common Platform Runtime Mechanism (PRM) definitions. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PRM_H_ +#define PRM_H_ + +#include +#include + +#if defined(_MSC_VER) + #define PRM_EXPORT_API __declspec(dllexport) +#else + #define PRM_EXPORT_API +#endif + +#define PRM_HANDLER_NAME_MAXIMUM_LENGTH 128 + +#define PRM_STRING_(x) #x +#define PRM_STRING(x) PRM_STRING_(x) + +/** + A Platform Runtime Mechanism (PRM) handler function. + + @param[in] ParameterBuffer A pointer to a buffer with arbitrary data that is allocated and populated + by the PRM handler caller. + @param[in] ContextBuffer A pointer to a buffer with arbitrary data that is allocated in the firmware + boot environment. + + @retval EFI_STATUS The PRM handler executed successfully. + @retval Others An error occurred in the PRM handler. + +**/ +typedef +EFI_STATUS +(EFIAPI PRM_HANDLER) ( + IN VOID *ParameterBuffer OPTIONAL, + IN PRM_CONTEXT_BUFFER *ContextBuffer OPTIONAL + ); + +#endif diff --git a/PrmPkg/Include/PrmContextBuffer.h b/PrmPkg/Include/PrmContextBuffer.h new file mode 100644 index 0000000000..8f8144545e --- /dev/null +++ b/PrmPkg/Include/PrmContextBuffer.h @@ -0,0 +1,131 @@ +/** @file + + Definitions for the Platform Runtime Mechanism (PRM) context buffer structures. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PRM_CONTEXT_BUFFER_H_ +#define PRM_CONTEXT_BUFFER_H_ + +#include +#include +#include + +#define PRM_CONTEXT_BUFFER_SIGNATURE SIGNATURE_32('P','R','M','C') +#define PRM_CONTEXT_BUFFER_INTERFACE_VERSION 1 + +#pragma pack(push, 1) + +// +// This is the context buffer structure that is passed to a PRM handler. +// +// At OS runtime, the OS will allocate and populate this structure and +// place virtual addresses in the pointer fields. +// +// It is also reused internally in FW (in the PRM_MODULE_CONTEXT_BUFFERS structure) +// to track context buffers within a given PRM module. In that internal usage, +// the addresses will be physical addresses. +// +typedef struct { + /// + /// Signature of this interface. + /// + UINT32 Signature; + + /// + /// Version of this interface. + /// + UINT16 Version; + + /// + /// Reserved field. + /// + UINT16 Reserved; + + /// + /// The GUID of the PRM handler represented by this context instance. + /// + EFI_GUID HandlerGuid; + + /// + /// A virtual address pointer to the static data buffer allocated for + /// the PRM handler represented by this context instance. + /// + /// The static buffer is intended to be populated in the PRM module + /// configuration library and treated as read-only data at OS runtime. + /// + /// This pointer may be NULL if a static data buffer is not needed. + /// + PRM_DATA_BUFFER *StaticDataBuffer; + + /// + /// A virtual address pointer to an array of PRM_RUNTIME_MMIO_RANGE + /// structures that describe MMIO physical address ranges mapped to + /// virtual memory addresses for access at OS runtime. + /// + /// This pointer is ignored in firmware internal usage of this structure + /// as this field is present to allow a PRM handler to get the list + /// of MMIO ranges described as accessible by its PRM module. + /// + /// The module list of MMIO ranges is specified by the PRM configuration + /// code as a single array in PRM_MODULE_CONTEXT_BUFFERS. + /// + /// The OS is responsible for ensuring the pointer to the array in this + /// structure is converted to a virtual address during construction of + /// of the context buffer in the OS. + /// + /// This pointer may be NULL if runtime memory ranges are not needed. + /// + PRM_RUNTIME_MMIO_RANGES *RuntimeMmioRanges; +} PRM_CONTEXT_BUFFER; + +// +// A firmware internal data structure used to track context buffer and +// runtime MMIO range usage across a PRM module. +// +typedef struct +{ + /// + /// The GUID of the PRM module. + /// + EFI_GUID ModuleGuid; + + /// + /// The number of PRM context buffers in ContextBuffers[]. + /// This count should equal the number of PRM handlers in the module being configured. + /// + UINTN BufferCount; + + /// + /// A pointer to an array of PRM context buffers + /// + PRM_CONTEXT_BUFFER *Buffer; + + /// The MMIO ranges are defined in the firmware boot environment. + /// The addresses within the PRM_RUNTIME_MMIO_RANGES structure will + /// be converted to virtual addresses by firmware. + + /// + /// A physical address pointer to an array of PRM_RUNTIME_MMIO_RANGE + /// structures that describe memory ranges that need to be mapped to + /// virtual memory addresses for access at OS runtime. + /// + /// This is a consolidated array of MMIO ranges accessed by any PRM + /// handler in the PRM module at OS runtime. The MMIO range physical + /// addresses registered here will automatically be converted to the + /// corresponding virtual address in the structure by PRM infrastructure + /// code. No action is required to convert MMIO range base physical + /// addresses to virtual addresses by either the PRM configuration code + /// or the OS. + /// + /// This pointer may be NULL if runtime memory ranges are not needed. + /// + PRM_RUNTIME_MMIO_RANGES *RuntimeMmioRanges; +} PRM_MODULE_CONTEXT_BUFFERS; + +#pragma pack(pop) + +#endif diff --git a/PrmPkg/Include/PrmDataBuffer.h b/PrmPkg/Include/PrmDataBuffer.h new file mode 100644 index 0000000000..70d690ca54 --- /dev/null +++ b/PrmPkg/Include/PrmDataBuffer.h @@ -0,0 +1,50 @@ +/** @file + + Definitions for the Platform Runtime Mechanism (PRM) data buffer structures. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PRM_DATA_BUFFER_H_ +#define PRM_DATA_BUFFER_H_ + +#include + +#define PRM_DATA_BUFFER_HEADER_SIGNATURE SIGNATURE_32('P','R','M','D') + +#pragma pack(push, 1) + +/// +/// A generic header that describes the PRM data buffer. +/// +typedef struct { + /// + /// PRM Data Buffer signature. + /// + UINT32 Signature; + /// + /// Length of the entire data buffer, including the size of the header. + /// + UINT32 Length; +} PRM_DATA_BUFFER_HEADER; + +/// +/// A PRM data buffer is a generic header followed by variable length arbitrary data. +/// +typedef struct { + /// + /// The header is required at the beginning of every PRM data buffer. + /// + PRM_DATA_BUFFER_HEADER Header; + + /// + /// The beginning of data immediately follows the header. + /// + UINT8 Data[1]; +} PRM_DATA_BUFFER; + +#pragma pack(pop) + +#endif diff --git a/PrmPkg/Include/PrmExportDescriptor.h b/PrmPkg/Include/PrmExportDescriptor.h new file mode 100644 index 0000000000..95198cef65 --- /dev/null +++ b/PrmPkg/Include/PrmExportDescriptor.h @@ -0,0 +1,87 @@ +/** @file + + Definitions for the Platform Runtime Mechanism (PRM) export descriptor structures. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PRM_EXPORT_DESCRIPTOR_H_ +#define PRM_EXPORT_DESCRIPTOR_H_ + +#include + +#define PRM_MODULE_EXPORT_DESCRIPTOR_NAME PrmModuleExportDescriptor +#define PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE SIGNATURE_64 ('P', 'R', 'M', '_', 'M', 'E', 'D', 'T') +#define PRM_MODULE_EXPORT_REVISION 0x0 + +// +// Platform Runtime Mechanism (PRM) Export Descriptor Structures +// +#pragma pack(push, 1) + +typedef struct { + GUID PrmHandlerGuid; + CHAR8 PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH]; +} PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT; + +typedef struct { + UINT64 Signature; + UINT16 Revision; + UINT16 NumberPrmHandlers; + GUID ModuleGuid; + PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT PrmHandlerExportDescriptors[3]; +} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT; + +#pragma pack(pop) + +/** + A macro that declares a PRM Handler Export Descriptor for a PRM Handler. + + This macro is intended to be used once per PRM Handler to describe the handler when the + module description is defined. It should be provided as an argument to PRM_MODULE_EXPORT. + + @param Guid The GUID of the PRM Handler being exported. + + @param Name The name of the PRM Handler being exported. This string should exactly + match the function name. + +**/ +#define PRM_HANDLER_EXPORT_ENTRY(Guid, Name) \ + { \ + Guid, \ + PRM_STRING_(Name) \ + } \ + +/** + A macro that returns the count of the number of variable-length arguments given. + + @param VariableArgumentList A variable argument list of elements that will be included + in the return value of the list count. +**/ +#define VA_ARG_COUNT(...) (sizeof((PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT[]){__VA_ARGS__})/sizeof(PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT)) + +/** + A macro that declares the PRM Module Export Descriptor for a PRM Module. + + This macro is intended to be used once in a PRM Module after all of the PRM Handler definitions + to describe the PRM Handlers being exported in the module. + + @param PrmHandlerExportEntries A variable argument list of PRM_HANDLER_EXPORT_ENTRY values. + This list should include all PRM Handlers being exported by + this module. + +**/ +#define PRM_MODULE_EXPORT(...) \ + PRM_EXPORT_API PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT PRM_MODULE_EXPORT_DESCRIPTOR_NAME = { \ + { \ + PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE, \ + PRM_MODULE_EXPORT_REVISION, \ + VA_ARG_COUNT(__VA_ARGS__), \ + EFI_CALLER_ID_GUID \ + }, \ + { __VA_ARGS__ } \ + } \ + +#endif diff --git a/PrmPkg/Include/PrmMmio.h b/PrmPkg/Include/PrmMmio.h new file mode 100644 index 0000000000..fb216c27e8 --- /dev/null +++ b/PrmPkg/Include/PrmMmio.h @@ -0,0 +1,45 @@ +/** @file + + Definitions for the Platform Runtime Mechanism (PRM) MMIO elements. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PRM_MMIO_H_ +#define PRM_MMIO_H_ + +#include + +#pragma pack(push, 1) + +/// +/// Describes a memory range that needs to be made accessible at OS runtime. +/// +/// The memory range with the given base address and length will be marked as EFI_MEMORY_RUNTIME. +/// +typedef struct { + EFI_PHYSICAL_ADDRESS PhysicalBaseAddress; + EFI_PHYSICAL_ADDRESS VirtualBaseAddress; + UINT32 Length; +} PRM_RUNTIME_MMIO_RANGE; + +/// +/// Describes a buffer with an array of PRM module +/// config runtime memory ranges. +/// +typedef struct { + /// + /// The number of runtime memory range elements in this buffer. + /// + UINT64 Count; + /// + /// The beginning of the runtime memory range data. + /// + PRM_RUNTIME_MMIO_RANGE Range[1]; +} PRM_RUNTIME_MMIO_RANGES; + +#pragma pack(pop) + +#endif diff --git a/PrmPkg/Include/PrmModule.h b/PrmPkg/Include/PrmModule.h new file mode 100644 index 0000000000..f40fb42a2b --- /dev/null +++ b/PrmPkg/Include/PrmModule.h @@ -0,0 +1,68 @@ +/** @file + + Common definitions needed for Platform Runtime Mechanism (PRM) modules. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PRM_MODULE_H_ +#define PRM_MODULE_H_ + +#include +#include +#include +#include +#include +#include +#include + +/** + Macro that provides a condensed form of a PRM Handler. + + This macro can be used to define a PRM Handler that uses the standard PRM Handle + signature. It is simply provided for convenience. + +**/ +#define PRM_HANDLER_EXPORT(Name) \ + STATIC_ASSERT (sizeof (PRM_STRING_(Name)) <= PRM_HANDLER_NAME_MAXIMUM_LENGTH, "The PRM handler exceeds the maximum allowed size of 128."); \ + \ +/** \ + A Platform Runtime Mechanism (PRM) handler. \ + \ + @param[in] ParameterBuffer A pointer to the PRM handler parameter buffer \ + @param[in] ContextBUffer A pointer to the PRM handler context buffer \ + \ + @retval EFI_STATUS The PRM handler executed successfully. \ + @retval Others An error occurred in the PRM handler. \ + \ +**/ \ + EFI_STATUS \ + PRM_EXPORT_API \ + EFIAPI \ + Name ( \ + IN VOID *ParameterBuffer, \ + IN PRM_CONTEXT_BUFFER *ContextBuffer \ + ) \ + +/** + A macro that declares the PRM Module Update Lock Descriptor for a PRM Module. + + This macro is intended to be used once in a PRM Module so the module update lock descriptor is + exported for the module. + +**/ +#define PRM_MODULE_UPDATE_LOCK_EXPORT \ + PRM_EXPORT_API PRM_MODULE_UPDATE_LOCK_DESCRIPTOR PRM_MODULE_UPDATE_LOCK_DESCRIPTOR_NAME = { \ + PRM_MODULE_UPDATE_LOCK_DESCRIPTOR_SIGNATURE, \ + PRM_MODULE_UPDATE_LOCK_REVISION, \ + { 0 } \ + } \ + +// +// A PRM module is required to export the PRM Module Update Lock +// +PRM_MODULE_UPDATE_LOCK_EXPORT; + +#endif diff --git a/PrmPkg/Include/PrmModuleUpdate.h b/PrmPkg/Include/PrmModuleUpdate.h new file mode 100644 index 0000000000..fde97eff04 --- /dev/null +++ b/PrmPkg/Include/PrmModuleUpdate.h @@ -0,0 +1,46 @@ +/** @file + + Definition for the Platform Runtime Mechanism (PRM) module update structures. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PRM_MODULE_UPDATE_H_ +#define PRM_MODULE_UPDATE_H_ + +#include + +#define PRM_MODULE_UPDATE_LOCK_DESCRIPTOR_NAME PrmModuleUpdateLock +#define PRM_MODULE_UPDATE_LOCK_DESCRIPTOR_SIGNATURE SIGNATURE_64 ('P', 'R', 'M', '_', 'M', 'U', 'L', '_') +#define PRM_MODULE_UPDATE_LOCK_REVISION 0x0 + +#pragma pack(push, 1) + +/// +/// Maintains the PRM Module Update Lock state +/// +typedef union { + /// + /// Individual bit fields + /// + struct { + UINT8 Acquired : 1; ///< [0] - If 1 lock is acquired. If 0 lock is released. + UINT8 Reserved : 7; ///< [7:1] - Reserved + } Bits; + /// + /// All bit fields as an 8-bit value + /// + UINT8 Uint8; +} PRM_MODULE_UPDATE_LOCK; + +typedef struct { + UINT64 Signature; + UINT16 Revision; + PRM_MODULE_UPDATE_LOCK Lock; +} PRM_MODULE_UPDATE_LOCK_DESCRIPTOR; + +#pragma pack(pop) + +#endif diff --git a/PrmPkg/Include/PrmOsServices.h b/PrmPkg/Include/PrmOsServices.h new file mode 100644 index 0000000000..62dfa00187 --- /dev/null +++ b/PrmPkg/Include/PrmOsServices.h @@ -0,0 +1,45 @@ +/** @file + + Definitions for the Platform Runtime Mechanism (PRM) OS Services. + + Note: OS Services have been removed from POR. This file has been reduced to just debug print + OS Service for use during PRM enabling. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PRM_OS_SERVICES_H_ +#define PRM_OS_SERVICES_H_ + +#include + +typedef struct _PRM_OS_SERVICES PRM_OS_SERVICES; + +// +// PRM OS Services function signatures +// +typedef +VOID +(EFIAPI *PRM_OS_SERVICE_DEBUG_PRINT) ( + IN CONST CHAR8 *String + ); + +#pragma pack(push, 1) + +// +// PRM OS Services table +// +struct _PRM_OS_SERVICES { + // Structure information + UINT16 MajorVersion; + UINT16 MinorVersion; + + // OS Services + PRM_OS_SERVICE_DEBUG_PRINT DebugPrint; +}; + +#pragma pack(pop) + +#endif diff --git a/PrmPkg/PrmPkg.dec b/PrmPkg/PrmPkg.dec new file mode 100644 index 0000000000..ff681d423d --- /dev/null +++ b/PrmPkg/PrmPkg.dec @@ -0,0 +1,49 @@ +## @file PrmPkg.dec +# This package provides support for the Platform Runtime Mechanism (PRM). +# +# The following key elements of PRM are maintained in this package: +# +# 1. PRM interfaces - Comprised of interfaces shared with the operating system such as ACPI table structures +# in addition to internal firmware interfaces such as protocols and library interfaces. +# +# 2. PRM generic drivers - EDK II drivers that implement generic functionality such that a platform can quickly +# and reliably adopt PRM. +# +# 3. PRM module - An independently updatable PE/COFF binary that conforms to the unique requirements of a PRM module. +# PRM modules expose functions for operating system invocation referred to as PRM handlers. +# +# 4. PRM handler - A function in a PRM module. The function is identified through PRM interfaces in the OS by a GUID. +# +# Copyright (c) Microsoft Corporation
+## SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = PrmPkg + PACKAGE_UNI_FILE = PrmPkg.uni + PACKAGE_GUID = 3D22F66E-9090-46CE-B260-1836070AFA5E + PACKAGE_VERSION = 0.1 + +[Includes] + Include + +[Guids] + gPrmPkgTokenSpaceGuid = { 0x46f56acc, 0x600b, 0x450f, { 0xa5, 0x9c, 0x3a, 0x1a, 0x4a, 0xd4, 0x35, 0x3e }} + +[LibraryClasses] + ## @libraryclass Provides a general abstraction for PRM context buffer management + # + PrmContextBufferLib|Include/Library/PrmContextBufferLib.h + +[Protocols] + ## PRM Configuration Protocol + # + gPrmConfigProtocolGuid = { 0x4e5b4fea, 0x936a, 0x45bc, { 0xac, 0x6a, 0x2f, 0x8f, 0x14, 0xa6, 0xc2, 0x9e }} + +[PcdsFixedAtBuild] + ## Flash base address of a PRM firmware volume + gPrmPkgTokenSpaceGuid.PcdFlashFvPrmBase|0x00000000|UINT32|0x00000001 + + ## Size in bytes of a PRM firmware volume + gPrmPkgTokenSpaceGuid.PcdFlashFvPrmSize|0x00000000|UINT32|0x00000002 diff --git a/PrmPkg/PrmPkg.uni b/PrmPkg/PrmPkg.uni new file mode 100644 index 0000000000..3575b35052 --- /dev/null +++ b/PrmPkg/PrmPkg.uni @@ -0,0 +1,10 @@ +// /** @file +// +// Copyright (c) Microsoft Corporation +// SPDX-License-Identifier: BSD-2-Clause-Patent +// **/ + + +#string STR_PACKAGE_ABSTRACT #language en-US "This package provides support for the Platform Runtime Mechanism (PRM)." + +#string STR_PACKAGE_DESCRIPTION #language en-US "Provides infrastructure support code and sample PRM modules for PRM authors." -- 2.39.2