From: "Michael Kubacki" <mikuback@linux.microsoft.com>
To: devel@edk2.groups.io
Cc: Andrew Fish <afish@apple.com>, Kang Gao <kang.gao@intel.com>,
Michael D Kinney <michael.d.kinney@intel.com>,
Michael Kubacki <michael.kubacki@microsoft.com>,
Leif Lindholm <leif@nuviainc.com>,
Benjamin You <benjamin.you@intel.com>,
Liu Yun <yun.y.liu@intel.com>,
Ankit Sinha <ankit.sinha@intel.com>,
Nate DeSimone <nathaniel.l.desimone@intel.com>
Subject: [PATCH v1 10/41] Readme.md: Add initial content
Date: Tue, 22 Mar 2022 12:19:16 -0400 [thread overview]
Message-ID: <20220322161947.9319-11-mikuback@linux.microsoft.com> (raw)
In-Reply-To: <20220322161947.9319-1-mikuback@linux.microsoft.com>
From: Michael Kubacki <michael.kubacki@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3812
Adds the following content to Readme.md:
1. A basic explanation of how the package is organized and where to
find important items.
2. Adds instructions for building PrmPkg with edk2.
3. Adds a "Build Flags" section to the build instructions to explain
any build flags that may be passed to influence the build.
The final package will not have any build flags. A reasonable
number are temporarily used to test different flows until final
decisions are made as to which flow to keep.
Most notably, only Visual Studio tool chains are currently
supported due to the modifications made to support export tables.
Cc: Andrew Fish <afish@apple.com>
Cc: Kang Gao <kang.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Michael Kubacki <michael.kubacki@microsoft.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Benjamin You <benjamin.you@intel.com>
Cc: Liu Yun <yun.y.liu@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
PrmPkg/Readme.md | 212 ++++++++++++++++++++
1 file changed, 212 insertions(+)
diff --git a/PrmPkg/Readme.md b/PrmPkg/Readme.md
new file mode 100644
index 000000000000..b67b3a391e37
--- /dev/null
+++ b/PrmPkg/Readme.md
@@ -0,0 +1,212 @@
+# **Platform Runtime Mechanism**
+
+Platform Runtime Mechanism (PRM) introduces the capability of moving platform-specific code out of SMM and into a
+code module that executes within the OS context. Moving this firmware to the OS context provides better transparency
+and mitigates the negative system impact currently accompanied with SMM solutions. Futhermore, the PRM code is
+packaged into modules with well-defined entry points, each representing a specific PRM functionality.
+
+The `PrmPkg` maintained in this branch provides a single cohesive set of generic PRM functionality that is intended
+to be leveraged by platform firmware with minimal overhead to integrate PRM functionality in the firmware.
+
+## **IMPORTANT NOTE**
+> The code provided in this package and branch are for proof-of-concept purposes only. The code does not represent a
+formal design and is not validated at product quality. The development of this feature is shared in the edk2-staging
+branch to simplify collaboration by allowing direct code contributions and early feedback throughout its development.
+
+## How to Build PrmPkg
+As noted earlier, resources in `PrmPkg` are intended to be referenced by a platform firmware so it can adopt support
+for PRM. In that case, the platform firmware should add the `PrmConfigDxe` and `PrmLoaderDxe` drivers to its DSC and
+FDF files so they are built in the platform firmware build and dispatched during its runtime. All that is left is to
+add individual PRM modules to the DSC and FDF. These can be built from source or included as binaries into the platform
+firmware flash map.
+
+### PrmPkg Standalone Build
+**All changes to `PrmPkg` must not regress the standalone package build**. Any time a change is made to `PrmPkg`, the
+package build must be tested. Since this is a forward looking package, to ease potential integration into the edk2
+project in the future, the build is tested against the tip of the master branch in the [edk2](https://github.com/tianocore/edk2)
+repository.
+
+To build `PrmPkg` as a standalone package:
+1. If new to EDK II, follow the directions in [Getting Started with EDK II](https://github.com/tianocore/tianocore.github.io/wiki/Getting-Started-with-EDK-II)
+
+2. Clone the *master* branch on the edk2 repository locally \
+ ``git clone https://github.com/tianocore/edk2.git``
+
+3. Clone the *PlatformRuntimeMechanism* branch on the edk2-staging repository locally \
+ ``git clone -b PlatformRuntimeMechanism --single-branch https://github.com/tianocore/edk2-staging.git``
+ > __*Note*__: The *--single-branch* argument is recommended since edk2-staging hosts many branches for completely
+ unrelated features. If you are just interested in PRM, this will avoid fetching all of the other branches.
+
+4. Change to the edk2 workspace directory \
+ ``cd edk2``
+
+5. Run *edksetup* to set local environment variables needed for build
+ * Windows:
+ * ``edksetup.bat``
+ * Linux:
+ * If you have not already built BaseTools:
+ * ``make -C BaseTools``
+ * ``. edksetup.sh``
+
+6. Set the PACKAGES_PATH environment variable to include the directory path that contains `PrmPkg`
+ * Windows example:
+ * ``set PACKAGES_PATH=c:\src\edk2-staging``
+
+7. Change to the edk2-staging workspace directory
+ * Example: ``cd ../edk2-staging``
+
+8. Build PrmPkg \
+ ``build -p PrmPkg/PrmPkg.dsc -a IA32 -a X64``
+ > __*Note*__: Due to the way PRM modules are compiled with exports, **only building on Visual Studio compiler tool
+ chains is currently supported**.
+
+### Build Flags
+As PRM is a new feature at a proof-of-concept (POC) level of maturity, there's some changes to the normal build
+available as build flags. By default, if no flags are specified, the build is done with the currently expected plan of
+record (POR) configuration.
+
+The following list are the currently defined build flags (if any) that may be passed to the `build` command
+(e.g. -D FLAG=VALUE).
+
+## Overview
+At a high-level, PRM can be viewed from three levels of granularity:
+
+1. PRM interface - Encompassing the entirety of firmware functionalities and data provided to OS runtime. Most
+ information is provided through ACPI tables to be agnostic to a UEFI implementation.
+2. PRM module - An independently updatable package of PRM handlers. The PRM interface will be composed of multiple
+ PRM modules. This requirement allows for the separation of OEM and IHV PRM code, each of which can be serviced
+ independently.
+3. PRM handler - The implementation/callback of a single PRM functionality as identified by a GUID.
+
+## Firmware Design
+The firmware has three key generic drivers to support PRM:
+
+1. A PRM Loader driver - Functionality is split across three phases:
+ 1. Discover - Find all PRM modules in the firmware image made available by the platform firmware author.
+ * This phase includes verifying authenticity/integrity of the image, the image executable type, the export
+ table is present and the PRM Export Module Descriptor is present and valid.
+ 2. Process - Convert PRM handler GUID to name mappings in the PRM Module Export Descriptor to PRM handler Name
+ to physical address mappings required to construct the PRM ACPI table.
+ 3. Publish - Publish the PRM ACPI table using the information from the Process phase.
+
+2. A PRM Configuration driver - A generic driver responsible for processing PRM module configuration information
+ consumed through a `PRM_CONFIG_PROTOCOL` per PRM module instance. Therefore, the `PRM_CONFIG_PROTOCOL` serves
+ as the dynamic interface for this driver to process PRM module resources and prepare the module's data to be
+ configured properly for OS runtime.
+
+3. A PRM Module - Not a single driver but a user written PE/COFF image that follows the PRM module authoring process.
+ A PRM module groups together cohesive sets of PRM functionality into functions referred to as "PRM handlers".
+
+## PrmPkg Code Organization
+The package follows a standard EDK II style package format. The list below contains some notable areas to
+explore in the package:
+
+* [ACPI Table Definitions](PrmPkg/PrmLoaderDxe/PrmAcpiTable.h)
+* [Common Interface Definitions](PrmPkg/Include)
+* [PRM Config Driver](PrmPkg/PrmConfigDxe)
+* [PRM Loader Driver](PrmPkg/PrmLoaderDxe)
+* [Sample PRM Modules](PrmPkg/Samples)
+
+While the package does provide sample PRM modules to be used as a reference, actual PRM modules should not be
+maintained in PrmPkg. It is intended to only contain PRM infrastructure code and a few samples of how to use
+that infrastructure. The PrmPkg is meant to be used as-is by firmware that supports PRM. Any shortcomings that
+prevent the package from being used as-is should be addressed directly in PrmPkg.
+
+## PRM Module
+
+By default, the EDK II implementation of UEFI does not allow images with the subsystem type
+IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER to be built with exports.
+
+```
+ERROR - Linker #1294 from LINK : fatal exports and import libraries are not supported with /SUBSYSTEM:EFI_RUNTIME_DRIVER
+```
+This can adjusted in the MSVC linker options.
+
+__For the purposes of this POC__, the subsystem type is changed in the firmware build to allow the export table to be
+added but the subsystem type in the final image is still 0xC (EFI Runtime Driver). This is important to allow the DXE
+dispatcher to use its standard image verification and loading algorithms to load the image into permanent memory during
+the DXE execution phase.
+
+All firmware-loaded PRM modules are loaded into a memory buffer of type EfiRuntimeServicesCode. This means the
+operating system must preserve all PRM handler code and the buffer will be reflected in the UEFI memory map. The
+execution for invoking PRM handlers is the same as that required for UEFI Runtime Services, notably 4KiB or more of
+available stack space must be provided and the stack must be 16-byte aligned.
+
+__*Note:*__ Long term it is possible to similarly load the modules into a EfiRuntimeServicesCode buffer and perform
+relocation fixups with a new EFI module type for PRM if desired. It was simply not done since it is not essential
+for this POC.
+
+Where possible, PRM module information is stored and generated using industry compiler tool chains. This is a key
+motivation behind using PE/COFF export tables to expose PRM module information and using a single PRM module binary
+definition consistent between firmware and OS load.
+
+### PRM Module Exports
+A PRM module must contain at least three exports: A PRM Module Export Descriptor, a PRM Module Update Lock Descriptor,
+and at least one PRM handler. Here's an example of an export table from a PRM module that has a single PRM handler:
+
+```
+ 0000000000005000: 00 00 00 00 FF FF FF FF 00 00 00 00 46 50 00 00 ....ÿÿÿÿ....FP..
+ 0000000000005010: 01 00 00 00 03 00 00 00 03 00 00 00 28 50 00 00 ............(P..
+ 0000000000005020: 34 50 00 00 40 50 00 00 78 13 00 00 30 40 00 00 4P..@P..x...0@..
+ 0000000000005030: 20 40 00 00 67 50 00 00 86 50 00 00 A0 50 00 00 @..gP...P...P..
+ 0000000000005040: 00 00 01 00 02 00 50 72 6D 53 61 6D 70 6C 65 43 ......PrmSampleC
+ 0000000000005050: 6F 6E 74 65 78 74 42 75 66 66 65 72 4D 6F 64 75 ontextBufferModu
+ 0000000000005060: 6C 65 2E 64 6C 6C 00 44 75 6D 70 53 74 61 74 69 le.dll.DumpStati
+ 0000000000005070: 63 44 61 74 61 42 75 66 66 65 72 50 72 6D 48 61 cDataBufferPrmHa
+ 0000000000005080: 6E 64 6C 65 72 00 50 72 6D 4D 6F 64 75 6C 65 45 ndler.PrmModuleE
+ 0000000000005090: 78 70 6F 72 74 44 65 73 63 72 69 70 74 6F 72 00 xportDescriptor.
+ 00000000000050A0: 50 72 6D 4D 6F 64 75 6C 65 55 70 64 61 74 65 4C PrmModuleUpdateL
+ 00000000000050B0: 6F 63 6B 00 ock.
+
+ 00000000 characteristics
+ FFFFFFFF time date stamp
+ 0.10 version
+ 1 ordinal base
+ 3 number of functions
+ 3 number of names
+
+ ordinal hint RVA name
+ 1 0 00001378 DumpStaticDataBufferPrmHandler
+ 2 1 00004030 PrmModuleExportDescriptor
+ 3 2 00004020 PrmModuleUpdateLock
+```
+### PRM Image Format
+PRM modules are ultimately PE/COFF images. However, when packaged in firmware the PE/COFF image is placed into a
+Firmware File System (FFS) file. This is transparent to the operating system but done to better align with the typical
+packaging of PE32(+) images managed in the firmware binary image. In the dump of the PRM FV binary image shown earlier,
+the FFS sections placed by EDK II build tools ("DXE dependency", "User interface", "Version") that reside alongside the
+PE/COFF binary are shown. A PRM module can be placed into a firmware image as a pre-built PE/COFF binary or built
+during the firmware build process. In either case, the PE/COFF section is contained in a FFS file as shown in that
+image.
+
+### PRM Module Implementation
+To simplify building the PRM Module Export Descriptor, a PRM module implementation can use the following macros to mark
+functions as PRM handlers. In this example, a PRM module registers three functions by name as PRM handlers with the
+associated GUIDs.
+
+```
+//
+// Register the PRM export information for this PRM Module
+//
+PRM_MODULE_EXPORT (
+ PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_1_GUID, PrmHandler1),
+ PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_2_GUID, PrmHandler2),
+ PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_N_GUID, PrmHandlerN)
+ );
+```
+
+`PRM_MODULE_EXPORT` take a variable-length argument list of `PRM_HANDLER_EXPORT_ENTRY` entries that each describe an
+individual PRM handler being exported for the module. Ultimately, this information is used to define the structure
+necessary to statically allocate the PRM Module Export Descriptor Structure (and its PRM Handler Export Descriptor
+substructures) in the image.
+
+Another required export for PRM modules is automatically provided in `PrmModule.h`, a header file that pulls together
+all the includes needed to author a PRM module. This export is `PRM_MODULE_UPDATE_LOCK_EXPORT`. By including,
+`PrmModule.h`, a PRM module has the `PRM_MODULE_UPDATE_LOCK_DESCRIPTOR` automatically exported.
+
+## PRM Handler Constraints
+At this time, PRM handlers are restricted to a maximum identifier length of 128 characters. This is checked when using
+the `PRM_HANDLER_EXPORT` macro by using a static assert that reports a violation at build-time.
+
+PRM handlers are **not** allowed to use UEFI Runtime Services and should not rely upon any UEFI constructs. For the
+purposes of this POC, this is currently not explicitly enforced but should be in the final changes.
--
2.28.0.windows.1
next prev parent reply other threads:[~2022-03-22 16:20 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 01/41] PrmPkg: Add package and include headers Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 02/41] PrmPkg: Add PrmConfig protocol interface Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 03/41] PrmPkg/PrmContextBufferLib: Add initial library instance Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 04/41] PrmPkg/PrmConfigDxe: Add initial driver Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 05/41] PrmPkg: Add initial PrmSamplePrintModule Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 06/41] PrmPkg: Add initial PrmSampleMemoryAllocationModule Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 07/41] PrmPkg: Add initial PrmSampleHardwareAccessModule Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 08/41] PrmPkg: Add initial PrmSampleContextBufferModule Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 09/41] PrmPkg: Add initial package DSC file Michael Kubacki
2022-03-22 16:19 ` Michael Kubacki [this message]
2022-03-22 16:19 ` [PATCH v1 11/41] PrmPkg: Add ALLOCATE_CONTEXT_BUFFER_IN_FW build option Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 12/41] PrmPkg: Enable variable growth for the PRM_MODULE_EXPORT macro Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 13/41] PrmPkg: Publish PRM operation region to support PRM ACPI _DSM invocation Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 14/41] PrmPkg: Export major/minor version in PRM module PE COFF header Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 15/41] PrmPkg: Add initial PrmSsdtInstallDxe module Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 16/41] PrmPkg: Remove PRM Module Update Lock Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 17/41] PrmPkg: Remove ALLOCATE_CONTEXT_BUFFER_IN_FW build flag Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 18/41] PrmPkg/PrmContextBuffer.h: Add ACPI parameter support structures Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 19/41] PrmPkg/PrmLoaderDxe: Add ACPI parameter buffer support Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 20/41] PrmPkg/PrmSampleContextBufferModule: Remove OS debug print requirement Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 21/41] PrmPkg/PrmSampleHardwareAccessModule: Add non-print PRM handlers Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 22/41] PrmPkg/SampleAcpiParameterBufferModule: Add initial module Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 23/41] PrmPkg/HardwareAccessModuleConfigLib: Add initial library Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 24/41] PrmPkg/Samples/Readme.md: Add initial file Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 25/41] PrmPkg: Refactor some PrmLoaderDxe functionality into libraries Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 26/41] PrmPkg/Application/PrmInfo: Add initial application Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 27/41] PrmPkg: Enforce stricter types Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 28/41] PrmPkg/Test/PrmPkgHostTest.dsc: Add initial file Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 29/41] PrmPkg/Test/UnitTest/Library: Add initial UEFI Boot Services test lib Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 30/41] PrmPkg/Library/DxePrmContextBufferLib: Add host-based unit tests Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 31/41] PrmPkg/DxePrmModuleDiscoveryLib: Add initial " Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 32/41] PrmPkg: Add PlatformGuid Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 33/41] PrmPkg: Update PRM OpRegion Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 34/41] Readme.md: Add iASL note and QEMU sample link Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 35/41] PrmPkg: Replace PcdPrmPlatformGuid with EDKII_DSC_PLATFORM_GUID Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 36/41] PrmPkg/Samples: Remove PrmSampleMemoryAllocationModule Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 37/41] PrmPkg/Samples: Remove PrmSamplePrintModule Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 38/41] PrmPkg: Remove the concept of OS services Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 39/41] Readme.md: Add a link to PRM Specification Michael Kubacki
2022-03-28 8:48 ` 回复: [edk2-devel] [PATCH v1 00/41] Add PrmPkg gaoliming
2022-03-28 14:05 ` Michael Kubacki
2022-03-29 16:28 ` Sinha, Ankit
2022-03-31 0:52 ` 回复: " gaoliming
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220322161947.9319-11-mikuback@linux.microsoft.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox