--- /dev/null
+# **Platform Runtime Mechanism**\r
+\r
+Platform Runtime Mechanism (PRM) introduces the capability of moving platform-specific code out of SMM and into a\r
+code module that executes within the OS context. Moving this firmware to the OS context provides better transparency\r
+and mitigates the negative system impact currently accompanied with SMM solutions. Futhermore, the PRM code is\r
+packaged into modules with well-defined entry points, each representing a specific PRM functionality.\r
+\r
+The `PrmPkg` maintained in this branch provides a single cohesive set of generic PRM functionality that is intended\r
+to be leveraged by platform firmware with minimal overhead to integrate PRM functionality in the firmware.\r
+\r
+## **IMPORTANT NOTE**\r
+> The code provided in this package and branch are for proof-of-concept purposes only. The code does not represent a\r
+formal design and is not validated at product quality. The development of this feature is shared in the edk2-staging\r
+branch to simplify collaboration by allowing direct code contributions and early feedback throughout its development.\r
+\r
+## How to Build PrmPkg\r
+As noted earlier, resources in `PrmPkg` are intended to be referenced by a platform firmware so it can adopt support\r
+for PRM. In that case, the platform firmware should add the `PrmConfigDxe` and `PrmLoaderDxe` drivers to its DSC and\r
+FDF files so they are built in the platform firmware build and dispatched during its runtime. All that is left is to\r
+add individual PRM modules to the DSC and FDF. These can be built from source or included as binaries into the platform\r
+firmware flash map.\r
+\r
+### PrmPkg Standalone Build\r
+**All changes to `PrmPkg` must not regress the standalone package build**. Any time a change is made to `PrmPkg`, the\r
+package build must be tested. Since this is a forward looking package, to ease potential integration into the edk2\r
+project in the future, the build is tested against the tip of the master branch in the [edk2](https://github.com/tianocore/edk2)\r
+repository.\r
+\r
+To build `PrmPkg` as a standalone package:\r
+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)\r
+\r
+2. Clone the *master* branch on the edk2 repository locally \\r
+ ``git clone https://github.com/tianocore/edk2.git``\r
+\r
+3. Clone the *PlatformRuntimeMechanism* branch on the edk2-staging repository locally \\r
+ ``git clone -b PlatformRuntimeMechanism --single-branch https://github.com/tianocore/edk2-staging.git``\r
+ > __*Note*__: The *--single-branch* argument is recommended since edk2-staging hosts many branches for completely\r
+ unrelated features. If you are just interested in PRM, this will avoid fetching all of the other branches.\r
+\r
+4. Change to the edk2 workspace directory \\r
+ ``cd edk2``\r
+\r
+5. Run *edksetup* to set local environment variables needed for build\r
+ * Windows:\r
+ * ``edksetup.bat``\r
+ * Linux:\r
+ * If you have not already built BaseTools:\r
+ * ``make -C BaseTools``\r
+ * ``. edksetup.sh``\r
+\r
+6. Set the PACKAGES_PATH environment variable to include the directory path that contains `PrmPkg`\r
+ * Windows example:\r
+ * ``set PACKAGES_PATH=c:\src\edk2-staging``\r
+\r
+7. Change to the edk2-staging workspace directory\r
+ * Example: ``cd ../edk2-staging``\r
+\r
+8. Build PrmPkg \\r
+ ``build -p PrmPkg/PrmPkg.dsc -a IA32 -a X64``\r
+ > __*Note*__: Due to the way PRM modules are compiled with exports, **only building on Visual Studio compiler tool\r
+ chains is currently supported**.\r
+\r
+### Build Flags\r
+As PRM is a new feature at a proof-of-concept (POC) level of maturity, there's some changes to the normal build\r
+available as build flags. By default, if no flags are specified, the build is done with the currently expected plan of\r
+record (POR) configuration.\r
+\r
+The following list are the currently defined build flags (if any) that may be passed to the `build` command\r
+(e.g. -D FLAG=VALUE).\r
+\r
+## Overview\r
+At a high-level, PRM can be viewed from three levels of granularity:\r
+\r
+1. PRM interface - Encompassing the entirety of firmware functionalities and data provided to OS runtime. Most\r
+ information is provided through ACPI tables to be agnostic to a UEFI implementation.\r
+2. PRM module - An independently updatable package of PRM handlers. The PRM interface will be composed of multiple\r
+ PRM modules. This requirement allows for the separation of OEM and IHV PRM code, each of which can be serviced\r
+ independently.\r
+3. PRM handler - The implementation/callback of a single PRM functionality as identified by a GUID.\r
+\r
+## Firmware Design\r
+The firmware has three key generic drivers to support PRM:\r
+\r
+1. A PRM Loader driver - Functionality is split across three phases:\r
+ 1. Discover - Find all PRM modules in the firmware image made available by the platform firmware author.\r
+ * This phase includes verifying authenticity/integrity of the image, the image executable type, the export\r
+ table is present and the PRM Export Module Descriptor is present and valid.\r
+ 2. Process - Convert PRM handler GUID to name mappings in the PRM Module Export Descriptor to PRM handler Name\r
+ to physical address mappings required to construct the PRM ACPI table.\r
+ 3. Publish - Publish the PRM ACPI table using the information from the Process phase.\r
+\r
+2. A PRM Configuration driver - A generic driver responsible for processing PRM module configuration information\r
+ consumed through a `PRM_CONFIG_PROTOCOL` per PRM module instance. Therefore, the `PRM_CONFIG_PROTOCOL` serves\r
+ as the dynamic interface for this driver to process PRM module resources and prepare the module's data to be\r
+ configured properly for OS runtime.\r
+\r
+3. A PRM Module - Not a single driver but a user written PE/COFF image that follows the PRM module authoring process.\r
+ A PRM module groups together cohesive sets of PRM functionality into functions referred to as "PRM handlers".\r
+\r
+## PrmPkg Code Organization\r
+The package follows a standard EDK II style package format. The list below contains some notable areas to\r
+explore in the package:\r
+\r
+* [ACPI Table Definitions](PrmPkg/PrmLoaderDxe/PrmAcpiTable.h)\r
+* [Common Interface Definitions](PrmPkg/Include)\r
+* [PRM Config Driver](PrmPkg/PrmConfigDxe)\r
+* [PRM Loader Driver](PrmPkg/PrmLoaderDxe)\r
+* [Sample PRM Modules](PrmPkg/Samples)\r
+\r
+While the package does provide sample PRM modules to be used as a reference, actual PRM modules should not be\r
+maintained in PrmPkg. It is intended to only contain PRM infrastructure code and a few samples of how to use\r
+that infrastructure. The PrmPkg is meant to be used as-is by firmware that supports PRM. Any shortcomings that\r
+prevent the package from being used as-is should be addressed directly in PrmPkg.\r
+\r
+## PRM Module\r
+\r
+By default, the EDK II implementation of UEFI does not allow images with the subsystem type\r
+IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER to be built with exports. \r
+\r
+```\r
+ERROR - Linker #1294 from LINK : fatal exports and import libraries are not supported with /SUBSYSTEM:EFI_RUNTIME_DRIVER\r
+```\r
+This can adjusted in the MSVC linker options.\r
+\r
+__For the purposes of this POC__, the subsystem type is changed in the firmware build to allow the export table to be\r
+added but the subsystem type in the final image is still 0xC (EFI Runtime Driver). This is important to allow the DXE\r
+dispatcher to use its standard image verification and loading algorithms to load the image into permanent memory during\r
+the DXE execution phase.\r
+\r
+All firmware-loaded PRM modules are loaded into a memory buffer of type EfiRuntimeServicesCode. This means the\r
+operating system must preserve all PRM handler code and the buffer will be reflected in the UEFI memory map. The\r
+execution for invoking PRM handlers is the same as that required for UEFI Runtime Services, notably 4KiB or more of\r
+available stack space must be provided and the stack must be 16-byte aligned. \r
+\r
+__*Note:*__ Long term it is possible to similarly load the modules into a EfiRuntimeServicesCode buffer and perform\r
+relocation fixups with a new EFI module type for PRM if desired. It was simply not done since it is not essential\r
+for this POC.\r
+\r
+Where possible, PRM module information is stored and generated using industry compiler tool chains. This is a key\r
+motivation behind using PE/COFF export tables to expose PRM module information and using a single PRM module binary\r
+definition consistent between firmware and OS load.\r
+\r
+### PRM Module Exports\r
+A PRM module must contain at least three exports: A PRM Module Export Descriptor, a PRM Module Update Lock Descriptor,\r
+and at least one PRM handler. Here's an example of an export table from a PRM module that has a single PRM handler:\r
+\r
+```\r
+ 0000000000005000: 00 00 00 00 FF FF FF FF 00 00 00 00 46 50 00 00 ....ÿÿÿÿ....FP..\r
+ 0000000000005010: 01 00 00 00 03 00 00 00 03 00 00 00 28 50 00 00 ............(P..\r
+ 0000000000005020: 34 50 00 00 40 50 00 00 78 13 00 00 30 40 00 00 4P..@P..x...0@..\r
+ 0000000000005030: 20 40 00 00 67 50 00 00 86 50 00 00 A0 50 00 00 @..gP...P...P..\r
+ 0000000000005040: 00 00 01 00 02 00 50 72 6D 53 61 6D 70 6C 65 43 ......PrmSampleC\r
+ 0000000000005050: 6F 6E 74 65 78 74 42 75 66 66 65 72 4D 6F 64 75 ontextBufferModu\r
+ 0000000000005060: 6C 65 2E 64 6C 6C 00 44 75 6D 70 53 74 61 74 69 le.dll.DumpStati\r
+ 0000000000005070: 63 44 61 74 61 42 75 66 66 65 72 50 72 6D 48 61 cDataBufferPrmHa\r
+ 0000000000005080: 6E 64 6C 65 72 00 50 72 6D 4D 6F 64 75 6C 65 45 ndler.PrmModuleE\r
+ 0000000000005090: 78 70 6F 72 74 44 65 73 63 72 69 70 74 6F 72 00 xportDescriptor.\r
+ 00000000000050A0: 50 72 6D 4D 6F 64 75 6C 65 55 70 64 61 74 65 4C PrmModuleUpdateL\r
+ 00000000000050B0: 6F 63 6B 00 ock.\r
+\r
+ 00000000 characteristics\r
+ FFFFFFFF time date stamp\r
+ 0.10 version\r
+ 1 ordinal base\r
+ 3 number of functions\r
+ 3 number of names\r
+\r
+ ordinal hint RVA name\r
+ 1 0 00001378 DumpStaticDataBufferPrmHandler\r
+ 2 1 00004030 PrmModuleExportDescriptor\r
+ 3 2 00004020 PrmModuleUpdateLock\r
+```\r
+### PRM Image Format\r
+PRM modules are ultimately PE/COFF images. However, when packaged in firmware the PE/COFF image is placed into a\r
+Firmware File System (FFS) file. This is transparent to the operating system but done to better align with the typical\r
+packaging of PE32(+) images managed in the firmware binary image. In the dump of the PRM FV binary image shown earlier,\r
+the FFS sections placed by EDK II build tools ("DXE dependency", "User interface", "Version") that reside alongside the\r
+PE/COFF binary are shown. A PRM module can be placed into a firmware image as a pre-built PE/COFF binary or built\r
+during the firmware build process. In either case, the PE/COFF section is contained in a FFS file as shown in that\r
+image.\r
+\r
+### PRM Module Implementation\r
+To simplify building the PRM Module Export Descriptor, a PRM module implementation can use the following macros to mark\r
+functions as PRM handlers. In this example, a PRM module registers three functions by name as PRM handlers with the\r
+associated GUIDs.\r
+\r
+```\r
+//\r
+// Register the PRM export information for this PRM Module\r
+//\r
+PRM_MODULE_EXPORT (\r
+ PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_1_GUID, PrmHandler1),\r
+ PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_2_GUID, PrmHandler2),\r
+ PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_N_GUID, PrmHandlerN)\r
+ );\r
+```\r
+\r
+`PRM_MODULE_EXPORT` take a variable-length argument list of `PRM_HANDLER_EXPORT_ENTRY` entries that each describe an\r
+individual PRM handler being exported for the module. Ultimately, this information is used to define the structure\r
+necessary to statically allocate the PRM Module Export Descriptor Structure (and its PRM Handler Export Descriptor\r
+substructures) in the image.\r
+\r
+Another required export for PRM modules is automatically provided in `PrmModule.h`, a header file that pulls together\r
+all the includes needed to author a PRM module. This export is `PRM_MODULE_UPDATE_LOCK_EXPORT`. By including,\r
+`PrmModule.h`, a PRM module has the `PRM_MODULE_UPDATE_LOCK_DESCRIPTOR` automatically exported.\r
+\r
+## PRM Handler Constraints\r
+At this time, PRM handlers are restricted to a maximum identifier length of 128 characters. This is checked when using\r
+the `PRM_HANDLER_EXPORT` macro by using a static assert that reports a violation at build-time.\r
+\r
+PRM handlers are **not** allowed to use UEFI Runtime Services and should not rely upon any UEFI constructs. For the\r
+purposes of this POC, this is currently not explicitly enforced but should be in the final changes.\r