]> git.proxmox.com Git - mirror_edk2.git/blob - PrmPkg/Readme.md
Readme.md: Add initial content
[mirror_edk2.git] / PrmPkg / Readme.md
1 # **Platform Runtime Mechanism**
2
3 Platform Runtime Mechanism (PRM) introduces the capability of moving platform-specific code out of SMM and into a
4 code module that executes within the OS context. Moving this firmware to the OS context provides better transparency
5 and mitigates the negative system impact currently accompanied with SMM solutions. Futhermore, the PRM code is
6 packaged into modules with well-defined entry points, each representing a specific PRM functionality.
7
8 The `PrmPkg` maintained in this branch provides a single cohesive set of generic PRM functionality that is intended
9 to be leveraged by platform firmware with minimal overhead to integrate PRM functionality in the firmware.
10
11 ## **IMPORTANT NOTE**
12 > The code provided in this package and branch are for proof-of-concept purposes only. The code does not represent a
13 formal design and is not validated at product quality. The development of this feature is shared in the edk2-staging
14 branch to simplify collaboration by allowing direct code contributions and early feedback throughout its development.
15
16 ## How to Build PrmPkg
17 As noted earlier, resources in `PrmPkg` are intended to be referenced by a platform firmware so it can adopt support
18 for PRM. In that case, the platform firmware should add the `PrmConfigDxe` and `PrmLoaderDxe` drivers to its DSC and
19 FDF files so they are built in the platform firmware build and dispatched during its runtime. All that is left is to
20 add individual PRM modules to the DSC and FDF. These can be built from source or included as binaries into the platform
21 firmware flash map.
22
23 ### PrmPkg Standalone Build
24 **All changes to `PrmPkg` must not regress the standalone package build**. Any time a change is made to `PrmPkg`, the
25 package build must be tested. Since this is a forward looking package, to ease potential integration into the edk2
26 project in the future, the build is tested against the tip of the master branch in the [edk2](https://github.com/tianocore/edk2)
27 repository.
28
29 To build `PrmPkg` as a standalone package:
30 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)
31
32 2. Clone the *master* branch on the edk2 repository locally \
33 ``git clone https://github.com/tianocore/edk2.git``
34
35 3. Clone the *PlatformRuntimeMechanism* branch on the edk2-staging repository locally \
36 ``git clone -b PlatformRuntimeMechanism --single-branch https://github.com/tianocore/edk2-staging.git``
37 > __*Note*__: The *--single-branch* argument is recommended since edk2-staging hosts many branches for completely
38 unrelated features. If you are just interested in PRM, this will avoid fetching all of the other branches.
39
40 4. Change to the edk2 workspace directory \
41 ``cd edk2``
42
43 5. Run *edksetup* to set local environment variables needed for build
44 * Windows:
45 * ``edksetup.bat``
46 * Linux:
47 * If you have not already built BaseTools:
48 * ``make -C BaseTools``
49 * ``. edksetup.sh``
50
51 6. Set the PACKAGES_PATH environment variable to include the directory path that contains `PrmPkg`
52 * Windows example:
53 * ``set PACKAGES_PATH=c:\src\edk2-staging``
54
55 7. Change to the edk2-staging workspace directory
56 * Example: ``cd ../edk2-staging``
57
58 8. Build PrmPkg \
59 ``build -p PrmPkg/PrmPkg.dsc -a IA32 -a X64``
60 > __*Note*__: Due to the way PRM modules are compiled with exports, **only building on Visual Studio compiler tool
61 chains is currently supported**.
62
63 ### Build Flags
64 As PRM is a new feature at a proof-of-concept (POC) level of maturity, there's some changes to the normal build
65 available as build flags. By default, if no flags are specified, the build is done with the currently expected plan of
66 record (POR) configuration.
67
68 The following list are the currently defined build flags (if any) that may be passed to the `build` command
69 (e.g. -D FLAG=VALUE).
70
71 ## Overview
72 At a high-level, PRM can be viewed from three levels of granularity:
73
74 1. PRM interface - Encompassing the entirety of firmware functionalities and data provided to OS runtime. Most
75 information is provided through ACPI tables to be agnostic to a UEFI implementation.
76 2. PRM module - An independently updatable package of PRM handlers. The PRM interface will be composed of multiple
77 PRM modules. This requirement allows for the separation of OEM and IHV PRM code, each of which can be serviced
78 independently.
79 3. PRM handler - The implementation/callback of a single PRM functionality as identified by a GUID.
80
81 ## Firmware Design
82 The firmware has three key generic drivers to support PRM:
83
84 1. A PRM Loader driver - Functionality is split across three phases:
85 1. Discover - Find all PRM modules in the firmware image made available by the platform firmware author.
86 * This phase includes verifying authenticity/integrity of the image, the image executable type, the export
87 table is present and the PRM Export Module Descriptor is present and valid.
88 2. Process - Convert PRM handler GUID to name mappings in the PRM Module Export Descriptor to PRM handler Name
89 to physical address mappings required to construct the PRM ACPI table.
90 3. Publish - Publish the PRM ACPI table using the information from the Process phase.
91
92 2. A PRM Configuration driver - A generic driver responsible for processing PRM module configuration information
93 consumed through a `PRM_CONFIG_PROTOCOL` per PRM module instance. Therefore, the `PRM_CONFIG_PROTOCOL` serves
94 as the dynamic interface for this driver to process PRM module resources and prepare the module's data to be
95 configured properly for OS runtime.
96
97 3. A PRM Module - Not a single driver but a user written PE/COFF image that follows the PRM module authoring process.
98 A PRM module groups together cohesive sets of PRM functionality into functions referred to as "PRM handlers".
99
100 ## PrmPkg Code Organization
101 The package follows a standard EDK II style package format. The list below contains some notable areas to
102 explore in the package:
103
104 * [ACPI Table Definitions](PrmPkg/PrmLoaderDxe/PrmAcpiTable.h)
105 * [Common Interface Definitions](PrmPkg/Include)
106 * [PRM Config Driver](PrmPkg/PrmConfigDxe)
107 * [PRM Loader Driver](PrmPkg/PrmLoaderDxe)
108 * [Sample PRM Modules](PrmPkg/Samples)
109
110 While the package does provide sample PRM modules to be used as a reference, actual PRM modules should not be
111 maintained in PrmPkg. It is intended to only contain PRM infrastructure code and a few samples of how to use
112 that infrastructure. The PrmPkg is meant to be used as-is by firmware that supports PRM. Any shortcomings that
113 prevent the package from being used as-is should be addressed directly in PrmPkg.
114
115 ## PRM Module
116
117 By default, the EDK II implementation of UEFI does not allow images with the subsystem type
118 IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER to be built with exports. 
119
120 ```
121 ERROR - Linker #1294 from LINK : fatal exports and import libraries are not supported with /SUBSYSTEM:EFI_RUNTIME_DRIVER
122 ```
123 This can adjusted in the MSVC linker options.
124
125 __For the purposes of this POC__, the subsystem type is changed in the firmware build to allow the export table to be
126 added but the subsystem type in the final image is still 0xC (EFI Runtime Driver). This is important to allow the DXE
127 dispatcher to use its standard image verification and loading algorithms to load the image into permanent memory during
128 the DXE execution phase.
129
130 All firmware-loaded PRM modules are loaded into a memory buffer of type EfiRuntimeServicesCode. This means the
131 operating system must preserve all PRM handler code and the buffer will be reflected in the UEFI memory map. The
132 execution for invoking PRM handlers is the same as that required for UEFI Runtime Services, notably 4KiB or more of
133 available stack space must be provided and the stack must be 16-byte aligned. 
134
135 __*Note:*__ Long term it is possible to similarly load the modules into a EfiRuntimeServicesCode buffer and perform
136 relocation fixups with a new EFI module type for PRM if desired. It was simply not done since it is not essential
137 for this POC.
138
139 Where possible, PRM module information is stored and generated using industry compiler tool chains. This is a key
140 motivation behind using PE/COFF export tables to expose PRM module information and using a single PRM module binary
141 definition consistent between firmware and OS load.
142
143 ### PRM Module Exports
144 A PRM module must contain at least three exports: A PRM Module Export Descriptor, a PRM Module Update Lock Descriptor,
145 and at least one PRM handler. Here's an example of an export table from a PRM module that has a single PRM handler:
146
147 ```
148 0000000000005000: 00 00 00 00 FF FF FF FF 00 00 00 00 46 50 00 00 ....ÿÿÿÿ....FP..
149 0000000000005010: 01 00 00 00 03 00 00 00 03 00 00 00 28 50 00 00 ............(P..
150 0000000000005020: 34 50 00 00 40 50 00 00 78 13 00 00 30 40 00 00 4P..@P..x...0@..
151 0000000000005030: 20 40 00 00 67 50 00 00 86 50 00 00 A0 50 00 00 @..gP...P...P..
152 0000000000005040: 00 00 01 00 02 00 50 72 6D 53 61 6D 70 6C 65 43 ......PrmSampleC
153 0000000000005050: 6F 6E 74 65 78 74 42 75 66 66 65 72 4D 6F 64 75 ontextBufferModu
154 0000000000005060: 6C 65 2E 64 6C 6C 00 44 75 6D 70 53 74 61 74 69 le.dll.DumpStati
155 0000000000005070: 63 44 61 74 61 42 75 66 66 65 72 50 72 6D 48 61 cDataBufferPrmHa
156 0000000000005080: 6E 64 6C 65 72 00 50 72 6D 4D 6F 64 75 6C 65 45 ndler.PrmModuleE
157 0000000000005090: 78 70 6F 72 74 44 65 73 63 72 69 70 74 6F 72 00 xportDescriptor.
158 00000000000050A0: 50 72 6D 4D 6F 64 75 6C 65 55 70 64 61 74 65 4C PrmModuleUpdateL
159 00000000000050B0: 6F 63 6B 00 ock.
160
161 00000000 characteristics
162 FFFFFFFF time date stamp
163 0.10 version
164 1 ordinal base
165 3 number of functions
166 3 number of names
167
168 ordinal hint RVA name
169 1 0 00001378 DumpStaticDataBufferPrmHandler
170 2 1 00004030 PrmModuleExportDescriptor
171 3 2 00004020 PrmModuleUpdateLock
172 ```
173 ### PRM Image Format
174 PRM modules are ultimately PE/COFF images. However, when packaged in firmware the PE/COFF image is placed into a
175 Firmware File System (FFS) file. This is transparent to the operating system but done to better align with the typical
176 packaging of PE32(+) images managed in the firmware binary image. In the dump of the PRM FV binary image shown earlier,
177 the FFS sections placed by EDK II build tools ("DXE dependency", "User interface", "Version") that reside alongside the
178 PE/COFF binary are shown. A PRM module can be placed into a firmware image as a pre-built PE/COFF binary or built
179 during the firmware build process. In either case, the PE/COFF section is contained in a FFS file as shown in that
180 image.
181
182 ### PRM Module Implementation
183 To simplify building the PRM Module Export Descriptor, a PRM module implementation can use the following macros to mark
184 functions as PRM handlers. In this example, a PRM module registers three functions by name as PRM handlers with the
185 associated GUIDs.
186
187 ```
188 //
189 // Register the PRM export information for this PRM Module
190 //
191 PRM_MODULE_EXPORT (
192 PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_1_GUID, PrmHandler1),
193 PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_2_GUID, PrmHandler2),
194 PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_N_GUID, PrmHandlerN)
195 );
196 ```
197
198 `PRM_MODULE_EXPORT` take a variable-length argument list of `PRM_HANDLER_EXPORT_ENTRY` entries that each describe an
199 individual PRM handler being exported for the module. Ultimately, this information is used to define the structure
200 necessary to statically allocate the PRM Module Export Descriptor Structure (and its PRM Handler Export Descriptor
201 substructures) in the image.
202
203 Another required export for PRM modules is automatically provided in `PrmModule.h`, a header file that pulls together
204 all the includes needed to author a PRM module. This export is `PRM_MODULE_UPDATE_LOCK_EXPORT`. By including,
205 `PrmModule.h`, a PRM module has the `PRM_MODULE_UPDATE_LOCK_DESCRIPTOR` automatically exported.
206
207 ## PRM Handler Constraints
208 At this time, PRM handlers are restricted to a maximum identifier length of 128 characters. This is checked when using
209 the `PRM_HANDLER_EXPORT` macro by using a static assert that reports a violation at build-time.
210
211 PRM handlers are **not** allowed to use UEFI Runtime Services and should not rely upon any UEFI constructs. For the
212 purposes of this POC, this is currently not explicitly enforced but should be in the final changes.