VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/PrmPkg/Readme.md

Last change on this file was 108794, checked in by vboxsync, 4 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 15.2 KB
Line 
1# **Platform Runtime Mechanism**
2
3Platform Runtime Mechanism (PRM) introduces the capability of moving platform-specific code out of SMM and into a
4code module that executes within the OS context. Moving this firmware to the OS context provides better transparency
5and mitigates the negative system impact currently accompanied with SMM solutions. Futhermore, the PRM code is
6packaged into modules with well-defined entry points, each representing a specific PRM functionality.
7
8For more details on PRM, refer to the [Platform Runtime Mechanism Specification on uefi.org](https://uefi.org/sites/default/files/resources/Platform%20Runtime%20Mechanism%20-%20with%20legal%20notice.pdf).
9
10The `PrmPkg` maintained in this branch provides a single cohesive set of generic PRM functionality that is intended
11to be leveraged by platform firmware with minimal overhead to integrate PRM functionality in the firmware.
12
13> By default, the build makes use of a new ACPI OperationRegion type specifically introduced for PRM called
14`PlatformRtMechanism`. Support for this OperationRegion is planned for the next release of the ACPI specification.
15However, support for `PlatformRtMechanism` is already included in the iASL Compiler/Disassembler for early prototyping
16(i.e. this package). If you would like the default build to work and/or to use PRM handlers that are invoked
17through ACPI, iASL compiler [20200528](https://www.intel.com/content/www/us/en/download/774849/774861/acpi-component-architecture-downloads-previous-releases-2020.html)
18or greater must be used. If you are only interested in compiling the code and/or using direct call style PRM
19handlers, you can simply remove `PrmSsdtInstallDxe` from `PrmPkg.dsc`.
20
21The changes in the ACPI Specification include two elements:
22
231. `BIT20` in Platform-Wide _OSC Capabilities DWORD2 will be used by an OS to indicate support for PRM
242. A new Operation Region Address Space Identifier Value is defined as `0xB` for `PlatformRtMechanism`
25
26## How to Build PrmPkg
27
28As noted earlier, resources in `PrmPkg` are intended to be referenced by a platform firmware so it can adopt support
29for PRM. In that case, the platform firmware should add the `PrmConfigDxe` and `PrmLoaderDxe` drivers to its DSC and
30FDF files so they are built in the platform firmware build and dispatched during its runtime. All that is left is to
31add individual PRM modules to the DSC and FDF. These can be built from source or included as binaries into the platform
32firmware flash map.
33
34### PrmPkg Standalone Build
35
36To build `PrmPkg` as a standalone package:
37
381. 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)
39
402. Clone the *master* branch on the edk2 repository locally \
41 ``git clone https://github.com/tianocore/edk2.git``
42
433. Change to the edk2 workspace directory \
44 ``cd edk2``
45
464. Run *edksetup* to set local environment variables needed for build
47 * Windows:
48 * ``edksetup.bat``
49 * Linux:
50 * If you have not already built BaseTools:
51 * ``make -C BaseTools``
52 * ``. edksetup.sh``
53
545. Build PrmPkg \
55
56The PrmPkg can be built targeting the X64 and AArch64 architectures. PRM is not supported on IA32 and ARM primarily
57because the OS support for PRM is only in 64 bit OSes. In addition, the MSVC toolchain does not support export tables
58on IA32 with the unique UEFI configuration required.
59
60* X64
61
62 ``build -p PrmPkg/PrmPkg.dsc -a X64``
63 > ***Note***: Due to the way PRM modules are compiled with exports, **only building on Visual Studio compiler tool
64 chains has been tested**.
65
66> ***Note***: \
67> This package has been used without modification in several environments including client, server,
68> and virtual systems.
69>
70> You can add your own PRM modules into the build and check them with the `PrmInfo` UEFI application described
71> later in this document and dump the PRMT table in the OS to check if your PRM module is represented as expected.
72
73* AArch64
74 ``build -p PrmPkg/PrmPkg.dsc -a AARCH64 -t GCC5``
75
76 > ***Note***: Only builds with the GCC5 toolchain have been tested.
77 > ***Note***: For builds with the GCC5 toolchain, the PrmModuleExportDescriptor and any other handler entry points
78 symbols, to be listed in the PRMT, must be explicitly preserved by enumerating these in the AARCH64 linker flags.
79 The --require-defined linker flag must be used for each symbol to be preserved.
80
81### PRM Platform GUID
82
83**IMPORTANT** PRM has a concept of a "Platform GUID" which associates a specific platform with a set of PRM modules
84built for that platform. This GUID is used to ensure system compatibility for a given collection of PRM modules.
85
86Therefore, each PRM module must only target a single platform and each platform must have a unique GUID. Even if a
87PRM module is unchanged between two different platforms now, there is no guarantee that will remain the case so always
88assign a unique Platform GUID for each platform.
89
90The PRM Platform GUID is primarily used during PRM module runtime updates in the OS to ensure that the Platform GUID
91in the system's ACPI table (PRMT) matches the Platform GUID of the module requested for update. Even if runtime
92updates are not a planned feature for a given platform, still assign a unique Platform GUID for binary module
93identification (the Platform GUID is in the module's export descriptor) and to ensure such updates can be seamlessly
94supported in the future if needed.
95
96In the `PrmPkg` implementation, the Platform GUID is automatically derived from the PLATFORM_GUID in the DSC file of
97the package being built.
98
99### Build Output
100
101Like a typical EDK II package, the PrmPkg binary build output can be found in the Build directory in the edk2
102workspace. The organization in that directory follows the same layout as other EDK II packages.
103
104For example, that path to PRM module sample binaries for a DEBUG VS2022 X64 build is: \
105``edk2/Build/Prm/DEBUG_VS2022/X64/PrmPkg/Samples``
106
107## Overview
108
109At a high-level, PRM can be viewed from three levels of granularity:
110
1111. `PRM interface` - Encompassing the entirety of firmware functionalities and data provided to OS runtime. Most
112 information is provided through ACPI tables to be agnostic to a UEFI implementation.
1132. `PRM module` - An independently updatable package of PRM handlers. The PRM interface will be composed of multiple
114 PRM modules. This requirement allows for the separation of OEM and IHV PRM code, each of which can be serviced
115 independently.
1163. `PRM handler` - The implementation/callback of a single PRM functionality as identified by a GUID.
117
118## Firmware Design
119
120The firmware has three key generic drivers to support PRM:
121
1221. A `PRM Loader driver` - Functionality is split across three phases:
123 1. Discover - Find all PRM modules in the firmware image made available by the platform firmware author.
124 * This phase includes verifying authenticity/integrity of the image, the image executable type, the export
125 table is present and the PRM Export Module Descriptor is present and valid.
126 2. Process - Convert PRM handler GUID to name mappings in the PRM Module Export Descriptor to PRM handler Name
127 to physical address mappings required to construct the PRM ACPI table.
128 3. Publish - Publish the PRM ACPI table using the information from the Process phase.
129
1302. A `PRM Configuration driver` - A generic driver responsible for processing PRM module configuration information
131 consumed through a `PRM_CONFIG_PROTOCOL` per PRM module instance. Therefore, the `PRM_CONFIG_PROTOCOL` serves
132 as the dynamic interface for this driver to process PRM module resources and prepare the module's data to be
133 configured properly for OS runtime.
134
1353. A `PRM Module` - Not a single driver but a user written PE/COFF image that follows the PRM module authoring process.
136 A PRM module groups together cohesive sets of PRM functionality into functions referred to as "PRM handlers".
137
138## PrmPkg Code Organization
139
140The package follows a standard EDK II style package format. The list below contains some notable areas to
141explore in the package:
142
143* [ACPI Table Definitions](PrmPkg/PrmLoaderDxe/PrmAcpiTable.h)
144* [Common Interface Definitions](PrmPkg/Include)
145* [PRM Config Driver](PrmPkg/PrmConfigDxe)
146* [PRM Loader Driver](PrmPkg/PrmLoaderDxe)
147* [Sample PRM Modules](PrmPkg/Samples)
148
149While the package does provide sample PRM modules to be used as a reference, actual PRM modules should not be
150maintained in PrmPkg. It is intended to only contain PRM infrastructure code and a few samples of how to use
151that infrastructure. The PrmPkg is meant to be used as-is by firmware that supports PRM. Any shortcomings that
152prevent the package from being used as-is should be addressed directly in PrmPkg.
153
154## PRM Information UEFI Application
155
156A UEFI application is provided in this package called `PrmInfo` that allows a user to display and test PRM
157modules on their system.
158
159[Link to application source code](PrmPkg/Application/PrmInfo).
160
161This application is intended to be helpful during PRM enabling by allowing the user to:
162
163 1. Confirm that their firmware port of the PRM infrastructure implemented in this package is functioning correctly.
164 2. Quickly get information about what PRM modules and handlers that are present on a given system.
165 3. Quickly test PRM handlers without booting into a full operating system.
166 4. Develop and exercise PRM handlers prior to the availability of an operating system that is PRM aware.
167
168Execute the application help command for detailed usage instructions and examples of how to use the application: \
169 ``PrmInfo -?``
170
171*Example Usage:*
172
173![PrmInfo Usage Example](https://raw.githubusercontent.com/tianocore/edk2-staging/PlatformRuntimeMechanism/PrmPkg/Application/PrmInfo/PrmInfo_Usage_Example.gif)
174
175## PRM Module
176
177> ***Note***: You can find simple examples of PRM modules in the Samples directory of this package.
178> [Samples/Readme.md](PrmPkg/Samples/Readme.md) has more information.
179
180By default, the EDK II implementation of UEFI does not allow images with the subsystem type
181`IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER` to be built with exports.
182
183```txt
184ERROR - Linker #1294 from LINK : fatal exports and import libraries are not supported with /SUBSYSTEM:EFI_RUNTIME_DRIVER
185```
186
187This can adjusted in the MSVC linker options.
188
189The subsystem type is changed in the firmware build to allow the export table to be added but the subsystem type in the
190final image is still `0xC` (`EFI Runtime Driver`). This is important to allow the DXE dispatcher to use its standard
191image verification and loading algorithms to load the image into permanent memory during the DXE execution phase.
192
193All firmware-loaded PRM modules are loaded into a memory buffer of type `EfiRuntimeServicesCode`. This means the
194operating system must preserve all PRM handler code and the buffer will be reflected in the UEFI memory map. The
195execution for invoking PRM handlers is the same as that required for UEFI Runtime Services, notably 4KiB or more of
196available stack space must be provided and the stack must be 16-byte aligned.
197
198***Note:*** Long term it is possible to similarly load the modules into a `EfiRuntimeServicesCode` buffer and perform
199relocation fixups with a new EFI module type for PRM if desired. It was simply not done since it is not essential
200for this POC.
201
202Where possible, PRM module information is stored and generated using industry compiler tool chains. This is a key
203motivation behind using PE/COFF export tables to expose PRM module information and using a single PRM module binary
204definition consistent between firmware and OS load.
205
206### PRM Module Exports
207
208A PRM module must contain at least two exports: A PRM Module Export Descriptor and at least one PRM handler. Here's
209an example of an export table from a PRM module that has a single PRM handler:
210
211```txt
212 0000000000005000: 00 00 00 00 FF FF FF FF 00 00 00 00 3C 50 00 00 ............<P..
213 0000000000005010: 01 00 00 00 02 00 00 00 02 00 00 00 28 50 00 00 ............(P..
214 0000000000005020: 30 50 00 00 38 50 00 00 78 13 00 00 20 40 00 00 0P..8P..x... @..
215 0000000000005030: 5D 50 00 00 7C 50 00 00 00 00 01 00 50 72 6D 53 ]P..|P......PrmS
216 0000000000005040: 61 6D 70 6C 65 43 6F 6E 74 65 78 74 42 75 66 66 ampleContextBuff
217 0000000000005050: 65 72 4D 6F 64 75 6C 65 2E 64 6C 6C 00 44 75 6D erModule.dll.Dum
218 0000000000005060: 70 53 74 61 74 69 63 44 61 74 61 42 75 66 66 65 pStaticDataBuffe
219 0000000000005070: 72 50 72 6D 48 61 6E 64 6C 65 72 00 50 72 6D 4D rPrmHandler.PrmM
220 0000000000005080: 6F 64 75 6C 65 45 78 70 6F 72 74 44 65 73 63 72 oduleExportDescr
221 0000000000005090: 69 70 74 6F 72 00 iptor.
222
223 00000000 characteristics
224 FFFFFFFF time date stamp
225 0.00 version
226 1 ordinal base
227 2 number of functions
228 2 number of names
229
230 ordinal hint RVA name
231
232 1 0 00001378 DumpStaticDataBufferPrmHandler
233 2 1 00004020 PrmModuleExportDescriptor
234
235```
236
237### PRM Image Format
238
239PRM modules are ultimately PE/COFF images. However, when packaged in firmware the PE/COFF image is placed into a
240Firmware File System (FFS) file. This is transparent to the operating system but done to better align with the typical
241packaging of PE32(+) images managed in the firmware binary image. In the dump of the PRM FV binary image shown earlier,
242the FFS sections placed by EDK II build tools ("DXE dependency", "User interface", "Version") that reside alongside the
243PE/COFF binary are shown. A PRM module can be placed into a firmware image as a pre-built PE/COFF binary or built
244during the firmware build process. In either case, the PE/COFF section is contained in a FFS file as shown in that
245image.
246
247### PRM Module Implementation
248
249To simplify building the PRM Module Export Descriptor, a PRM module implementation can use the following macros to mark
250functions as PRM handlers. In this example, a PRM module registers three functions by name as PRM handlers with the
251associated GUIDs.
252
253```c
254//
255// Register the PRM export information for this PRM Module
256//
257PRM_MODULE_EXPORT (
258 PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_1_GUID, PrmHandler1),
259 PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_2_GUID, PrmHandler2),
260 PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_N_GUID, PrmHandlerN)
261 );
262```
263
264`PRM_MODULE_EXPORT` take a variable-length argument list of `PRM_HANDLER_EXPORT_ENTRY` entries that each describe an
265individual PRM handler being exported for the module. Ultimately, this information is used to define the structure
266necessary to statically allocate the PRM Module Export Descriptor Structure (and its PRM Handler Export Descriptor
267substructures) in the image.
268
269Another required export for PRM modules is automatically provided in `PrmModule.h`, a header file that pulls together
270all the includes needed to author a PRM module. This export is `PRM_MODULE_UPDATE_LOCK_EXPORT`. By including,
271`PrmModule.h`, a PRM module has the `PRM_MODULE_UPDATE_LOCK_DESCRIPTOR` automatically exported.
272
273## PRM Handler Constraints
274
275At this time, PRM handlers are restricted to a maximum identifier length of 128 characters. This is checked when using
276the `PRM_HANDLER_EXPORT` macro by using a static assert that reports a violation at build-time.
277
278PRM handlers are **not** allowed to use UEFI Runtime Services and should not rely upon any UEFI constructs. For the
279purposes of this POC, this is currently not explicitly enforced but should be in the final changes.
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette