* [PATCH v1 00/41] Add PrmPkg
@ 2022-03-22 16:19 Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 01/41] PrmPkg: Add package and include headers Michael Kubacki
` (40 more replies)
0 siblings, 41 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
This patch series adds a new package called PrmPkg. An RFC was sent
to the edk2 mailing list on January 28, 2022 detailing the proposal,
see https://edk2.groups.io/g/devel/message/86181.
Platform Runtime Mechanism (PRM) is a new firmware solution that has
been developed in edk2-staging/PlatformRuntimeMechanism.
This patch series has been organized to greatly condense the history
from the edk2-staging branch but to preserve important decisions and
changes in history that help establish context of changes and will
serve as valuable references for future development.
Interest in PRM has increased across various vendors and we believe
it is beneficial to make the source code more widely available for
the following reasons:
1. PRM specification adoption
2. Feature completeness
3. Overall validation coverage
4. Interest from the community and future collaboration
The technical details of PRM are covered in the PRM Specification
in addition to the Readme.md file located in the root of PrmPkg
in this patch series.
1. PRM specification adoption
Intel and Microsoft have worked together to standardize PRM in the
ACPI Specification and the PRM Specification hosted on uefi.org.
* ACPI 6.4 Specification:
https://uefi.org/node/4149
* PRM Specification:
https://uefi.org/sites/default/files/resources/Platform%20Runtime%20Mechanism%20-%20with%20legal%20notice.pdf
2. Feature completeness
PrmPkg implements the full firmware functionality described in the
PRM Specification and there are no significant changes to
functionality planned at this time.
Though we are very much interested in evolving PRM based on
feedback.
3. Overall validation coverage
PrmPkg has been integrated and tested on client and server systems
in addition to virtual platforms (OvmfPkg/QEMU).
Platform integration is simple and a demonstration of this
integration for OvmfPkg is available in the following branch:
https://github.com/makubacki/edk2/tree/ovmf_prmpkg_integration
The code has been built with:
* MSFT VS2015, VS2017, and VS2019
* GCC5 (see https://bugzilla.tianocore.org/show_bug.cgi?id=3802)
* iASL compiler (20200528 - https://acpica.org/node/181)
The Linux kernel currently includes the following PRM support:
* _OSC PRM bit - allows FW to know determine the OS is
PRM-capable and can redirect _DSM method from alternate
triggers (such as SMI) to PRM.
* PRM invocation via _DSM, includes PRM module and handler parsing
from ACPI PRMT table, and also the PRM operation region handler
for runtime PRM service invocation.
* An OS configuration for PRM enabling, PRM support can be
disabled during OS image build.
Note that upstream Linux does not currently support the following:
* Ability for the OS driver to call a PRM handler directly,
it has to be via ACPI _DSM.
* Run time update PRM module and handler via PE/COFF PRM image.
This commit provides additional context of the changes in Linux:
https://github.com/torvalds/linux/commit/cefc7ca46235f01d5233e3abd4b79452af01d9e9
Windows 11 (https://www.microsoft.com/software-download/windows11)
and Windows Server 2022 (https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk)
include the PRM functionality noted above in addition to PRM direct
call and PRM runtime updates.
PRM has been tested on IA32, X64, and AARCH64 targets.
4. Interest from the community and future collaboration
PRM has been presented at several industry conferences:
* OSFC 2020 - "PRM: SMM Goes on a Diet"
https://cfp.osfc.io/osfc2020/talk/MCJASB/
* OCP Summit 2019 - "Case Study Alternatives for SMM Usage in
Intel Platforms"
https://www.youtube.com/watch?v=mu3DRLM1dPA
In addition, Microsoft plans to publish the Windows PRM driver
interface and a WDF sample driver that uses the interface to the
Windows Driver Samples GitHub repository
(https://github.com/microsoft/Windows-driver-samples).
We believe a PrmPkg in edk2 can increase accessibility to PRM and
ease collaboration.
PrmPkg
------
PrmPkg contains the common functionality needed to enable PRM on
any system. It does not contain platform-specific code such as PRM
modules (and by extension PRM handlers). Other than sample modules,
PrmPkg will only contain code needed to provide PRM feature
functionality as defined in the PRM Specification.
PrmPkg is scoped to continue to only contain platform-agnostic
functionality in the future.
The proposed maintainers of PrmPkg are:
* Michael Kubacki <mikuback@linux.microsoft.com>
* Nate DeSimone <nathaniel.l.desimone@intel.com>
The proposed reviewers of PrmPkg are:
* Ankit Sinha <ankit.sinha@intel.com>
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>
Liu (2):
PrmPkg: Publish PRM operation region to support PRM ACPI _DSM
invocation
PrmPkg: Export major/minor version in PRM module PE COFF header
Liu Yun Y (1):
PrmPkg: Update PRM OpRegion
Michael Kubacki (38):
PrmPkg: Add package and include headers
PrmPkg: Add PrmConfig protocol interface
PrmPkg/PrmContextBufferLib: Add initial library instance
PrmPkg/PrmConfigDxe: Add initial driver
PrmPkg: Add initial PrmSamplePrintModule
PrmPkg: Add initial PrmSampleMemoryAllocationModule
PrmPkg: Add initial PrmSampleHardwareAccessModule
PrmPkg: Add initial PrmSampleContextBufferModule
PrmPkg: Add initial package DSC file
Readme.md: Add initial content
PrmPkg: Add ALLOCATE_CONTEXT_BUFFER_IN_FW build option
PrmPkg: Enable variable growth for the PRM_MODULE_EXPORT macro
PrmPkg: Add initial PrmSsdtInstallDxe module
PrmPkg: Remove PRM Module Update Lock
PrmPkg: Remove ALLOCATE_CONTEXT_BUFFER_IN_FW build flag
PrmPkg/PrmContextBuffer.h: Add ACPI parameter support structures
PrmPkg/PrmLoaderDxe: Add ACPI parameter buffer support
PrmPkg/PrmSampleContextBufferModule: Remove OS debug print requirement
PrmPkg/PrmSampleHardwareAccessModule: Add non-print PRM handlers
PrmPkg/SampleAcpiParameterBufferModule: Add initial module
PrmPkg/HardwareAccessModuleConfigLib: Add initial library
PrmPkg/Samples/Readme.md: Add initial file
PrmPkg: Refactor some PrmLoaderDxe functionality into libraries
PrmPkg/Application/PrmInfo: Add initial application
PrmPkg: Enforce stricter types
PrmPkg/Test/PrmPkgHostTest.dsc: Add initial file
PrmPkg/Test/UnitTest/Library: Add initial UEFI Boot Services test lib
PrmPkg/Library/DxePrmContextBufferLib: Add host-based unit tests
PrmPkg/DxePrmModuleDiscoveryLib: Add initial host-based unit tests
PrmPkg: Add PlatformGuid
Readme.md: Add iASL note and QEMU sample link
PrmPkg: Replace PcdPrmPlatformGuid with EDKII_DSC_PLATFORM_GUID
PrmPkg/Samples: Remove PrmSampleMemoryAllocationModule
PrmPkg/Samples: Remove PrmSamplePrintModule
PrmPkg: Remove the concept of OS services
Readme.md: Add a link to PRM Specification
PrmPkg: Changes for edk2 repo transition
PrmPkg: Apply uncrustify changes
PrmPkg/Application/PrmInfo/PrmInfo.c | 732 +++++++++
PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c | 199 +++
PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTest.c | 649 ++++++++
PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c | 386 +++++
PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTest.c | 210 +++
PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c | 417 +++++
PrmPkg/PrmConfigDxe/PrmConfigDxe.c | 512 ++++++
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c | 377 +++++
PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c | 110 ++
PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.c | 127 ++
PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.c | 78 +
PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c | 218 +++
PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.c | 84 +
PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c | 108 ++
PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c | 335 ++++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.c | 119 ++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestEventTimer.c | 180 +++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestImage.c | 163 ++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMemory.c | 145 ++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMisc.c | 198 +++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.c | 1650 ++++++++++++++++++++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestTpl.c | 43 +
.azurepipelines/templates/pr-gate-build-job.yml | 2 +-
.pytool/CISettings.py | 1 +
Maintainers.txt | 8 +
PrmPkg/Application/PrmInfo/PrmInfo.h | 49 +
PrmPkg/Application/PrmInfo/PrmInfo.inf | 66 +
PrmPkg/Application/PrmInfo/PrmInfo.uni | 11 +
PrmPkg/Application/PrmInfo/PrmInfoExtra.uni | 12 +
PrmPkg/Application/PrmInfo/PrmInfoStrings.uni | 132 ++
PrmPkg/Include/Library/PrmContextBufferLib.h | 99 ++
PrmPkg/Include/Library/PrmModuleDiscoveryLib.h | 60 +
PrmPkg/Include/Library/PrmPeCoffLib.h | 111 ++
PrmPkg/Include/Prm.h | 46 +
PrmPkg/Include/PrmContextBuffer.h | 171 ++
PrmPkg/Include/PrmDataBuffer.h | 50 +
PrmPkg/Include/PrmExportDescriptor.h | 109 ++
PrmPkg/Include/PrmMmio.h | 45 +
PrmPkg/Include/PrmModule.h | 47 +
PrmPkg/Include/PrmModuleImageContext.h | 28 +
PrmPkg/Include/Protocol/PrmConfig.h | 31 +
PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf | 35 +
PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf | 46 +
PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf | 41 +
PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h | 39 +
PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf | 39 +
PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf | 32 +
PrmPkg/PrmConfigDxe/PrmConfigDxe.inf | 48 +
PrmPkg/PrmLoaderDxe/PrmAcpiTable.h | 96 ++
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf | 61 +
PrmPkg/PrmPkg.ci.yaml | 110 ++
PrmPkg/PrmPkg.dec | 67 +
PrmPkg/PrmPkg.dsc | 142 ++
PrmPkg/PrmPkg.uni | 10 +
PrmPkg/PrmSsdtInstallDxe/Prm.asl | 115 ++
PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf | 52 +
PrmPkg/Readme.md | 264 ++++
PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf | 39 +
PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf | 41 +
PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h | 24 +
PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf | 39 +
PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf | 44 +
PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h | 108 ++
PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf | 39 +
PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf | 43 +
PrmPkg/Samples/Readme.md | 146 ++
PrmPkg/Test/PrmPkgHostTest.dsc | 39 +
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibTest.uni | 12 +
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.h | 1042 ++++++++++++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf | 46 +
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.h | 120 ++
71 files changed, 11096 insertions(+), 1 deletion(-)
create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.c
create mode 100644 PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
create mode 100644 PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTest.c
create mode 100644 PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
create mode 100644 PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTest.c
create mode 100644 PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c
create mode 100644 PrmPkg/PrmConfigDxe/PrmConfigDxe.c
create mode 100644 PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
create mode 100644 PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
create mode 100644 PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.c
create mode 100644 PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.c
create mode 100644 PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
create mode 100644 PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.c
create mode 100644 PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c
create mode 100644 PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
create mode 100644 PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.c
create mode 100644 PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestEventTimer.c
create mode 100644 PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestImage.c
create mode 100644 PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMemory.c
create mode 100644 PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMisc.c
create mode 100644 PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.c
create mode 100644 PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestTpl.c
create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.h
create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.inf
create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.uni
create mode 100644 PrmPkg/Application/PrmInfo/PrmInfoExtra.uni
create mode 100644 PrmPkg/Application/PrmInfo/PrmInfoStrings.uni
create mode 100644 PrmPkg/Include/Library/PrmContextBufferLib.h
create mode 100644 PrmPkg/Include/Library/PrmModuleDiscoveryLib.h
create mode 100644 PrmPkg/Include/Library/PrmPeCoffLib.h
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/PrmModuleImageContext.h
create mode 100644 PrmPkg/Include/Protocol/PrmConfig.h
create mode 100644 PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
create mode 100644 PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf
create mode 100644 PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf
create mode 100644 PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
create mode 100644 PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf
create mode 100644 PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
create mode 100644 PrmPkg/PrmConfigDxe/PrmConfigDxe.inf
create mode 100644 PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
create mode 100644 PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
create mode 100644 PrmPkg/PrmPkg.ci.yaml
create mode 100644 PrmPkg/PrmPkg.dec
create mode 100644 PrmPkg/PrmPkg.dsc
create mode 100644 PrmPkg/PrmPkg.uni
create mode 100644 PrmPkg/PrmSsdtInstallDxe/Prm.asl
create mode 100644 PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
create mode 100644 PrmPkg/Readme.md
create mode 100644 PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf
create mode 100644 PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf
create mode 100644 PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h
create mode 100644 PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf
create mode 100644 PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf
create mode 100644 PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
create mode 100644 PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
create mode 100644 PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf
create mode 100644 PrmPkg/Samples/Readme.md
create mode 100644 PrmPkg/Test/PrmPkgHostTest.dsc
create mode 100644 PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibTest.uni
create mode 100644 PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.h
create mode 100644 PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf
create mode 100644 PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.h
--
2.28.0.windows.1
^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH v1 01/41] PrmPkg: Add package and include headers
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 02/41] PrmPkg: Add PrmConfig protocol interface Michael Kubacki
` (39 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
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 <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/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(+)
diff --git a/PrmPkg/Include/Prm.h b/PrmPkg/Include/Prm.h
new file mode 100644
index 000000000000..0e3ccfffa333
--- /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 <Uefi.h>
+#include <PrmContextBuffer.h>
+
+#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 000000000000..8f8144545e64
--- /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 <PrmDataBuffer.h>
+#include <PrmMmio.h>
+#include <Uefi.h>
+
+#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 000000000000..70d690ca5446
--- /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 <Uefi.h>
+
+#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 000000000000..95198cef659c
--- /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 <Prm.h>
+
+#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 000000000000..fb216c27e8e3
--- /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 <Uefi.h>
+
+#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 000000000000..f40fb42a2b4f
--- /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 <Prm.h>
+#include <PrmContextBuffer.h>
+#include <PrmDataBuffer.h>
+#include <PrmExportDescriptor.h>
+#include <PrmMmio.h>
+#include <PrmModuleUpdate.h>
+#include <PrmOsServices.h>
+
+/**
+ 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 000000000000..fde97eff0462
--- /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 <Uefi.h>
+
+#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 000000000000..62dfa0018787
--- /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 <Uefi.h>
+
+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 000000000000..ff681d423d30
--- /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<BR>
+## 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 000000000000..3575b3505213
--- /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.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 02/41] PrmPkg: Add PrmConfig protocol interface
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 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 03/41] PrmPkg/PrmContextBufferLib: Add initial library instance Michael Kubacki
` (38 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3812
The PRM Configuration protocol is used by PRM module configuration
libraries to describe their resources so that a generic PRM Configuration
DXE driver can prepare those resources for OS runtime.
Therefore, multiple instances are expected in the system per boot with
approximately one instance per PRM module. All PRM Configuration Protocol
instances must be installed prior to end of DXE.
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/Include/Protocol/PrmConfig.h | 32 ++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/PrmPkg/Include/Protocol/PrmConfig.h b/PrmPkg/Include/Protocol/PrmConfig.h
new file mode 100644
index 000000000000..d90fe5a0dd73
--- /dev/null
+++ b/PrmPkg/Include/Protocol/PrmConfig.h
@@ -0,0 +1,32 @@
+/** @file
+
+ PRM Configuration protocol
+
+ PRM Configuration protocol is used by PRM module configuration libraries to
+ describe their resources so that a generic PRM Configuration DXE driver can prepare those
+ resources for OS runtime.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PRM_CONFIG_H_
+#define PRM_CONFIG_H_
+
+#include <PrmContextBuffer.h>
+#include <Uefi.h>
+
+typedef struct _PRM_CONFIG_PROTOCOL PRM_CONFIG_PROTOCOL;
+
+#define PRM_CONFIG_PROTOCOL_SIGNATURE SIGNATURE_32('P','M','C','P')
+#define PRM_CONFIG_PROTOCOL_VERSION 1
+
+struct _PRM_CONFIG_PROTOCOL
+{
+ PRM_MODULE_CONTEXT_BUFFERS ModuleContextBuffers;
+};
+
+extern EFI_GUID gPrmConfigProtocolGuid;
+
+#endif
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 03/41] PrmPkg/PrmContextBufferLib: Add initial library instance
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 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 04/41] PrmPkg/PrmConfigDxe: Add initial driver Michael Kubacki
` (37 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3812
This library is introduced to add a general abstraction for PRM context
buffer management.
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/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c | 196 ++++++++++++++++++++
PrmPkg/Include/Library/PrmContextBufferLib.h | 99 ++++++++++
PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf | 35 ++++
3 files changed, 330 insertions(+)
diff --git a/PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c b/PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
new file mode 100644
index 000000000000..1a1a15b5cdbb
--- /dev/null
+++ b/PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
@@ -0,0 +1,196 @@
+/** @file
+
+ The PRM Buffer Context library provides a general abstraction for context buffer management.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PrmContextBufferLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/PrmConfig.h>
+
+#define _DBGMSGID_ "[PRMCONTEXTBUFFERLIB]"
+
+/**
+ Finds a PRM context buffer for the given PRM handler GUID.
+
+ Note: PRM_MODULE_CONTEXT_BUFFERS is at the PRM module level while PRM_CONTEXT_BUFFER is at the PRM handler level.
+
+ @param[in] HandlerGuid A pointer to the PRM handler GUID.
+ @param[in] ModuleContextBuffers A pointer to the PRM context buffers structure for the PRM module.
+ @param[out] PrmModuleContextBuffer A pointer to a pointer that will be set to the PRM context buffer
+ if successfully found.
+
+ @retval EFI_SUCCESS The PRM context buffer was found.
+ @retval EFI_INVALID_PARAMETER A required parameter pointer is NULL.
+ @retval EFI_NOT_FOUND The context buffer for the given PRM handler GUID could not be found.
+
+**/
+EFI_STATUS
+FindContextBufferInModuleBuffers (
+ IN CONST EFI_GUID *HandlerGuid,
+ IN CONST PRM_MODULE_CONTEXT_BUFFERS *ModuleContextBuffers,
+ OUT CONST PRM_CONTEXT_BUFFER **ContextBuffer
+ )
+{
+ UINTN Index;
+
+ DEBUG ((DEBUG_INFO, " %a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ if (HandlerGuid == NULL || ModuleContextBuffers == NULL || ContextBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Index = 0; Index < ModuleContextBuffers->BufferCount; Index++) {
+ if (CompareGuid (&ModuleContextBuffers->Buffer[Index].HandlerGuid, HandlerGuid)) {
+ *ContextBuffer = &ModuleContextBuffers->Buffer[Index];
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Returns a PRM context buffers structure for the given PRM search type.
+
+ This function allows a caller to get the context buffers structure for a PRM module with either the PRM module
+ GUID or the GUID for a PRM handler in the module.
+
+ Note: PRM_MODULE_CONTEXT_BUFFERS is at the PRM module level while PRM_CONTEXT_BUFFER is at the PRM handler level.
+
+ @param[in] GuidSearchType The type of GUID passed in the Guid argument.
+ @param[in] Guid A pointer to the GUID of a PRM module or PRM handler. The actual GUID type
+ will be interpreted based on the value passed in GuidSearchType.
+ @param[out] PrmModuleContextBuffers A pointer to a pointer that will be set to the PRM context buffers
+ structure if successfully found.
+
+ @retval EFI_SUCCESS The PRM context buffers structure was found.
+ @retval EFI_INVALID_PARAMETER A required parameter pointer is NULL.
+ @retval EFI_NOT_FOUND The context buffers for the given GUID could not be found.
+
+**/
+EFI_STATUS
+GetModuleContextBuffers (
+ IN PRM_GUID_SEARCH_TYPE GuidSearchType,
+ IN CONST EFI_GUID *Guid,
+ OUT CONST PRM_MODULE_CONTEXT_BUFFERS **PrmModuleContextBuffers
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_HANDLE *HandleBuffer;
+ PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
+ CONST PRM_CONTEXT_BUFFER *PrmContextBuffer;
+
+ DEBUG ((DEBUG_INFO, " %a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ if (Guid == NULL || PrmModuleContextBuffers == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *PrmModuleContextBuffers = NULL;
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gPrmConfigProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gPrmConfigProtocolGuid,
+ (VOID **) &PrmConfigProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status) || PrmConfigProtocol == NULL) {
+ continue;
+ }
+
+ if (GuidSearchType == ByModuleGuid) {
+ if (CompareGuid (&PrmConfigProtocol->ModuleContextBuffers.ModuleGuid, Guid)) {
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Found a PRM configuration protocol for PRM module %g.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ Guid
+ ));
+
+ *PrmModuleContextBuffers = &PrmConfigProtocol->ModuleContextBuffers;
+ return EFI_SUCCESS;
+ }
+ } else {
+ Status = FindContextBufferInModuleBuffers (Guid, &PrmConfigProtocol->ModuleContextBuffers, &PrmContextBuffer);
+ if (!EFI_ERROR (Status)) {
+ *PrmModuleContextBuffers = &PrmConfigProtocol->ModuleContextBuffers;
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Could not locate a PRM configuration protocol for PRM handler %g.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ Guid
+ ));
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Returns a PRM context buffer for the given PRM handler.
+
+ @param[in] PrmHandlerGuid A pointer to the GUID for the PRM handler.
+ @param[in] PrmModuleContextBuffers A pointer to a PRM_MODULE_CONTEXT_BUFFERS structure. If this optional
+ parameter is provided, the handler context buffer will be searched for in this
+ buffer structure which saves time by not performing a global search for the
+ module buffer structure.
+ @param[out] PrmContextBuffer A pointer to a pointer that will be set to the PRM context buffer
+ if successfully found.
+
+ @retval EFI_SUCCESS The PRM context buffer was found.
+ @retval EFI_INVALID_PARAMETER A required parameter pointer is NULL.
+ @retval EFI_NOT_FOUND The context buffer for the PRM handler could not be found.
+
+**/
+EFI_STATUS
+GetContextBuffer (
+ IN CONST EFI_GUID *PrmHandlerGuid,
+ IN CONST PRM_MODULE_CONTEXT_BUFFERS *PrmModuleContextBuffers OPTIONAL,
+ OUT CONST PRM_CONTEXT_BUFFER **PrmContextBuffer
+ )
+{
+ EFI_STATUS Status;
+ CONST PRM_MODULE_CONTEXT_BUFFERS *ContextBuffers;
+
+ DEBUG ((DEBUG_INFO, " %a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ if (PrmHandlerGuid == NULL || PrmContextBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *PrmContextBuffer = NULL;
+
+ if (PrmModuleContextBuffers == NULL) {
+ Status = GetModuleContextBuffers (ByHandlerGuid, PrmHandlerGuid, &ContextBuffers);
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ ContextBuffers = PrmModuleContextBuffers;
+ }
+ Status = FindContextBufferInModuleBuffers (PrmHandlerGuid, ContextBuffers, PrmContextBuffer);
+
+ return Status;
+}
diff --git a/PrmPkg/Include/Library/PrmContextBufferLib.h b/PrmPkg/Include/Library/PrmContextBufferLib.h
new file mode 100644
index 000000000000..93dcd1e76642
--- /dev/null
+++ b/PrmPkg/Include/Library/PrmContextBufferLib.h
@@ -0,0 +1,99 @@
+/** @file
+
+ The PRM Buffer Context library provides a general abstraction for context buffer management.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PRM_CONTEXT_BUFFER_LIB_H_
+#define PRM_CONTEXT_BUFFER_LIB_H_
+
+#include <Base.h>
+#include <PrmContextBuffer.h>
+#include <Uefi.h>
+
+typedef enum {
+ ///
+ /// Search by the PRM module GUID
+ ///
+ ByModuleGuid,
+ ///
+ /// Search by the PRM handler GUID
+ ///
+ ByHandlerGuid
+} PRM_GUID_SEARCH_TYPE;
+
+/**
+ Finds a PRM context buffer for the given PRM handler GUID.
+
+ Note: PRM_MODULE_CONTEXT_BUFFERS is at the PRM module level while PRM_CONTEXT_BUFFER is at the PRM handler level.
+
+ @param[in] HandlerGuid A pointer to the PRM handler GUID.
+ @param[in] ModuleContextBuffers A pointer to the PRM context buffers structure for the PRM module.
+ @param[out] PrmModuleContextBuffer A pointer to a pointer that will be set to the PRM context buffer
+ if successfully found.
+
+ @retval EFI_SUCCESS The PRM context buffer was found.
+ @retval EFI_INVALID_PARAMETER A required parameter pointer is NULL.
+ @retval EFI_NOT_FOUND The context buffer for the given PRM handler GUID could not be found.
+
+**/
+EFI_STATUS
+FindContextBufferInModuleBuffers (
+ IN CONST EFI_GUID *HandlerGuid,
+ IN CONST PRM_MODULE_CONTEXT_BUFFERS *ModuleContextBuffers,
+ OUT CONST PRM_CONTEXT_BUFFER **ContextBuffer
+ );
+
+/**
+ Returns a PRM context buffers structure for the given PRM search type.
+
+ This function allows a caller to get the context buffers structure for a PRM module with either the PRM module
+ GUID or the GUID for a PRM handler in the module.
+
+ Note: PRM_MODULE_CONTEXT_BUFFERS is at the PRM module level while PRM_CONTEXT_BUFFER is at the PRM handler level.
+
+ @param[in] GuidSearchType The type of GUID passed in the Guid argument.
+ @param[in] Guid A pointer to the GUID of a PRM module or PRM handler. The actual GUID type
+ will be interpreted based on the value passed in GuidSearchType.
+ @param[out] PrmModuleContextBuffers A pointer to a pointer that will be set to the PRM context buffers
+ structure if successfully found.
+
+ @retval EFI_SUCCESS The PRM context buffers structure was found.
+ @retval EFI_INVALID_PARAMETER A required parameter pointer is NULL.
+ @retval EFI_NOT_FOUND The context buffers for the given GUID could not be found.
+
+**/
+EFI_STATUS
+GetModuleContextBuffers (
+ IN PRM_GUID_SEARCH_TYPE GuidSearchType,
+ IN CONST EFI_GUID *Guid,
+ OUT CONST PRM_MODULE_CONTEXT_BUFFERS **PrmModuleContextBuffers
+ );
+
+/**
+ Returns a PRM context buffer for the given PRM handler.
+
+ @param[in] PrmHandlerGuid A pointer to the GUID for the PRM handler.
+ @param[in] PrmModuleContextBuffers A pointer to a PRM_MODULE_CONTEXT_BUFFERS structure. If this optional
+ parameter is provided, the handler context buffer will be searched for in this
+ buffer structure which saves time by not performing a global search for the
+ module buffer structure.
+ @param[out] PrmContextBuffer A pointer to a pointer that will be set to the PRM context buffer
+ if successfully found.
+
+ @retval EFI_SUCCESS The PRM context buffer was found.
+ @retval EFI_INVALID_PARAMETER A required parameter pointer is NULL.
+ @retval EFI_NOT_FOUND The context buffer for the PRM handler could not be found.
+
+**/
+EFI_STATUS
+GetContextBuffer (
+ IN CONST EFI_GUID *PrmHandlerGuid,
+ IN CONST PRM_MODULE_CONTEXT_BUFFERS *PrmModuleContextBuffers OPTIONAL,
+ OUT CONST PRM_CONTEXT_BUFFER **PrmContextBuffer
+ );
+
+#endif
diff --git a/PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf b/PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
new file mode 100644
index 000000000000..16ed1edfe36a
--- /dev/null
+++ b/PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
@@ -0,0 +1,35 @@
+## @file
+# PRM Context Buffer Library
+#
+# Provides a general abstraction for PRM context buffer management.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxePrmContextBufferLib
+ FILE_GUID = 49828E93-29FA-4665-B8B1-19BA4059D140
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PrmContextBufferLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+[Sources]
+ DxePrmContextBufferLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[Protocols]
+ gPrmConfigProtocolGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ UefiBootServicesTableLib
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 04/41] PrmPkg/PrmConfigDxe: Add initial driver
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (2 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 03/41] PrmPkg/PrmContextBufferLib: Add initial library instance Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 05/41] PrmPkg: Add initial PrmSamplePrintModule Michael Kubacki
` (36 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3812
This driver serves as a generic PRM configuration driver. Its primary
role is to prepare PRM resources published by PRM module configuration
libraries for OS runtime. As such, it locates all PRM Configuration
Protocol instances and consumes the information to ready those resources.
For example, set runtime memory attributes on MMIO ranges and convert
physical addresses to virtual addresses in PRM buffers.
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/PrmConfigDxe/PrmConfigDxe.c | 559 ++++++++++++
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c | 925 ++++++++++++++++++++
PrmPkg/PrmConfigDxe/PrmConfigDxe.inf | 48 +
PrmPkg/PrmLoaderDxe/PrmAcpiTable.h | 97 ++
PrmPkg/PrmLoaderDxe/PrmLoader.h | 51 ++
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf | 59 ++
6 files changed, 1739 insertions(+)
diff --git a/PrmPkg/PrmConfigDxe/PrmConfigDxe.c b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
new file mode 100644
index 000000000000..cb38146bc9e0
--- /dev/null
+++ b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
@@ -0,0 +1,559 @@
+/** @file
+
+ This file contains the implementation for a Platform Runtime Mechanism (PRM) configuration driver.
+
+ Copyright (c) Microsoft Corporation
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <PiDxe.h>
+#include <PrmContextBuffer.h>
+#include <PrmDataBuffer.h>
+#include <PrmMmio.h>
+#include <Protocol/PrmConfig.h>
+
+#define _DBGMSGID_ "[PRMCONFIG]"
+
+STATIC UINTN mMaxRuntimeMmioRangeCount;
+STATIC UINTN mMaxStaticDataBufferCount;
+
+STATIC PRM_RUNTIME_MMIO_RANGES **mRuntimeMmioRanges;
+STATIC PRM_DATA_BUFFER ***mStaticDataBuffers;
+
+/**
+ Converts the runtime memory range physical addresses to virtual addresses.
+
+ @param[in] RuntimeMmioRanges A pointer to a PRM_RUNTIME_MMIO_RANGES buffer.
+
+**/
+VOID
+ConvertRuntimeMemoryRangeAddresses (
+ IN PRM_RUNTIME_MMIO_RANGES *RuntimeMmioRanges
+ )
+{
+ UINTN Index;
+
+ if (RuntimeMmioRanges == NULL || RuntimeMmioRanges->Count == 0) {
+ return;
+ }
+
+ for (Index = 0; Index < (UINTN) RuntimeMmioRanges->Count; Index++) {
+ RuntimeMmioRanges->Range[Index].VirtualBaseAddress = RuntimeMmioRanges->Range[Index].PhysicalBaseAddress;
+ gRT->ConvertPointer (0x0, (VOID **) &(RuntimeMmioRanges->Range[Index].VirtualBaseAddress));
+ }
+}
+
+/**
+ Sets the runtime memory range attributes.
+
+ The EFI_MEMORY_RUNTIME attribute is set for each PRM_RUNTIME_MMIO_RANGE present
+ in the buffer provided.
+
+ @param[in] RuntimeMmioRanges A pointer to a PRM_RUNTIME_MMIO_RANGES buffer.
+
+**/
+VOID
+SetRuntimeMemoryRangeAttributes (
+ IN PRM_RUNTIME_MMIO_RANGES *RuntimeMmioRanges
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status2;
+ UINTN Index;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ if (RuntimeMmioRanges == NULL || RuntimeMmioRanges->Count == 0) {
+ return;
+ }
+
+ for (Index = 0; Index < (UINTN) RuntimeMmioRanges->Count; Index++) {
+ DEBUG ((
+ DEBUG_INFO, " %a %a: Runtime MMIO Range [%d].\n", _DBGMSGID_, __FUNCTION__, Index));
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Physical address = 0x%016x. Length = 0x%x.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
+ RuntimeMmioRanges->Range[Index].Length
+ ));
+
+ // Runtime memory ranges should cover ranges on a page boundary
+ ASSERT ((RuntimeMmioRanges->Range[Index].PhysicalBaseAddress & EFI_PAGE_MASK) == 0);
+ ASSERT ((RuntimeMmioRanges->Range[Index].Length & EFI_PAGE_MASK) == 0);
+
+ Status2 = EFI_NOT_FOUND;
+ Status = gDS->GetMemorySpaceDescriptor (RuntimeMmioRanges->Range[Index].PhysicalBaseAddress, &Descriptor);
+ if (!EFI_ERROR (Status) &&
+ (
+ (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo && Descriptor.GcdMemoryType != EfiGcdMemoryTypeReserved) ||
+ ((Descriptor.Length & EFI_PAGE_MASK) != 0)
+ )
+ ) {
+ Status2 = gDS->RemoveMemorySpace (
+ RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
+ Descriptor.Length
+ );
+ }
+
+ if (Status == EFI_NOT_FOUND || !EFI_ERROR (Status2)) {
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
+ (UINT64) RuntimeMmioRanges->Range[Index].Length,
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ 0,
+ (UINT64) RuntimeMmioRanges->Range[Index].Length,
+ &RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
+ gImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ Status = gDS->GetMemorySpaceDescriptor (RuntimeMmioRanges->Range[Index].PhysicalBaseAddress, &Descriptor);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ " %a %a: Error [%r] finding descriptor for runtime memory range 0x%016x.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ Status,
+ RuntimeMmioRanges->Range[Index].PhysicalBaseAddress
+ ));
+ continue;
+ }
+ if ((Descriptor.Attributes & EFI_MEMORY_RUNTIME) != 0) {
+ continue;
+ }
+
+ Status = gDS->SetMemorySpaceAttributes (
+ RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
+ (UINT64) RuntimeMmioRanges->Range[Index].Length,
+ Descriptor.Attributes | EFI_MEMORY_RUNTIME
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ " %a %a: Error [%r] setting descriptor for runtime memory range 0x%016x.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ Status,
+ RuntimeMmioRanges->Range[Index].PhysicalBaseAddress
+ ));
+ } else {
+ DEBUG ((DEBUG_INFO, " %a %a: Successfully set runtime attribute for the MMIO range.\n", _DBGMSGID_, __FUNCTION__));
+ }
+ }
+}
+
+/**
+ Stores pointers or pointer to resources that should be converted in the virtual address change event.
+
+**/
+VOID
+StoreVirtualMemoryAddressChangePointers (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferIndex;
+ UINTN HandleCount;
+ UINTN HandleIndex;
+ UINTN RangeIndex;
+ UINTN StaticDataBufferIndex;
+ EFI_HANDLE *HandleBuffer;
+ PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
+ PRM_CONTEXT_BUFFER *CurrentContextBuffer;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ RangeIndex = 0;
+ StaticDataBufferIndex = 0;
+
+ mRuntimeMmioRanges = AllocateRuntimeZeroPool (sizeof (*mRuntimeMmioRanges) * mMaxRuntimeMmioRangeCount);
+ if (mRuntimeMmioRanges == NULL && mMaxRuntimeMmioRangeCount > 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ " %a %a: Memory allocation for runtime MMIO pointer array failed.\n",
+ _DBGMSGID_,
+ __FUNCTION__
+ ));
+ ASSERT (FALSE);
+ return;
+ }
+
+ mStaticDataBuffers = AllocateRuntimeZeroPool (sizeof (*mStaticDataBuffers) * mMaxStaticDataBufferCount);
+ if (mStaticDataBuffers == NULL && mMaxStaticDataBufferCount > 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ " %a %a: Memory allocation for PRM static data buffer pointer array failed.\n",
+ _DBGMSGID_,
+ __FUNCTION__
+ ));
+ ASSERT (FALSE);
+ return;
+ }
+
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gPrmConfigProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[HandleIndex],
+ &gPrmConfigProtocolGuid,
+ (VOID **) &PrmConfigProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status) || PrmConfigProtocol == NULL) {
+ continue;
+ }
+
+ for (BufferIndex = 0; BufferIndex < PrmConfigProtocol->ModuleContextBuffers.BufferCount; BufferIndex++) {
+ CurrentContextBuffer = &(PrmConfigProtocol->ModuleContextBuffers.Buffer[BufferIndex]);
+
+ if (CurrentContextBuffer->StaticDataBuffer != NULL) {
+ if (StaticDataBufferIndex >= mMaxStaticDataBufferCount) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ DEBUG ((
+ DEBUG_ERROR,
+ " %a %a: Index out of bounds - Actual count (%d) of PRM data buffers exceeds maximum count (%d).\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ StaticDataBufferIndex + 1,
+ mMaxStaticDataBufferCount
+ ));
+ ASSERT_EFI_ERROR (Status);
+ return;
+ }
+ mStaticDataBuffers[StaticDataBufferIndex++] = &CurrentContextBuffer->StaticDataBuffer;
+ }
+ }
+ if (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges != NULL) {
+ if (RangeIndex >= mMaxRuntimeMmioRangeCount) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ DEBUG ((
+ DEBUG_ERROR,
+ " %a %a: Index out of bounds - Actual count (%d) of runtime MMIO ranges exceeds maximum count (%d).\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ RangeIndex + 1,
+ mMaxRuntimeMmioRangeCount
+ ));
+ ASSERT_EFI_ERROR (Status);
+ return;
+ }
+ mRuntimeMmioRanges[RangeIndex++] = PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges;
+ }
+ }
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: %d MMIO ranges buffers saved for future virtual memory conversion.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ RangeIndex
+ ));
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: %d static buffers saved for future virtual memory conversion.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ StaticDataBufferIndex
+ ));
+ }
+}
+
+/**
+ Validates a data buffer for a PRM module.
+
+ Verifies the buffer header signature is valid and the length meets the minimum size.
+
+ @param[in] PrmDataBuffer A pointer to the data buffer for this PRM module.
+
+ @retval EFI_SUCCESS The data buffer was validated successfully.
+ @retval EFI_INVALID_PARAMETER The pointer given for PrmDataBuffer is NULL.
+ @retval EFI_NOT_FOUND The data buffer signature is not valid.
+ @retval EFI_BUFFER_TOO_SMALL The buffer size is too small.
+
+**/
+EFI_STATUS
+ValidatePrmDataBuffer (
+ IN CONST PRM_DATA_BUFFER *PrmDataBuffer
+ )
+{
+ if (PrmDataBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (PrmDataBuffer->Header.Signature != PRM_DATA_BUFFER_HEADER_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, " %a %a: The PRM data buffer signature is invalid. PRM module.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_NOT_FOUND;
+ }
+ if (PrmDataBuffer->Header.Length < sizeof (PRM_DATA_BUFFER_HEADER)) {
+ DEBUG ((DEBUG_ERROR, " %a %a: The PRM data buffer length is invalid.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Validates a PRM context buffer.
+
+ Verifies the buffer header signature is valid and the GUID is set to a non-zero value.
+
+ @param[in] PrmContextBuffer A pointer to the context buffer for this PRM handler.
+
+ @retval EFI_SUCCESS The context buffer was validated successfully.
+ @retval EFI_INVALID_PARAMETER The pointer given for ContextBuffer is NULL.
+ @retval EFI_NOT_FOUND The proper value for a field was not found.
+
+**/
+EFI_STATUS
+ValidatePrmContextBuffer (
+ IN CONST PRM_CONTEXT_BUFFER *PrmContextBuffer
+ )
+{
+ if (PrmContextBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (PrmContextBuffer->Signature != PRM_CONTEXT_BUFFER_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, " %a %a: The PRM context buffer signature is invalid.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_NOT_FOUND;
+ }
+
+ if (IsZeroGuid (&PrmContextBuffer->HandlerGuid)) {
+ DEBUG ((DEBUG_ERROR, " %a %a: The PRM context buffer GUID is zero.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_NOT_FOUND;
+ }
+
+ if (PrmContextBuffer->StaticDataBuffer != NULL && EFI_ERROR (ValidatePrmDataBuffer (PrmContextBuffer->StaticDataBuffer))) {
+ DEBUG ((
+ DEBUG_ERROR,
+ " %a %a: Error in static buffer for PRM handler %g.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ &PrmContextBuffer->HandlerGuid
+ ));
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+
+ This is notification function converts any registered PRM_RUNTIME_MMIO_RANGE
+ addresses to a virtual address.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+PrmConfigVirtualAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Index;
+
+ //
+ // Convert static data buffer pointers
+ //
+ for (Index = 0; Index < mMaxStaticDataBufferCount; Index++) {
+ gRT->ConvertPointer (0x0, (VOID **) mStaticDataBuffers[Index]);
+ }
+
+ //
+ // Convert runtime MMIO ranges
+ //
+ for (Index = 0; Index < mMaxRuntimeMmioRangeCount; Index++) {
+ ConvertRuntimeMemoryRangeAddresses (mRuntimeMmioRanges[Index]);
+ }
+}
+
+/**
+ The PRM Config END_OF_DXE protocol notification event handler.
+
+ Finds all of the PRM_CONFIG_PROTOCOL instances installed at end of DXE and
+ marks all PRM_RUNTIME_MMIO_RANGE entries as EFI_MEMORY_RUNTIME.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+ @retval EFI_SUCCESS The function executed successfully
+
+**/
+EFI_STATUS
+EFIAPI
+PrmConfigEndOfDxeNotification (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ UINTN BufferIndex;
+ UINTN HandleIndex;
+ EFI_HANDLE *HandleBuffer;
+ PRM_CONTEXT_BUFFER *CurrentContextBuffer;
+ PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gPrmConfigProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[HandleIndex],
+ &gPrmConfigProtocolGuid,
+ (VOID **) &PrmConfigProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status) || PrmConfigProtocol == NULL) {
+ continue;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Found PRM configuration protocol for PRM module %g.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ &PrmConfigProtocol->ModuleContextBuffers.ModuleGuid
+ ));
+
+ DEBUG ((DEBUG_INFO, " %a %a: Validating module context buffers...\n", _DBGMSGID_, __FUNCTION__));
+ for (BufferIndex = 0; BufferIndex < PrmConfigProtocol->ModuleContextBuffers.BufferCount; BufferIndex++) {
+ CurrentContextBuffer = &(PrmConfigProtocol->ModuleContextBuffers.Buffer[BufferIndex]);
+
+ Status = ValidatePrmContextBuffer (CurrentContextBuffer);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ " %a %a: Context buffer validation failed for PRM handler %g.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ CurrentContextBuffer->HandlerGuid
+ ));
+ }
+ if (CurrentContextBuffer->StaticDataBuffer != NULL) {
+ mMaxStaticDataBufferCount++;
+ }
+ }
+ DEBUG ((DEBUG_INFO, " %a %a: Module context buffer validation complete.\n", _DBGMSGID_, __FUNCTION__));
+
+ if (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges != NULL) {
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Found %d PRM runtime MMIO ranges to convert.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges->Count
+ ));
+ SetRuntimeMemoryRangeAttributes (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges);
+ mMaxRuntimeMmioRangeCount++;
+ }
+ }
+
+ StoreVirtualMemoryAddressChangePointers ();
+ }
+
+ if (HandleBuffer != NULL) {
+ gBS->FreePool (HandleBuffer);
+ }
+ gBS->CloseEvent(Event);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The entry point for this module.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval Others An error occurred when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+PrmConfigEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ //
+ // Register a notification function to change memory attributes at end of DXE
+ //
+ Event = NULL;
+ Status = gBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ PrmConfigEndOfDxeNotification,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register a notification function for virtual address change
+ //
+ Event = NULL;
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ PrmConfigVirtualAddressChangeEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
new file mode 100644
index 000000000000..b43e6d6bf078
--- /dev/null
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -0,0 +1,925 @@
+/** @file
+
+ This file contains the implementation for a Platform Runtime Mechanism (PRM)
+ loader driver.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PrmAcpiTable.h"
+#include "PrmLoader.h"
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrmContextBufferLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/PrmConfig.h>
+
+#include <PrmContextBuffer.h>
+#include <PrmMmio.h>
+#include <PrmModuleUpdate.h>
+
+LIST_ENTRY mPrmModuleList;
+
+// Todo: Potentially refactor mPrmHandlerCount and mPrmModuleCount into localized structures
+// in the future.
+UINT32 mPrmHandlerCount;
+UINT32 mPrmModuleCount;
+
+/**
+ Gets a pointer to the export directory in a given PE/COFF image.
+
+ @param[in] ImageExportDirectory A pointer to an export directory table in a PE/COFF image.
+ @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
+ PE/COFF image context for the Image containing the PRM Module Export
+ Descriptor table.
+ @param[out] ExportDescriptor A pointer to a pointer to the PRM Module Export Descriptor table found
+ in the ImageExportDirectory given.
+
+ @retval EFI_SUCCESS The PRM Module Export Descriptor table was found successfully.
+ @retval EFI_INVALID_PARAMETER A required parameter is NULL.
+ @retval EFI_NOT_FOUND The PRM Module Export Descriptor table was not found in the given
+ ImageExportDirectory.
+
+**/
+EFI_STATUS
+GetPrmModuleExportDescriptorTable (
+ IN EFI_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory,
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
+ OUT PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT **ExportDescriptor
+ )
+{
+ UINTN Index;
+ EFI_PHYSICAL_ADDRESS CurrentImageAddress;
+ UINT16 PrmModuleExportDescriptorOrdinal;
+ CONST CHAR8 *CurrentExportName;
+ UINT16 *OrdinalTable;
+ UINT32 *ExportNamePointerTable;
+ UINT32 *ExportAddressTable;
+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *TempExportDescriptor;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ *ExportDescriptor = NULL;
+
+ if (ImageExportDirectory == NULL ||
+ PeCoffLoaderImageContext == NULL ||
+ PeCoffLoaderImageContext->ImageAddress == 0 ||
+ ExportDescriptor == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: %d exported names found in this image.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ ImageExportDirectory->NumberOfNames
+ ));
+
+ //
+ // The export name pointer table and export ordinal table form two parallel arrays associated by index.
+ //
+ CurrentImageAddress = PeCoffLoaderImageContext->ImageAddress;
+ ExportAddressTable = (UINT32 *) ((UINTN) CurrentImageAddress + ImageExportDirectory->AddressOfFunctions);
+ ExportNamePointerTable = (UINT32 *) ((UINTN) CurrentImageAddress + ImageExportDirectory->AddressOfNames);
+ OrdinalTable = (UINT16 *) ((UINTN) CurrentImageAddress + ImageExportDirectory->AddressOfNameOrdinals);
+
+ for (Index = 0; Index < ImageExportDirectory->NumberOfNames; Index++) {
+ CurrentExportName = (CONST CHAR8 *) ((UINTN) CurrentImageAddress + ExportNamePointerTable[Index]);
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Export Name[0x%x] - %a.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ Index,
+ CurrentExportName
+ ));
+ if (
+ AsciiStrnCmp (
+ PRM_STRING(PRM_MODULE_EXPORT_DESCRIPTOR_NAME),
+ CurrentExportName,
+ AsciiStrLen (PRM_STRING(PRM_MODULE_EXPORT_DESCRIPTOR_NAME))
+ ) == 0) {
+ PrmModuleExportDescriptorOrdinal = OrdinalTable[Index];
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: PRM Module Export Descriptor found. Ordinal = %d.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ PrmModuleExportDescriptorOrdinal
+ ));
+ if (PrmModuleExportDescriptorOrdinal >= ImageExportDirectory->NumberOfFunctions) {
+ DEBUG ((DEBUG_ERROR, "%a %a: The PRM Module Export Descriptor ordinal value is invalid.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_NOT_FOUND;
+ }
+ TempExportDescriptor = (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *) ((UINTN) CurrentImageAddress + ExportAddressTable[PrmModuleExportDescriptorOrdinal]);
+ if (TempExportDescriptor->Signature == PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE) {
+ *ExportDescriptor = TempExportDescriptor;
+ DEBUG ((DEBUG_INFO, " %a %a: PRM Module Export Descriptor found at 0x%x.\n", _DBGMSGID_, __FUNCTION__, (UINTN) ExportDescriptor));
+ } else {
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: PRM Module Export Descriptor found at 0x%x but signature check failed.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ (UINTN) TempExportDescriptor
+ ));
+ }
+ DEBUG ((DEBUG_INFO, " %a %a: Exiting export iteration since export descriptor found.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Gets a pointer to the export directory in a given PE/COFF image.
+
+ @param[in] Image A pointer to a PE32/COFF image base address that is loaded into memory
+ and already relocated to the memory base address. RVAs in the image given
+ should be valid.
+ @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
+ PE/COFF image context for the Image given.
+ @param[out] ImageExportDirectory A pointer to a pointer to the export directory found in the Image given.
+
+ @retval EFI_SUCCESS The export directory was found successfully.
+ @retval EFI_INVALID_PARAMETER A required parameter is NULL.
+ @retval EFI_UNSUPPORTED The PE/COFF image given is not supported as a PRM Module.
+ @retval EFI_NOT_FOUND The image export directory could not be found for this image.
+
+**/
+EFI_STATUS
+GetExportDirectoryInPeCoffImage (
+ IN VOID *Image,
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
+ OUT EFI_IMAGE_EXPORT_DIRECTORY **ImageExportDirectory
+ )
+{
+ UINT16 Magic;
+ UINT32 NumberOfRvaAndSizes;
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION OptionalHeaderPtrUnion;
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
+ EFI_IMAGE_EXPORT_DIRECTORY *ExportDirectory;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+
+ if (Image == NULL || PeCoffLoaderImageContext == NULL || ImageExportDirectory == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DirectoryEntry = NULL;
+ ExportDirectory = NULL;
+
+ //
+ // NOTE: For backward compatibility, use the Machine field to identify a PE32/PE32+
+ // image instead of using the Magic field. Some systems might generate a PE32+
+ // image with PE32 magic.
+ //
+ switch (PeCoffLoaderImageContext->Machine) {
+ case EFI_IMAGE_MACHINE_IA32:
+ // Todo: Add EFI_IMAGE_MACHINE_ARMT
+ //
+ // Assume PE32 image with IA32 Machine field.
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ break;
+ case EFI_IMAGE_MACHINE_X64:
+ //
+ // Assume PE32+ image with X64 Machine field
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ break;
+ default:
+ //
+ // For unknown Machine field, use Magic in optional header
+ //
+ DEBUG ((
+ DEBUG_WARN,
+ "%a %a: The machine type for this image is not valid for a PRM module.\n",
+ _DBGMSGID_,
+ __FUNCTION__
+ ));
+ return EFI_UNSUPPORTED;
+ }
+
+ OptionalHeaderPtrUnion.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) (
+ (UINTN) Image +
+ PeCoffLoaderImageContext->PeCoffHeaderOffset
+ );
+
+ //
+ // Check the PE/COFF Header Signature. Determine if the image is valid and/or a TE image.
+ //
+ if (OptionalHeaderPtrUnion.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, "%a %a: The PE signature is not valid for the current image.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_UNSUPPORTED;
+ }
+
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN) Image +
+ PeCoffLoaderImageContext->PeCoffHeaderOffset +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ PeCoffLoaderImageContext->SizeOfHeaders
+ );
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use the PE32 offset to get the Export Directory Entry
+ //
+ NumberOfRvaAndSizes = OptionalHeaderPtrUnion.Pe32->OptionalHeader.NumberOfRvaAndSizes;
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHeaderPtrUnion.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT]);
+ } else if (OptionalHeaderPtrUnion.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ //
+ // Use the PE32+ offset get the Export Directory Entry
+ //
+ NumberOfRvaAndSizes = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT]);
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_EXPORT || DirectoryEntry->VirtualAddress == 0) {
+ //
+ // The export directory is not present
+ //
+ return EFI_NOT_FOUND;
+ } else if (((UINT32) (~0) - DirectoryEntry->VirtualAddress) < DirectoryEntry->Size) {
+ //
+ // The directory address overflows
+ //
+ DEBUG ((DEBUG_ERROR, "%a %a: The export directory entry in this image results in overflow.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_UNSUPPORTED;
+ } else {
+ DEBUG ((DEBUG_INFO, "%a %a: Export Directory Entry found in the image at 0x%x.\n", _DBGMSGID_, __FUNCTION__, (UINTN) OptionalHeaderPtrUnion.Pe32));
+ DEBUG ((DEBUG_INFO, " %a %a: Directory Entry Virtual Address = 0x%x.\n", _DBGMSGID_, __FUNCTION__, DirectoryEntry->VirtualAddress));
+
+ ExportDirectory = (EFI_IMAGE_EXPORT_DIRECTORY *) ((UINTN) Image + DirectoryEntry->VirtualAddress);
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Export Directory Table found successfully at 0x%x. Name address = 0x%x. Name = %a.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ (UINTN) ExportDirectory,
+ ((UINTN) Image + ExportDirectory->Name),
+ (CHAR8 *) ((UINTN) Image + ExportDirectory->Name)
+ ));
+ }
+ *ImageExportDirectory = ExportDirectory;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Returns the image major and image minor version in a given PE/COFF image.
+
+ @param[in] Image A pointer to a PE32/COFF image base address that is loaded into memory
+ and already relocated to the memory base address. RVAs in the image given
+ should be valid.
+ @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
+ PE/COFF image context for the Image given.
+ @param[out] ImageMajorVersion A pointer to a UINT16 buffer to hold the image major version.
+ @param[out] ImageMinorVersion A pointer to a UINT16 buffer to hold the image minor version.
+
+ @retval EFI_SUCCESS The image version was read successfully.
+ @retval EFI_INVALID_PARAMETER A required parameter is NULL.
+ @retval EFI_UNSUPPORTED The PE/COFF image given is not supported.
+
+**/
+EFI_STATUS
+GetImageVersionInPeCoffImage (
+ IN VOID *Image,
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
+ OUT UINT16 *ImageMajorVersion,
+ OUT UINT16 *ImageMinorVersion
+ )
+{
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION OptionalHeaderPtrUnion;
+ UINT16 Magic;
+
+ DEBUG ((DEBUG_INFO, " %a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ if (Image == NULL || PeCoffLoaderImageContext == NULL || ImageMajorVersion == NULL || ImageMinorVersion == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // NOTE: For backward compatibility, use the Machine field to identify a PE32/PE32+
+ // image instead of using the Magic field. Some systems might generate a PE32+
+ // image with PE32 magic.
+ //
+ switch (PeCoffLoaderImageContext->Machine) {
+ case EFI_IMAGE_MACHINE_IA32:
+ // Todo: Add EFI_IMAGE_MACHINE_ARMT
+ //
+ // Assume PE32 image with IA32 Machine field.
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ break;
+ case EFI_IMAGE_MACHINE_X64:
+ //
+ // Assume PE32+ image with X64 Machine field
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ break;
+ default:
+ //
+ // For unknown Machine field, use Magic in optional header
+ //
+ DEBUG ((
+ DEBUG_WARN,
+ "%a %a: The machine type for this image is not valid for a PRM module.\n",
+ _DBGMSGID_,
+ __FUNCTION__
+ ));
+ return EFI_UNSUPPORTED;
+ }
+
+ OptionalHeaderPtrUnion.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) (
+ (UINTN) Image +
+ PeCoffLoaderImageContext->PeCoffHeaderOffset
+ );
+ //
+ // Check the PE/COFF Header Signature. Determine if the image is valid and/or a TE image.
+ //
+ if (OptionalHeaderPtrUnion.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, "%a %a: The PE signature is not valid for the current image.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use the PE32 offset to get the Export Directory Entry
+ //
+ *ImageMajorVersion = OptionalHeaderPtrUnion.Pe32->OptionalHeader.MajorImageVersion;
+ *ImageMinorVersion = OptionalHeaderPtrUnion.Pe32->OptionalHeader.MinorImageVersion;
+ } else {
+ //
+ // Use the PE32+ offset to get the Export Directory Entry
+ //
+ *ImageMajorVersion = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.MajorImageVersion;
+ *ImageMinorVersion = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.MinorImageVersion;
+ }
+
+ DEBUG ((DEBUG_INFO, " %a %a - Image Major Version: 0x%02x.\n", _DBGMSGID_, __FUNCTION__, *ImageMajorVersion));
+ DEBUG ((DEBUG_INFO, " %a %a - Image Minor Version: 0x%02x.\n", _DBGMSGID_, __FUNCTION__, *ImageMinorVersion));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Creates a new PRM Module Image Context linked list entry.
+
+ @retval PrmModuleImageContextListEntry If successful, a pointer a PRM Module Image Context linked list entry
+ otherwise, NULL is returned.
+
+**/
+STATIC
+PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *
+CreateNewPrmModuleImageContextListEntry (
+ VOID
+ )
+{
+ PRM_MODULE_IMAGE_CONTEXT *PrmModuleImageContext;
+ PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *PrmModuleImageContextListEntry;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ PrmModuleImageContext = AllocateZeroPool (sizeof (*PrmModuleImageContext));
+ if (PrmModuleImageContext == NULL) {
+ return NULL;
+ }
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Allocated PrmModuleImageContext at 0x%x of size 0x%x bytes.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ (UINTN) PrmModuleImageContext,
+ sizeof (*PrmModuleImageContext)
+ ));
+
+ PrmModuleImageContextListEntry = AllocateZeroPool (sizeof (*PrmModuleImageContextListEntry));
+ if (PrmModuleImageContextListEntry == NULL) {
+ FreePool (PrmModuleImageContext);
+ return NULL;
+ }
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Allocated PrmModuleImageContextListEntry at 0x%x of size 0x%x bytes.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ (UINTN) PrmModuleImageContextListEntry,
+ sizeof (*PrmModuleImageContextListEntry)
+ ));
+
+ PrmModuleImageContextListEntry->Signature = PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE;
+ PrmModuleImageContextListEntry->Context = PrmModuleImageContext;
+
+ return PrmModuleImageContextListEntry;
+}
+
+/**
+ Discovers all PRM Modules loaded during the DXE boot phase.
+
+ Each PRM Module discovered is placed into a linked list so the list can br processsed in the future.
+
+ @retval EFI_SUCCESS All PRM Modules were discovered successfully.
+ @retval EFI_NOT_FOUND The gEfiLoadedImageProtocolGuid protocol could not be found.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to allocate the new PRM Context
+ linked list nodes.
+
+**/
+EFI_STATUS
+DiscoverPrmModules (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ PRM_MODULE_IMAGE_CONTEXT TempPrmModuleImageContext;
+ PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *PrmModuleImageContextListEntry;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocol;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiLoadedImageProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status) && (HandleCount == 0)) {
+ DEBUG ((DEBUG_ERROR, "%a %a: No LoadedImageProtocol instances found!\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_NOT_FOUND;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImageProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ ZeroMem (&TempPrmModuleImageContext, sizeof (TempPrmModuleImageContext));
+ TempPrmModuleImageContext.PeCoffImageContext.Handle = LoadedImageProtocol->ImageBase;
+ TempPrmModuleImageContext.PeCoffImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+ Status = PeCoffLoaderGetImageInfo (&TempPrmModuleImageContext.PeCoffImageContext);
+ if (EFI_ERROR (Status) || TempPrmModuleImageContext.PeCoffImageContext.ImageError != IMAGE_ERROR_SUCCESS) {
+ DEBUG ((
+ DEBUG_WARN,
+ "%a %a: ImageHandle 0x%016lx is not a valid PE/COFF image. It cannot be considered a PRM module.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ (EFI_PHYSICAL_ADDRESS) (UINTN) LoadedImageProtocol->ImageBase
+ ));
+ continue;
+ }
+ if (TempPrmModuleImageContext.PeCoffImageContext.IsTeImage) {
+ // A PRM Module is not allowed to be a TE image
+ continue;
+ }
+
+ // Attempt to find an export table in this image
+ Status = GetExportDirectoryInPeCoffImage (
+ LoadedImageProtocol->ImageBase,
+ &TempPrmModuleImageContext.PeCoffImageContext,
+ &TempPrmModuleImageContext.ExportDirectory
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ // Attempt to find the PRM Module Export Descriptor in the export table
+ Status = GetPrmModuleExportDescriptorTable (
+ TempPrmModuleImageContext.ExportDirectory,
+ &TempPrmModuleImageContext.PeCoffImageContext,
+ &TempPrmModuleImageContext.ExportDescriptor
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ // A PRM Module Export Descriptor was successfully found, this is considered a PRM Module.
+
+ //
+ // Create a new PRM Module image context node
+ //
+ PrmModuleImageContextListEntry = CreateNewPrmModuleImageContextListEntry ();
+ if (PrmModuleImageContextListEntry == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (
+ PrmModuleImageContextListEntry->Context,
+ &TempPrmModuleImageContext,
+ sizeof (*(PrmModuleImageContextListEntry->Context))
+ );
+ InsertTailList (&mPrmModuleList, &PrmModuleImageContextListEntry->Link);
+ mPrmHandlerCount += TempPrmModuleImageContext.ExportDescriptor->NumberPrmHandlers;
+ mPrmModuleCount++; // Todo: Match with global variable refactor change in the future
+ DEBUG ((DEBUG_INFO, "%a %a: New PRM Module inserted into list to be processed.\n", _DBGMSGID_, __FUNCTION__));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the address of an entry in an image export table by ASCII name.
+
+ @param[in] ExportName A pointer to an ASCII name string of the entry name.
+ @param[in] ImageBaseAddress The base address of the PE/COFF image.
+ @param[in] ImageExportDirectory A pointer to the export directory in the image.
+ @param[out] ExportPhysicalAddress A pointer that will be updated with the address of the address of the
+ export entry if found.
+
+ @retval EFI_SUCCESS The export entry was found successfully.
+ @retval EFI_INVALID_PARAMETER A required pointer argument is NULL.
+ @retval EFI_NOT_FOUND An entry with the given ExportName was not found.
+
+**/
+EFI_STATUS
+GetExportEntryAddress (
+ IN CONST CHAR8 *ExportName,
+ IN EFI_PHYSICAL_ADDRESS ImageBaseAddress,
+ IN EFI_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory,
+ OUT EFI_PHYSICAL_ADDRESS *ExportPhysicalAddress
+ )
+{
+ UINTN ExportNameIndex;
+ UINT16 CurrentExportOrdinal;
+ UINT32 *ExportAddressTable;
+ UINT32 *ExportNamePointerTable;
+ UINT16 *OrdinalTable;
+ CONST CHAR8 *ExportNameTablePointerName;
+
+ if (ExportName == NULL || ImageBaseAddress == 0 || ImageExportDirectory == NULL || ExportPhysicalAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *ExportPhysicalAddress = 0;
+
+ ExportAddressTable = (UINT32 *) ((UINTN) ImageBaseAddress + ImageExportDirectory->AddressOfFunctions);
+ ExportNamePointerTable = (UINT32 *) ((UINTN) ImageBaseAddress + ImageExportDirectory->AddressOfNames);
+ OrdinalTable = (UINT16 *) ((UINTN) ImageBaseAddress + ImageExportDirectory->AddressOfNameOrdinals);
+
+ for (ExportNameIndex = 0; ExportNameIndex < ImageExportDirectory->NumberOfNames; ExportNameIndex++) {
+ ExportNameTablePointerName = (CONST CHAR8 *) ((UINTN) ImageBaseAddress + ExportNamePointerTable[ExportNameIndex]);
+
+ if (AsciiStrnCmp (ExportName, ExportNameTablePointerName, PRM_HANDLER_NAME_MAXIMUM_LENGTH) == 0) {
+ CurrentExportOrdinal = OrdinalTable[ExportNameIndex];
+
+ ASSERT (CurrentExportOrdinal < ImageExportDirectory->NumberOfFunctions);
+ if (CurrentExportOrdinal >= ImageExportDirectory->NumberOfFunctions) {
+ DEBUG ((DEBUG_ERROR, " %a %a: The export ordinal value is invalid.\n", _DBGMSGID_, __FUNCTION__));
+ break;
+ }
+
+ *ExportPhysicalAddress = (EFI_PHYSICAL_ADDRESS) ((UINTN) ImageBaseAddress + ExportAddressTable[CurrentExportOrdinal]);
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Processes a list of PRM context entries to build a PRM ACPI table.
+
+ The ACPI table buffer is allocated and the table structure is built inside this function.
+
+ @param[out] PrmAcpiDescriptionTable A pointer to a pointer to a buffer that is allocated within this function
+ and will contain the PRM ACPI table. In case of an error in this function,
+ *PrmAcpiDescriptorTable will be NULL.
+
+ @retval EFI_SUCCESS All PRM Modules were processed to construct the PRM ACPI table successfully.
+ @retval EFI_INVALID_PARAMETER THe parameter PrmAcpiDescriptionTable is NULL.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to allocate the PRM ACPI table boot services
+ memory data buffer.
+
+**/
+EFI_STATUS
+ProcessPrmModules (
+ OUT PRM_ACPI_DESCRIPTION_TABLE **PrmAcpiDescriptionTable
+ )
+{
+ EFI_IMAGE_EXPORT_DIRECTORY *CurrentImageExportDirectory;
+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *CurrentExportDescriptorStruct;
+ LIST_ENTRY *Link;
+ PRM_ACPI_DESCRIPTION_TABLE *PrmAcpiTable;
+ PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *TempListEntry;
+ CONST CHAR8 *CurrentExportDescriptorHandlerName;
+
+ PRM_CONTEXT_BUFFER *CurrentContextBuffer;
+ PRM_MODULE_CONTEXT_BUFFERS *CurrentModuleContextBuffers;
+ PRM_MODULE_INFORMATION_STRUCT *CurrentModuleInfoStruct;
+ PRM_HANDLER_INFORMATION_STRUCT *CurrentHandlerInfoStruct;
+
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS CurrentImageAddress;
+ UINTN HandlerIndex;
+ UINT32 PrmAcpiDescriptionTableBufferSize;
+
+ UINT64 HandlerPhysicalAddress;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ if (PrmAcpiDescriptionTable == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Link = NULL;
+ *PrmAcpiDescriptionTable = NULL;
+
+ DEBUG ((DEBUG_INFO, " %a %a: %d total PRM modules to process.\n", _DBGMSGID_, __FUNCTION__, mPrmModuleCount));
+ DEBUG ((DEBUG_INFO, " %a %a: %d total PRM handlers to process.\n", _DBGMSGID_, __FUNCTION__, mPrmHandlerCount));
+
+ PrmAcpiDescriptionTableBufferSize = (OFFSET_OF (PRM_ACPI_DESCRIPTION_TABLE, PrmModuleInfoStructure) +
+ (OFFSET_OF (PRM_MODULE_INFORMATION_STRUCT, HandlerInfoStructure) * mPrmModuleCount) +
+ (sizeof (PRM_HANDLER_INFORMATION_STRUCT) * mPrmHandlerCount)
+ );
+ DEBUG ((DEBUG_INFO, " %a %a: Total PRM ACPI table size: 0x%x.\n", _DBGMSGID_, __FUNCTION__, PrmAcpiDescriptionTableBufferSize));
+
+ PrmAcpiTable = AllocateZeroPool ((UINTN) PrmAcpiDescriptionTableBufferSize);
+ if (PrmAcpiTable == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PrmAcpiTable->Header.Signature = PRM_TABLE_SIGNATURE;
+ PrmAcpiTable->Header.Length = PrmAcpiDescriptionTableBufferSize;
+ PrmAcpiTable->Header.Revision = PRM_TABLE_REVISION;
+ PrmAcpiTable->Header.Checksum = 0x0;
+ CopyMem (&PrmAcpiTable->Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (PrmAcpiTable->Header.OemId));
+ PrmAcpiTable->Header.OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
+ PrmAcpiTable->Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
+ PrmAcpiTable->Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
+ PrmAcpiTable->Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+ PrmAcpiTable->PrmModuleInfoOffset = OFFSET_OF (PRM_ACPI_DESCRIPTION_TABLE, PrmModuleInfoStructure);
+ PrmAcpiTable->PrmModuleInfoCount = mPrmModuleCount;
+
+ //
+ // Iterate across all PRM Modules on the list
+ //
+ CurrentModuleInfoStruct = &PrmAcpiTable->PrmModuleInfoStructure[0];
+ EFI_LIST_FOR_EACH(Link, &mPrmModuleList)
+ {
+ TempListEntry = CR(Link, PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY, Link, PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE);
+ CurrentImageAddress = TempListEntry->Context->PeCoffImageContext.ImageAddress;
+ CurrentImageExportDirectory = TempListEntry->Context->ExportDirectory;
+ CurrentExportDescriptorStruct = TempListEntry->Context->ExportDescriptor;
+
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: PRM Module - %a with %d handlers.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ (CHAR8 *) ((UINTN) CurrentImageAddress + CurrentImageExportDirectory->Name),
+ CurrentExportDescriptorStruct->NumberPrmHandlers
+ ));
+
+ CurrentModuleInfoStruct->StructureRevision = PRM_MODULE_INFORMATION_STRUCT_REVISION;
+ CurrentModuleInfoStruct->StructureLength = (
+ OFFSET_OF (PRM_MODULE_INFORMATION_STRUCT, HandlerInfoStructure) +
+ (CurrentExportDescriptorStruct->NumberPrmHandlers * sizeof (PRM_HANDLER_INFORMATION_STRUCT))
+ );
+ CopyGuid (&CurrentModuleInfoStruct->Identifier, &CurrentExportDescriptorStruct->ModuleGuid);
+ CurrentModuleInfoStruct->HandlerCount = (UINT32) CurrentExportDescriptorStruct->NumberPrmHandlers;
+ CurrentModuleInfoStruct->HandlerInfoOffset = OFFSET_OF (PRM_MODULE_INFORMATION_STRUCT, HandlerInfoStructure);
+
+ CurrentModuleInfoStruct->MajorRevision = 0;
+ CurrentModuleInfoStruct->MinorRevision = 0;
+ Status = GetImageVersionInPeCoffImage (
+ (VOID *) (UINTN) CurrentImageAddress,
+ &TempListEntry->Context->PeCoffImageContext,
+ &CurrentModuleInfoStruct->MajorRevision,
+ &CurrentModuleInfoStruct->MinorRevision
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetExportEntryAddress (
+ PRM_STRING (PRM_MODULE_UPDATE_LOCK_DESCRIPTOR_NAME),
+ CurrentImageAddress,
+ CurrentImageExportDirectory,
+ (EFI_PHYSICAL_ADDRESS *) &(CurrentModuleInfoStruct->ModuleUpdateLock)
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Found PRM module update lock physical address at 0x%016x.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ CurrentModuleInfoStruct->ModuleUpdateLock
+ ));
+ }
+
+ // It is currently valid for a PRM module not to use a context buffer
+ Status = GetModuleContextBuffers (
+ ByModuleGuid,
+ &CurrentModuleInfoStruct->Identifier,
+ &CurrentModuleContextBuffers
+ );
+ ASSERT (!EFI_ERROR (Status) || Status == EFI_NOT_FOUND);
+ if (!EFI_ERROR (Status) && CurrentModuleContextBuffers != NULL) {
+ CurrentModuleInfoStruct->RuntimeMmioRanges = (UINT64) (UINTN) CurrentModuleContextBuffers->RuntimeMmioRanges;
+ }
+
+ //
+ // Iterate across all PRM handlers in the PRM Module
+ //
+ for (HandlerIndex = 0; HandlerIndex < CurrentExportDescriptorStruct->NumberPrmHandlers; HandlerIndex++) {
+ CurrentHandlerInfoStruct = &(CurrentModuleInfoStruct->HandlerInfoStructure[HandlerIndex]);
+
+ CurrentHandlerInfoStruct->StructureRevision = PRM_HANDLER_INFORMATION_STRUCT_REVISION;
+ CurrentHandlerInfoStruct->StructureLength = sizeof (PRM_HANDLER_INFORMATION_STRUCT);
+ CopyGuid (
+ &CurrentHandlerInfoStruct->Identifier,
+ &CurrentExportDescriptorStruct->PrmHandlerExportDescriptors[HandlerIndex].PrmHandlerGuid
+ );
+
+ CurrentExportDescriptorHandlerName = (CONST CHAR8 *) CurrentExportDescriptorStruct->PrmHandlerExportDescriptors[HandlerIndex].PrmHandlerName;
+
+ Status = GetContextBuffer (
+ &CurrentHandlerInfoStruct->Identifier,
+ CurrentModuleContextBuffers,
+ &CurrentContextBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ CurrentHandlerInfoStruct->PrmContextBuffer = (UINT64) CurrentContextBuffer;
+ }
+
+ Status = GetExportEntryAddress (
+ CurrentExportDescriptorHandlerName,
+ CurrentImageAddress,
+ CurrentImageExportDirectory,
+ &HandlerPhysicalAddress
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ CurrentHandlerInfoStruct->PhysicalAddress = HandlerPhysicalAddress;
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Found %a handler physical address at 0x%016x.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ CurrentExportDescriptorHandlerName,
+ CurrentHandlerInfoStruct->PhysicalAddress
+ ));
+ }
+ }
+ CurrentModuleInfoStruct = (PRM_MODULE_INFORMATION_STRUCT *) ((UINTN) CurrentModuleInfoStruct + CurrentModuleInfoStruct->StructureLength);
+ }
+ *PrmAcpiDescriptionTable = PrmAcpiTable;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Publishes the PRM ACPI table (PRMT).
+
+ @param[in] PrmAcpiDescriptionTable A pointer to a buffer with a completely populated and valid PRM
+ ACPI description table.
+
+ @retval EFI_SUCCESS The PRM ACPI was installed successfully.
+ @retval EFI_INVALID_PARAMETER THe parameter PrmAcpiDescriptionTable is NULL or the table signature
+ in the table provided is invalid.
+ @retval EFI_NOT_FOUND The protocol gEfiAcpiTableProtocolGuid could not be found.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to allocate the PRM ACPI table buffer.
+
+**/
+EFI_STATUS
+PublishPrmAcpiTable (
+ IN PRM_ACPI_DESCRIPTION_TABLE *PrmAcpiDescriptionTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+ UINTN TableKey;
+
+ if (PrmAcpiDescriptionTable == NULL || PrmAcpiDescriptionTable->Header.Signature != PRM_TABLE_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);
+ if (!EFI_ERROR (Status)) {
+ TableKey = 0;
+ //
+ // Publish the PRM ACPI table. The table checksum will be computed during installation.
+ //
+ Status = AcpiTableProtocol->InstallAcpiTable (
+ AcpiTableProtocol,
+ PrmAcpiDescriptionTable,
+ PrmAcpiDescriptionTable->Header.Length,
+ &TableKey
+ );
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "%a %a: The PRMT ACPI table was installed successfully.\n", _DBGMSGID_, __FUNCTION__));
+ }
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ The PRM Loader END_OF_DXE protocol notification event handler.
+
+ All PRM Modules that are eligible for dispatch should have been loaded the DXE Dispatcher at the
+ time of this function invocation.
+
+ The main responsibilities of the PRM Loader are executed from this function which include 3 phases:
+ 1.) Disover PRM Modules - Find all PRM modules loaded during DXE dispatch and insert a PRM Module
+ Context entry into a linked list to be handed off to phase 2.
+ 2.) Process PRM Modules - Build a GUID to PRM handler mapping for each module that is described in the
+ PRM ACPI table so the OS can resolve a PRM Handler GUID to the corresponding PRM Handler physical address.
+ 3.) Publish PRM ACPI Table - Publish the PRM ACPI table with the information gathered in the phase 2.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+ @retval EFI_SUCCESS The function executed successfully
+
+**/
+EFI_STATUS
+EFIAPI
+PrmLoaderEndOfDxeNotification (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ PRM_ACPI_DESCRIPTION_TABLE *PrmAcpiDescriptionTable;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ InitializeListHead (&mPrmModuleList);
+
+ Status = DiscoverPrmModules ();
+ ASSERT_EFI_ERROR (Status);
+
+ Status = ProcessPrmModules (&PrmAcpiDescriptionTable);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PublishPrmAcpiTable (PrmAcpiDescriptionTable);
+ ASSERT_EFI_ERROR (Status);
+
+ if (PrmAcpiDescriptionTable != NULL) {
+ FreePool (PrmAcpiDescriptionTable);
+ }
+ gBS->CloseEvent (Event);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The entry point for this module.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval Others An error occurred when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+PrmLoaderEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT EndOfDxeEvent;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ //
+ // Discover and process installed PRM modules at the End of DXE
+ // The PRM ACPI table is published if one or PRM modules are discovered
+ //
+ Status = gBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ PrmLoaderEndOfDxeNotification,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a %a: EndOfDxe callback registration failed! %r.\n", _DBGMSGID_, __FUNCTION__, Status));
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/PrmPkg/PrmConfigDxe/PrmConfigDxe.inf b/PrmPkg/PrmConfigDxe/PrmConfigDxe.inf
new file mode 100644
index 000000000000..88613c146a0b
--- /dev/null
+++ b/PrmPkg/PrmConfigDxe/PrmConfigDxe.inf
@@ -0,0 +1,48 @@
+## @file
+# PRM Configuration Driver
+#
+# This driver configures PRM Module settings during the boot services environment.
+#
+# Copyright (c) Microsoft Corporation
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PrmConfigDxe
+ FILE_GUID = 18D93D57-0B00-4213-B0A2-A2FF5EC214E4
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PrmConfigEntryPoint
+
+[Sources]
+ PrmConfigDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid
+ gEfiEventVirtualAddressChangeGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DxeServicesTableLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiRuntimeServicesTableLib
+ UefiLib
+
+[Protocols]
+ gPrmConfigProtocolGuid
+
+[Depex]
+ TRUE
diff --git a/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h b/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
new file mode 100644
index 000000000000..6b9099ca7ba7
--- /dev/null
+++ b/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
@@ -0,0 +1,97 @@
+/** @file
+
+ Definition for the Platform Runtime Mechanism (PRM) ACPI table (PRMT).
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PRMT_ACPI_TABLE_H_
+#define PRMT_ACPI_TABLE_H_
+
+#include <Base.h>
+#include <IndustryStandard/Acpi10.h>
+
+#define PRM_TABLE_SIGNATURE SIGNATURE_32 ('P', 'R', 'M', 'T')
+
+#define PRM_TABLE_REVISION 0x0
+#define PRM_MODULE_INFORMATION_STRUCT_REVISION 0x00
+#define PRM_HANDLER_INFORMATION_STRUCT_REVISION 0x00
+
+#pragma pack(push, 1)
+
+//
+// Platform Runtime Mechanism (PRM) ACPI Table (PRMT) structures
+//
+typedef struct {
+ UINT16 StructureRevision; ///< Revision of this structure
+ UINT16 StructureLength; ///< Length in bytes of this structure
+ GUID Identifier; ///< GUID of the PRM handler for this structure
+ UINT64 PhysicalAddress; ///< Physical address of this PRM handler
+ UINT64 PrmContextBuffer; ///< Physical address of the context buffer for this
+ ///< PRM handler (PRM_CONTEXT_BUFFER *)
+ UINT64 StaticDataBuffer; ///< Physical address of the static data buffer for
+ ///< this PRM handler (PRM_DATA_BUFFER *)
+ UINT64 AcpiParameterBuffer; ///< Physical address of the parameter buffer
+ ///< for this PRM handler (PRM_DATA_BUFFER *)
+ ///< that is only used in the case of _DSM invocation.
+ ///< If _DSM invocation is not used, this value is
+ ///< ignored.
+} PRM_HANDLER_INFORMATION_STRUCT;
+
+typedef struct {
+ UINT16 StructureRevision; ///< Revision of this structure
+ UINT16 StructureLength; ///< Length in bytes of this structure including the
+ ///< variable length PRM Handler Info array
+ GUID Identifier; ///< GUID of the PRM module for this structure
+ UINT16 MajorRevision; ///< PRM module major revision
+ UINT16 MinorRevision; ///< PRM module minor revision
+ UINT16 HandlerCount; ///< Number of entries in the Handler Info array
+ UINT32 HandlerInfoOffset; ///< Offset in bytes from the beginning of this
+ ///< structure to the Handler Info array
+ UINT64 ModuleUpdateLock; ///< Physical address of the PRM Module Update Lock
+ ///< descriptor (PRM_MODULE_UPDATE_LOCK_DESCRIPTOR *)
+ UINT64 RuntimeMmioRanges; ///< Physical address of the PRM MMIO Ranges
+ ///< structure (PRM_MODULE_RUNTIME_MMIO_RANGES *)
+ PRM_HANDLER_INFORMATION_STRUCT HandlerInfoStructure[1];
+} PRM_MODULE_INFORMATION_STRUCT;
+
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header; ///< Standard ACPI description header
+ UINT32 PrmModuleInfoOffset; ///< Offset in bytes from the beginning of this
+ ///< structure to the PRM Module Info array
+ UINT32 PrmModuleInfoCount; ///< Number of entries in the PRM Module Info array
+ PRM_MODULE_INFORMATION_STRUCT PrmModuleInfoStructure[1];
+} PRM_ACPI_DESCRIPTION_TABLE;
+
+#pragma pack(pop)
+
+//
+// Helper macros to build PRM Information structures
+//
+// Todo: Revisit whether to use; currently both macros are not used
+//
+#define PRM_MODULE_INFORMATION_STRUCTURE(ModuleGuid, ModuleRevision, HandlerCount, PrmHanderInfoStructureArray) { \
+ { \
+ PRM_MODULE_INFORMATION_STRUCT_REVISION, /* UINT16 StructureRevision; */ \
+ (OFFSET_OF (PRM_MODULE_INFORMATION_STRUCT, HandlerInfoStructure) + (HandlerCount * sizeof (PRM_HANDLER_INFORMATION_STRUCT))) /* UINT16 StructureLength; */ \
+ ModuleGuid, /* GUID ModuleGuid; */ \
+ ModuleRevision, /* UINT16 ModuleRevision */ \
+ HandlerCount, /* UINT16 HandlerCount */ \
+ OFFSET_OF (PRM_MODULE_INFORMATION_STRUCT, HandlerInfoOffset), /* UINT32 HandlerInfoOffset */ \
+ PrmHanderInfoStructureArray /* PRM_HANDLER_INFORMATION_STRUCT HandlerInfoStructure */ \
+ } \
+ }
+
+#define PRM_HANDLER_INFORMATION_STRUCTURE(HandlerGuid, PhysicalAddress) { \
+ { \
+ PRM_HANDLER_INFORMATION_STRUCT_REVISION, /* UINT16 StructureRevision; */ \
+ sizeof (PRM_HANDLER_INFORMATION_STRUCT), /* UINT16 StructureLength; */ \
+ HandlerGuid, /* GUID HandlerGuid; */ \
+ PhysicalAddress, /* UINT64 PhysicalAddress */ \
+ } \
+ }
+
+#endif // _PRMT_ACPI_TABLE_H_
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoader.h b/PrmPkg/PrmLoaderDxe/PrmLoader.h
new file mode 100644
index 000000000000..1356c7a0c923
--- /dev/null
+++ b/PrmPkg/PrmLoaderDxe/PrmLoader.h
@@ -0,0 +1,51 @@
+/** @file
+
+ Definitions specific to the Platform Runtime Mechanism (PRM) loader.x
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PRM_LOADER_H_
+#define PRM_LOADER_H_
+
+#include <IndustryStandard/PeImage.h>
+#include <Library/PeCoffLib.h>
+
+#include <PrmExportDescriptor.h>
+
+#define _DBGMSGID_ "[PRMLOADER]"
+#define PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE SIGNATURE_32('P','R','M','E')
+
+#pragma pack(push, 1)
+
+typedef struct {
+ PE_COFF_LOADER_IMAGE_CONTEXT PeCoffImageContext;
+ EFI_IMAGE_EXPORT_DIRECTORY *ExportDirectory;
+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *ExportDescriptor;
+} PRM_MODULE_IMAGE_CONTEXT;
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link;
+ PRM_MODULE_IMAGE_CONTEXT *Context;
+} PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY;
+
+#pragma pack(pop)
+
+//
+// Iterate through the double linked list. NOT delete safe.
+//
+#define EFI_LIST_FOR_EACH(Entry, ListHead) \
+ for(Entry = (ListHead)->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink)
+
+//
+// Iterate through the double linked list. This is delete-safe.
+// Don't touch NextEntry.
+//
+#define EFI_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead) \
+ for(Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink;\
+ Entry != (ListHead); Entry = NextEntry, NextEntry = Entry->ForwardLin
+
+#endif
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
new file mode 100644
index 000000000000..643e1a7989f2
--- /dev/null
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
@@ -0,0 +1,59 @@
+## @file
+# PRM Loader Driver
+#
+# This driver discovers PRM Modules loaded in memory and places those modules and the
+# PRM handlers within those modules into a PRMT ACPI table such that the handlers are
+# made available for invocation in the OS.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PrmLoaderDxe
+ FILE_GUID = 226A500A-E14F-414A-A956-40E5762D3D1E
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PrmLoaderEntryPoint
+
+[Sources]
+ PrmAcpiTable.h
+ PrmLoader.h
+ PrmLoaderDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ PeCoffLib
+ PrmContextBufferLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## CONSUMES
+
+[Protocols]
+ gEfiAcpiTableProtocolGuid
+ gEfiLoadedImageProtocolGuid
+ gPrmConfigProtocolGuid
+
+[Depex]
+ TRUE
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 05/41] PrmPkg: Add initial PrmSamplePrintModule
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (3 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 04/41] PrmPkg/PrmConfigDxe: Add initial driver Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 06/41] PrmPkg: Add initial PrmSampleMemoryAllocationModule Michael Kubacki
` (35 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3812
Adds a simple sample PRM module that demonstrates:
1. How to write a PRM module
2. How to use multiple PRM handlers in a module
3. How to use a basic PRM OS service
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/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c | 157 ++++++++++++++++++++
PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf | 39 +++++
2 files changed, 196 insertions(+)
diff --git a/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c
new file mode 100644
index 000000000000..85e8eb28a231
--- /dev/null
+++ b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c
@@ -0,0 +1,157 @@
+/** @file
+
+ A sample PRM Module implementation. This PRM Module provides 3 PRM handlers that simply take a DEBUG print
+ function from the OS and invoke it with a debug message internal the PRM handler.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PrmModule.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+
+//
+// PRM Handler GUIDs
+//
+
+// {d5f2ad5f-a347-4d3e-87bc-c2ce63029cc8}
+#define PRM_HANDLER_1_GUID {0xd5f2ad5f, 0xa347, 0x4d3e, {0x87, 0xbc, 0xc2, 0xce, 0x63, 0x02, 0x9c, 0xc8}}
+
+// {a9e7adc3-8cd0-429a-8915-10946ebde318}
+#define PRM_HANDLER_2_GUID {0xa9e7adc3, 0x8cd0, 0x429a, {0x89, 0x15, 0x10, 0x94, 0x6e, 0xbd, 0xe3, 0x18}}
+
+// {b688c214-4081-4eeb-8d26-1eb5a3bcf11a}
+#define PRM_HANDLER_N_GUID {0xb688c214, 0x4081, 0x4eeb, {0x8d, 0x26, 0x1e, 0xb5, 0xa3, 0xbc, 0xf1, 0x1a}}
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler currently uses the OS_SERVICES to write a debug message
+ indicating this is PRM handler 1.
+
+ @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
+PrmHandler1 (
+ IN VOID *ParameterBuffer,
+ IN PRM_CONTEXT_BUFFER *ContextBUffer
+ )
+{
+ PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
+
+ if (ParameterBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+ OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
+ if (OsServiceDebugPrint == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ OsServiceDebugPrint ("PRM1 handler sample message!\n");
+
+ return EFI_SUCCESS;
+}
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler currently uses the OS_SERVICES to write a debug message
+ indicating this is PRM handler 2.
+
+ @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
+PrmHandler2 (
+ IN VOID *ParameterBuffer,
+ IN PRM_CONTEXT_BUFFER *ContextBUffer
+ )
+{
+ PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
+
+ if (ParameterBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+ OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
+ if (OsServiceDebugPrint == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ OsServiceDebugPrint ("PRM2 handler sample message!\n");
+
+ return EFI_SUCCESS;
+}
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler currently uses the OS_SERVICES to write a debug message
+ indicating this is PRM handler N.
+
+ @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
+PrmHandlerN (
+ IN VOID *ParameterBuffer,
+ IN PRM_CONTEXT_BUFFER *ContextBUffer
+ )
+{
+ PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
+
+ if (ParameterBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+ OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
+ if (OsServiceDebugPrint == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ OsServiceDebugPrint ("PRMN handler sample message!\n");
+
+ return EFI_SUCCESS;
+}
+
+//
+// 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)
+ );
+
+EFI_STATUS
+EFIAPI
+PrmSamplePrintModuleInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
diff --git a/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
new file mode 100644
index 000000000000..d685bf888a1c
--- /dev/null
+++ b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
@@ -0,0 +1,39 @@
+## @file
+# Sample PRM Driver
+#
+# This driver simply uses an OS-provided debug message print service to write
+# a debug message. Three PRM handlers are provided that each print a unique
+# debug message.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PrmSamplePrintModule
+ FILE_GUID = 1652B3C2-A7A1-46AC-AF93-DD6DEE446669
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PrmSamplePrintModuleInit
+
+[Sources]
+ PrmSamplePrintModule.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Depex]
+ TRUE
+
+[BuildOptions.common]
+ MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 06/41] PrmPkg: Add initial PrmSampleMemoryAllocationModule
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (4 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 05/41] PrmPkg: Add initial PrmSamplePrintModule Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 07/41] PrmPkg: Add initial PrmSampleHardwareAccessModule Michael Kubacki
` (34 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3812
DEPRECATED: This module is no longer relevant since OS Services that
allow memory allocation have been removed. It is still present in the
source tree in the event dynamic memory allocation at OS runtime is
needed again.
Adds a sample PRM module that demonstrates:
1. How to write a PRM module
2. How to use a basic PRM OS service
3. How to dynamically allocate memory at OS runtime
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/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.c | 115 ++++++++++++++++++++
PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf | 41 +++++++
2 files changed, 156 insertions(+)
diff --git a/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.c b/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.c
new file mode 100644
index 000000000000..f1245664ab9c
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.c
@@ -0,0 +1,115 @@
+/** @file
+
+ A sample PRM Module implementation. This PRM Module provides 3 PRM handlers that simply take a DEBUG print
+ function from the OS and invoke it with a debug message internal the PRM handler.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PrmModule.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+
+//
+// PRM Handler GUIDs
+//
+
+// {149a5cb3-6a9c-403f-940a-156abf63938a}
+#define PRM_HANDLER_1_GUID {0x149a5cb3, 0x6a9c, 0x403f, {0x94, 0x0a, 0x15, 0x6a, 0xbf, 0x63, 0x93, 0x8a}}
+
+// Note: If the signature size is modified, the PRM Handler test code in this module needs to be updated.
+#define MEMORY_ALLOCATION_TEST_DATA_SIGNATURE SIGNATURE_32('T','E','S','T')
+#define MEMORY_ALLOCATION_TEST_DATA_SIZE sizeof(UINT32)
+#define MEMORY_ALLOCATION_TEST_DATA_BUFFER_SIZE 256
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler currently uses the OS_SERVICES to write a debug message
+ indicating this is PRM handler 1.
+
+ @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
+PrmHandler1 (
+ IN VOID *ParameterBuffer,
+ IN PRM_CONTEXT_BUFFER *ContextBUffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ VOID *NonPagedPool;
+ CHAR8 DebugMessage[256];
+
+ if (OsServices == NULL || OsServices->DebugPrint == NULL || OsServices->AllocateMemory == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OsServices->DebugPrint ("Memory Allocation PrmHandler1 entry.\n");
+ OsServices->DebugPrint (" Requesting allocation of a 256 byte non-paged pool...\n");
+
+ NonPagedPool = NULL;
+ NonPagedPool = OsServices->AllocateMemory (MEMORY_ALLOCATION_TEST_DATA_BUFFER_SIZE, FALSE);
+ if (NonPagedPool == NULL) {
+ OsServices->DebugPrint (" NULL was returned from AllocateMemory()...\n");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " Buffer address returned from AllocateMemory() = 0x%016lx.\n",
+ (UINTN) NonPagedPool
+ );
+ OsServices->DebugPrint (&DebugMessage[0]);
+
+ // Write the test data
+ OsServices->DebugPrint (" Beginning memory buffer write and read back test...\n");
+ SetMem32 (NonPagedPool, MEMORY_ALLOCATION_TEST_DATA_BUFFER_SIZE, MEMORY_ALLOCATION_TEST_DATA_SIGNATURE);
+
+ // Read back and verify the test data is valid
+ for (Index = 0, Status = EFI_SUCCESS; Index < (MEMORY_ALLOCATION_TEST_DATA_BUFFER_SIZE / MEMORY_ALLOCATION_TEST_DATA_SIZE); Index++) {
+ if (((UINT32 *) NonPagedPool)[Index] != MEMORY_ALLOCATION_TEST_DATA_SIGNATURE) {
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+ }
+ if (EFI_ERROR (Status)) {
+ OsServices->DebugPrint (" Memory write & read test failed.\n");
+ } else {
+ OsServices->DebugPrint (" Memory write & read test passed.\n");
+ }
+
+ OsServices->DebugPrint ("Memory Allocation PrmHandler1 exit.\n");
+
+ return EFI_SUCCESS;
+}
+
+//
+// Register the PRM export information for this PRM Module
+//
+PRM_MODULE_EXPORT (
+ PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_1_GUID, PrmHandler1)
+ );
+
+EFI_STATUS
+EFIAPI
+PrmSampleMemoryAllocationModuleInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
diff --git a/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf b/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf
new file mode 100644
index 000000000000..e6798afe19e8
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf
@@ -0,0 +1,41 @@
+## @file
+# Sample PRM Driver
+#
+# This driver simply uses an OS-provided debug message print service to write
+# a debug message. Three PRM handlers are provided that each print a unique
+# debug message.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PrmSampleMemoryAllocationModule
+ FILE_GUID = C6B3E74A-12E3-4364-8FB4-8C8B34DD153B
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PrmSampleMemoryAllocationModuleInit
+
+[Sources]
+ PrmSampleMemoryAllocationModule.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ PrintLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Depex]
+ TRUE
+
+[BuildOptions.common]
+ MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 07/41] PrmPkg: Add initial PrmSampleHardwareAccessModule
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (5 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 06/41] PrmPkg: Add initial PrmSampleMemoryAllocationModule Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 08/41] PrmPkg: Add initial PrmSampleContextBufferModule Michael Kubacki
` (33 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3812
Adds a sample PRM module that demonstrates:
1. How to write a PRM module
2. How to use multiple PRM handlers in a module
3. How to use a basic PRM OS service
4. MSR access at OS runtime
Note: This module contains a PRM handler to read from the HPET MMIO
range but the memory map changes needed for this to succeed
are currently not implemented. These will be implemented in a
future change.
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/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c | 537 ++++++++++++++++++++
PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h | 105 ++++
PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf | 42 ++
3 files changed, 684 insertions(+)
diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
new file mode 100644
index 000000000000..87fe9cafc912
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
@@ -0,0 +1,537 @@
+/** @file
+
+ A sample PRM Module implementation. This PRM Module provides PRM handlers that perform various types
+ of hardware access. This is simply meant to demonstrate hardware access capabilities from a PRM handler.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PrmModule.h>
+
+#include <Library/BaseLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+
+#include <Register/Intel/ArchitecturalMsr.h>
+#include <Register/Intel/Cpuid.h>
+
+#include "Hpet.h"
+
+//
+// PRM Handler GUIDs
+//
+
+// {2120cd3c-848b-4d8f-abbb-4b74ce64ac89}
+#define MSR_ACCESS_MICROCODE_SIGNATURE_PRM_HANDLER_GUID {0x2120cd3c, 0x848b, 0x4d8f, {0xab, 0xbb, 0x4b, 0x74, 0xce, 0x64, 0xac, 0x89}}
+
+// {ea0935a7-506b-4159-bbbb-48deeecb6f58}
+#define MSR_ACCESS_MTRR_DUMP_PRM_HANDLER_GUID {0xea0935a7, 0x506b, 0x4159, {0xbb, 0xbb, 0x48, 0xde, 0xee, 0xcb, 0x6f, 0x58}}
+
+// {1bd1bda9-909a-4614-9699-25ec0c2783f7}
+#define MMIO_ACCESS_HPET_PRM_HANDLER_GUID {0x1bd1bda9, 0x909a, 0x4614, {0x96, 0x99, 0x25, 0xec, 0x0c, 0x27, 0x83, 0xf7}}
+
+#define HPET_BASE_ADDRESS 0xFED00000
+
+//
+// BEGIN: MtrrLib internal library globals and function prototypes here for testing
+//
+extern CONST CHAR8 *mMtrrMemoryCacheTypeShortName[];
+
+/**
+ Initializes the valid bits mask and valid address mask for MTRRs.
+
+ This function initializes the valid bits mask and valid address mask for MTRRs.
+
+ @param[out] MtrrValidBitsMask The mask for the valid bit of the MTRR
+ @param[out] MtrrValidAddressMask The valid address mask for the MTRR
+
+**/
+VOID
+MtrrLibInitializeMtrrMask (
+ OUT UINT64 *MtrrValidBitsMask,
+ OUT UINT64 *MtrrValidAddressMask
+ );
+
+/**
+ Convert variable MTRRs to a RAW MTRR_MEMORY_RANGE array.
+ One MTRR_MEMORY_RANGE element is created for each MTRR setting.
+ The routine doesn't remove the overlap or combine the near-by region.
+
+ @param[in] VariableSettings The variable MTRR values to shadow
+ @param[in] VariableMtrrCount The number of variable MTRRs
+ @param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR
+ @param[in] MtrrValidAddressMask The valid address mask for MTRR
+ @param[out] VariableMtrr The array to shadow variable MTRRs content
+
+ @return Number of MTRRs which has been used.
+
+**/
+UINT32
+MtrrLibGetRawVariableRanges (
+ IN MTRR_VARIABLE_SETTINGS *VariableSettings,
+ IN UINTN VariableMtrrCount,
+ IN UINT64 MtrrValidBitsMask,
+ IN UINT64 MtrrValidAddressMask,
+ OUT MTRR_MEMORY_RANGE *VariableMtrr
+ );
+
+/**
+ Apply the fixed MTRR settings to memory range array.
+
+ @param Fixed The fixed MTRR settings.
+ @param Ranges Return the memory range array holding memory type
+ settings for all memory address.
+ @param RangeCapacity The capacity of memory range array.
+ @param RangeCount Return the count of memory range.
+
+ @retval RETURN_SUCCESS The memory range array is returned successfully.
+ @retval RETURN_OUT_OF_RESOURCES The count of memory ranges exceeds capacity.
+**/
+RETURN_STATUS
+MtrrLibApplyFixedMtrrs (
+ IN MTRR_FIXED_SETTINGS *Fixed,
+ IN OUT MTRR_MEMORY_RANGE *Ranges,
+ IN UINTN RangeCapacity,
+ IN OUT UINTN *RangeCount
+ );
+
+/**
+ Apply the variable MTRR settings to memory range array.
+
+ @param VariableMtrr The variable MTRR array.
+ @param VariableMtrrCount The count of variable MTRRs.
+ @param Ranges Return the memory range array with new MTRR settings applied.
+ @param RangeCapacity The capacity of memory range array.
+ @param RangeCount Return the count of memory range.
+
+ @retval RETURN_SUCCESS The memory range array is returned successfully.
+ @retval RETURN_OUT_OF_RESOURCES The count of memory ranges exceeds capacity.
+**/
+RETURN_STATUS
+MtrrLibApplyVariableMtrrs (
+ IN CONST MTRR_MEMORY_RANGE *VariableMtrr,
+ IN UINT32 VariableMtrrCount,
+ IN OUT MTRR_MEMORY_RANGE *Ranges,
+ IN UINTN RangeCapacity,
+ IN OUT UINTN *RangeCount
+ );
+
+//
+// END: MtrrLib internal library function prototypes here for testing
+//
+
+/**
+ Prints all MTRR values including architectural and variable MTTRs.
+
+**/
+VOID
+EFIAPI
+PrintAllMtrrs (
+ IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint
+ )
+{
+ MTRR_SETTINGS LocalMtrrs;
+ MTRR_SETTINGS *Mtrrs;
+ UINTN Index;
+ UINTN RangeCount;
+ UINT64 MtrrValidBitsMask;
+ UINT64 MtrrValidAddressMask;
+ UINT32 VariableMtrrCount;
+ BOOLEAN ContainVariableMtrr;
+ CHAR8 DebugMessage[256];
+
+ MTRR_MEMORY_RANGE Ranges[
+ MTRR_NUMBER_OF_FIXED_MTRR * sizeof (UINT64) + 2 * ARRAY_SIZE (Mtrrs->Variables.Mtrr) + 1
+ ];
+ MTRR_MEMORY_RANGE RawVariableRanges[ARRAY_SIZE (Mtrrs->Variables.Mtrr)];
+
+ if (OsServiceDebugPrint == NULL || !IsMtrrSupported ()) {
+ return;
+ }
+
+ VariableMtrrCount = GetVariableMtrrCount ();
+
+ MtrrGetAllMtrrs (&LocalMtrrs);
+ Mtrrs = &LocalMtrrs;
+
+ //
+ // Dump RAW MTRR contents
+ //
+ OsServiceDebugPrint (" MTRR Settings:\n");
+ OsServiceDebugPrint (" =============\n");
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " MTRR Default Type: %016lx\n",
+ Mtrrs->MtrrDefType
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " Fixed MTRR[%02d] : %016lx\n",
+ Index,
+ Mtrrs->Fixed.Mtrr[Index]
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+ }
+ ContainVariableMtrr = FALSE;
+ for (Index = 0; Index < VariableMtrrCount; Index++) {
+ if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) {
+ //
+ // If mask is not valid, then do not display range
+ //
+ continue;
+ }
+ ContainVariableMtrr = TRUE;
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",
+ Index,
+ Mtrrs->Variables.Mtrr[Index].Base,
+ Mtrrs->Variables.Mtrr[Index].Mask
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+ }
+ if (!ContainVariableMtrr) {
+ OsServiceDebugPrint (" Variable MTRR : None.\n");
+ }
+ OsServiceDebugPrint ("\n");
+
+ //
+ // Dump MTRR setting in ranges
+ //
+ OsServiceDebugPrint (" Memory Ranges:\n");
+ OsServiceDebugPrint (" ====================================\n");
+ MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
+ Ranges[0].BaseAddress = 0;
+ Ranges[0].Length = MtrrValidBitsMask + 1;
+ Ranges[0].Type = MtrrGetDefaultMemoryType ();
+ RangeCount = 1;
+
+ MtrrLibGetRawVariableRanges (
+ &Mtrrs->Variables, VariableMtrrCount,
+ MtrrValidBitsMask, MtrrValidAddressMask, RawVariableRanges
+ );
+ MtrrLibApplyVariableMtrrs (
+ RawVariableRanges, VariableMtrrCount,
+ Ranges, ARRAY_SIZE (Ranges), &RangeCount
+ );
+
+ MtrrLibApplyFixedMtrrs (&Mtrrs->Fixed, Ranges, ARRAY_SIZE (Ranges), &RangeCount);
+
+ for (Index = 0; Index < RangeCount; Index++) {
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " %a:%016lx-%016lx\n",
+ mMtrrMemoryCacheTypeShortName[Ranges[Index].Type],
+ Ranges[Index].BaseAddress, Ranges[Index].BaseAddress + Ranges[Index].Length - 1
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+ }
+}
+
+/**
+ Reads a HPET MMIO register.
+
+ Reads the 64-bit HPET MMIO register specified by Address.
+
+ This function must guarantee that all MMIO read and write
+ operations are serialized.
+
+ If Address is not aligned on a 64-bit boundary, zero will be returned.
+
+ @param Offset Specifies the offset of the HPET register to read.
+
+ @return The value read.
+
+**/
+UINT64
+EFIAPI
+HpetRead (
+ IN UINTN Offset
+ )
+{
+ UINTN Address;
+ UINT64 Value;
+
+ Address = HPET_BASE_ADDRESS + Offset;
+
+ if ((Address & 7) == 0) {
+ return 0;
+ }
+
+ MemoryFence ();
+ Value = *(volatile UINT64*)Address;
+ MemoryFence ();
+
+ return Value;
+}
+
+/**
+ Prints HPET configuration information.
+
+**/
+VOID
+EFIAPI
+PrintHpetConfiguration (
+ IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint
+ )
+{
+ UINTN TimerIndex;
+ HPET_GENERAL_CAPABILITIES_ID_REGISTER HpetGeneralCapabilities;
+ HPET_GENERAL_CONFIGURATION_REGISTER HpetGeneralConfiguration;
+ CHAR8 DebugMessage[256];
+
+ if (OsServiceDebugPrint == NULL) {
+ return;
+ }
+
+ HpetGeneralCapabilities.Uint64 = HpetRead (HPET_GENERAL_CAPABILITIES_ID_OFFSET);
+ HpetGeneralConfiguration.Uint64 = HpetRead (HPET_GENERAL_CONFIGURATION_OFFSET);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET Base Address = 0x%08x\n",
+ HPET_BASE_ADDRESS
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_GENERAL_CAPABILITIES_ID = 0x%016lx\n",
+ HpetGeneralCapabilities
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_GENERAL_CONFIGURATION = 0x%016lx\n",
+ HpetGeneralConfiguration.Uint64
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_GENERAL_INTERRUPT_STATUS = 0x%016lx\n",
+ HpetRead (HPET_GENERAL_INTERRUPT_STATUS_OFFSET)
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_MAIN_COUNTER = 0x%016lx\n",
+ HpetRead (HPET_MAIN_COUNTER_OFFSET)
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET Main Counter Period = %d (fs)\n",
+ HpetGeneralCapabilities.Bits.CounterClockPeriod
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ for (TimerIndex = 0; TimerIndex <= HpetGeneralCapabilities.Bits.NumberOfTimers; TimerIndex++) {
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_TIMER%d_CONFIGURATION = 0x%016lx\n",
+ TimerIndex,
+ HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_TIMER%d_COMPARATOR = 0x%016lx\n",
+ TimerIndex,
+ HpetRead (HPET_TIMER_COMPARATOR_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_TIMER%d_MSI_ROUTE = 0x%016lx\n",
+ TimerIndex,
+ HpetRead (HPET_TIMER_MSI_ROUTE_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+ }
+}
+
+/**
+ Prints the microcode update signature as read from architectural MSR 0x8B.
+
+**/
+VOID
+EFIAPI
+PrintMicrocodeUpdateSignature (
+ IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint
+ )
+{
+ MSR_IA32_BIOS_SIGN_ID_REGISTER BiosSignIdMsr;
+ CHAR8 DebugMessage[256];
+
+ if (OsServiceDebugPrint == NULL) {
+ return;
+ }
+
+ AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
+ BiosSignIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " Signature read = 0x%x.\n",
+ BiosSignIdMsr.Bits.MicrocodeUpdateSignature
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+}
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler attempts to read the microcode update signature MSR and print the result to a debug message.
+
+ @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.
+
+**/
+PRM_HANDLER_EXPORT (MsrAccessMicrocodeSignaturePrmHandler)
+{
+ PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
+
+ if (ParameterBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+ OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
+ if (OsServiceDebugPrint == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OsServiceDebugPrint ("Hardware Access MsrAccessMicrocodeSignaturePrmHandler entry.\n");
+ OsServiceDebugPrint (" Attempting to read the Microcode Update Signature MSR (0x8B)...\n");
+ PrintMicrocodeUpdateSignature (OsServiceDebugPrint);
+ OsServiceDebugPrint ("Hardware Access MsrAccessMicrocodeSignaturePrmHandler exit.\n");
+
+ return EFI_SUCCESS;
+}
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler attempts to read the current MTRR settings and print the result to a debug message.
+
+ @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.
+
+**/
+PRM_HANDLER_EXPORT (MsrAccessMtrrDumpPrmHandler)
+{
+ PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
+
+ if (ParameterBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+ OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
+ if (OsServiceDebugPrint == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OsServiceDebugPrint ("Hardware Access MsrAccessMtrrDumpPrmHandler entry.\n");
+ OsServiceDebugPrint (" Attempting to dump MTRR values:\n");
+ PrintAllMtrrs (OsServiceDebugPrint);
+ OsServiceDebugPrint ("Hardware Access MsrAccessMtrrDumpPrmHandler exit.\n");
+
+ return EFI_SUCCESS;
+}
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler attempts to read from a HPET MMIO resource and print the result to a debug message.
+
+ @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.
+
+**/
+PRM_HANDLER_EXPORT (MmioAccessHpetPrmHandler)
+{
+ PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
+
+ if (ParameterBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+ OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
+ if (OsServiceDebugPrint == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OsServiceDebugPrint ("Hardware Access MmioAccessHpetPrmHandler entry.\n");
+ OsServiceDebugPrint (" Attempting to read HPET configuration...\n");
+ PrintHpetConfiguration (OsServiceDebugPrint);
+ OsServiceDebugPrint ("Hardware Access MmioAccessHpetPrmHandler exit.\n");
+
+ return EFI_SUCCESS;
+}
+
+//
+// Register the PRM export information for this PRM Module
+//
+PRM_MODULE_EXPORT (
+ PRM_HANDLER_EXPORT_ENTRY (MSR_ACCESS_MICROCODE_SIGNATURE_PRM_HANDLER_GUID, MsrAccessMicrocodeSignaturePrmHandler),
+ PRM_HANDLER_EXPORT_ENTRY (MSR_ACCESS_MTRR_DUMP_PRM_HANDLER_GUID, MsrAccessMtrrDumpPrmHandler),
+ PRM_HANDLER_EXPORT_ENTRY (MMIO_ACCESS_HPET_PRM_HANDLER_GUID, MmioAccessHpetPrmHandler)
+ );
+
+/**
+ Module entry point.
+
+ @param[in] ImageHandle The image handle.
+ @param[in] SystemTable A pointer to the system table.
+
+ @retval EFI_SUCCESS This function always returns success.
+
+**/
+EFI_STATUS
+EFIAPI
+PrmSampleHardwareAccessModuleInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h b/PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
new file mode 100644
index 000000000000..c7eb0cbfa747
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
@@ -0,0 +1,105 @@
+/** @file
+ HPET register definitions from the IA-PC HPET (High Precision Event Timers)
+ Specification, Revision 1.0a, October 2004.
+
+ PRM Module Note:
+ This specific header was copied from PcAtChipsetPkg to avoid a module dependency on the package
+ just for this header. This is done for temporary testing purposes of the PRM module.
+
+ Copyright (c) Microsoft Corporation
+ Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef HPET_REGISTER_H_
+#define HPET_REGISTER_H_
+
+///
+/// HPET General Register Offsets
+///
+#define HPET_GENERAL_CAPABILITIES_ID_OFFSET 0x000
+#define HPET_GENERAL_CONFIGURATION_OFFSET 0x010
+#define HPET_GENERAL_INTERRUPT_STATUS_OFFSET 0x020
+
+///
+/// HPET Timer Register Offsets
+///
+#define HPET_MAIN_COUNTER_OFFSET 0x0F0
+#define HPET_TIMER_CONFIGURATION_OFFSET 0x100
+#define HPET_TIMER_COMPARATOR_OFFSET 0x108
+#define HPET_TIMER_MSI_ROUTE_OFFSET 0x110
+
+///
+/// Stride between sets of HPET Timer Registers
+///
+#define HPET_TIMER_STRIDE 0x20
+
+#pragma pack(1)
+
+///
+/// HPET General Capabilities and ID Register
+///
+typedef union {
+ struct {
+ UINT32 Revision:8;
+ UINT32 NumberOfTimers:5;
+ UINT32 CounterSize:1;
+ UINT32 Reserved0:1;
+ UINT32 LegacyRoute:1;
+ UINT32 VendorId:16;
+ UINT32 CounterClockPeriod:32;
+ } Bits;
+ UINT64 Uint64;
+} HPET_GENERAL_CAPABILITIES_ID_REGISTER;
+
+///
+/// HPET General Configuration Register
+///
+typedef union {
+ struct {
+ UINT32 MainCounterEnable:1;
+ UINT32 LegacyRouteEnable:1;
+ UINT32 Reserved0:30;
+ UINT32 Reserved1:32;
+ } Bits;
+ UINT64 Uint64;
+} HPET_GENERAL_CONFIGURATION_REGISTER;
+
+///
+/// HPET Timer Configuration Register
+///
+typedef union {
+ struct {
+ UINT32 Reserved0:1;
+ UINT32 LevelTriggeredInterrupt:1;
+ UINT32 InterruptEnable:1;
+ UINT32 PeriodicInterruptEnable:1;
+ UINT32 PeriodicInterruptCapability:1;
+ UINT32 CounterSizeCapability:1;
+ UINT32 ValueSetEnable:1;
+ UINT32 Reserved1:1;
+ UINT32 CounterSizeEnable:1;
+ UINT32 InterruptRoute:5;
+ UINT32 MsiInterruptEnable:1;
+ UINT32 MsiInterruptCapability:1;
+ UINT32 Reserved2:16;
+ UINT32 InterruptRouteCapability;
+ } Bits;
+ UINT64 Uint64;
+} HPET_TIMER_CONFIGURATION_REGISTER;
+
+///
+/// HPET Timer MSI Route Register
+///
+typedef union {
+ struct {
+ UINT32 Value:32;
+ UINT32 Address:32;
+ } Bits;
+ UINT64 Uint64;
+} HPET_TIMER_MSI_ROUTE_REGISTER;
+
+#pragma pack()
+
+#endif
diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf
new file mode 100644
index 000000000000..302183c576f9
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf
@@ -0,0 +1,42 @@
+## @file
+# Sample PRM Driver
+#
+# A sample PRM Module implementation. This PRM Module provides PRM handlers that perform various types
+# of hardware access. This is simply meant to demonstrate hardware access capabilities from a PRM handler.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PrmSampleHardwareAccessModule
+ FILE_GUID = 0EF93ED7-14AE-425B-928F-B85A6213B57E
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PrmSampleHardwareAccessModuleInit
+
+[Sources]
+ Hpet.h
+ PrmSampleHardwareAccessModule.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ PrmPkg/PrmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MtrrLib
+ PrintLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Depex]
+ TRUE
+
+[BuildOptions.common]
+ MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE /VERSION:1.0
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 08/41] PrmPkg: Add initial PrmSampleContextBufferModule
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (6 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 07/41] PrmPkg: Add initial PrmSampleHardwareAccessModule Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 09/41] PrmPkg: Add initial package DSC file Michael Kubacki
` (32 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3812
Adds a sample PRM module that demonstrates:
1. How to write a PRM module
2. How to use a basic PRM OS services
3. How to use a basic PRM module configuration library
4. How to use a context buffer during PRM handler execution
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/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c | 203 ++++++++++++++++++++
PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.c | 182 ++++++++++++++++++
PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h | 24 +++
PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf | 39 ++++
PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf | 42 ++++
5 files changed, 490 insertions(+)
diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
new file mode 100644
index 000000000000..3bf5beba7d4a
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
@@ -0,0 +1,203 @@
+/** @file
+
+ The boot services environment configuration library for the Context Buffer Sample PRM module.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/PrmConfig.h>
+#include <Samples/PrmSampleContextBufferModule/Include/StaticData.h>
+
+#include <PrmContextBuffer.h>
+#include <PrmDataBuffer.h>
+
+STATIC EFI_HANDLE mPrmConfigProtocolHandle;
+
+// {5a6cf42b-8bb4-472c-a233-5c4dc4033dc7}
+STATIC CONST EFI_GUID mPrmModuleGuid = {0x5a6cf42b, 0x8bb4, 0x472c, {0xa2, 0x33, 0x5c, 0x4d, 0xc4, 0x03, 0x3d, 0xc7}};
+
+// {e1466081-7562-430f-896b-b0e523dc335a}
+STATIC CONST EFI_GUID mDumpStaticDataBufferPrmHandlerGuid = {0xe1466081, 0x7562, 0x430f, {0x89, 0x6b, 0xb0, 0xe5, 0x23, 0xdc, 0x33, 0x5a}};
+
+/**
+ Populates the static data buffer for this PRM module.
+
+ @param[out] StaticDataBuffer A pointer to the static data buffer.
+
+ @retval EFI_SUCCESS The static data buffer was populated successfully.
+ @retval EFI_INVALID_PARAMETER The StaticDataBuffer pointer argument is NULL.
+
+**/
+EFI_STATUS
+PopulateStaticDataBuffer (
+ OUT STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE *StaticDataBuffer
+ )
+{
+ if (StaticDataBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Note: In a real-world module these values would likely come from somewhere
+ // like a Setup menu option, PCD, binary data, runtime device info, etc. Ideally,
+ // this configuration library would be provided an API to get what it needs (the data)
+ // and not be concerned with how the data is provided. This makes the PRM module more
+ // portable across systems.
+ //
+ StaticDataBuffer->Policy1Enabled = TRUE;
+ StaticDataBuffer->Policy2Enabled = FALSE;
+ SetMem (StaticDataBuffer->SomeValueArray, ARRAY_SIZE (StaticDataBuffer->SomeValueArray), 'D');
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Allocates and populates the static data buffer for this PRM module.
+
+ @param[out] StaticDataBuffer A pointer to a pointer to the static data buffer.
+
+ @retval EFI_SUCCESS The static data buffer was allocated and filled successfully.
+ @retval EFI_INVALID_PARAMETER The StaticDataBuffer pointer argument is NULL.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to allocate the static data buffer.
+
+**/
+EFI_STATUS
+GetStaticDataBuffer (
+ OUT PRM_DATA_BUFFER **StaticDataBuffer
+ )
+{
+ EFI_STATUS Status;
+ PRM_DATA_BUFFER *DataBuffer;
+ UINTN DataBufferLength;
+
+ if (StaticDataBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *StaticDataBuffer = NULL;
+
+ //
+ // Length of the data buffer = Buffer Header Size + Buffer Data Size
+ //
+ DataBufferLength = sizeof (PRM_DATA_BUFFER_HEADER) + sizeof (STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE);
+
+ DataBuffer = AllocateRuntimeZeroPool (DataBufferLength);
+ if (DataBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize the data buffer header
+ //
+ DataBuffer->Header.Signature = PRM_DATA_BUFFER_HEADER_SIGNATURE;
+ DataBuffer->Header.Length = (UINT32) DataBufferLength;
+
+ Status = PopulateStaticDataBuffer ((STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE *) &DataBuffer->Data[0]);
+ ASSERT_EFI_ERROR (Status);
+
+ *StaticDataBuffer = DataBuffer;
+ return EFI_SUCCESS;
+}
+
+/**
+ Constructor of the PRM configuration library.
+
+ @param[in] ImageHandle The image handle of the driver.
+ @param[in] SystemTable The EFI System Table pointer.
+
+ @retval EFI_SUCCESS The shell command handlers were installed successfully.
+ @retval EFI_UNSUPPORTED The shell level required was not found.
+**/
+EFI_STATUS
+EFIAPI
+ContextBufferModuleConfigLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ PRM_CONTEXT_BUFFER *PrmContextBuffer;
+ PRM_DATA_BUFFER *StaticDataBuffer;
+ PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
+
+ PrmContextBuffer = NULL;
+ StaticDataBuffer = NULL;
+ PrmConfigProtocol = NULL;
+
+ /*
+ In this sample PRM module, the protocol describing this sample module's resources is simply
+ installed in the constructor.
+
+ However, if some data is not available until later, this constructor could register a callback
+ on the dependency for the data to be available (e.g. ability to communicate with some device)
+ and then install the protocol. The requirement is that the protocol is installed before end of DXE.
+ */
+
+ //
+ // Allocate and populate the static data buffer
+ //
+ Status = GetStaticDataBuffer (&StaticDataBuffer);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status) || StaticDataBuffer == NULL) {
+ goto Done;
+ }
+
+ //
+ // Allocate and populate the context buffer
+ //
+ // This sample module uses a single context buffer for all the handlers
+ // Todo: This can be done more elegantly in the future. Likely though a library service.
+ //
+ PrmContextBuffer = AllocateRuntimeZeroPool (sizeof (*PrmContextBuffer));
+ ASSERT (PrmContextBuffer != NULL);
+ if (PrmContextBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ CopyGuid (&PrmContextBuffer->HandlerGuid, &mDumpStaticDataBufferPrmHandlerGuid);
+ PrmContextBuffer->Signature = PRM_CONTEXT_BUFFER_SIGNATURE;
+ PrmContextBuffer->Version = PRM_CONTEXT_BUFFER_INTERFACE_VERSION;
+ PrmContextBuffer->StaticDataBuffer = StaticDataBuffer;
+
+ PrmConfigProtocol = AllocateZeroPool (sizeof (*PrmConfigProtocol));
+ ASSERT (PrmConfigProtocol != NULL);
+ if (PrmConfigProtocol == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ CopyGuid (&PrmConfigProtocol->ModuleContextBuffers.ModuleGuid, &mPrmModuleGuid);
+ PrmConfigProtocol->ModuleContextBuffers.BufferCount = 1;
+ PrmConfigProtocol->ModuleContextBuffers.Buffer = PrmContextBuffer;
+
+ //
+ // Install the PRM Configuration Protocol for this module. This indicates the configuration
+ // library has completed resource initialization for the PRM module.
+ //
+ Status = gBS->InstallProtocolInterface (
+ &mPrmConfigProtocolHandle,
+ &gPrmConfigProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID *) PrmConfigProtocol
+ );
+
+Done:
+ if (EFI_ERROR (Status)) {
+ if (StaticDataBuffer != NULL) {
+ FreePool (StaticDataBuffer);
+ }
+ if (PrmContextBuffer != NULL) {
+ FreePool (PrmContextBuffer);
+ }
+ if (PrmConfigProtocol != NULL) {
+ FreePool (PrmConfigProtocol);
+ }
+ }
+
+ return Status;
+}
diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.c b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.c
new file mode 100644
index 000000000000..074552d0c07e
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.c
@@ -0,0 +1,182 @@
+/** @file
+
+ This PRM Module demonstrates how to configure the module data resources in the firmware boot environment
+ and access those resources in a PRM handler at OS runtime.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PrmModule.h>
+
+#include <Library/BaseLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+
+#include <Samples/PrmSampleContextBufferModule/Include/StaticData.h>
+
+//
+// PRM Handler GUIDs
+//
+
+// {e1466081-7562-430f-896b-b0e523dc335a}
+#define DUMP_STATIC_DATA_BUFFER_PRM_HANDLER_GUID {0xe1466081, 0x7562, 0x430f, {0x89, 0x6b, 0xb0, 0xe5, 0x23, 0xdc, 0x33, 0x5a}}
+
+/**
+ Dumps the contents of a given buffer.
+
+ @param[in] OsServiceDebugPrint A pointer to the debug print OS service.
+ @param[in] Buffer A pointer to the buffer that should be dumped.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+**/
+STATIC
+VOID
+DumpBuffer (
+ IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint,
+ IN CONST VOID *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ UINTN Count;
+ CONST UINT8 *Char = Buffer;
+ CHAR8 DebugMessage[16];
+
+ if (OsServiceDebugPrint == NULL || Buffer == NULL) {
+ return;
+ }
+
+ OsServiceDebugPrint (" ");
+ for (Count = 0; Count < BufferSize; Count++)
+ {
+ if (Count && !(Count % 16)) {
+ OsServiceDebugPrint ("\n ");
+ }
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ "%02X ",
+ Char[Count]
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+ }
+ OsServiceDebugPrint ("\n\n");
+}
+
+/**
+ Prints the contents of this PRM module's static data buffer.
+
+ @param[in] OsServiceDebugPrint A pointer to the debug print OS service.
+ @param[in] StaticDataBuffer A pointer to the static buffer.
+
+**/
+VOID
+EFIAPI
+PrintStaticDataBuffer (
+ IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint,
+ IN CONST STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE *StaticDataBuffer
+ )
+{
+ CHAR8 DebugMessage[256];
+
+ if (OsServiceDebugPrint == NULL || StaticDataBuffer == NULL) {
+ return;
+ }
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " Policy1Enabled = 0x%x.\n",
+ StaticDataBuffer->Policy1Enabled
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " Policy2Enabled = 0x%x.\n",
+ StaticDataBuffer->Policy2Enabled
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ OsServiceDebugPrint (" Dumping SomeValueArray:\n");
+ DumpBuffer (
+ OsServiceDebugPrint,
+ (CONST VOID *) &StaticDataBuffer->SomeValueArray[0],
+ ARRAY_SIZE (StaticDataBuffer->SomeValueArray)
+ );
+}
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler attempts to read the contents of the static data buffer that were configured
+ during the firmware boot environment and print those contents at OS runtime.
+
+ @param[in] OsServices An array of pointers to OS provided services for PRM handlers
+ @param[in] Context Handler context info
+
+ @retval EFI_STATUS The PRM handler executed successfully.
+ @retval Others An error occurred in the PRM handler.
+
+**/
+PRM_HANDLER_EXPORT (DumpStaticDataBufferPrmHandler)
+{
+ PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
+
+ if (ContextBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+ OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
+ if (OsServiceDebugPrint == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OsServiceDebugPrint ("Context Buffer DumpStaticDataBufferPrmHandler entry.\n");
+
+ if (ContextBuffer->StaticDataBuffer == NULL) {
+ OsServiceDebugPrint ("The static buffer is not allocated!\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OsServiceDebugPrint (" Printing the contents of the static data buffer:\n");
+
+ //
+ // Verify PRM data buffer signature is valid
+ //
+ if (
+ ContextBuffer->Signature != PRM_CONTEXT_BUFFER_SIGNATURE ||
+ ContextBuffer->StaticDataBuffer->Header.Signature != PRM_DATA_BUFFER_HEADER_SIGNATURE) {
+ OsServiceDebugPrint (" A buffer signature is invalid!\n");
+ return EFI_NOT_FOUND;
+ }
+
+ PrintStaticDataBuffer (
+ OsServiceDebugPrint,
+ (CONST STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE *) &(ContextBuffer->StaticDataBuffer->Data[0])
+ );
+
+ OsServiceDebugPrint ("Context Buffer DumpStaticDataBufferPrmHandler exit.\n");
+
+ return EFI_SUCCESS;
+}
+
+//
+// Register the PRM export information for this PRM Module
+//
+PRM_MODULE_EXPORT (
+ PRM_HANDLER_EXPORT_ENTRY (DUMP_STATIC_DATA_BUFFER_PRM_HANDLER_GUID, DumpStaticDataBufferPrmHandler)
+ );
+
+EFI_STATUS
+EFIAPI
+PrmSampleContextBufferModuleInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h b/PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h
new file mode 100644
index 000000000000..8fe3cf901fad
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h
@@ -0,0 +1,24 @@
+/** @file
+ PRM Module Static Data
+
+ Defines the structure of the static data buffer for the PRM Sample Context Buffer module.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PRM_STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE_H_
+#define PRM_STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE_H_
+
+#include <Base.h>
+
+#define SOME_VALUE_ARRAY_MAX_VALUES 16
+
+typedef struct {
+ BOOLEAN Policy1Enabled;
+ BOOLEAN Policy2Enabled;
+ UINT8 SomeValueArray[SOME_VALUE_ARRAY_MAX_VALUES];
+} STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE;
+
+#endif
diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf
new file mode 100644
index 000000000000..db604680e91e
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Sample PRM Configuration Library Instance
+#
+# The PRM configuration library instance is responsible for initializing and setting the corresponding
+# PRM module's configuration in the boot environment.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeContextBufferModuleConfigLib
+ FILE_GUID = FFB56F09-65E3-4462-A799-2F0D1930D38C
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL |DXE_DRIVER
+ CONSTRUCTOR = ContextBufferModuleConfigLibConstructor
+
+[Sources]
+ DxeContextBufferModuleConfigLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[Protocols]
+ gPrmConfigProtocolGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf
new file mode 100644
index 000000000000..4dd77f526116
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf
@@ -0,0 +1,42 @@
+## @file
+# Sample PRM Driver
+#
+# A sample PRM Module implementation. This PRM Module includes a PRM Module configuration library instance
+# that applies the configuration for the PRM context data in the boot environment. A PRM handler
+# is provided that accesses the context buffer resources and prints their value at OS runtime.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PrmSampleContextBufferModule
+ FILE_GUID = 5A6CF42B-8BB4-472C-A233-5C4DC4033DC7
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PrmSampleContextBufferModuleInit
+
+[Sources]
+ Include/StaticData.h
+ PrmSampleContextBufferModule.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ PrmPkg/PrmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ PrintLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Depex]
+ TRUE
+
+[BuildOptions.common]
+ MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE /VERSION:1.0
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 09/41] PrmPkg: Add initial package DSC file
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (7 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 08/41] PrmPkg: Add initial PrmSampleContextBufferModule Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 10/41] Readme.md: Add initial content Michael Kubacki
` (31 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3812
Adds the PrmPkg DSC file so all of the contents can be built as a
stand-alone package.
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/PrmPkg.dsc | 107 ++++++++++++++++++++
1 file changed, 107 insertions(+)
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
new file mode 100644
index 000000000000..a0237d1fe059
--- /dev/null
+++ b/PrmPkg/PrmPkg.dsc
@@ -0,0 +1,107 @@
+## @file
+# Build description file for PrmPkg
+#
+# Copyright (C) Microsoft Corporation
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ PLATFORM_NAME = Prm
+ PLATFORM_GUID = C29BB610-84F9-448D-A7DD-5A04C5A54F52
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME)
+ SUPPORTED_ARCHITECTURES = IA32|X64
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+
+ DEFINE PLATFORM_PACKAGE = $(PLATFORM_NAME)Pkg
+
+[LibraryClasses.common]
+ #
+ # EDK II Packages
+ #
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+ MemoryAllocationLib|MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf
+ MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
+ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+
+[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER]
+ #
+ # EDK II Packages
+ #
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+
+ #
+ # PRM Package
+ #
+ PrmContextBufferLib|$(PLATFORM_PACKAGE)/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
+
+###################################################################################################
+#
+# Components Section - List of the modules and components that will be processed by compilation
+# tools and the EDK II tools to generate PE32/PE32+/Coff image file.
+#
+###################################################################################################
+
+[Components]
+ #
+ # PRM Libraries
+ #
+ $(PLATFORM_PACKAGE)/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
+ $(PLATFORM_PACKAGE)/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf
+ $(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
+
+ #
+ # PRM Configuration Driver
+ #
+ $(PLATFORM_PACKAGE)/PrmConfigDxe/PrmConfigDxe.inf {
+ <LibraryClasses>
+ NULL|$(PLATFORM_PACKAGE)/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf
+ }
+
+ #
+ # PRM Module Loader Driver
+ #
+ $(PLATFORM_PACKAGE)/PrmLoaderDxe/PrmLoaderDxe.inf
+
+ #
+ # PRM Sample Modules
+ #
+ $(PLATFORM_PACKAGE)/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
+ $(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf {
+ <LibraryClasses>
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ }
+ $(PLATFORM_PACKAGE)/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf
+
+ #
+ # The SampleMemoryAllocationModule was used during a time in the POC when the OS
+ # provided memory allocation services. This module was successful in using those services.
+ # Since OS services have been removed (aside from debug prints), this module is no longer
+ # relevant but kept around for archival purposes.
+ #
+ #$(PLATFORM_PACKAGE)/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf
+
+[BuildOptions]
+# Force deprecated interfaces off
+ *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 10/41] Readme.md: Add initial content
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (8 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 09/41] PrmPkg: Add initial package DSC file Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 11/41] PrmPkg: Add ALLOCATE_CONTEXT_BUFFER_IN_FW build option Michael Kubacki
` (30 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
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
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 11/41] PrmPkg: Add ALLOCATE_CONTEXT_BUFFER_IN_FW build option
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (9 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 10/41] Readme.md: Add initial content Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 12/41] PrmPkg: Enable variable growth for the PRM_MODULE_EXPORT macro Michael Kubacki
` (29 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
There's currently two approaches being considered for how to allocate the
context buffer passed to PRM handlers:
1. The context buffer is allocated and populated in firmware. As such, the
FW converts all pointers internal to the buffer to virtual memory
addresses at the virtual address change event. A single context buffer
pointer is given to the OS via the PRM ACPI table and the OS converts
this single physical address to a virtual address when it passes the
context buffer as a pointer to PRM handlers.
2. The context buffer is allocated and populated in the OS. The OS gets
all the information needed to populate the context buffer from other
pre-existing resources (mainly physical addresses in the PRM ACPI
table). The OS converts all the physical addresses to virtual addresses,
allocates the context buffer instances, and fills in the information.
The OS passes the context buffer virtual address to PRM handlers.
The prior behavior was (1). The current POR behavior has moved to (2).
Until (2) is used more widely, it can be kept around with fairly minimal
overhead via a build flag in a few places.
So the default behavior is now (2) (the expected permanent behavior) with
(1) easily enabled by defining "ALLOCATE_CONTEXT_BUFFER_IN_FW" in the
compiler defined macros. A DSC define was added in PrmPkg.dsc to set this
compiler macro in the package build.
At some point in the future, all code (and some peripheral code)
surrounded with this build flag can be removed if (2) is fully
decided upon.
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/PrmConfigDxe/PrmConfigDxe.c | 51 +++++++++++++-------
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c | 6 ++-
PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c | 16 ++++++
PrmPkg/PrmLoaderDxe/PrmAcpiTable.h | 4 ++
PrmPkg/PrmPkg.dsc | 5 ++
PrmPkg/Readme.md | 12 +++++
6 files changed, 76 insertions(+), 18 deletions(-)
diff --git a/PrmPkg/PrmConfigDxe/PrmConfigDxe.c b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
index cb38146bc9e0..7215c2e1dc6f 100644
--- a/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
+++ b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
@@ -28,8 +28,8 @@
STATIC UINTN mMaxRuntimeMmioRangeCount;
STATIC UINTN mMaxStaticDataBufferCount;
-STATIC PRM_RUNTIME_MMIO_RANGES **mRuntimeMmioRanges;
-STATIC PRM_DATA_BUFFER ***mStaticDataBuffers;
+GLOBAL_REMOVE_IF_UNREFERENCED STATIC PRM_RUNTIME_MMIO_RANGES **mRuntimeMmioRanges;
+GLOBAL_REMOVE_IF_UNREFERENCED STATIC PRM_DATA_BUFFER ***mStaticDataBuffers;
/**
Converts the runtime memory range physical addresses to virtual addresses.
@@ -178,32 +178,23 @@ StoreVirtualMemoryAddressChangePointers (
)
{
EFI_STATUS Status;
- UINTN BufferIndex;
UINTN HandleCount;
UINTN HandleIndex;
UINTN RangeIndex;
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
+ UINTN BufferIndex;
UINTN StaticDataBufferIndex;
+ PRM_CONTEXT_BUFFER *CurrentContextBuffer;
+#endif
EFI_HANDLE *HandleBuffer;
PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
- PRM_CONTEXT_BUFFER *CurrentContextBuffer;
DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
RangeIndex = 0;
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
StaticDataBufferIndex = 0;
- mRuntimeMmioRanges = AllocateRuntimeZeroPool (sizeof (*mRuntimeMmioRanges) * mMaxRuntimeMmioRangeCount);
- if (mRuntimeMmioRanges == NULL && mMaxRuntimeMmioRangeCount > 0) {
- DEBUG ((
- DEBUG_ERROR,
- " %a %a: Memory allocation for runtime MMIO pointer array failed.\n",
- _DBGMSGID_,
- __FUNCTION__
- ));
- ASSERT (FALSE);
- return;
- }
-
mStaticDataBuffers = AllocateRuntimeZeroPool (sizeof (*mStaticDataBuffers) * mMaxStaticDataBufferCount);
if (mStaticDataBuffers == NULL && mMaxStaticDataBufferCount > 0) {
DEBUG ((
@@ -215,6 +206,19 @@ StoreVirtualMemoryAddressChangePointers (
ASSERT (FALSE);
return;
}
+#endif
+
+ mRuntimeMmioRanges = AllocateRuntimeZeroPool (sizeof (*mRuntimeMmioRanges) * mMaxRuntimeMmioRangeCount);
+ if (mRuntimeMmioRanges == NULL && mMaxRuntimeMmioRangeCount > 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ " %a %a: Memory allocation for runtime MMIO pointer array failed.\n",
+ _DBGMSGID_,
+ __FUNCTION__
+ ));
+ ASSERT (FALSE);
+ return;
+ }
HandleBuffer = NULL;
Status = gBS->LocateHandleBuffer (
@@ -236,6 +240,7 @@ StoreVirtualMemoryAddressChangePointers (
continue;
}
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
for (BufferIndex = 0; BufferIndex < PrmConfigProtocol->ModuleContextBuffers.BufferCount; BufferIndex++) {
CurrentContextBuffer = &(PrmConfigProtocol->ModuleContextBuffers.Buffer[BufferIndex]);
@@ -256,6 +261,7 @@ StoreVirtualMemoryAddressChangePointers (
mStaticDataBuffers[StaticDataBufferIndex++] = &CurrentContextBuffer->StaticDataBuffer;
}
}
+#endif
if (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges != NULL) {
if (RangeIndex >= mMaxRuntimeMmioRangeCount) {
Status = EFI_BUFFER_TOO_SMALL;
@@ -280,6 +286,7 @@ StoreVirtualMemoryAddressChangePointers (
__FUNCTION__,
RangeIndex
));
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
DEBUG ((
DEBUG_INFO,
" %a %a: %d static buffers saved for future virtual memory conversion.\n",
@@ -287,6 +294,7 @@ StoreVirtualMemoryAddressChangePointers (
__FUNCTION__,
StaticDataBufferIndex
));
+#endif
}
}
@@ -388,12 +396,14 @@ PrmConfigVirtualAddressChangeEvent (
{
UINTN Index;
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
//
// Convert static data buffer pointers
//
for (Index = 0; Index < mMaxStaticDataBufferCount; Index++) {
gRT->ConvertPointer (0x0, (VOID **) mStaticDataBuffers[Index]);
}
+#endif
//
// Convert runtime MMIO ranges
@@ -484,7 +494,7 @@ PrmConfigEndOfDxeNotification (
if (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges != NULL) {
DEBUG ((
DEBUG_INFO,
- " %a %a: Found %d PRM runtime MMIO ranges to convert.\n",
+ " %a %a: Found %d PRM runtime MMIO ranges.\n",
_DBGMSGID_,
__FUNCTION__,
PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges->Count
@@ -541,6 +551,13 @@ PrmConfigEntryPoint (
);
ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, " %a %a: Context buffers will be allocated in ", _DBGMSGID_, __FUNCTION__));
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
+ DEBUG ((DEBUG_INFO, "firmware.\n"));
+#else
+ DEBUG ((DEBUG_INFO, "the operating system.\n"));
+#endif
+
//
// Register a notification function for virtual address change
//
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
index b43e6d6bf078..85fffdcbd9f1 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -755,7 +755,11 @@ ProcessPrmModules (
&CurrentContextBuffer
);
if (!EFI_ERROR (Status)) {
- CurrentHandlerInfoStruct->PrmContextBuffer = (UINT64) CurrentContextBuffer;
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
+ CurrentHandlerInfoStruct->PrmContextBuffer = (UINT64) (UINTN) CurrentContextBuffer;
+#else
+ CurrentHandlerInfoStruct->StaticDataBuffer = (UINT64) (UINTN) CurrentContextBuffer->StaticDataBuffer;
+#endif
}
Status = GetExportEntryAddress (
diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
index 3bf5beba7d4a..b0b12c012a41 100644
--- a/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
+++ b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
@@ -151,10 +151,26 @@ ContextBufferModuleConfigLibConstructor (
//
// Allocate and populate the context buffer
//
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
+ //
+ // The context buffer allocated in FW will continue being used at OS runtime so it must
+ // be a runtime services data buffer.
+ //
// This sample module uses a single context buffer for all the handlers
// Todo: This can be done more elegantly in the future. Likely though a library service.
//
PrmContextBuffer = AllocateRuntimeZeroPool (sizeof (*PrmContextBuffer));
+#else
+ //
+ // This context buffer is not actually used by PRM handler at OS runtime. The OS will allocate
+ // the actual context buffer passed to the PRM handler.
+ //
+ // This context buffer is used internally in the firmware to associate a PRM handler with a
+ // a static data buffer and a runtime MMIO ranges array so those can be placed into the
+ // PRM_HANDLER_INFORMATION_STRUCT and PRM_MODULE_INFORMATION_STRUCT respectively for the PRM handler.
+ //
+ PrmContextBuffer = AllocateZeroPool (sizeof (*PrmContextBuffer));
+#endif
ASSERT (PrmContextBuffer != NULL);
if (PrmContextBuffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
diff --git a/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h b/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
index 6b9099ca7ba7..8a9c82347d93 100644
--- a/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
+++ b/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
@@ -30,8 +30,10 @@ typedef struct {
UINT16 StructureLength; ///< Length in bytes of this structure
GUID Identifier; ///< GUID of the PRM handler for this structure
UINT64 PhysicalAddress; ///< Physical address of this PRM handler
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
UINT64 PrmContextBuffer; ///< Physical address of the context buffer for this
///< PRM handler (PRM_CONTEXT_BUFFER *)
+#else
UINT64 StaticDataBuffer; ///< Physical address of the static data buffer for
///< this PRM handler (PRM_DATA_BUFFER *)
UINT64 AcpiParameterBuffer; ///< Physical address of the parameter buffer
@@ -39,6 +41,8 @@ typedef struct {
///< that is only used in the case of _DSM invocation.
///< If _DSM invocation is not used, this value is
///< ignored.
+#endif
+
} PRM_HANDLER_INFORMATION_STRUCT;
typedef struct {
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
index a0237d1fe059..1a0ddc6ac181 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -105,3 +105,8 @@ [Components]
[BuildOptions]
# Force deprecated interfaces off
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
+
+# Append package-specific build settings
+!ifdef $(ALLOCATE_CONTEXT_BUFFER_IN_FW)
+ *_*_*_CC_FLAGS = -D ALLOCATE_CONTEXT_BUFFER_IN_FW
+!endif
diff --git a/PrmPkg/Readme.md b/PrmPkg/Readme.md
index b67b3a391e37..00ef41bc5f42 100644
--- a/PrmPkg/Readme.md
+++ b/PrmPkg/Readme.md
@@ -68,6 +68,18 @@ 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).
+* `ALLOCATE_CONTEXT_BUFFER_IN_FW` - Allocates the context buffer for each PRM handler in the firmware instead of
+ the operating system (OS).
+
+ Additional detail: The context buffer structure is defined in [PrmContextBuffer.h](PrmPkg/Include/PrmContextBuffer.h).
+ This structure can be instantiated by either firmware with a physical pointer to the buffer placed in the
+ `PRM_HANDLER_INFORMATION_STRUCT` for each handler wherein the OS would convert that physical pointer and pass it
+ as a virtual address pointer to each PRM handler. Alternatively, the context buffer can be allocated and populated
+ by the OS where it would get all the information to populate the context buffer from other structures.
+
+ The default is for the OS to allocate and populate the buffer. The alternative option of the firmware doing this
+ work is kept in the source code until broader OS testing is completed.
+
## Overview
At a high-level, PRM can be viewed from three levels of granularity:
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 12/41] PrmPkg: Enable variable growth for the PRM_MODULE_EXPORT macro
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (10 preceding siblings ...)
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 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 13/41] PrmPkg: Publish PRM operation region to support PRM ACPI _DSM invocation Michael Kubacki
` (28 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
The PRM_MODULE_EXPORT parameterized macro allows a caller to produce
a static PRM module export descriptor structure in the binary by
simply passing PRM_HANDLER_EXPORT_ENTRY arguments with each argument
representing a PRM handler to be exported by the module.
Previously, the PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT used in the
PRM_MODULE_EXPORT macro was fixed to a maximum of three handlers.
This change removes that restriction and allows the structure to
grow based on the number of PRM handlers given to the macro. This
means a local type will be customized per PRM module. The reference
type PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT keeps a field at the end
that allows array access to PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT
members.
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/PrmLoaderDxe/PrmLoaderDxe.c | 14 +++++------
PrmPkg/Include/PrmExportDescriptor.h | 25 +++++++++++++++++---
2 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
index 85fffdcbd9f1..5fda4c1b01da 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -122,7 +122,7 @@ GetPrmModuleExportDescriptorTable (
return EFI_NOT_FOUND;
}
TempExportDescriptor = (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *) ((UINTN) CurrentImageAddress + ExportAddressTable[PrmModuleExportDescriptorOrdinal]);
- if (TempExportDescriptor->Signature == PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE) {
+ if (TempExportDescriptor->Header.Signature == PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE) {
*ExportDescriptor = TempExportDescriptor;
DEBUG ((DEBUG_INFO, " %a %a: PRM Module Export Descriptor found at 0x%x.\n", _DBGMSGID_, __FUNCTION__, (UINTN) ExportDescriptor));
} else {
@@ -528,7 +528,7 @@ DiscoverPrmModules (
sizeof (*(PrmModuleImageContextListEntry->Context))
);
InsertTailList (&mPrmModuleList, &PrmModuleImageContextListEntry->Link);
- mPrmHandlerCount += TempPrmModuleImageContext.ExportDescriptor->NumberPrmHandlers;
+ mPrmHandlerCount += TempPrmModuleImageContext.ExportDescriptor->Header.NumberPrmHandlers;
mPrmModuleCount++; // Todo: Match with global variable refactor change in the future
DEBUG ((DEBUG_INFO, "%a %a: New PRM Module inserted into list to be processed.\n", _DBGMSGID_, __FUNCTION__));
}
@@ -684,16 +684,16 @@ ProcessPrmModules (
_DBGMSGID_,
__FUNCTION__,
(CHAR8 *) ((UINTN) CurrentImageAddress + CurrentImageExportDirectory->Name),
- CurrentExportDescriptorStruct->NumberPrmHandlers
+ CurrentExportDescriptorStruct->Header.NumberPrmHandlers
));
CurrentModuleInfoStruct->StructureRevision = PRM_MODULE_INFORMATION_STRUCT_REVISION;
CurrentModuleInfoStruct->StructureLength = (
OFFSET_OF (PRM_MODULE_INFORMATION_STRUCT, HandlerInfoStructure) +
- (CurrentExportDescriptorStruct->NumberPrmHandlers * sizeof (PRM_HANDLER_INFORMATION_STRUCT))
+ (CurrentExportDescriptorStruct->Header.NumberPrmHandlers * sizeof (PRM_HANDLER_INFORMATION_STRUCT))
);
- CopyGuid (&CurrentModuleInfoStruct->Identifier, &CurrentExportDescriptorStruct->ModuleGuid);
- CurrentModuleInfoStruct->HandlerCount = (UINT32) CurrentExportDescriptorStruct->NumberPrmHandlers;
+ CopyGuid (&CurrentModuleInfoStruct->Identifier, &CurrentExportDescriptorStruct->Header.ModuleGuid);
+ CurrentModuleInfoStruct->HandlerCount = (UINT32) CurrentExportDescriptorStruct->Header.NumberPrmHandlers;
CurrentModuleInfoStruct->HandlerInfoOffset = OFFSET_OF (PRM_MODULE_INFORMATION_STRUCT, HandlerInfoStructure);
CurrentModuleInfoStruct->MajorRevision = 0;
@@ -737,7 +737,7 @@ ProcessPrmModules (
//
// Iterate across all PRM handlers in the PRM Module
//
- for (HandlerIndex = 0; HandlerIndex < CurrentExportDescriptorStruct->NumberPrmHandlers; HandlerIndex++) {
+ for (HandlerIndex = 0; HandlerIndex < CurrentExportDescriptorStruct->Header.NumberPrmHandlers; HandlerIndex++) {
CurrentHandlerInfoStruct = &(CurrentModuleInfoStruct->HandlerInfoStructure[HandlerIndex]);
CurrentHandlerInfoStruct->StructureRevision = PRM_HANDLER_INFORMATION_STRUCT_REVISION;
diff --git a/PrmPkg/Include/PrmExportDescriptor.h b/PrmPkg/Include/PrmExportDescriptor.h
index 95198cef659c..fc313fd1acc7 100644
--- a/PrmPkg/Include/PrmExportDescriptor.h
+++ b/PrmPkg/Include/PrmExportDescriptor.h
@@ -31,11 +31,23 @@ typedef struct {
UINT16 Revision;
UINT16 NumberPrmHandlers;
GUID ModuleGuid;
- PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT PrmHandlerExportDescriptors[3];
+} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;
+
+typedef struct {
+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header;
+ PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT PrmHandlerExportDescriptors[1];
} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT;
#pragma pack(pop)
+#if defined(_MSC_VER)
+ #define PRM_PACKED_STRUCT(definition) \
+ __pragma(pack(push, 1)) typedef struct definition __pragma(pack(pop))
+#elif defined (__GNUC__) || defined (__clang__)
+ #define PRM_PACKED_STRUCT(definition) \
+ typedef struct __attribute__((packed)) definition
+#endif
+
/**
A macro that declares a PRM Handler Export Descriptor for a PRM Handler.
@@ -73,8 +85,15 @@ typedef struct {
this module.
**/
-#define PRM_MODULE_EXPORT(...) \
- PRM_EXPORT_API PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT PRM_MODULE_EXPORT_DESCRIPTOR_NAME = { \
+#define PRM_MODULE_EXPORT(...) \
+ PRM_PACKED_STRUCT( \
+ { \
+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header; \
+ PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT PrmHandlerExportDescriptors[VA_ARG_COUNT(__VA_ARGS__)]; \
+ } PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_ \
+ ); \
+ \
+ PRM_EXPORT_API PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_ PRM_MODULE_EXPORT_DESCRIPTOR_NAME = { \
{ \
PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE, \
PRM_MODULE_EXPORT_REVISION, \
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 13/41] PrmPkg: Publish PRM operation region to support PRM ACPI _DSM invocation
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (11 preceding siblings ...)
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 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 14/41] PrmPkg: Export major/minor version in PRM module PE COFF header Michael Kubacki
` (27 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Liu <yun.y.liu@intel.com>
A PRM Handler has a 1-to-1 mapping to the corresponding _DSM method.
The UUID of the _DSM Method will be passed by the ASL code to the
OpRegionHandler which will look up the PRMT Table to extract the
pointer of the corresponding PRM Handler.
PRM loader pre-builds an SSDT that includes this PRM operation region.
In boot time, the PRM loader will load and publish this SSDT, so that
in OS runtime ACPI _DSM can invoke the PRM handler by pass the UUID to
PRM operation region.
The pre-build SSDT also includes a PRMT device as a Sample ACPI _DSM to
invoke PRM handler.
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: Liu Yun <yun.y.liu@intel.com>
---
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c | 34 ++++++++
PrmPkg/PrmLoaderDxe/Prm.asl | 87 ++++++++++++++++++++
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf | 4 +
3 files changed, 125 insertions(+)
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
index 5fda4c1b01da..5e14b8e09dd0 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -3,6 +3,7 @@
This file contains the implementation for a Platform Runtime Mechanism (PRM)
loader driver.
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -19,6 +20,7 @@
#include <Library/PrmContextBufferLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
+#include <Library/DxeServicesLib.h>
#include <Protocol/AcpiTable.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/PrmConfig.h>
@@ -809,6 +811,8 @@ PublishPrmAcpiTable (
EFI_STATUS Status;
EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
UINTN TableKey;
+ EFI_ACPI_DESCRIPTION_HEADER *Ssdt;
+ UINTN SsdtSize;
if (PrmAcpiDescriptionTable == NULL || PrmAcpiDescriptionTable->Header.Signature != PRM_TABLE_SIGNATURE) {
return EFI_INVALID_PARAMETER;
@@ -832,6 +836,36 @@ PublishPrmAcpiTable (
}
ASSERT_EFI_ERROR (Status);
+ //
+ // Load SSDT
+ //
+ Status = GetSectionFromFv (
+ &gEfiCallerIdGuid,
+ EFI_SECTION_RAW,
+ 0,
+ (VOID **) &Ssdt,
+ &SsdtSize
+ );
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, "%a %a: SSDT loaded ...\n", _DBGMSGID_, __FUNCTION__));
+
+ //
+ // Update OEM ID
+ //
+ CopyMem (&Ssdt->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Ssdt->OemId));
+
+ //
+ // Publish the SSDT. Table is re-checksumed.
+ //
+ TableKey = 0;
+ Status = AcpiTableProtocol->InstallAcpiTable (
+ AcpiTableProtocol,
+ Ssdt,
+ SsdtSize,
+ &TableKey
+ );
+ ASSERT_EFI_ERROR (Status);
+
return Status;
}
diff --git a/PrmPkg/PrmLoaderDxe/Prm.asl b/PrmPkg/PrmLoaderDxe/Prm.asl
new file mode 100644
index 000000000000..76b56de732da
--- /dev/null
+++ b/PrmPkg/PrmLoaderDxe/Prm.asl
@@ -0,0 +1,87 @@
+/** @file
+ The definition block in ACPI table for PRM Operation Region
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock (
+ "Prm.aml",
+ "SSDT",
+ 0x01,
+ "OEMID",
+ "PRMOPREG",
+ 0x3000
+ )
+{
+ Scope (\_SB)
+ {
+ //
+ // PRM Bridge Device
+ //
+
+ Device (PRMB)
+ {
+ Name (_HID, "80860222")
+ Name (_CID, "80860222")
+ Name (_DDN, "PRM Bridge Device")
+ Name (_STA, 0xF)
+ OperationRegion (OPR1, 0x80, 0, 16)
+ Field (OPR1, DWordAcc, NoLock, Preserve) //Make it ByteAcc for parameter validation
+ {
+ Var0, 128
+ }
+ Method (SETV, 1, Serialized)
+ {
+ CopyObject (Arg0, \_SB.PRMB.Var0)
+ }
+ }
+
+ //
+ // PRM Test Device
+ //
+
+ Device (PRMT)
+ {
+ Name (_HID, "80860223")
+ Name (_CID, "80860223")
+ Name (_DDN, "PRM Test Device")
+ Name (_STA, 0xF)
+ Name (BUF1, Buffer(16)
+ {
+ 0x5F, 0xAD, 0xF2, 0xD5, 0x47, 0xA3, 0x3E, 0x4D, //Guid_0
+ 0x87, 0xBC, 0xC2, 0xCE, 0x63, 0x02, 0x9C, 0xC8, //Guid_1
+ })
+ Name (BUF2, Buffer(16)
+ {
+ 0xC3, 0xAD, 0xE7, 0xA9, 0xD0, 0x8C, 0x9A, 0x42, //Guid_0
+ 0x89, 0x15, 0x10, 0x94, 0x6E, 0xBD, 0xE3, 0x18, //Guid_1
+ })
+ Name (BUF3, Buffer(16)
+ {
+ 0x14, 0xC2, 0x88, 0xB6, 0x81, 0x40, 0xEB, 0x4E, //Guid_0
+ 0x8D, 0x26, 0x1E, 0xB5, 0xA3, 0xBC, 0xF1, 0x1A, //Guid_1
+ })
+ Method (NTST)
+ {
+ \_SB.PRMB.SETV (BUF1)
+ }
+ Method (TST1)
+ {
+ \_SB.PRMB.SETV (BUF1)
+ }
+ Method (TST2)
+ {
+ \_SB.PRMB.SETV (BUF2)
+ }
+ Method (TST3)
+ {
+ \_SB.PRMB.SETV (BUF3)
+ }
+ }
+ }
+
+} // End of Definition Block
+
+
+
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
index 643e1a7989f2..016ced4b3732 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
@@ -5,6 +5,7 @@
# PRM handlers within those modules into a PRMT ACPI table such that the handlers are
# made available for invocation in the OS.
#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -23,6 +24,7 @@ [Sources]
PrmAcpiTable.h
PrmLoader.h
PrmLoaderDxe.c
+ Prm.asl
[Packages]
MdePkg/MdePkg.dec
@@ -42,6 +44,8 @@ [LibraryClasses]
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
+ DxeServicesLib
+ PcdLib
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## CONSUMES
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 14/41] PrmPkg: Export major/minor version in PRM module PE COFF header
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (12 preceding siblings ...)
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 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 15/41] PrmPkg: Add initial PrmSsdtInstallDxe module Michael Kubacki
` (26 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Liu <yun.y.liu@intel.com>
PRMT ACPI defined major version and minor version for each PRM module.
PRM module will build its major/minor version in its PE COFF header.
In boot time, PRM loader will collect the major/minor version from PE COFF
header and fill them into PRMT ACPI table.
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: Liu Yun <yun.y.liu@intel.com>
---
PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf | 2 ++
PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf | 2 ++
PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf | 4 +++-
PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf | 4 +++-
4 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf
index 4dd77f526116..b97af923c47a 100644
--- a/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf
+++ b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf
@@ -5,6 +5,7 @@
# that applies the configuration for the PRM context data in the boot environment. A PRM handler
# is provided that accesses the context buffer resources and prints their value at OS runtime.
#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -40,3 +41,4 @@ [Depex]
[BuildOptions.common]
MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE /VERSION:1.0
+ MSFT:*_*_*_GENFW_FLAGS = --keepoptionalheader
diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf
index 302183c576f9..369d1eb1e86d 100644
--- a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf
+++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf
@@ -4,6 +4,7 @@
# A sample PRM Module implementation. This PRM Module provides PRM handlers that perform various types
# of hardware access. This is simply meant to demonstrate hardware access capabilities from a PRM handler.
#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -40,3 +41,4 @@ [Depex]
[BuildOptions.common]
MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE /VERSION:1.0
+ MSFT:*_*_*_GENFW_FLAGS = --keepoptionalheader
diff --git a/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf b/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf
index e6798afe19e8..06be8f40f4ec 100644
--- a/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf
+++ b/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf
@@ -5,6 +5,7 @@
# a debug message. Three PRM handlers are provided that each print a unique
# debug message.
#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -38,4 +39,5 @@ [Depex]
TRUE
[BuildOptions.common]
- MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE
+ MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE /VERSION:1.0
+ MSFT:*_*_*_GENFW_FLAGS = --keepoptionalheader
diff --git a/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
index d685bf888a1c..7ac291bc6e8a 100644
--- a/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
+++ b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
@@ -5,6 +5,7 @@
# a debug message. Three PRM handlers are provided that each print a unique
# debug message.
#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -36,4 +37,5 @@ [Depex]
TRUE
[BuildOptions.common]
- MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE
+ MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE /VERSION:1.0
+ MSFT:*_*_*_GENFW_FLAGS = --keepoptionalheader
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 15/41] PrmPkg: Add initial PrmSsdtInstallDxe module
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (13 preceding siblings ...)
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 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 16/41] PrmPkg: Remove PRM Module Update Lock Michael Kubacki
` (25 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a new module that installs a PRM SSDT.
Note: A library class would allow a high degree of flexibility for
platforms that choose:
1. To not install a PRM SSDT at all (using a NULL library instance)
2. To install a specific PRM SSDT implementation
However, it is implemented as a driver since build tools are not
linking ACPI tables to drivers from linked library classes.
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/PrmLoaderDxe/PrmLoaderDxe.c | 33 ------
PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c | 110 ++++++++++++++++++++
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf | 4 +-
PrmPkg/PrmPkg.dsc | 5 +
PrmPkg/{PrmLoaderDxe => PrmSsdtInstallDxe}/Prm.asl | 18 +---
PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf | 52 +++++++++
6 files changed, 171 insertions(+), 51 deletions(-)
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
index 5e14b8e09dd0..e45f8685e81f 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -20,7 +20,6 @@
#include <Library/PrmContextBufferLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
-#include <Library/DxeServicesLib.h>
#include <Protocol/AcpiTable.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/PrmConfig.h>
@@ -811,8 +810,6 @@ PublishPrmAcpiTable (
EFI_STATUS Status;
EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
UINTN TableKey;
- EFI_ACPI_DESCRIPTION_HEADER *Ssdt;
- UINTN SsdtSize;
if (PrmAcpiDescriptionTable == NULL || PrmAcpiDescriptionTable->Header.Signature != PRM_TABLE_SIGNATURE) {
return EFI_INVALID_PARAMETER;
@@ -836,36 +833,6 @@ PublishPrmAcpiTable (
}
ASSERT_EFI_ERROR (Status);
- //
- // Load SSDT
- //
- Status = GetSectionFromFv (
- &gEfiCallerIdGuid,
- EFI_SECTION_RAW,
- 0,
- (VOID **) &Ssdt,
- &SsdtSize
- );
- ASSERT_EFI_ERROR (Status);
- DEBUG ((DEBUG_INFO, "%a %a: SSDT loaded ...\n", _DBGMSGID_, __FUNCTION__));
-
- //
- // Update OEM ID
- //
- CopyMem (&Ssdt->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Ssdt->OemId));
-
- //
- // Publish the SSDT. Table is re-checksumed.
- //
- TableKey = 0;
- Status = AcpiTableProtocol->InstallAcpiTable (
- AcpiTableProtocol,
- Ssdt,
- SsdtSize,
- &TableKey
- );
- ASSERT_EFI_ERROR (Status);
-
return Status;
}
diff --git a/PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c b/PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
new file mode 100644
index 000000000000..bd9ce2c6fa02
--- /dev/null
+++ b/PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
@@ -0,0 +1,110 @@
+/** @file
+
+ This file contains a sample implementation of the Platform Runtime Mechanism (PRM)
+ SSDT Install library.
+
+ Copyright (c) Microsoft Corporation
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+
+#define _DBGMSGID_ "[PRMSSDTINSTALL]"
+
+/**
+ Installs the PRM SSDT.
+
+ @param[in] OemId OEM ID to be used in the SSDT installation.
+
+ @retval EFI_SUCCESS The PRM SSDT was installed successfully.
+ @retval EFI_INVALID_PARAMETER The OemId pointer argument is NULL.
+ @retval EFI_NOT_FOUND An instance of gEfiAcpiTableProtocolGuid was not found installed or
+ the SSDT (AML RAW section) could not be found in the current FV.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to install the PRM SSDT.
+
+**/
+EFI_STATUS
+InstallPrmSsdt (
+ IN CONST UINT8 *OemId
+ )
+{
+ EFI_STATUS Status;
+ UINTN SsdtSize;
+ UINTN TableKey;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+ EFI_ACPI_DESCRIPTION_HEADER *Ssdt;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ if (OemId == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Discover the SSDT
+ //
+ Status = GetSectionFromFv (
+ &gEfiCallerIdGuid,
+ EFI_SECTION_RAW,
+ 0,
+ (VOID **) &Ssdt,
+ &SsdtSize
+ );
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, "%a %a: SSDT loaded...\n", _DBGMSGID_, __FUNCTION__));
+
+ //
+ // Update OEM ID in the SSDT
+ //
+ CopyMem (&Ssdt->OemId, OemId, sizeof (Ssdt->OemId));
+
+ //
+ // Publish the SSDT. Table is re-checksummed.
+ //
+ TableKey = 0;
+ Status = AcpiTableProtocol->InstallAcpiTable (
+ AcpiTableProtocol,
+ Ssdt,
+ SsdtSize,
+ &TableKey
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return Status;
+}
+
+/**
+ The entry point for this module.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval Others An error occurred when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+PrmSsdtInstallEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = InstallPrmSsdt ((UINT8 *) PcdGetPtr (PcdAcpiDefaultOemId));
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
index 016ced4b3732..4d959ccd35a3 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
@@ -24,7 +24,6 @@ [Sources]
PrmAcpiTable.h
PrmLoader.h
PrmLoaderDxe.c
- Prm.asl
[Packages]
MdePkg/MdePkg.dec
@@ -39,13 +38,12 @@ [LibraryClasses]
BaseMemoryLib
DebugLib
MemoryAllocationLib
+ PcdLib
PeCoffLib
PrmContextBufferLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
- DxeServicesLib
- PcdLib
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## CONSUMES
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
index 1a0ddc6ac181..d3aeffa152e0 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -84,6 +84,11 @@ [Components]
#
$(PLATFORM_PACKAGE)/PrmLoaderDxe/PrmLoaderDxe.inf
+ #
+ # PRM SSDT Installation Driver
+ #
+ $(PLATFORM_PACKAGE)/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
+
#
# PRM Sample Modules
#
diff --git a/PrmPkg/PrmLoaderDxe/Prm.asl b/PrmPkg/PrmSsdtInstallDxe/Prm.asl
similarity index 82%
rename from PrmPkg/PrmLoaderDxe/Prm.asl
rename to PrmPkg/PrmSsdtInstallDxe/Prm.asl
index 76b56de732da..0457d09e6954 100644
--- a/PrmPkg/PrmLoaderDxe/Prm.asl
+++ b/PrmPkg/PrmSsdtInstallDxe/Prm.asl
@@ -8,10 +8,10 @@
DefinitionBlock (
"Prm.aml",
"SSDT",
- 0x01,
- "OEMID",
+ 2,
+ "OEMID ",
"PRMOPREG",
- 0x3000
+ 0x1000
)
{
Scope (\_SB)
@@ -66,18 +66,6 @@ DefinitionBlock (
{
\_SB.PRMB.SETV (BUF1)
}
- Method (TST1)
- {
- \_SB.PRMB.SETV (BUF1)
- }
- Method (TST2)
- {
- \_SB.PRMB.SETV (BUF2)
- }
- Method (TST3)
- {
- \_SB.PRMB.SETV (BUF3)
- }
}
}
diff --git a/PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf b/PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
new file mode 100644
index 000000000000..e68e9460ddc5
--- /dev/null
+++ b/PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
@@ -0,0 +1,52 @@
+## @file
+# PRM SSDT Installation Driver
+#
+# This driver installs the PRM SSDT.
+# * Not all PRM implementations may need this support and if it is not needed, the driver
+# can simply be removed from the platform build.
+# * The platform may also choose to use this driver but modify the ASL file.
+#
+# Copyright (c) Microsoft Corporation
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PrmSsdtInstallDxe
+ FILE_GUID = B0423E2F-3B2C-4A36-BF98-3EB3B4B7CB0E
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PrmSsdtInstallEntryPoint
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ PrmSsdtInstallDxe.c
+ Prm.asl
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DxeServicesLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## CONSUMES
+
+[Protocols]
+ gEfiAcpiTableProtocolGuid
+
+[Depex]
+ gEfiAcpiTableProtocolGuid
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 16/41] PrmPkg: Remove PRM Module Update Lock
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (14 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 15/41] PrmPkg: Add initial PrmSsdtInstallDxe module Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 17/41] PrmPkg: Remove ALLOCATE_CONTEXT_BUFFER_IN_FW build flag Michael Kubacki
` (24 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Per latest design direction, we've abandoned treating the PRM Module
Update Lock as an exported object. There was concern sharing the PRM
module address space (where the lock structure resided in a data section)
with the OS kernel mode driver. The lock will now be entirely maintained
in OS context with interaces to control the lock available to ASL
(for _DSM invocation) and OS native code (for direct call).
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/PrmLoaderDxe/PrmLoaderDxe.c | 18 --------
PrmPkg/Include/PrmModule.h | 20 ---------
PrmPkg/Include/PrmModuleUpdate.h | 46 --------------------
PrmPkg/PrmLoaderDxe/PrmAcpiTable.h | 2 -
PrmPkg/Readme.md | 37 ++++++++--------
5 files changed, 18 insertions(+), 105 deletions(-)
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
index e45f8685e81f..e2a838ea29bd 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -26,7 +26,6 @@
#include <PrmContextBuffer.h>
#include <PrmMmio.h>
-#include <PrmModuleUpdate.h>
LIST_ENTRY mPrmModuleList;
@@ -707,23 +706,6 @@ ProcessPrmModules (
);
ASSERT_EFI_ERROR (Status);
- Status = GetExportEntryAddress (
- PRM_STRING (PRM_MODULE_UPDATE_LOCK_DESCRIPTOR_NAME),
- CurrentImageAddress,
- CurrentImageExportDirectory,
- (EFI_PHYSICAL_ADDRESS *) &(CurrentModuleInfoStruct->ModuleUpdateLock)
- );
- ASSERT_EFI_ERROR (Status);
- if (!EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_INFO,
- " %a %a: Found PRM module update lock physical address at 0x%016x.\n",
- _DBGMSGID_,
- __FUNCTION__,
- CurrentModuleInfoStruct->ModuleUpdateLock
- ));
- }
-
// It is currently valid for a PRM module not to use a context buffer
Status = GetModuleContextBuffers (
ByModuleGuid,
diff --git a/PrmPkg/Include/PrmModule.h b/PrmPkg/Include/PrmModule.h
index f40fb42a2b4f..d7047d8eec58 100644
--- a/PrmPkg/Include/PrmModule.h
+++ b/PrmPkg/Include/PrmModule.h
@@ -15,7 +15,6 @@
#include <PrmDataBuffer.h>
#include <PrmExportDescriptor.h>
#include <PrmMmio.h>
-#include <PrmModuleUpdate.h>
#include <PrmOsServices.h>
/**
@@ -46,23 +45,4 @@
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
deleted file mode 100644
index fde97eff0462..000000000000
--- a/PrmPkg/Include/PrmModuleUpdate.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/** @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 <Uefi.h>
-
-#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/PrmLoaderDxe/PrmAcpiTable.h b/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
index 8a9c82347d93..ca09be389235 100644
--- a/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
+++ b/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
@@ -55,8 +55,6 @@ typedef struct {
UINT16 HandlerCount; ///< Number of entries in the Handler Info array
UINT32 HandlerInfoOffset; ///< Offset in bytes from the beginning of this
///< structure to the Handler Info array
- UINT64 ModuleUpdateLock; ///< Physical address of the PRM Module Update Lock
- ///< descriptor (PRM_MODULE_UPDATE_LOCK_DESCRIPTOR *)
UINT64 RuntimeMmioRanges; ///< Physical address of the PRM MMIO Ranges
///< structure (PRM_MODULE_RUNTIME_MMIO_RANGES *)
PRM_HANDLER_INFORMATION_STRUCT HandlerInfoStructure[1];
diff --git a/PrmPkg/Readme.md b/PrmPkg/Readme.md
index 00ef41bc5f42..f430006905c5 100644
--- a/PrmPkg/Readme.md
+++ b/PrmPkg/Readme.md
@@ -153,34 +153,33 @@ motivation behind using PE/COFF export tables to expose PRM module information a
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:
+A PRM module must contain at least two exports: A PRM Module Export 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.
+ 0000000000005000: 00 00 00 00 FF FF FF FF 00 00 00 00 3C 50 00 00 ............<P..
+ 0000000000005010: 01 00 00 00 02 00 00 00 02 00 00 00 28 50 00 00 ............(P..
+ 0000000000005020: 30 50 00 00 38 50 00 00 78 13 00 00 20 40 00 00 0P..8P..x... @..
+ 0000000000005030: 5D 50 00 00 7C 50 00 00 00 00 01 00 50 72 6D 53 ]P..|P......PrmS
+ 0000000000005040: 61 6D 70 6C 65 43 6F 6E 74 65 78 74 42 75 66 66 ampleContextBuff
+ 0000000000005050: 65 72 4D 6F 64 75 6C 65 2E 64 6C 6C 00 44 75 6D erModule.dll.Dum
+ 0000000000005060: 70 53 74 61 74 69 63 44 61 74 61 42 75 66 66 65 pStaticDataBuffe
+ 0000000000005070: 72 50 72 6D 48 61 6E 64 6C 65 72 00 50 72 6D 4D rPrmHandler.PrmM
+ 0000000000005080: 6F 64 75 6C 65 45 78 70 6F 72 74 44 65 73 63 72 oduleExportDescr
+ 0000000000005090: 69 70 74 6F 72 00 iptor.
00000000 characteristics
FFFFFFFF time date stamp
- 0.10 version
+ 0.00 version
1 ordinal base
- 3 number of functions
- 3 number of names
+ 2 number of functions
+ 2 number of names
ordinal hint RVA name
+
1 0 00001378 DumpStaticDataBufferPrmHandler
- 2 1 00004030 PrmModuleExportDescriptor
- 3 2 00004020 PrmModuleUpdateLock
+ 2 1 00004020 PrmModuleExportDescriptor
+
```
### PRM Image Format
PRM modules are ultimately PE/COFF images. However, when packaged in firmware the PE/COFF image is placed into a
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 17/41] PrmPkg: Remove ALLOCATE_CONTEXT_BUFFER_IN_FW build flag
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (15 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 16/41] PrmPkg: Remove PRM Module Update Lock Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 18/41] PrmPkg/PrmContextBuffer.h: Add ACPI parameter support structures Michael Kubacki
` (23 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
The POR is firmly to use an OS allocated context buffer now so the
build flag that allows firmware to allocate the context buffer
is removed along with supporting code.
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/PrmConfigDxe/PrmConfigDxe.c | 72 --------------------
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c | 4 --
PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c | 12 +---
PrmPkg/PrmLoaderDxe/PrmAcpiTable.h | 6 --
PrmPkg/PrmPkg.dsc | 5 --
PrmPkg/Readme.md | 12 +---
6 files changed, 4 insertions(+), 107 deletions(-)
diff --git a/PrmPkg/PrmConfigDxe/PrmConfigDxe.c b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
index 7215c2e1dc6f..c547db3eca5e 100644
--- a/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
+++ b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
@@ -26,10 +26,8 @@
#define _DBGMSGID_ "[PRMCONFIG]"
STATIC UINTN mMaxRuntimeMmioRangeCount;
-STATIC UINTN mMaxStaticDataBufferCount;
GLOBAL_REMOVE_IF_UNREFERENCED STATIC PRM_RUNTIME_MMIO_RANGES **mRuntimeMmioRanges;
-GLOBAL_REMOVE_IF_UNREFERENCED STATIC PRM_DATA_BUFFER ***mStaticDataBuffers;
/**
Converts the runtime memory range physical addresses to virtual addresses.
@@ -181,32 +179,12 @@ StoreVirtualMemoryAddressChangePointers (
UINTN HandleCount;
UINTN HandleIndex;
UINTN RangeIndex;
-#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
- UINTN BufferIndex;
- UINTN StaticDataBufferIndex;
- PRM_CONTEXT_BUFFER *CurrentContextBuffer;
-#endif
EFI_HANDLE *HandleBuffer;
PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
RangeIndex = 0;
-#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
- StaticDataBufferIndex = 0;
-
- mStaticDataBuffers = AllocateRuntimeZeroPool (sizeof (*mStaticDataBuffers) * mMaxStaticDataBufferCount);
- if (mStaticDataBuffers == NULL && mMaxStaticDataBufferCount > 0) {
- DEBUG ((
- DEBUG_ERROR,
- " %a %a: Memory allocation for PRM static data buffer pointer array failed.\n",
- _DBGMSGID_,
- __FUNCTION__
- ));
- ASSERT (FALSE);
- return;
- }
-#endif
mRuntimeMmioRanges = AllocateRuntimeZeroPool (sizeof (*mRuntimeMmioRanges) * mMaxRuntimeMmioRangeCount);
if (mRuntimeMmioRanges == NULL && mMaxRuntimeMmioRangeCount > 0) {
@@ -240,28 +218,6 @@ StoreVirtualMemoryAddressChangePointers (
continue;
}
-#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
- for (BufferIndex = 0; BufferIndex < PrmConfigProtocol->ModuleContextBuffers.BufferCount; BufferIndex++) {
- CurrentContextBuffer = &(PrmConfigProtocol->ModuleContextBuffers.Buffer[BufferIndex]);
-
- if (CurrentContextBuffer->StaticDataBuffer != NULL) {
- if (StaticDataBufferIndex >= mMaxStaticDataBufferCount) {
- Status = EFI_BUFFER_TOO_SMALL;
- DEBUG ((
- DEBUG_ERROR,
- " %a %a: Index out of bounds - Actual count (%d) of PRM data buffers exceeds maximum count (%d).\n",
- _DBGMSGID_,
- __FUNCTION__,
- StaticDataBufferIndex + 1,
- mMaxStaticDataBufferCount
- ));
- ASSERT_EFI_ERROR (Status);
- return;
- }
- mStaticDataBuffers[StaticDataBufferIndex++] = &CurrentContextBuffer->StaticDataBuffer;
- }
- }
-#endif
if (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges != NULL) {
if (RangeIndex >= mMaxRuntimeMmioRangeCount) {
Status = EFI_BUFFER_TOO_SMALL;
@@ -286,15 +242,6 @@ StoreVirtualMemoryAddressChangePointers (
__FUNCTION__,
RangeIndex
));
-#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
- DEBUG ((
- DEBUG_INFO,
- " %a %a: %d static buffers saved for future virtual memory conversion.\n",
- _DBGMSGID_,
- __FUNCTION__,
- StaticDataBufferIndex
- ));
-#endif
}
}
@@ -396,15 +343,6 @@ PrmConfigVirtualAddressChangeEvent (
{
UINTN Index;
-#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
- //
- // Convert static data buffer pointers
- //
- for (Index = 0; Index < mMaxStaticDataBufferCount; Index++) {
- gRT->ConvertPointer (0x0, (VOID **) mStaticDataBuffers[Index]);
- }
-#endif
-
//
// Convert runtime MMIO ranges
//
@@ -485,9 +423,6 @@ PrmConfigEndOfDxeNotification (
CurrentContextBuffer->HandlerGuid
));
}
- if (CurrentContextBuffer->StaticDataBuffer != NULL) {
- mMaxStaticDataBufferCount++;
- }
}
DEBUG ((DEBUG_INFO, " %a %a: Module context buffer validation complete.\n", _DBGMSGID_, __FUNCTION__));
@@ -551,13 +486,6 @@ PrmConfigEntryPoint (
);
ASSERT_EFI_ERROR (Status);
- DEBUG ((DEBUG_INFO, " %a %a: Context buffers will be allocated in ", _DBGMSGID_, __FUNCTION__));
-#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
- DEBUG ((DEBUG_INFO, "firmware.\n"));
-#else
- DEBUG ((DEBUG_INFO, "the operating system.\n"));
-#endif
-
//
// Register a notification function for virtual address change
//
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
index e2a838ea29bd..433d81cf8009 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -738,11 +738,7 @@ ProcessPrmModules (
&CurrentContextBuffer
);
if (!EFI_ERROR (Status)) {
-#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
- CurrentHandlerInfoStruct->PrmContextBuffer = (UINT64) (UINTN) CurrentContextBuffer;
-#else
CurrentHandlerInfoStruct->StaticDataBuffer = (UINT64) (UINTN) CurrentContextBuffer->StaticDataBuffer;
-#endif
}
Status = GetExportEntryAddress (
diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
index b0b12c012a41..c222c961f23b 100644
--- a/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
+++ b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
@@ -151,16 +151,7 @@ ContextBufferModuleConfigLibConstructor (
//
// Allocate and populate the context buffer
//
-#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
- //
- // The context buffer allocated in FW will continue being used at OS runtime so it must
- // be a runtime services data buffer.
- //
- // This sample module uses a single context buffer for all the handlers
- // Todo: This can be done more elegantly in the future. Likely though a library service.
- //
- PrmContextBuffer = AllocateRuntimeZeroPool (sizeof (*PrmContextBuffer));
-#else
+
//
// This context buffer is not actually used by PRM handler at OS runtime. The OS will allocate
// the actual context buffer passed to the PRM handler.
@@ -170,7 +161,6 @@ ContextBufferModuleConfigLibConstructor (
// PRM_HANDLER_INFORMATION_STRUCT and PRM_MODULE_INFORMATION_STRUCT respectively for the PRM handler.
//
PrmContextBuffer = AllocateZeroPool (sizeof (*PrmContextBuffer));
-#endif
ASSERT (PrmContextBuffer != NULL);
if (PrmContextBuffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
diff --git a/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h b/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
index ca09be389235..ec3be529d119 100644
--- a/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
+++ b/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
@@ -30,10 +30,6 @@ typedef struct {
UINT16 StructureLength; ///< Length in bytes of this structure
GUID Identifier; ///< GUID of the PRM handler for this structure
UINT64 PhysicalAddress; ///< Physical address of this PRM handler
-#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW
- UINT64 PrmContextBuffer; ///< Physical address of the context buffer for this
- ///< PRM handler (PRM_CONTEXT_BUFFER *)
-#else
UINT64 StaticDataBuffer; ///< Physical address of the static data buffer for
///< this PRM handler (PRM_DATA_BUFFER *)
UINT64 AcpiParameterBuffer; ///< Physical address of the parameter buffer
@@ -41,8 +37,6 @@ typedef struct {
///< that is only used in the case of _DSM invocation.
///< If _DSM invocation is not used, this value is
///< ignored.
-#endif
-
} PRM_HANDLER_INFORMATION_STRUCT;
typedef struct {
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
index d3aeffa152e0..6d352dfadb26 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -110,8 +110,3 @@ [Components]
[BuildOptions]
# Force deprecated interfaces off
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
-
-# Append package-specific build settings
-!ifdef $(ALLOCATE_CONTEXT_BUFFER_IN_FW)
- *_*_*_CC_FLAGS = -D ALLOCATE_CONTEXT_BUFFER_IN_FW
-!endif
diff --git a/PrmPkg/Readme.md b/PrmPkg/Readme.md
index f430006905c5..52b44a95ddbc 100644
--- a/PrmPkg/Readme.md
+++ b/PrmPkg/Readme.md
@@ -68,17 +68,11 @@ 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).
-* `ALLOCATE_CONTEXT_BUFFER_IN_FW` - Allocates the context buffer for each PRM handler in the firmware instead of
- the operating system (OS).
+* NONE - No build flags are currently used.
Additional detail: The context buffer structure is defined in [PrmContextBuffer.h](PrmPkg/Include/PrmContextBuffer.h).
- This structure can be instantiated by either firmware with a physical pointer to the buffer placed in the
- `PRM_HANDLER_INFORMATION_STRUCT` for each handler wherein the OS would convert that physical pointer and pass it
- as a virtual address pointer to each PRM handler. Alternatively, the context buffer can be allocated and populated
- by the OS where it would get all the information to populate the context buffer from other structures.
-
- The default is for the OS to allocate and populate the buffer. The alternative option of the firmware doing this
- work is kept in the source code until broader OS testing is completed.
+ This structure is passed as the context buffer to PRM handlers. The structure actually passed to PRM handlers is
+ allocated and populated by the OS where it gets all the information to populate the context buffer from other structures.
## Overview
At a high-level, PRM can be viewed from three levels of granularity:
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 18/41] PrmPkg/PrmContextBuffer.h: Add ACPI parameter support structures
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (16 preceding siblings ...)
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 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 19/41] PrmPkg/PrmLoaderDxe: Add ACPI parameter buffer support Michael Kubacki
` (22 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a new type ACPI_PARAMETER_BUFFER_DESCRIPTOR that can be
used by PRM module configuration code to associate a PRM handler
GUID with an ACPI parameter buffer allocated by the PRM module
configuration code.
The ACPI parameter buffer descriptors for a given PRM module
are tracked in the firmware internal structure
PRM_MODULE_CONTEXT_BUFFERS produced by the module configuration
code.
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/Include/PrmContextBuffer.h | 41 ++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/PrmPkg/Include/PrmContextBuffer.h b/PrmPkg/Include/PrmContextBuffer.h
index 8f8144545e64..869480101773 100644
--- a/PrmPkg/Include/PrmContextBuffer.h
+++ b/PrmPkg/Include/PrmContextBuffer.h
@@ -19,6 +19,18 @@
#pragma pack(push, 1)
+//
+// Associates an ACPI parameter buffer with a particular PRM handler in
+// a PRM module.
+//
+// If either the GUID or address are zero then neither value is used to
+// copy the ACPI parameter buffer address to the PRMT ACPI table.
+//
+typedef struct {
+ EFI_GUID HandlerGuid;
+ UINT64 AcpiParameterBufferAddress;
+} ACPI_PARAMETER_BUFFER_DESCRIPTOR;
+
//
// This is the context buffer structure that is passed to a PRM handler.
//
@@ -124,6 +136,35 @@ typedef struct
/// This pointer may be NULL if runtime memory ranges are not needed.
///
PRM_RUNTIME_MMIO_RANGES *RuntimeMmioRanges;
+
+ ///
+ /// The number of ACPI parameter buffer descriptors in the array
+ /// AcpiParameterBufferDescriptors
+ ///
+ UINTN AcpiParameterBufferDescriptorCount;
+
+ ///
+ /// A pointer to an array of ACPI parameter buffer descriptors. PRM module
+ /// configuration code uses this structure to associate a specific PRM
+ /// handler with an ACPI parameter buffer.
+ ///
+ /// An ACPI parameter buffer is a parameter buffer allocated by the PRM
+ /// module configuration code to be used by ACPI as a parameter buffer
+ /// to the associated PRM handler at OS runtime.
+ ///
+ /// This buffer is not required if:
+ /// 1. A parameter buffer is not used by a PRM handler at all
+ /// 2. A parameter buffer is used but the PRM handler is never invoked
+ /// from ACPI (it is directly called by an OS device driver for example)
+ ///
+ /// In case #2 above, the direct PRM handler is responsible for allocating
+ /// a parameter buffer and passing that buffer to the PRM handler.
+ ///
+ /// A PRM module only needs to provide an ACPI_PARAMETER_BUFFER_DESCRIPTOR
+ /// for each PRM handler that actually uses an ACPI parameter buffer. If
+ /// no handlers use an ACPI parameter buffer this pointer should be NULL.
+ ///
+ ACPI_PARAMETER_BUFFER_DESCRIPTOR *AcpiParameterBufferDescriptors;
} PRM_MODULE_CONTEXT_BUFFERS;
#pragma pack(pop)
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 19/41] PrmPkg/PrmLoaderDxe: Add ACPI parameter buffer support
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (17 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 18/41] PrmPkg/PrmContextBuffer.h: Add ACPI parameter support structures Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 20/41] PrmPkg/PrmSampleContextBufferModule: Remove OS debug print requirement Michael Kubacki
` (21 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds support to PrmLoaderDxe to move the ACPI parameter buffer
address for a given PRM handler to the corresponding field
in the PRM handler information structure (PRMT ACPI table).
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/PrmLoaderDxe/PrmLoaderDxe.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
index 433d81cf8009..6416e388a668 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -621,6 +621,7 @@ ProcessPrmModules (
PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *TempListEntry;
CONST CHAR8 *CurrentExportDescriptorHandlerName;
+ ACPI_PARAMETER_BUFFER_DESCRIPTOR *CurrentModuleAcpiParamDescriptors;
PRM_CONTEXT_BUFFER *CurrentContextBuffer;
PRM_MODULE_CONTEXT_BUFFERS *CurrentModuleContextBuffers;
PRM_MODULE_INFORMATION_STRUCT *CurrentModuleInfoStruct;
@@ -628,6 +629,7 @@ ProcessPrmModules (
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS CurrentImageAddress;
+ UINTN AcpiParamIndex;
UINTN HandlerIndex;
UINT32 PrmAcpiDescriptionTableBufferSize;
@@ -677,6 +679,7 @@ ProcessPrmModules (
CurrentImageAddress = TempListEntry->Context->PeCoffImageContext.ImageAddress;
CurrentImageExportDirectory = TempListEntry->Context->ExportDirectory;
CurrentExportDescriptorStruct = TempListEntry->Context->ExportDescriptor;
+ CurrentModuleAcpiParamDescriptors = NULL;
DEBUG ((
DEBUG_INFO,
@@ -715,6 +718,7 @@ ProcessPrmModules (
ASSERT (!EFI_ERROR (Status) || Status == EFI_NOT_FOUND);
if (!EFI_ERROR (Status) && CurrentModuleContextBuffers != NULL) {
CurrentModuleInfoStruct->RuntimeMmioRanges = (UINT64) (UINTN) CurrentModuleContextBuffers->RuntimeMmioRanges;
+ CurrentModuleAcpiParamDescriptors = CurrentModuleContextBuffers->AcpiParameterBufferDescriptors;
}
//
@@ -759,6 +763,19 @@ ProcessPrmModules (
CurrentHandlerInfoStruct->PhysicalAddress
));
}
+
+ //
+ // Update the handler ACPI parameter buffer address if applicable
+ //
+ if (CurrentModuleAcpiParamDescriptors != NULL) {
+ for (AcpiParamIndex = 0; AcpiParamIndex < CurrentModuleContextBuffers->AcpiParameterBufferDescriptorCount; AcpiParamIndex++) {
+ if (CompareGuid (&CurrentModuleAcpiParamDescriptors[AcpiParamIndex].HandlerGuid, &CurrentHandlerInfoStruct->Identifier)) {
+ CurrentHandlerInfoStruct->AcpiParameterBuffer = (UINT64) (UINTN) (
+ CurrentModuleAcpiParamDescriptors[AcpiParamIndex].AcpiParameterBufferAddress
+ );
+ }
+ }
+ }
}
CurrentModuleInfoStruct = (PRM_MODULE_INFORMATION_STRUCT *) ((UINTN) CurrentModuleInfoStruct + CurrentModuleInfoStruct->StructureLength);
}
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 20/41] PrmPkg/PrmSampleContextBufferModule: Remove OS debug print requirement
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (18 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 19/41] PrmPkg/PrmLoaderDxe: Add ACPI parameter buffer support Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 21/41] PrmPkg/PrmSampleHardwareAccessModule: Add non-print PRM handlers Michael Kubacki
` (20 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Removes the expectation that the parameter buffer contain an OS
debug print service at the beginning of the buffer. All supporting
code related to printing is also removed.
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/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c | 4 +-
PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.c | 128 +++-----------------
2 files changed, 17 insertions(+), 115 deletions(-)
diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
index c222c961f23b..4c0c3348459c 100644
--- a/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
+++ b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c
@@ -24,7 +24,7 @@ STATIC EFI_HANDLE mPrmConfigProtocolHandle;
STATIC CONST EFI_GUID mPrmModuleGuid = {0x5a6cf42b, 0x8bb4, 0x472c, {0xa2, 0x33, 0x5c, 0x4d, 0xc4, 0x03, 0x3d, 0xc7}};
// {e1466081-7562-430f-896b-b0e523dc335a}
-STATIC CONST EFI_GUID mDumpStaticDataBufferPrmHandlerGuid = {0xe1466081, 0x7562, 0x430f, {0x89, 0x6b, 0xb0, 0xe5, 0x23, 0xdc, 0x33, 0x5a}};
+STATIC CONST EFI_GUID mCheckStaticDataBufferPrmHandlerGuid = {0xe1466081, 0x7562, 0x430f, {0x89, 0x6b, 0xb0, 0xe5, 0x23, 0xdc, 0x33, 0x5a}};
/**
Populates the static data buffer for this PRM module.
@@ -166,7 +166,7 @@ ContextBufferModuleConfigLibConstructor (
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
- CopyGuid (&PrmContextBuffer->HandlerGuid, &mDumpStaticDataBufferPrmHandlerGuid);
+ CopyGuid (&PrmContextBuffer->HandlerGuid, &mCheckStaticDataBufferPrmHandlerGuid);
PrmContextBuffer->Signature = PRM_CONTEXT_BUFFER_SIGNATURE;
PrmContextBuffer->Version = PRM_CONTEXT_BUFFER_INTERFACE_VERSION;
PrmContextBuffer->StaticDataBuffer = StaticDataBuffer;
diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.c b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.c
index 074552d0c07e..5c4e5c7a10eb 100644
--- a/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.c
+++ b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.c
@@ -21,146 +21,39 @@
//
// {e1466081-7562-430f-896b-b0e523dc335a}
-#define DUMP_STATIC_DATA_BUFFER_PRM_HANDLER_GUID {0xe1466081, 0x7562, 0x430f, {0x89, 0x6b, 0xb0, 0xe5, 0x23, 0xdc, 0x33, 0x5a}}
-
-/**
- Dumps the contents of a given buffer.
-
- @param[in] OsServiceDebugPrint A pointer to the debug print OS service.
- @param[in] Buffer A pointer to the buffer that should be dumped.
- @param[in] BufferSize The size of Buffer in bytes.
-
-**/
-STATIC
-VOID
-DumpBuffer (
- IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint,
- IN CONST VOID *Buffer,
- IN UINTN BufferSize
- )
-{
- UINTN Count;
- CONST UINT8 *Char = Buffer;
- CHAR8 DebugMessage[16];
-
- if (OsServiceDebugPrint == NULL || Buffer == NULL) {
- return;
- }
-
- OsServiceDebugPrint (" ");
- for (Count = 0; Count < BufferSize; Count++)
- {
- if (Count && !(Count % 16)) {
- OsServiceDebugPrint ("\n ");
- }
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- "%02X ",
- Char[Count]
- );
- OsServiceDebugPrint (&DebugMessage[0]);
- }
- OsServiceDebugPrint ("\n\n");
-}
-
-/**
- Prints the contents of this PRM module's static data buffer.
-
- @param[in] OsServiceDebugPrint A pointer to the debug print OS service.
- @param[in] StaticDataBuffer A pointer to the static buffer.
-
-**/
-VOID
-EFIAPI
-PrintStaticDataBuffer (
- IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint,
- IN CONST STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE *StaticDataBuffer
- )
-{
- CHAR8 DebugMessage[256];
-
- if (OsServiceDebugPrint == NULL || StaticDataBuffer == NULL) {
- return;
- }
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " Policy1Enabled = 0x%x.\n",
- StaticDataBuffer->Policy1Enabled
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " Policy2Enabled = 0x%x.\n",
- StaticDataBuffer->Policy2Enabled
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- OsServiceDebugPrint (" Dumping SomeValueArray:\n");
- DumpBuffer (
- OsServiceDebugPrint,
- (CONST VOID *) &StaticDataBuffer->SomeValueArray[0],
- ARRAY_SIZE (StaticDataBuffer->SomeValueArray)
- );
-}
+#define CHECK_STATIC_DATA_BUFFER_PRM_HANDLER_GUID {0xe1466081, 0x7562, 0x430f, {0x89, 0x6b, 0xb0, 0xe5, 0x23, 0xdc, 0x33, 0x5a}}
/**
A sample Platform Runtime Mechanism (PRM) handler.
- This sample handler attempts to read the contents of the static data buffer that were configured
- during the firmware boot environment and print those contents at OS runtime.
+ This sample handler checks that a static data buffer can be accessed from a given context buffer.
- @param[in] OsServices An array of pointers to OS provided services for PRM handlers
- @param[in] Context Handler context info
+ @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.
**/
-PRM_HANDLER_EXPORT (DumpStaticDataBufferPrmHandler)
+PRM_HANDLER_EXPORT (CheckStaticDataBufferPrmHandler)
{
- PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
-
if (ContextBuffer == NULL) {
return EFI_INVALID_PARAMETER;
}
- // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
- OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
- if (OsServiceDebugPrint == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- OsServiceDebugPrint ("Context Buffer DumpStaticDataBufferPrmHandler entry.\n");
-
if (ContextBuffer->StaticDataBuffer == NULL) {
- OsServiceDebugPrint ("The static buffer is not allocated!\n");
return EFI_INVALID_PARAMETER;
}
- OsServiceDebugPrint (" Printing the contents of the static data buffer:\n");
-
//
// Verify PRM data buffer signature is valid
//
if (
ContextBuffer->Signature != PRM_CONTEXT_BUFFER_SIGNATURE ||
ContextBuffer->StaticDataBuffer->Header.Signature != PRM_DATA_BUFFER_HEADER_SIGNATURE) {
- OsServiceDebugPrint (" A buffer signature is invalid!\n");
return EFI_NOT_FOUND;
}
- PrintStaticDataBuffer (
- OsServiceDebugPrint,
- (CONST STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE *) &(ContextBuffer->StaticDataBuffer->Data[0])
- );
-
- OsServiceDebugPrint ("Context Buffer DumpStaticDataBufferPrmHandler exit.\n");
-
return EFI_SUCCESS;
}
@@ -168,9 +61,18 @@ PRM_HANDLER_EXPORT (DumpStaticDataBufferPrmHandler)
// Register the PRM export information for this PRM Module
//
PRM_MODULE_EXPORT (
- PRM_HANDLER_EXPORT_ENTRY (DUMP_STATIC_DATA_BUFFER_PRM_HANDLER_GUID, DumpStaticDataBufferPrmHandler)
+ PRM_HANDLER_EXPORT_ENTRY (CHECK_STATIC_DATA_BUFFER_PRM_HANDLER_GUID, CheckStaticDataBufferPrmHandler)
);
+/**
+ Module entry point.
+
+ @param[in] ImageHandle The image handle.
+ @param[in] SystemTable A pointer to the system table.
+
+ @retval EFI_SUCCESS This function always returns success.
+
+**/
EFI_STATUS
EFIAPI
PrmSampleContextBufferModuleInit (
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 21/41] PrmPkg/PrmSampleHardwareAccessModule: Add non-print PRM handlers
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (19 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 20/41] PrmPkg/PrmSampleContextBufferModule: Remove OS debug print requirement Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 22/41] PrmPkg/SampleAcpiParameterBufferModule: Add initial module Michael Kubacki
` (19 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
For each PRM handler that is currently present, a corresponding PRM
handler is added that does not print. This allows a caller to execute
a sample hardware access PRM handler without requiring that caller to
provide a debug print service.
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/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c | 375 +++++++++++++-------
1 file changed, 243 insertions(+), 132 deletions(-)
diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
index 87fe9cafc912..32e04c5e8592 100644
--- a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
+++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
@@ -27,12 +27,21 @@
// {2120cd3c-848b-4d8f-abbb-4b74ce64ac89}
#define MSR_ACCESS_MICROCODE_SIGNATURE_PRM_HANDLER_GUID {0x2120cd3c, 0x848b, 0x4d8f, {0xab, 0xbb, 0x4b, 0x74, 0xce, 0x64, 0xac, 0x89}}
+// {5d28b4e7-3867-4aee-aa09-51fc282c3b22}
+#define MSR_PRINT_MICROCODE_SIGNATURE_PRM_HANDLER_GUID {0x5d28b4e7, 0x3867, 0x4aee, {0xaa, 0x09, 0x51, 0xfc, 0x28, 0x2c, 0x3b, 0x22}}
+
// {ea0935a7-506b-4159-bbbb-48deeecb6f58}
#define MSR_ACCESS_MTRR_DUMP_PRM_HANDLER_GUID {0xea0935a7, 0x506b, 0x4159, {0xbb, 0xbb, 0x48, 0xde, 0xee, 0xcb, 0x6f, 0x58}}
+// {4b64b702-4d2b-4dfe-ac5a-0b4110a2ca47}
+#define MSR_PRINT_MTRR_DUMP_PRM_HANDLER_GUID {0x4b64b702, 0x4d2b, 0x4dfe, {0xac, 0x5a, 0x0b, 0x41, 0x10, 0xa2, 0xca, 0x47}}
+
// {1bd1bda9-909a-4614-9699-25ec0c2783f7}
#define MMIO_ACCESS_HPET_PRM_HANDLER_GUID {0x1bd1bda9, 0x909a, 0x4614, {0x96, 0x99, 0x25, 0xec, 0x0c, 0x27, 0x83, 0xf7}}
+// {8a0efdde-78d0-45f0-aea0-c28245c7e1db}
+#define MMIO_PRINT_HPET_PRM_HANDLER_GUID {0x8a0efdde, 0x78d0, 0x45f0, {0xae, 0xa0, 0xc2, 0x82, 0x45, 0xc7, 0xe1, 0xdb}}
+
#define HPET_BASE_ADDRESS 0xFED00000
//
@@ -124,13 +133,18 @@ MtrrLibApplyVariableMtrrs (
//
/**
- Prints all MTRR values including architectural and variable MTTRs.
+ Accesses MTRR values including architectural and variable MTRRs.
+
+ If the optional OsServiceDebugPrint function pointer is provided that function is
+ used to print the MTRR settings.
+
+ @param[in] OsServiceDebugPrint A pointer to an OS-provided debug print function.
**/
VOID
EFIAPI
-PrintAllMtrrs (
- IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint
+AccessAllMtrrs (
+ IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint OPTIONAL
)
{
MTRR_SETTINGS LocalMtrrs;
@@ -148,7 +162,7 @@ PrintAllMtrrs (
];
MTRR_MEMORY_RANGE RawVariableRanges[ARRAY_SIZE (Mtrrs->Variables.Mtrr)];
- if (OsServiceDebugPrint == NULL || !IsMtrrSupported ()) {
+ if (!IsMtrrSupported ()) {
return;
}
@@ -160,56 +174,63 @@ PrintAllMtrrs (
//
// Dump RAW MTRR contents
//
- OsServiceDebugPrint (" MTRR Settings:\n");
- OsServiceDebugPrint (" =============\n");
+ if (OsServiceDebugPrint != NULL) {
+ OsServiceDebugPrint (" MTRR Settings:\n");
+ OsServiceDebugPrint (" =============\n");
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " MTRR Default Type: %016lx\n",
- Mtrrs->MtrrDefType
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
AsciiSPrint (
&DebugMessage[0],
ARRAY_SIZE (DebugMessage),
- " Fixed MTRR[%02d] : %016lx\n",
- Index,
- Mtrrs->Fixed.Mtrr[Index]
+ " MTRR Default Type: %016lx\n",
+ Mtrrs->MtrrDefType
);
OsServiceDebugPrint (&DebugMessage[0]);
}
- ContainVariableMtrr = FALSE;
- for (Index = 0; Index < VariableMtrrCount; Index++) {
- if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) {
- //
- // If mask is not valid, then do not display range
- //
- continue;
+
+ if (OsServiceDebugPrint != NULL) {
+ for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " Fixed MTRR[%02d] : %016lx\n",
+ Index,
+ Mtrrs->Fixed.Mtrr[Index]
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+ }
+
+ ContainVariableMtrr = FALSE;
+ for (Index = 0; Index < VariableMtrrCount; Index++) {
+ if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) {
+ //
+ // If mask is not valid, then do not display range
+ //
+ continue;
+ }
+ ContainVariableMtrr = TRUE;
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",
+ Index,
+ Mtrrs->Variables.Mtrr[Index].Base,
+ Mtrrs->Variables.Mtrr[Index].Mask
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
}
- ContainVariableMtrr = TRUE;
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",
- Index,
- Mtrrs->Variables.Mtrr[Index].Base,
- Mtrrs->Variables.Mtrr[Index].Mask
- );
- OsServiceDebugPrint (&DebugMessage[0]);
- }
- if (!ContainVariableMtrr) {
- OsServiceDebugPrint (" Variable MTRR : None.\n");
+ if (!ContainVariableMtrr) {
+ OsServiceDebugPrint (" Variable MTRR : None.\n");
+ }
+ OsServiceDebugPrint ("\n");
}
- OsServiceDebugPrint ("\n");
//
// Dump MTRR setting in ranges
//
- OsServiceDebugPrint (" Memory Ranges:\n");
- OsServiceDebugPrint (" ====================================\n");
+ if (OsServiceDebugPrint != NULL) {
+ OsServiceDebugPrint (" Memory Ranges:\n");
+ OsServiceDebugPrint (" ====================================\n");
+ }
MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
Ranges[0].BaseAddress = 0;
Ranges[0].Length = MtrrValidBitsMask + 1;
@@ -227,15 +248,17 @@ PrintAllMtrrs (
MtrrLibApplyFixedMtrrs (&Mtrrs->Fixed, Ranges, ARRAY_SIZE (Ranges), &RangeCount);
- for (Index = 0; Index < RangeCount; Index++) {
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " %a:%016lx-%016lx\n",
- mMtrrMemoryCacheTypeShortName[Ranges[Index].Type],
- Ranges[Index].BaseAddress, Ranges[Index].BaseAddress + Ranges[Index].Length - 1
- );
- OsServiceDebugPrint (&DebugMessage[0]);
+ if (OsServiceDebugPrint != NULL) {
+ for (Index = 0; Index < RangeCount; Index++) {
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " %a:%016lx-%016lx\n",
+ mMtrrMemoryCacheTypeShortName[Ranges[Index].Type],
+ Ranges[Index].BaseAddress, Ranges[Index].BaseAddress + Ranges[Index].Length - 1
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+ }
}
}
@@ -277,12 +300,17 @@ HpetRead (
}
/**
- Prints HPET configuration information.
+ Accesses HPET configuration information.
+
+ If the optional OsServiceDebugPrint function pointer is provided that function is
+ used to print HPET settings.
+
+ @param[in] OsServiceDebugPrint A pointer to an OS-provided debug print function
**/
VOID
EFIAPI
-PrintHpetConfiguration (
+AccessHpetConfiguration (
IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint
)
{
@@ -291,117 +319,132 @@ PrintHpetConfiguration (
HPET_GENERAL_CONFIGURATION_REGISTER HpetGeneralConfiguration;
CHAR8 DebugMessage[256];
- if (OsServiceDebugPrint == NULL) {
- return;
- }
-
HpetGeneralCapabilities.Uint64 = HpetRead (HPET_GENERAL_CAPABILITIES_ID_OFFSET);
HpetGeneralConfiguration.Uint64 = HpetRead (HPET_GENERAL_CONFIGURATION_OFFSET);
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET Base Address = 0x%08x\n",
- HPET_BASE_ADDRESS
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET_GENERAL_CAPABILITIES_ID = 0x%016lx\n",
- HpetGeneralCapabilities
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET_GENERAL_CONFIGURATION = 0x%016lx\n",
- HpetGeneralConfiguration.Uint64
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET_GENERAL_INTERRUPT_STATUS = 0x%016lx\n",
- HpetRead (HPET_GENERAL_INTERRUPT_STATUS_OFFSET)
- );
- OsServiceDebugPrint (&DebugMessage[0]);
+ if (OsServiceDebugPrint != NULL) {
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET Base Address = 0x%08x\n",
+ HPET_BASE_ADDRESS
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET_MAIN_COUNTER = 0x%016lx\n",
- HpetRead (HPET_MAIN_COUNTER_OFFSET)
- );
- OsServiceDebugPrint (&DebugMessage[0]);
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_GENERAL_CAPABILITIES_ID = 0x%016lx\n",
+ HpetGeneralCapabilities
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET Main Counter Period = %d (fs)\n",
- HpetGeneralCapabilities.Bits.CounterClockPeriod
- );
- OsServiceDebugPrint (&DebugMessage[0]);
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_GENERAL_CONFIGURATION = 0x%016lx\n",
+ HpetGeneralConfiguration.Uint64
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
- for (TimerIndex = 0; TimerIndex <= HpetGeneralCapabilities.Bits.NumberOfTimers; TimerIndex++) {
AsciiSPrint (
&DebugMessage[0],
ARRAY_SIZE (DebugMessage),
- " HPET_TIMER%d_CONFIGURATION = 0x%016lx\n",
- TimerIndex,
- HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
+ " HPET_GENERAL_INTERRUPT_STATUS = 0x%016lx\n",
+ HpetRead (HPET_GENERAL_INTERRUPT_STATUS_OFFSET)
);
OsServiceDebugPrint (&DebugMessage[0]);
AsciiSPrint (
&DebugMessage[0],
ARRAY_SIZE (DebugMessage),
- " HPET_TIMER%d_COMPARATOR = 0x%016lx\n",
- TimerIndex,
- HpetRead (HPET_TIMER_COMPARATOR_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
+ " HPET_MAIN_COUNTER = 0x%016lx\n",
+ HpetRead (HPET_MAIN_COUNTER_OFFSET)
);
OsServiceDebugPrint (&DebugMessage[0]);
AsciiSPrint (
&DebugMessage[0],
ARRAY_SIZE (DebugMessage),
- " HPET_TIMER%d_MSI_ROUTE = 0x%016lx\n",
- TimerIndex,
- HpetRead (HPET_TIMER_MSI_ROUTE_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
+ " HPET Main Counter Period = %d (fs)\n",
+ HpetGeneralCapabilities.Bits.CounterClockPeriod
);
OsServiceDebugPrint (&DebugMessage[0]);
+
+ for (TimerIndex = 0; TimerIndex <= HpetGeneralCapabilities.Bits.NumberOfTimers; TimerIndex++) {
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_TIMER%d_CONFIGURATION = 0x%016lx\n",
+ TimerIndex,
+ HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_TIMER%d_COMPARATOR = 0x%016lx\n",
+ TimerIndex,
+ HpetRead (HPET_TIMER_COMPARATOR_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+
+ AsciiSPrint (
+ &DebugMessage[0],
+ ARRAY_SIZE (DebugMessage),
+ " HPET_TIMER%d_MSI_ROUTE = 0x%016lx\n",
+ TimerIndex,
+ HpetRead (HPET_TIMER_MSI_ROUTE_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
+ );
+ OsServiceDebugPrint (&DebugMessage[0]);
+ }
}
}
/**
- Prints the microcode update signature as read from architectural MSR 0x8B.
+ Reads the microcode signature from architectural MSR 0x8B.
+ @retval MicrocodeSignature The microcode signature value.
**/
-VOID
-EFIAPI
-PrintMicrocodeUpdateSignature (
- IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint
+UINT32
+GetMicrocodeSignature (
+ VOID
)
{
MSR_IA32_BIOS_SIGN_ID_REGISTER BiosSignIdMsr;
- CHAR8 DebugMessage[256];
-
- if (OsServiceDebugPrint == NULL) {
- return;
- }
AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
BiosSignIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID);
+ return BiosSignIdMsr.Bits.MicrocodeUpdateSignature;
+}
+
+/**
+ Prints the microcode update signature as read from architectural MSR 0x8B.
+
+**/
+VOID
+EFIAPI
+PrintMicrocodeUpdateSignature (
+ IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint
+ )
+{
+ UINT32 MicrocodeSignature;
+ CHAR8 DebugMessage[256];
+
+ if (OsServiceDebugPrint == NULL) {
+ return;
+ }
+
+ MicrocodeSignature = GetMicrocodeSignature ();
+
AsciiSPrint (
&DebugMessage[0],
ARRAY_SIZE (DebugMessage),
" Signature read = 0x%x.\n",
- BiosSignIdMsr.Bits.MicrocodeUpdateSignature
+ MicrocodeSignature
);
OsServiceDebugPrint (&DebugMessage[0]);
}
@@ -409,7 +452,7 @@ PrintMicrocodeUpdateSignature (
/**
A sample Platform Runtime Mechanism (PRM) handler.
- This sample handler attempts to read the microcode update signature MSR and print the result to a debug message.
+ This sample handler attempts to read the microcode update signature.
@param[in] ParameterBuffer A pointer to the PRM handler parameter buffer
@param[in] ContextBUffer A pointer to the PRM handler context buffer
@@ -419,6 +462,32 @@ PrintMicrocodeUpdateSignature (
**/
PRM_HANDLER_EXPORT (MsrAccessMicrocodeSignaturePrmHandler)
+{
+ UINT32 MicrocodeSignature;
+
+ MicrocodeSignature = 0;
+ MicrocodeSignature = GetMicrocodeSignature ();
+
+ if (MicrocodeSignature == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler attempts to read the microcode update signature MSR and print the result to a debug message.
+
+ @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.
+
+**/
+PRM_HANDLER_EXPORT (MsrPrintMicrocodeSignaturePrmHandler)
{
PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
@@ -426,7 +495,7 @@ PRM_HANDLER_EXPORT (MsrAccessMicrocodeSignaturePrmHandler)
return EFI_INVALID_PARAMETER;
}
- // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+ // The OS debug print service is assumed to be at the beginning of ParameterBuffer
OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
if (OsServiceDebugPrint == NULL) {
return EFI_INVALID_PARAMETER;
@@ -443,7 +512,7 @@ PRM_HANDLER_EXPORT (MsrAccessMicrocodeSignaturePrmHandler)
/**
A sample Platform Runtime Mechanism (PRM) handler.
- This sample handler attempts to read the current MTRR settings and print the result to a debug message.
+ This sample handler attempts to read the current MTRR settings.
@param[in] ParameterBuffer A pointer to the PRM handler parameter buffer
@param[in] ContextBUffer A pointer to the PRM handler context buffer
@@ -453,6 +522,25 @@ PRM_HANDLER_EXPORT (MsrAccessMicrocodeSignaturePrmHandler)
**/
PRM_HANDLER_EXPORT (MsrAccessMtrrDumpPrmHandler)
+{
+ AccessAllMtrrs (NULL);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler attempts to read the current MTRR settings and print the result to a debug message.
+
+ @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.
+
+**/
+PRM_HANDLER_EXPORT (MsrPrintMtrrDumpPrmHandler)
{
PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
@@ -468,16 +556,17 @@ PRM_HANDLER_EXPORT (MsrAccessMtrrDumpPrmHandler)
OsServiceDebugPrint ("Hardware Access MsrAccessMtrrDumpPrmHandler entry.\n");
OsServiceDebugPrint (" Attempting to dump MTRR values:\n");
- PrintAllMtrrs (OsServiceDebugPrint);
+ AccessAllMtrrs (OsServiceDebugPrint);
OsServiceDebugPrint ("Hardware Access MsrAccessMtrrDumpPrmHandler exit.\n");
return EFI_SUCCESS;
}
+
/**
A sample Platform Runtime Mechanism (PRM) handler.
- This sample handler attempts to read from a HPET MMIO resource and print the result to a debug message.
+ This sample handler attempts to read from a HPET MMIO resource.
@param[in] ParameterBuffer A pointer to the PRM handler parameter buffer
@param[in] ContextBUffer A pointer to the PRM handler context buffer
@@ -487,6 +576,25 @@ PRM_HANDLER_EXPORT (MsrAccessMtrrDumpPrmHandler)
**/
PRM_HANDLER_EXPORT (MmioAccessHpetPrmHandler)
+{
+ AccessHpetConfiguration (NULL);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler attempts to read from a HPET MMIO resource and print the result to a debug message.
+
+ @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.
+
+**/
+PRM_HANDLER_EXPORT (MmioPrintHpetPrmHandler)
{
PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
@@ -494,16 +602,16 @@ PRM_HANDLER_EXPORT (MmioAccessHpetPrmHandler)
return EFI_INVALID_PARAMETER;
}
- // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
+ // An OS debug print service is assumed to be at the beginning of ParameterBuffer
OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
if (OsServiceDebugPrint == NULL) {
return EFI_INVALID_PARAMETER;
}
- OsServiceDebugPrint ("Hardware Access MmioAccessHpetPrmHandler entry.\n");
+ OsServiceDebugPrint ("Hardware Access MmioPrintHpetPrmHandler entry.\n");
OsServiceDebugPrint (" Attempting to read HPET configuration...\n");
- PrintHpetConfiguration (OsServiceDebugPrint);
- OsServiceDebugPrint ("Hardware Access MmioAccessHpetPrmHandler exit.\n");
+ AccessHpetConfiguration (OsServiceDebugPrint);
+ OsServiceDebugPrint ("Hardware Access MmioPrintHpetPrmHandler exit.\n");
return EFI_SUCCESS;
}
@@ -514,7 +622,10 @@ PRM_HANDLER_EXPORT (MmioAccessHpetPrmHandler)
PRM_MODULE_EXPORT (
PRM_HANDLER_EXPORT_ENTRY (MSR_ACCESS_MICROCODE_SIGNATURE_PRM_HANDLER_GUID, MsrAccessMicrocodeSignaturePrmHandler),
PRM_HANDLER_EXPORT_ENTRY (MSR_ACCESS_MTRR_DUMP_PRM_HANDLER_GUID, MsrAccessMtrrDumpPrmHandler),
- PRM_HANDLER_EXPORT_ENTRY (MMIO_ACCESS_HPET_PRM_HANDLER_GUID, MmioAccessHpetPrmHandler)
+ PRM_HANDLER_EXPORT_ENTRY (MMIO_ACCESS_HPET_PRM_HANDLER_GUID, MmioAccessHpetPrmHandler),
+ PRM_HANDLER_EXPORT_ENTRY (MSR_PRINT_MICROCODE_SIGNATURE_PRM_HANDLER_GUID, MsrPrintMicrocodeSignaturePrmHandler),
+ PRM_HANDLER_EXPORT_ENTRY (MSR_PRINT_MTRR_DUMP_PRM_HANDLER_GUID, MsrPrintMtrrDumpPrmHandler),
+ PRM_HANDLER_EXPORT_ENTRY (MMIO_PRINT_HPET_PRM_HANDLER_GUID, MmioPrintHpetPrmHandler)
);
/**
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 22/41] PrmPkg/SampleAcpiParameterBufferModule: Add initial module
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (20 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 21/41] PrmPkg/PrmSampleHardwareAccessModule: Add non-print PRM handlers Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 23/41] PrmPkg/HardwareAccessModuleConfigLib: Add initial library Michael Kubacki
` (18 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a new PRM module called SampleAcpiParameterBufferModule that
demonstrates how a PRM module can use an ACPI parameter buffer with
a PRM handler.
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/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.c | 120 ++++++++++++++++++++
PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.c | 79 +++++++++++++
PrmPkg/PrmPkg.dsc | 3 +
PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf | 39 +++++++
PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf | 41 +++++++
5 files changed, 282 insertions(+)
diff --git a/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.c b/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.c
new file mode 100644
index 000000000000..b135517232f7
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.c
@@ -0,0 +1,120 @@
+/** @file
+
+ The boot services environment configuration library for the ACPI Parameter Buffer Sample PRM module.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/PrmConfig.h>
+
+STATIC EFI_HANDLE mPrmConfigProtocolHandle;
+
+// {dc2a58a6-5927-4776-b995-d118a27335a2}
+STATIC CONST EFI_GUID mPrmModuleGuid = {0xdc2a58a6, 0x5927, 0x4776, {0xb9, 0x95, 0xd1, 0x18, 0xa2, 0x73, 0x35, 0xa2}};
+
+// {2e4f2d13-6240-4ed0-a401-c723fbdc34e8}
+STATIC CONST EFI_GUID mCheckParamBufferPrmHandlerGuid = {0x2e4f2d13, 0x6240, 0x4ed0, {0xa4, 0x01, 0xc7, 0x23, 0xfb, 0xdc, 0x34, 0xe8}};
+
+/**
+ Constructor of the PRM configuration library.
+
+ @param[in] ImageHandle The image handle of the driver.
+ @param[in] SystemTable The EFI System Table pointer.
+
+ @retval EFI_SUCCESS The shell command handlers were installed successfully.
+ @retval EFI_UNSUPPORTED The shell level required was not found.
+**/
+EFI_STATUS
+EFIAPI
+AcpiParameterBufferModuleConfigLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ VOID *AcpiParameterBuffer;
+ ACPI_PARAMETER_BUFFER_DESCRIPTOR *AcpiParamBufferDescriptor;
+ PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
+
+ AcpiParameterBuffer = NULL;
+ AcpiParamBufferDescriptor = NULL;
+ PrmConfigProtocol = NULL;
+
+ /*
+ In this sample PRM module, the protocol describing this sample module's resources is simply
+ installed in the constructor.
+
+ However, if some data is not available until later, this constructor could register a callback
+ on the dependency for the data to be available (e.g. ability to communicate with some device)
+ and then install the protocol. The requirement is that the protocol is installed before end of DXE.
+ */
+
+ // Allocate the ACPI parameter buffer
+
+ // A parameter buffer is arbitrary data that is handler specific. This handler buffer is specified
+ // to consist of a UINT32 that represents the test data signature ('T', 'E', 'S', 'T').
+ AcpiParameterBuffer = AllocateRuntimeZeroPool (sizeof (UINT32));
+ ASSERT (AcpiParameterBuffer != NULL);
+ if (AcpiParameterBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ // Allocate the ACPI Parameter Buffer Descriptor structure for a single PRM handler
+ AcpiParamBufferDescriptor = AllocateZeroPool (sizeof (*AcpiParamBufferDescriptor));
+ ASSERT (AcpiParamBufferDescriptor != NULL);
+ if (AcpiParamBufferDescriptor == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ // Allocate the PRM Configuration protocol structure for this PRM module
+ PrmConfigProtocol = AllocateZeroPool (sizeof (*PrmConfigProtocol));
+ ASSERT (PrmConfigProtocol != NULL);
+ if (PrmConfigProtocol == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ CopyGuid (&PrmConfigProtocol->ModuleContextBuffers.ModuleGuid, &mPrmModuleGuid);
+
+ // Populate the ACPI Parameter Buffer Descriptor structure
+ CopyGuid (&AcpiParamBufferDescriptor->HandlerGuid, &mCheckParamBufferPrmHandlerGuid);
+ AcpiParamBufferDescriptor->AcpiParameterBufferAddress = (UINT64) (UINTN) AcpiParameterBuffer;
+
+ // Populate the PRM Module Context Buffers structure
+ PrmConfigProtocol->ModuleContextBuffers.AcpiParameterBufferDescriptorCount = 1;
+ PrmConfigProtocol->ModuleContextBuffers.AcpiParameterBufferDescriptors = AcpiParamBufferDescriptor;
+
+ //
+ // Install the PRM Configuration Protocol for this module. This indicates the configuration
+ // library has completed resource initialization for the PRM module.
+ //
+ Status = gBS->InstallProtocolInterface (
+ &mPrmConfigProtocolHandle,
+ &gPrmConfigProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID *) PrmConfigProtocol
+ );
+
+Done:
+ if (EFI_ERROR (Status)) {
+ if (AcpiParameterBuffer != NULL) {
+ FreePool (AcpiParameterBuffer);
+ }
+ if (AcpiParamBufferDescriptor != NULL) {
+ FreePool (AcpiParamBufferDescriptor);
+ }
+ if (PrmConfigProtocol != NULL) {
+ FreePool (PrmConfigProtocol);
+ }
+ }
+
+ return Status;
+}
diff --git a/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.c b/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.c
new file mode 100644
index 000000000000..ebb5ba01a30c
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.c
@@ -0,0 +1,79 @@
+/** @file
+
+ This PRM Module demonstrates how to define an ACPI parameter buffer that is used by a PRM handler.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PrmModule.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+
+// TEMP
+#include <Library/DebugLib.h>
+
+#define PARAM_BUFFER_TEST_SIGNATURE SIGNATURE_32('T','E','S','T')
+
+//
+// PRM Handler GUIDs
+//
+
+// {2e4f2d13-6240-4ed0-a401-c723fbdc34e8}
+#define CHECK_PARAM_BUFFER_PRM_HANDLER_GUID {0x2e4f2d13, 0x6240, 0x4ed0, {0xa4, 0x01, 0xc7, 0x23, 0xfb, 0xdc, 0x34, 0xe8}}
+
+/**
+ A sample Platform Runtime Mechanism (PRM) handler.
+
+ This sample handler checks if a parameter buffer is provided with the data signature
+ ('T', 'E', 'S', 'T') at the beginning of the buffer.
+
+ The contents are expected to be updated by ACPI code at OS runtime.
+
+ @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.
+
+**/
+PRM_HANDLER_EXPORT (CheckParamBufferPrmHandler)
+{
+ if (ParameterBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*((UINT32 *) ParameterBuffer) == PARAM_BUFFER_TEST_SIGNATURE) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+//
+// Register the PRM export information for this PRM Module
+//
+PRM_MODULE_EXPORT (
+ PRM_HANDLER_EXPORT_ENTRY (CHECK_PARAM_BUFFER_PRM_HANDLER_GUID, CheckParamBufferPrmHandler)
+ );
+
+/**
+ Module entry point.
+
+ @param[in] ImageHandle The image handle.
+ @param[in] SystemTable A pointer to the system table.
+
+ @retval EFI_SUCCESS This function always returns success.
+
+**/
+EFI_STATUS
+EFIAPI
+PrmSampleAcpiParameterBufferModuleInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
index 6d352dfadb26..2409378926b9 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -68,6 +68,7 @@ [Components]
# PRM Libraries
#
$(PLATFORM_PACKAGE)/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
+ $(PLATFORM_PACKAGE)/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf
$(PLATFORM_PACKAGE)/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf
$(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
@@ -76,6 +77,7 @@ [Components]
#
$(PLATFORM_PACKAGE)/PrmConfigDxe/PrmConfigDxe.inf {
<LibraryClasses>
+ NULL|$(PLATFORM_PACKAGE)/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf
NULL|$(PLATFORM_PACKAGE)/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf
}
@@ -93,6 +95,7 @@ [Components]
# PRM Sample Modules
#
$(PLATFORM_PACKAGE)/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
+ $(PLATFORM_PACKAGE)/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf
$(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf {
<LibraryClasses>
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
diff --git a/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf b/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf
new file mode 100644
index 000000000000..9ac83857cf8e
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Sample PRM Configuration Library Instance
+#
+# The PRM configuration library instance is responsible for initializing and setting the corresponding
+# PRM module's configuration in the boot environment.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeAcpiParameterBufferModuleConfigLib
+ FILE_GUID = D43D19E9-007A-4D40-AC4A-418F958AFB9D
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL |DXE_DRIVER
+ CONSTRUCTOR = AcpiParameterBufferModuleConfigLibConstructor
+
+[Sources]
+ DxeAcpiParameterBufferModuleConfigLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[Protocols]
+ gPrmConfigProtocolGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
diff --git a/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf b/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf
new file mode 100644
index 000000000000..e8b71a970d83
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf
@@ -0,0 +1,41 @@
+## @file
+# Sample PRM Driver
+#
+# A sample PRM Module implementation. This PRM Module includes a PRM Module configuration library instance
+# that applies the configuration for an ACPI parameter buffer in the boot environment. A PRM handler
+# is provided that checks for a specific value in the parameter buffer that should be provided by ACPI
+# code at OS runtime.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PrmSampleAcpiParameterBufferModule
+ FILE_GUID = DC2A58A6-5927-4776-B995-D118A27335A2
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PrmSampleAcpiParameterBufferModuleInit
+
+[Sources]
+ PrmSampleAcpiParameterBufferModule.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Depex]
+ TRUE
+
+[BuildOptions.common]
+ MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE /VERSION:1.0
+ MSFT:*_*_*_GENFW_FLAGS = --keepoptionalheader
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 23/41] PrmPkg/HardwareAccessModuleConfigLib: Add initial library
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (21 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 22/41] PrmPkg/SampleAcpiParameterBufferModule: Add initial module Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 24/41] PrmPkg/Samples/Readme.md: Add initial file Michael Kubacki
` (17 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a PRM module configuration library for PrmSampleHardwareAccessModule
that demonstrates marking a runtime MMIO range. In the case of this
sample module, the range used is for HPET.
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/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c | 104 ++++++++++++++++++++
PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c | 2 -
PrmPkg/PrmPkg.dsc | 1 +
PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h | 3 +
PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf | 39 ++++++++
5 files changed, 147 insertions(+), 2 deletions(-)
diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c b/PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c
new file mode 100644
index 000000000000..c00ab9ffbbe3
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c
@@ -0,0 +1,104 @@
+/** @file
+
+ The boot services environment configuration library for the Hardware Access Sample PRM module.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/PrmConfig.h>
+#include <Samples/PrmSampleHardwareAccessModule/Hpet.h>
+
+STATIC EFI_HANDLE mPrmConfigProtocolHandle;
+
+// {0ef93ed7-14ae-425b-928f-b85a6213b57e}
+STATIC CONST EFI_GUID mPrmModuleGuid = {0x0ef93ed7, 0x14ae, 0x425b, {0x92, 0x8f, 0xb8, 0x5a, 0x62, 0x13, 0xb5, 0x7e}};
+
+/**
+ Constructor of the PRM configuration library.
+
+ @param[in] ImageHandle The image handle of the driver.
+ @param[in] SystemTable The EFI System Table pointer.
+
+ @retval EFI_SUCCESS The shell command handlers were installed successfully.
+ @retval EFI_UNSUPPORTED The shell level required was not found.
+**/
+EFI_STATUS
+EFIAPI
+HardwareAccessModuleConfigLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ PRM_RUNTIME_MMIO_RANGES *RuntimeMmioRanges;
+ PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
+
+ RuntimeMmioRanges = NULL;
+ PrmConfigProtocol = NULL;
+
+ /*
+ In this sample PRM module, the protocol describing this sample module's resources is simply
+ installed in the constructor.
+
+ However, if some data is not available until later, this constructor could register a callback
+ on the dependency for the data to be available (e.g. ability to communicate with some device)
+ and then install the protocol. The requirement is that the protocol is installed before end of DXE.
+ */
+
+ // Runtime MMIO Ranges structure
+
+ // Since this sample module only uses 1 runtime MMIO range, it can use the PRM_RUNTIME_MMIO_RANGES
+ // type directly without extending the size of the data buffer for additional MMIO ranges.
+ RuntimeMmioRanges = AllocateRuntimeZeroPool (sizeof (*RuntimeMmioRanges));
+ ASSERT (RuntimeMmioRanges != NULL);
+ if (RuntimeMmioRanges == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ // Allocate the PRM Configuration protocol structure for this PRM module
+ PrmConfigProtocol = AllocateZeroPool (sizeof (*PrmConfigProtocol));
+ ASSERT (PrmConfigProtocol != NULL);
+ if (PrmConfigProtocol == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ CopyGuid (&PrmConfigProtocol->ModuleContextBuffers.ModuleGuid, &mPrmModuleGuid);
+
+ // Populate the Runtime MMIO Ranges structure
+ RuntimeMmioRanges->Count = 1;
+ RuntimeMmioRanges->Range[0].PhysicalBaseAddress = HPET_BASE_ADDRESS;
+ RuntimeMmioRanges->Range[0].Length = HPET_RANGE_LENGTH;
+
+ PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges = RuntimeMmioRanges;
+
+ //
+ // Install the PRM Configuration Protocol for this module. This indicates the configuration
+ // library has completed resource initialization for the PRM module.
+ //
+ Status = gBS->InstallProtocolInterface (
+ &mPrmConfigProtocolHandle,
+ &gPrmConfigProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID *) PrmConfigProtocol
+ );
+
+Done:
+ if (EFI_ERROR (Status)) {
+ if (RuntimeMmioRanges != NULL) {
+ FreePool (RuntimeMmioRanges);
+ }
+ if (PrmConfigProtocol != NULL) {
+ FreePool (PrmConfigProtocol);
+ }
+ }
+
+ return Status;
+}
diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
index 32e04c5e8592..35da1fcf5f17 100644
--- a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
+++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
@@ -42,8 +42,6 @@
// {8a0efdde-78d0-45f0-aea0-c28245c7e1db}
#define MMIO_PRINT_HPET_PRM_HANDLER_GUID {0x8a0efdde, 0x78d0, 0x45f0, {0xae, 0xa0, 0xc2, 0x82, 0x45, 0xc7, 0xe1, 0xdb}}
-#define HPET_BASE_ADDRESS 0xFED00000
-
//
// BEGIN: MtrrLib internal library globals and function prototypes here for testing
//
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
index 2409378926b9..19b996eb3a02 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -79,6 +79,7 @@ [Components]
<LibraryClasses>
NULL|$(PLATFORM_PACKAGE)/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf
NULL|$(PLATFORM_PACKAGE)/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf
+ NULL|$(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
}
#
diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h b/PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
index c7eb0cbfa747..a4f8758516c0 100644
--- a/PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
+++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
@@ -15,6 +15,9 @@
#ifndef HPET_REGISTER_H_
#define HPET_REGISTER_H_
+#define HPET_BASE_ADDRESS 0xFED00000
+#define HPET_RANGE_LENGTH 0x1000
+
///
/// HPET General Register Offsets
///
diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf b/PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
new file mode 100644
index 000000000000..1a50480dd2c5
--- /dev/null
+++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Sample PRM Configuration Library Instance
+#
+# The PRM configuration library instance is responsible for initializing and setting the corresponding
+# PRM module's configuration in the boot environment.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeHardwareAccessModuleConfigLib
+ FILE_GUID = 88AA72FE-AE5A-435F-A267-E24D526C666C
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL |DXE_DRIVER
+ CONSTRUCTOR = HardwareAccessModuleConfigLibConstructor
+
+[Sources]
+ DxeHardwareAccessModuleConfigLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[Protocols]
+ gPrmConfigProtocolGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 24/41] PrmPkg/Samples/Readme.md: Add initial file
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (22 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 23/41] PrmPkg/HardwareAccessModuleConfigLib: Add initial library Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 25/41] PrmPkg: Refactor some PrmLoaderDxe functionality into libraries Michael Kubacki
` (16 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a Readme.md file for the Samples to help a user get started
building and using the PRM sample modules.
Includes a reference to the Samples/Readme.md file in the top-level
file to help make the reader aware the file exists.
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 | 5 +-
PrmPkg/Samples/Readme.md | 263 ++++++++++++++++++++
2 files changed, 267 insertions(+), 1 deletion(-)
diff --git a/PrmPkg/Readme.md b/PrmPkg/Readme.md
index 52b44a95ddbc..b79cb66c4790 100644
--- a/PrmPkg/Readme.md
+++ b/PrmPkg/Readme.md
@@ -9,7 +9,7 @@ The `PrmPkg` maintained in this branch provides a single cohesive set of generic
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
+> 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.
@@ -120,6 +120,9 @@ prevent the package from being used as-is should be addressed directly in PrmPkg
## PRM Module
+> __*Note*__: You can find simple examples of PRM modules in the Samples directory of this package.
+> [Samples/Readme.md](PrmPkg/Samples/Readme.md) has more information.
+
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.
diff --git a/PrmPkg/Samples/Readme.md b/PrmPkg/Samples/Readme.md
new file mode 100644
index 000000000000..4926be243018
--- /dev/null
+++ b/PrmPkg/Samples/Readme.md
@@ -0,0 +1,263 @@
+# **Platform Runtime Mechanism Sample Modules**
+
+The PRM module samples provided here serve as focused examples of how to perform various tasks in a PRM module. The
+samples can also be used to verify the basic infrastructure needed in your firmware implementation is working as
+expected by checking that the sample modules are found properly and the handlers perform their tasks as noted.
+
+## **IMPORTANT NOTE**
+> The sample modules have currently only been tested on the Visual Studio compiler tool chain. Sample module
+build may fail on other tool chains. A future work item is to enable broader build support.
+
+## How to Build PRM Sample Modules
+The sample modules are built as part of the normal `PrmPkg` build so you can follow the
+[package build instructions](../../Readme.md#how-to-build-prmpkg) and then find the PRM sample binaries in your
+workspace build output directory. For example, if your build workspace is called "edk2" and you build
+64-bit binaries on the Visual Studio 2017 tool chain, your sample module binaries will be in the following
+location: \
+``edk2/Build/Prm/DEBUG_VS2017/X64/PrmPkg/Samples``
+
+### Build an Individual PRM Sample Module
+Note that the build command does provide the option to build a specific module in a package which can result in
+faster build time. If you would like to just build a single PRM module that can be done by specifying the path to
+the module INF file with the "-m" argument to `build`. For example, this command builds 32-bit and 64-bit binaries
+with Visual Studio 2019: \
+``build -p PrmPkg/PrmPkg.dsc -m PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf -a IA32 -a X64 -t VS2019``
+
+## PRM Sample Module User's Guide
+
+The following table provides an overview of each sample module provided. By nature, different PRM handlers have
+different requirements. The information here is summarized for a user to understand how to use a given sample
+PRM handler along with GUID/name information to identify the sample PRM modules and their PRM handlers.
+
+It is recommended that all PRM authors write a similar set of documentation for their users to better understand
+and interact with their PRM modules.
+
+---
+### Module: PRM Sample Print Module
+>* Name: `PrmSamplePrintModule`
+>* GUID: `1652b3c2-a7a1-46ac-af93-dd6dee446669`
+> * Purpose:
+> * Simplest PRM module example
+> * Example of a PRM module with multiple PRM handlers
+
+**Handlers:**
+#### Handler: PRM Handler 1
+* Name: `PrmHandler1`
+* GUID: `d5f2ad5f-a347-4d3e-87bc-c2ce63029cc8`
+* Actions:
+ * Use an OS-provided function pointer (pointer at the beginning of the parameter buffer) to write the message
+ “PRM1 handler sample message!”
+
+* Parameter Buffer Required: Yes
+* Parameter Buffer Contents:
+ ```c
+ typedef struct {
+
+ PRM_OS_SERVICE_DEBUG_PRINT *
+
+ } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
+ ```
+
+* Context Buffer Required: No
+
+* Runtime MMIO Range(s) Required: No
+
+#### Handler: PRM Handler 2
+* Name: `PrmHandler2`
+* GUID: `a9e7adc3-8cd0-429a-8915-10946ebde318`
+* Actions:
+ * Use an OS-provided function pointer (pointer at the beginning of the parameter buffer) to write the message
+ “PRM2 handler sample message!”
+
+* Parameter Buffer Required: Yes
+* Parameter Buffer Contents:
+ ```c
+ typedef struct {
+
+ PRM_OS_SERVICE_DEBUG_PRINT *
+
+ } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
+ ```
+
+* Context Buffer Required: No
+
+* Runtime MMIO Range(s) Required: No
+
+#### Handler: PRM Handler N
+* Name: `PrmHandlerN`
+* GUID: `b688c214-4081-4eeb-8d26-1eb5a3bcf11a`
+* Actions:
+ * Use an OS-provided function pointer (pointer at the beginning of the parameter buffer) to write the message
+ “PRMN handler sample message!”
+
+* Parameter Buffer Required: Yes
+* Parameter Buffer Contents:
+ ```c
+ typedef struct {
+
+ PRM_OS_SERVICE_DEBUG_PRINT *
+
+ } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
+ ```
+
+* Context Buffer Required: No
+
+* Runtime MMIO Range(s) Required: No
+
+### Module: PRM Sample ACPI Parameter Buffer
+>* Name: `PrmSampleAcpiParameterBufferModule`
+>* GUID: `dc2a58a6-5927-4776-b995-d118a27335a2`
+> * Purpose:
+> * Provides an example of how to configure an ACPI parameter buffer
+
+**Handlers:**
+#### Handler: Check Parameter Buffer PRM Handler
+* Name: `CheckParamBufferPrmHandler`
+* GUID: `2e4f2d13-6240-4ed0-a401-c723fbdc34e8`
+* Actions:
+ * Checks for the data signature ‘T’, ‘E’, ‘S’, ‘T’ (DWORD) at the beginning of the parameter buffer.
+
+* Parameter Buffer Required: Yes
+* Parameter Buffer Contents:
+ * A data signature of ['T', 'E', 'S', 'T'] (DWORD) at the beginning of the buffer.
+
+* Context Buffer Required: No
+
+* Runtime MMIO Range(s) Required: No
+
+### Module: PRM Sample Context Buffer
+>* Name: `PrmSampleContextBufferModule`
+>* GUID: `5a6cf42b-8bb4-472c-a233-5c4dc4033dc7`
+> * Purpose:
+> * Provides an example of how to configure a static data buffer (which is pointed to in a context buffer) in
+ firmware and consume the buffer contents at runtime
+
+**Handlers:**
+#### Handler: Check Static Data Buffer PRM Handler
+* Name: `CheckStaticDataBufferPrmHandler`
+* GUID: `e1466081-7562-430f-896b-b0e523dc335a`
+* Actions:
+ * Checks that the context buffer signature and static data buffer signature match in the context buffer provided.
+
+* Parameter Buffer Required: No
+
+* Context Buffer Required: Yes
+ * Static Data Buffer Contents:
+ ```c
+ #define SOME_VALUE_ARRAY_MAX_VALUES 16
+
+ typedef struct {
+ BOOLEAN Policy1Enabled;
+ BOOLEAN Policy2Enabled;
+ UINT8 SomeValueArray[SOME_VALUE_ARRAY_MAX_VALUES];
+ } STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE;
+ ```
+
+* Runtime MMIO Range(s) Required: No
+
+### Module: PRM Sample Hardware Access Buffer
+>* Name: `PrmSampleHardwareAccessModule`
+>* GUID: `0ef93ed7-14ae-425b-928f-b85a6213b57e`
+> * Purpose:
+> * Demonstrate access of several types of hardware resources from a PRM module
+
+**Handlers:**
+#### Handler: MSR Access Microcode Signature PRM Handler
+* Name: `MsrAccessMicrocodeSignaturePrmHandler`
+* GUID: `2120cd3c-848b-4d8f-abbb-4b74ce64ac89`
+* Actions:
+ * Access the loaded microcode signature at MSR 0x8B.
+
+* Parameter Buffer Required: No
+
+* Context Buffer Required: No
+
+* Runtime MMIO Range(s) Required: No
+
+#### Handler: MSR Access MTRR Dump PRM Handler
+* Name: `MsrAccessMtrrDumpPrmHandler`
+* GUID: `ea0935a7-506b-4159-bbbb-48deeecb6f58`
+* Actions:
+ * Access the fixed and variable MTRR values using MSRs.
+
+* Parameter Buffer Required: No
+
+* Context Buffer Required: No
+
+* Runtime MMIO Range(s) Required: No
+
+#### Handler: HPET MMIO Access PRM Handler
+* Name: `MmioAccessHpetPrmHandler`
+* GUID: `1bd1bda9-909a-4614-9699-25ec0c2783f7`
+* Actions:
+ * Access some HPET registers using MMIO at 0xFED00000.
+
+* Parameter Buffer Required: No
+
+* Context Buffer Required: No
+
+* Runtime MMIO Range(s) Required: Yes
+ * Physical Base Address: 0xFED00000
+ * Length: 0x1000
+
+#### Handler: MSR Print Microcode Signature PRM Handler
+* Name: `MsrPrintMicrocodeSignaturePrmHandler`
+* GUID: `5d28b4e7-3867-4aee-aa09-51fc282c3b22`
+* Actions:
+ * Use the provided print function to print the loaded microcode signature at MSR 0x8B.
+
+* Parameter Buffer Required: Yes
+* Parameter Buffer Contents:
+ ```c
+ typedef struct {
+
+ PRM_OS_SERVICE_DEBUG_PRINT *
+
+ } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
+ ```
+
+* Context Buffer Required: No
+
+* Runtime MMIO Range(s) Required: No
+
+#### Handler: MSR Print MTRR Dump PRM Handler
+* Name: `MsrPrintMtrrDumpPrmHandler`
+* GUID: `4b64b702-4d2b-4dfe-ac5a-0b4110a2ca47`
+* Actions:
+ * Use the provided print function to print the fixed and variable MTRR values using MSRs.
+
+* Parameter Buffer Required: Yes
+* Parameter Buffer Contents:
+ ```c
+ typedef struct {
+
+ PRM_OS_SERVICE_DEBUG_PRINT *
+
+ } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
+ ```
+
+* Context Buffer Required: No
+
+* Runtime MMIO Range(s) Required: No
+
+#### Handler: HPET MMIO Print PRM Handler
+* Name: `MmioPrintHpetPrmHandler`
+* GUID: `8a0efdde-78d0-45f0-aea0-c28245c7e1db`
+* Actions:
+ * Use the provided print function to print some HPET registers using MMIO at 0xFED00000.
+
+* Parameter Buffer Required: Yes
+* Parameter Buffer Contents:
+ ```c
+ typedef struct {
+
+ PRM_OS_SERVICE_DEBUG_PRINT *
+
+ } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
+ ```
+
+* Context Buffer Required: No
+
+* Runtime MMIO Range(s) Required: Yes
+ * Physical Base Address: 0xFED00000
+ * Length: 0x1000
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 25/41] PrmPkg: Refactor some PrmLoaderDxe functionality into libraries
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (23 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 24/41] PrmPkg/Samples/Readme.md: Add initial file Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 26/41] PrmPkg/Application/PrmInfo: Add initial application Michael Kubacki
` (15 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
This change breaks out two sets of responsibilities in
PrmLoaderDxe into libraries:
* PE/COFF functions -> PrmPeCoffLib
* PRM module discovery functions -> PrmModuleDiscoveryLib
This is core infrastructure code for PRM functionality that needs
to be directly reused and tested in other places. At this time,
the primary motivating factor is to use this code in two other
locations:
1.) Link the functionality into unit testing modules
2.) Link the functionality into a PRM UEFI application
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/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c | 382 +++++++++++++
PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c | 411 ++++++++++++++
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c | 600 +-------------------
PrmPkg/Include/Library/PrmModuleDiscoveryLib.h | 60 ++
PrmPkg/Include/Library/PrmPeCoffLib.h | 111 ++++
PrmPkg/Include/PrmModuleImageContext.h | 28 +
PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf | 41 ++
PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h | 27 +
PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf | 32 ++
PrmPkg/PrmLoaderDxe/PrmLoader.h | 51 --
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf | 5 +-
PrmPkg/PrmPkg.dec | 8 +
PrmPkg/PrmPkg.dsc | 13 +
13 files changed, 1133 insertions(+), 636 deletions(-)
diff --git a/PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c b/PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
new file mode 100644
index 000000000000..6977799aa8f3
--- /dev/null
+++ b/PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
@@ -0,0 +1,382 @@
+/** @file
+
+ The PRM Module Discovery library provides functionality to discover PRM modules installed by platform firmware.
+
+ Copyright (c) Microsoft Corporation
+ Copyright (c) 2020 - 2022, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiMm.h>
+#include <Protocol/MmAccess.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrmModuleDiscoveryLib.h>
+#include <Library/PrmPeCoffLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/LoadedImage.h>
+
+#include "PrmModuleDiscovery.h"
+
+#define _DBGMSGID_ "[PRMMODULEDISCOVERYLIB]"
+
+LIST_ENTRY mPrmModuleList;
+
+/**
+ Gets the next PRM module discovered after the given PRM module.
+
+ @param[in,out] ModuleImageContext A pointer to a pointer to a PRM module image context structure.
+ ModuleImageContext should point to a pointer that points to NULL to
+ get the first PRM module discovered.
+
+ @retval EFI_SUCCESS The next PRM module was found successfully.
+ @retval EFI_INVALID_PARAMETER The given ModuleImageContext structure is invalid or the pointer is NULL.
+ @retval EFI_NOT_FOUND The next PRM module was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+GetNextPrmModuleEntry (
+ IN OUT PRM_MODULE_IMAGE_CONTEXT **ModuleImageContext
+ )
+{
+ LIST_ENTRY *CurrentLink;
+ LIST_ENTRY *ForwardLink;
+ PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *CurrentListEntry;
+ PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *ForwardListEntry;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ if (ModuleImageContext == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*ModuleImageContext == NULL) {
+ ForwardLink = GetFirstNode (&mPrmModuleList);
+ } else {
+ CurrentListEntry = NULL;
+ CurrentListEntry = CR (*ModuleImageContext, PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY, Context, PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE);
+ if (CurrentListEntry == NULL || CurrentListEntry->Signature != PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CurrentLink = &CurrentListEntry->Link;
+ ForwardLink = GetNextNode (&mPrmModuleList, CurrentLink);
+
+ if (ForwardLink == &mPrmModuleList) {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ ForwardListEntry = BASE_CR (ForwardLink, PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY, Link);
+ if (ForwardListEntry->Signature == PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE) {
+ *ModuleImageContext = &ForwardListEntry->Context;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Creates a new PRM Module Image Context linked list entry.
+
+ @retval PrmModuleImageContextListEntry If successful, a pointer a PRM Module Image Context linked list entry
+ otherwise, NULL is returned.
+
+**/
+STATIC
+PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *
+CreateNewPrmModuleImageContextListEntry (
+ VOID
+ )
+{
+ PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *PrmModuleImageContextListEntry;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ PrmModuleImageContextListEntry = AllocateZeroPool (sizeof (*PrmModuleImageContextListEntry));
+ if (PrmModuleImageContextListEntry == NULL) {
+ return NULL;
+ }
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Allocated PrmModuleImageContextListEntry at 0x%x of size 0x%x bytes.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ (UINTN) PrmModuleImageContextListEntry,
+ sizeof (*PrmModuleImageContextListEntry)
+ ));
+
+ PrmModuleImageContextListEntry->Signature = PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE;
+
+ return PrmModuleImageContextListEntry;
+}
+
+/**
+ Check whether the address is within any of the MMRAM ranges.
+
+ @param[in] Address The address to be checked.
+ @param[in] MmramRanges Pointer to MMRAM descriptor.
+ @param[in] MmramRangeCount MMRAM range count.
+
+ @retval TRUE The address is in MMRAM ranges.
+ @retval FALSE The address is out of MMRAM ranges.
+**/
+BOOLEAN
+EFIAPI
+IsAddressInMmram (
+ IN EFI_PHYSICAL_ADDRESS Address,
+ IN EFI_MMRAM_DESCRIPTOR *MmramRanges,
+ IN UINTN MmramRangeCount
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < MmramRangeCount; Index++) {
+ if ((Address >= MmramRanges[Index].CpuStart) &&
+ (Address < (MmramRanges[Index].CpuStart + MmramRanges[Index].PhysicalSize)))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Discovers all PRM Modules loaded during boot.
+
+ Each PRM Module discovered is placed into a linked list so the list can br processsed in the future.
+
+ @param[out] ModuleCount An optional pointer parameter that, if provided, is set to the number
+ of PRM modules discovered.
+ @param[out] HandlerCount An optional pointer parameter that, if provided, is set to the number
+ of PRM handlers discovered.
+
+ @retval EFI_SUCCESS All PRM Modules were discovered successfully.
+ @retval EFI_INVALID_PARAMETER An actual pointer parameter was passed as NULL.
+ @retval EFI_NOT_FOUND The gEfiLoadedImageProtocolGuid protocol could not be found.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to allocate the new PRM Context
+ linked list nodes.
+ @retval EFI_ALREADY_STARTED The function was called previously and already discovered the PRM modules
+ loaded on this boot.
+
+**/
+EFI_STATUS
+EFIAPI
+DiscoverPrmModules (
+ OUT UINTN *ModuleCount OPTIONAL,
+ OUT UINTN *HandlerCount OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ PRM_MODULE_IMAGE_CONTEXT TempPrmModuleImageContext;
+ PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *PrmModuleImageContextListEntry;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocol;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+ UINTN PrmHandlerCount;
+ UINTN PrmModuleCount;
+ EFI_MM_ACCESS_PROTOCOL *MmAccess;
+ UINTN Size;
+ EFI_MMRAM_DESCRIPTOR *MmramRanges;
+ UINTN MmramRangeCount;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ PrmHandlerCount = 0;
+ PrmModuleCount = 0;
+
+ if (!IsListEmpty (&mPrmModuleList)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiLoadedImageProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status) && (HandleCount == 0)) {
+ DEBUG ((DEBUG_ERROR, "%a %a: No LoadedImageProtocol instances found!\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_NOT_FOUND;
+ }
+
+ MmramRanges = NULL;
+ MmramRangeCount = 0;
+ Status = gBS->LocateProtocol (
+ &gEfiMmAccessProtocolGuid,
+ NULL,
+ (VOID **)&MmAccess
+ );
+ if (Status == EFI_SUCCESS) {
+ //
+ // Get MMRAM range information
+ //
+ Size = 0;
+ Status = MmAccess->GetCapabilities (MmAccess, &Size, NULL);
+ if ((Status == EFI_BUFFER_TOO_SMALL) && (Size != 0)) {
+ MmramRanges = (EFI_MMRAM_DESCRIPTOR *)AllocatePool (Size);
+ if (MmramRanges != NULL) {
+ Status = MmAccess->GetCapabilities (MmAccess, &Size, MmramRanges);
+ if (Status == EFI_SUCCESS) {
+ MmramRangeCount = Size / sizeof (EFI_MMRAM_DESCRIPTOR);
+ }
+ }
+ }
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImageProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ if (IsAddressInMmram ((EFI_PHYSICAL_ADDRESS)(UINTN)(LoadedImageProtocol->ImageBase), MmramRanges, MmramRangeCount)) {
+ continue;
+ }
+
+ ZeroMem (&TempPrmModuleImageContext, sizeof (TempPrmModuleImageContext));
+ TempPrmModuleImageContext.PeCoffImageContext.Handle = LoadedImageProtocol->ImageBase;
+ TempPrmModuleImageContext.PeCoffImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+ Status = PeCoffLoaderGetImageInfo (&TempPrmModuleImageContext.PeCoffImageContext);
+ if (EFI_ERROR (Status) || TempPrmModuleImageContext.PeCoffImageContext.ImageError != IMAGE_ERROR_SUCCESS) {
+ DEBUG ((
+ DEBUG_WARN,
+ "%a %a: ImageHandle 0x%016lx is not a valid PE/COFF image. It cannot be considered a PRM module.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ (EFI_PHYSICAL_ADDRESS) (UINTN) LoadedImageProtocol->ImageBase
+ ));
+ continue;
+ }
+ if (TempPrmModuleImageContext.PeCoffImageContext.IsTeImage) {
+ // A PRM Module is not allowed to be a TE image
+ continue;
+ }
+
+ // Attempt to find an export table in this image
+ Status = GetExportDirectoryInPeCoffImage (
+ LoadedImageProtocol->ImageBase,
+ &TempPrmModuleImageContext.PeCoffImageContext,
+ &TempPrmModuleImageContext.ExportDirectory
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ // Attempt to find the PRM Module Export Descriptor in the export table
+ Status = GetPrmModuleExportDescriptorTable (
+ TempPrmModuleImageContext.ExportDirectory,
+ &TempPrmModuleImageContext.PeCoffImageContext,
+ &TempPrmModuleImageContext.ExportDescriptor
+ );
+ if (EFI_ERROR (Status) || TempPrmModuleImageContext.ExportDescriptor == NULL) {
+ continue;
+ }
+ // A PRM Module Export Descriptor was successfully found, this is considered a PRM Module.
+
+ //
+ // Create a new PRM Module image context node
+ //
+ PrmModuleImageContextListEntry = CreateNewPrmModuleImageContextListEntry ();
+ if (PrmModuleImageContextListEntry == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (
+ &PrmModuleImageContextListEntry->Context,
+ &TempPrmModuleImageContext,
+ sizeof (PrmModuleImageContextListEntry->Context)
+ );
+ InsertTailList (&mPrmModuleList, &PrmModuleImageContextListEntry->Link);
+ PrmHandlerCount += TempPrmModuleImageContext.ExportDescriptor->Header.NumberPrmHandlers;
+ PrmModuleCount++;
+ DEBUG ((DEBUG_INFO, "%a %a: New PRM Module inserted into list to be processed.\n", _DBGMSGID_, __FUNCTION__));
+ }
+
+ if (HandlerCount != NULL) {
+ *HandlerCount = PrmHandlerCount;
+ }
+ if (ModuleCount != NULL) {
+ *ModuleCount = PrmModuleCount;
+ }
+
+ if (MmramRanges != NULL) {
+ FreePool (MmramRanges);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The destructor function for this library instance.
+
+ Frees global resources allocated by this library instance.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The destructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+PrmModuleDiscoveryLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NextLink;
+ PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *ListEntry;
+
+ if (IsListEmpty (&mPrmModuleList)) {
+ return EFI_SUCCESS;
+ }
+
+ Link = GetFirstNode (&mPrmModuleList);
+ while (!IsNull (&mPrmModuleList, Link)) {
+ ListEntry = CR (Link, PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY, Link, PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE);
+ NextLink = GetNextNode (&mPrmModuleList, Link);
+
+ RemoveEntryList (Link);
+ FreePool (ListEntry);
+
+ Link = NextLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The constructor function for this library instance.
+
+ Internally initializes data structures used later during library execution.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+PrmModuleDiscoveryLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ InitializeListHead (&mPrmModuleList);
+
+ return EFI_SUCCESS;
+}
diff --git a/PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c b/PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c
new file mode 100644
index 000000000000..d760d137dc2b
--- /dev/null
+++ b/PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c
@@ -0,0 +1,411 @@
+/** @file
+
+ This file contains implementation for additional PE/COFF functionality needed to use
+ Platform Runtime Mechanism (PRM) modules.
+
+ Copyright (c) Microsoft Corporation
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/PeImage.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeCoffLib.h>
+
+#include <PrmExportDescriptor.h>
+#include <PrmModuleImageContext.h>
+
+#define _DBGMSGID_ "[PRMPECOFFLIB]"
+
+/**
+ Gets a pointer to the export directory in a given PE/COFF image.
+
+ @param[in] ImageExportDirectory A pointer to an export directory table in a PE/COFF image.
+ @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
+ PE/COFF image context for the Image containing the PRM Module Export
+ Descriptor table.
+ @param[out] ExportDescriptor A pointer to a pointer to the PRM Module Export Descriptor table found
+ in the ImageExportDirectory given.
+
+ @retval EFI_SUCCESS The PRM Module Export Descriptor table was found successfully.
+ @retval EFI_INVALID_PARAMETER A required parameter is NULL.
+ @retval EFI_NOT_FOUND The PRM Module Export Descriptor table was not found in the given
+ ImageExportDirectory.
+
+**/
+EFI_STATUS
+GetPrmModuleExportDescriptorTable (
+ IN EFI_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory,
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
+ OUT PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT **ExportDescriptor
+ )
+{
+ UINTN Index;
+ EFI_PHYSICAL_ADDRESS CurrentImageAddress;
+ UINT16 PrmModuleExportDescriptorOrdinal;
+ CONST CHAR8 *CurrentExportName;
+ UINT16 *OrdinalTable;
+ UINT32 *ExportNamePointerTable;
+ UINT32 *ExportAddressTable;
+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *TempExportDescriptor;
+
+ DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ if (ImageExportDirectory == NULL ||
+ PeCoffLoaderImageContext == NULL ||
+ PeCoffLoaderImageContext->ImageAddress == 0 ||
+ ExportDescriptor == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *ExportDescriptor = NULL;
+
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: %d exported names found in this image.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ ImageExportDirectory->NumberOfNames
+ ));
+
+ //
+ // The export name pointer table and export ordinal table form two parallel arrays associated by index.
+ //
+ CurrentImageAddress = PeCoffLoaderImageContext->ImageAddress;
+ ExportAddressTable = (UINT32 *) ((UINTN) CurrentImageAddress + ImageExportDirectory->AddressOfFunctions);
+ ExportNamePointerTable = (UINT32 *) ((UINTN) CurrentImageAddress + ImageExportDirectory->AddressOfNames);
+ OrdinalTable = (UINT16 *) ((UINTN) CurrentImageAddress + ImageExportDirectory->AddressOfNameOrdinals);
+
+ for (Index = 0; Index < ImageExportDirectory->NumberOfNames; Index++) {
+ CurrentExportName = (CONST CHAR8 *) ((UINTN) CurrentImageAddress + ExportNamePointerTable[Index]);
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Export Name[0x%x] - %a.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ Index,
+ CurrentExportName
+ ));
+ if (
+ AsciiStrnCmp (
+ PRM_STRING(PRM_MODULE_EXPORT_DESCRIPTOR_NAME),
+ CurrentExportName,
+ AsciiStrLen (PRM_STRING(PRM_MODULE_EXPORT_DESCRIPTOR_NAME))
+ ) == 0) {
+ PrmModuleExportDescriptorOrdinal = OrdinalTable[Index];
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: PRM Module Export Descriptor found. Ordinal = %d.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ PrmModuleExportDescriptorOrdinal
+ ));
+ if (PrmModuleExportDescriptorOrdinal >= ImageExportDirectory->NumberOfFunctions) {
+ DEBUG ((DEBUG_ERROR, "%a %a: The PRM Module Export Descriptor ordinal value is invalid.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_NOT_FOUND;
+ }
+ TempExportDescriptor = (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *) ((UINTN) CurrentImageAddress + ExportAddressTable[PrmModuleExportDescriptorOrdinal]);
+ if (TempExportDescriptor->Header.Signature == PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE) {
+ *ExportDescriptor = TempExportDescriptor;
+ DEBUG ((DEBUG_INFO, " %a %a: PRM Module Export Descriptor found at 0x%x.\n", _DBGMSGID_, __FUNCTION__, (UINTN) ExportDescriptor));
+ } else {
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: PRM Module Export Descriptor found at 0x%x but signature check failed.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ (UINTN) TempExportDescriptor
+ ));
+ }
+ DEBUG ((DEBUG_INFO, " %a %a: Exiting export iteration since export descriptor found.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Gets a pointer to the export directory in a given PE/COFF image.
+
+ @param[in] Image A pointer to a PE32/COFF image base address that is loaded into memory
+ and already relocated to the memory base address. RVAs in the image given
+ should be valid.
+ @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
+ PE/COFF image context for the Image given.
+ @param[out] ImageExportDirectory A pointer to a pointer to the export directory found in the Image given.
+
+ @retval EFI_SUCCESS The export directory was found successfully.
+ @retval EFI_INVALID_PARAMETER A required parameter is NULL.
+ @retval EFI_UNSUPPORTED The PE/COFF image given is not supported as a PRM Module.
+ @retval EFI_NOT_FOUND The image export directory could not be found for this image.
+
+**/
+EFI_STATUS
+GetExportDirectoryInPeCoffImage (
+ IN VOID *Image,
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
+ OUT EFI_IMAGE_EXPORT_DIRECTORY **ImageExportDirectory
+ )
+{
+ UINT16 Magic;
+ UINT32 NumberOfRvaAndSizes;
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION OptionalHeaderPtrUnion;
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
+ EFI_IMAGE_EXPORT_DIRECTORY *ExportDirectory;
+
+ if (Image == NULL || PeCoffLoaderImageContext == NULL || ImageExportDirectory == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DirectoryEntry = NULL;
+ ExportDirectory = NULL;
+
+ //
+ // NOTE: For backward compatibility, use the Machine field to identify a PE32/PE32+
+ // image instead of using the Magic field. Some systems might generate a PE32+
+ // image with PE32 magic.
+ //
+ switch (PeCoffLoaderImageContext->Machine) {
+ case EFI_IMAGE_MACHINE_IA32:
+ //
+ // Assume PE32 image with IA32 Machine field.
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ break;
+ case EFI_IMAGE_MACHINE_X64:
+ case EFI_IMAGE_MACHINE_AARCH64:
+ //
+ // Assume PE32+ image with X64 Machine field
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ break;
+ default:
+ //
+ // For unknown Machine field, use Magic in optional header
+ //
+ DEBUG ((
+ DEBUG_WARN,
+ "%a %a: The machine type for this image is not valid for a PRM module.\n",
+ _DBGMSGID_,
+ __FUNCTION__
+ ));
+ return EFI_UNSUPPORTED;
+ }
+
+ OptionalHeaderPtrUnion.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) (
+ (UINTN) Image +
+ PeCoffLoaderImageContext->PeCoffHeaderOffset
+ );
+
+ //
+ // Check the PE/COFF Header Signature. Determine if the image is valid and/or a TE image.
+ //
+ if (OptionalHeaderPtrUnion.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, "%a %a: The PE signature is not valid for the current image.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use the PE32 offset to get the Export Directory Entry
+ //
+ NumberOfRvaAndSizes = OptionalHeaderPtrUnion.Pe32->OptionalHeader.NumberOfRvaAndSizes;
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHeaderPtrUnion.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT]);
+ } else if (OptionalHeaderPtrUnion.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ //
+ // Use the PE32+ offset get the Export Directory Entry
+ //
+ NumberOfRvaAndSizes = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT]);
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_EXPORT || DirectoryEntry->VirtualAddress == 0) {
+ //
+ // The export directory is not present
+ //
+ return EFI_NOT_FOUND;
+ } else if (((UINT32) (~0) - DirectoryEntry->VirtualAddress) < DirectoryEntry->Size) {
+ //
+ // The directory address overflows
+ //
+ DEBUG ((DEBUG_ERROR, "%a %a: The export directory entry in this image results in overflow.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_UNSUPPORTED;
+ } else {
+ DEBUG ((DEBUG_INFO, "%a %a: Export Directory Entry found in the image at 0x%x.\n", _DBGMSGID_, __FUNCTION__, (UINTN) OptionalHeaderPtrUnion.Pe32));
+ DEBUG ((DEBUG_INFO, " %a %a: Directory Entry Virtual Address = 0x%x.\n", _DBGMSGID_, __FUNCTION__, DirectoryEntry->VirtualAddress));
+
+ ExportDirectory = (EFI_IMAGE_EXPORT_DIRECTORY *) ((UINTN) Image + DirectoryEntry->VirtualAddress);
+ DEBUG ((
+ DEBUG_INFO,
+ " %a %a: Export Directory Table found successfully at 0x%x. Name address = 0x%x. Name = %a.\n",
+ _DBGMSGID_,
+ __FUNCTION__,
+ (UINTN) ExportDirectory,
+ ((UINTN) Image + ExportDirectory->Name),
+ (CHAR8 *) ((UINTN) Image + ExportDirectory->Name)
+ ));
+ }
+ *ImageExportDirectory = ExportDirectory;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Returns the image major and image minor version in a given PE/COFF image.
+
+ @param[in] Image A pointer to a PE32/COFF image base address that is loaded into memory
+ and already relocated to the memory base address. RVAs in the image given
+ should be valid.
+ @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
+ PE/COFF image context for the Image given.
+ @param[out] ImageMajorVersion A pointer to a UINT16 buffer to hold the image major version.
+ @param[out] ImageMinorVersion A pointer to a UINT16 buffer to hold the image minor version.
+
+ @retval EFI_SUCCESS The image version was read successfully.
+ @retval EFI_INVALID_PARAMETER A required parameter is NULL.
+ @retval EFI_UNSUPPORTED The PE/COFF image given is not supported.
+
+**/
+EFI_STATUS
+GetImageVersionInPeCoffImage (
+ IN VOID *Image,
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
+ OUT UINT16 *ImageMajorVersion,
+ OUT UINT16 *ImageMinorVersion
+ )
+{
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION OptionalHeaderPtrUnion;
+ UINT16 Magic;
+
+ DEBUG ((DEBUG_INFO, " %a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
+
+ if (Image == NULL || PeCoffLoaderImageContext == NULL || ImageMajorVersion == NULL || ImageMinorVersion == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // NOTE: For backward compatibility, use the Machine field to identify a PE32/PE32+
+ // image instead of using the Magic field. Some systems might generate a PE32+
+ // image with PE32 magic.
+ //
+ switch (PeCoffLoaderImageContext->Machine) {
+ case EFI_IMAGE_MACHINE_IA32:
+ //
+ // Assume PE32 image
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ break;
+ case EFI_IMAGE_MACHINE_X64:
+ case EFI_IMAGE_MACHINE_AARCH64:
+ //
+ // Assume PE32+ image
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ break;
+ default:
+ //
+ // For unknown Machine field, use Magic in optional header
+ //
+ DEBUG ((
+ DEBUG_WARN,
+ "%a %a: The machine type for this image is not valid for a PRM module.\n",
+ _DBGMSGID_,
+ __FUNCTION__
+ ));
+ return EFI_UNSUPPORTED;
+ }
+
+ OptionalHeaderPtrUnion.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) (
+ (UINTN) Image +
+ PeCoffLoaderImageContext->PeCoffHeaderOffset
+ );
+ //
+ // Check the PE/COFF Header Signature. Determine if the image is valid and/or a TE image.
+ //
+ if (OptionalHeaderPtrUnion.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, "%a %a: The PE signature is not valid for the current image.\n", _DBGMSGID_, __FUNCTION__));
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use the PE32 offset to get the Export Directory Entry
+ //
+ *ImageMajorVersion = OptionalHeaderPtrUnion.Pe32->OptionalHeader.MajorImageVersion;
+ *ImageMinorVersion = OptionalHeaderPtrUnion.Pe32->OptionalHeader.MinorImageVersion;
+ } else {
+ //
+ // Use the PE32+ offset to get the Export Directory Entry
+ //
+ *ImageMajorVersion = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.MajorImageVersion;
+ *ImageMinorVersion = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.MinorImageVersion;
+ }
+
+ DEBUG ((DEBUG_INFO, " %a %a - Image Major Version: 0x%02x.\n", _DBGMSGID_, __FUNCTION__, *ImageMajorVersion));
+ DEBUG ((DEBUG_INFO, " %a %a - Image Minor Version: 0x%02x.\n", _DBGMSGID_, __FUNCTION__, *ImageMinorVersion));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the address of an entry in an image export table by ASCII name.
+
+ @param[in] ExportName A pointer to an ASCII name string of the entry name.
+ @param[in] ImageBaseAddress The base address of the PE/COFF image.
+ @param[in] ImageExportDirectory A pointer to the export directory in the image.
+ @param[out] ExportPhysicalAddress A pointer that will be updated with the address of the address of the
+ export entry if found.
+
+ @retval EFI_SUCCESS The export entry was found successfully.
+ @retval EFI_INVALID_PARAMETER A required pointer argument is NULL.
+ @retval EFI_NOT_FOUND An entry with the given ExportName was not found.
+
+**/
+EFI_STATUS
+GetExportEntryAddress (
+ IN CONST CHAR8 *ExportName,
+ IN EFI_PHYSICAL_ADDRESS ImageBaseAddress,
+ IN EFI_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory,
+ OUT EFI_PHYSICAL_ADDRESS *ExportPhysicalAddress
+ )
+{
+ UINTN ExportNameIndex;
+ UINT16 CurrentExportOrdinal;
+ UINT32 *ExportAddressTable;
+ UINT32 *ExportNamePointerTable;
+ UINT16 *OrdinalTable;
+ CONST CHAR8 *ExportNameTablePointerName;
+
+ if (ExportName == NULL || ImageBaseAddress == 0 || ImageExportDirectory == NULL || ExportPhysicalAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *ExportPhysicalAddress = 0;
+
+ ExportAddressTable = (UINT32 *) ((UINTN) ImageBaseAddress + ImageExportDirectory->AddressOfFunctions);
+ ExportNamePointerTable = (UINT32 *) ((UINTN) ImageBaseAddress + ImageExportDirectory->AddressOfNames);
+ OrdinalTable = (UINT16 *) ((UINTN) ImageBaseAddress + ImageExportDirectory->AddressOfNameOrdinals);
+
+ for (ExportNameIndex = 0; ExportNameIndex < ImageExportDirectory->NumberOfNames; ExportNameIndex++) {
+ ExportNameTablePointerName = (CONST CHAR8 *) ((UINTN) ImageBaseAddress + ExportNamePointerTable[ExportNameIndex]);
+
+ if (AsciiStrnCmp (ExportName, ExportNameTablePointerName, PRM_HANDLER_NAME_MAXIMUM_LENGTH) == 0) {
+ CurrentExportOrdinal = OrdinalTable[ExportNameIndex];
+
+ ASSERT (CurrentExportOrdinal < ImageExportDirectory->NumberOfFunctions);
+ if (CurrentExportOrdinal >= ImageExportDirectory->NumberOfFunctions) {
+ DEBUG ((DEBUG_ERROR, " %a %a: The export ordinal value is invalid.\n", _DBGMSGID_, __FUNCTION__));
+ break;
+ }
+
+ *ExportPhysicalAddress = (EFI_PHYSICAL_ADDRESS) ((UINTN) ImageBaseAddress + ExportAddressTable[CurrentExportOrdinal]);
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
index 6416e388a668..407c48257432 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -10,7 +10,6 @@
**/
#include "PrmAcpiTable.h"
-#include "PrmLoader.h"
#include <IndustryStandard/Acpi.h>
#include <Library/BaseLib.h>
@@ -18,581 +17,20 @@
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrmContextBufferLib.h>
+#include <Library/PrmModuleDiscoveryLib.h>
+#include <Library/PrmPeCoffLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Protocol/AcpiTable.h>
-#include <Protocol/LoadedImage.h>
#include <Protocol/PrmConfig.h>
#include <PrmContextBuffer.h>
#include <PrmMmio.h>
-LIST_ENTRY mPrmModuleList;
+#define _DBGMSGID_ "[PRMLOADER]"
-// Todo: Potentially refactor mPrmHandlerCount and mPrmModuleCount into localized structures
-// in the future.
-UINT32 mPrmHandlerCount;
-UINT32 mPrmModuleCount;
-
-/**
- Gets a pointer to the export directory in a given PE/COFF image.
-
- @param[in] ImageExportDirectory A pointer to an export directory table in a PE/COFF image.
- @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
- PE/COFF image context for the Image containing the PRM Module Export
- Descriptor table.
- @param[out] ExportDescriptor A pointer to a pointer to the PRM Module Export Descriptor table found
- in the ImageExportDirectory given.
-
- @retval EFI_SUCCESS The PRM Module Export Descriptor table was found successfully.
- @retval EFI_INVALID_PARAMETER A required parameter is NULL.
- @retval EFI_NOT_FOUND The PRM Module Export Descriptor table was not found in the given
- ImageExportDirectory.
-
-**/
-EFI_STATUS
-GetPrmModuleExportDescriptorTable (
- IN EFI_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory,
- IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
- OUT PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT **ExportDescriptor
- )
-{
- UINTN Index;
- EFI_PHYSICAL_ADDRESS CurrentImageAddress;
- UINT16 PrmModuleExportDescriptorOrdinal;
- CONST CHAR8 *CurrentExportName;
- UINT16 *OrdinalTable;
- UINT32 *ExportNamePointerTable;
- UINT32 *ExportAddressTable;
- PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *TempExportDescriptor;
-
- DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
-
- *ExportDescriptor = NULL;
-
- if (ImageExportDirectory == NULL ||
- PeCoffLoaderImageContext == NULL ||
- PeCoffLoaderImageContext->ImageAddress == 0 ||
- ExportDescriptor == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- DEBUG ((
- DEBUG_INFO,
- " %a %a: %d exported names found in this image.\n",
- _DBGMSGID_,
- __FUNCTION__,
- ImageExportDirectory->NumberOfNames
- ));
-
- //
- // The export name pointer table and export ordinal table form two parallel arrays associated by index.
- //
- CurrentImageAddress = PeCoffLoaderImageContext->ImageAddress;
- ExportAddressTable = (UINT32 *) ((UINTN) CurrentImageAddress + ImageExportDirectory->AddressOfFunctions);
- ExportNamePointerTable = (UINT32 *) ((UINTN) CurrentImageAddress + ImageExportDirectory->AddressOfNames);
- OrdinalTable = (UINT16 *) ((UINTN) CurrentImageAddress + ImageExportDirectory->AddressOfNameOrdinals);
-
- for (Index = 0; Index < ImageExportDirectory->NumberOfNames; Index++) {
- CurrentExportName = (CONST CHAR8 *) ((UINTN) CurrentImageAddress + ExportNamePointerTable[Index]);
- DEBUG ((
- DEBUG_INFO,
- " %a %a: Export Name[0x%x] - %a.\n",
- _DBGMSGID_,
- __FUNCTION__,
- Index,
- CurrentExportName
- ));
- if (
- AsciiStrnCmp (
- PRM_STRING(PRM_MODULE_EXPORT_DESCRIPTOR_NAME),
- CurrentExportName,
- AsciiStrLen (PRM_STRING(PRM_MODULE_EXPORT_DESCRIPTOR_NAME))
- ) == 0) {
- PrmModuleExportDescriptorOrdinal = OrdinalTable[Index];
- DEBUG ((
- DEBUG_INFO,
- " %a %a: PRM Module Export Descriptor found. Ordinal = %d.\n",
- _DBGMSGID_,
- __FUNCTION__,
- PrmModuleExportDescriptorOrdinal
- ));
- if (PrmModuleExportDescriptorOrdinal >= ImageExportDirectory->NumberOfFunctions) {
- DEBUG ((DEBUG_ERROR, "%a %a: The PRM Module Export Descriptor ordinal value is invalid.\n", _DBGMSGID_, __FUNCTION__));
- return EFI_NOT_FOUND;
- }
- TempExportDescriptor = (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *) ((UINTN) CurrentImageAddress + ExportAddressTable[PrmModuleExportDescriptorOrdinal]);
- if (TempExportDescriptor->Header.Signature == PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE) {
- *ExportDescriptor = TempExportDescriptor;
- DEBUG ((DEBUG_INFO, " %a %a: PRM Module Export Descriptor found at 0x%x.\n", _DBGMSGID_, __FUNCTION__, (UINTN) ExportDescriptor));
- } else {
- DEBUG ((
- DEBUG_INFO,
- " %a %a: PRM Module Export Descriptor found at 0x%x but signature check failed.\n",
- _DBGMSGID_,
- __FUNCTION__,
- (UINTN) TempExportDescriptor
- ));
- }
- DEBUG ((DEBUG_INFO, " %a %a: Exiting export iteration since export descriptor found.\n", _DBGMSGID_, __FUNCTION__));
- return EFI_SUCCESS;
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Gets a pointer to the export directory in a given PE/COFF image.
-
- @param[in] Image A pointer to a PE32/COFF image base address that is loaded into memory
- and already relocated to the memory base address. RVAs in the image given
- should be valid.
- @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
- PE/COFF image context for the Image given.
- @param[out] ImageExportDirectory A pointer to a pointer to the export directory found in the Image given.
-
- @retval EFI_SUCCESS The export directory was found successfully.
- @retval EFI_INVALID_PARAMETER A required parameter is NULL.
- @retval EFI_UNSUPPORTED The PE/COFF image given is not supported as a PRM Module.
- @retval EFI_NOT_FOUND The image export directory could not be found for this image.
-
-**/
-EFI_STATUS
-GetExportDirectoryInPeCoffImage (
- IN VOID *Image,
- IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
- OUT EFI_IMAGE_EXPORT_DIRECTORY **ImageExportDirectory
- )
-{
- UINT16 Magic;
- UINT32 NumberOfRvaAndSizes;
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION OptionalHeaderPtrUnion;
- EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
- EFI_IMAGE_EXPORT_DIRECTORY *ExportDirectory;
- EFI_IMAGE_SECTION_HEADER *SectionHeader;
-
- if (Image == NULL || PeCoffLoaderImageContext == NULL || ImageExportDirectory == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- DirectoryEntry = NULL;
- ExportDirectory = NULL;
-
- //
- // NOTE: For backward compatibility, use the Machine field to identify a PE32/PE32+
- // image instead of using the Magic field. Some systems might generate a PE32+
- // image with PE32 magic.
- //
- switch (PeCoffLoaderImageContext->Machine) {
- case EFI_IMAGE_MACHINE_IA32:
- // Todo: Add EFI_IMAGE_MACHINE_ARMT
- //
- // Assume PE32 image with IA32 Machine field.
- //
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
- break;
- case EFI_IMAGE_MACHINE_X64:
- //
- // Assume PE32+ image with X64 Machine field
- //
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
- break;
- default:
- //
- // For unknown Machine field, use Magic in optional header
- //
- DEBUG ((
- DEBUG_WARN,
- "%a %a: The machine type for this image is not valid for a PRM module.\n",
- _DBGMSGID_,
- __FUNCTION__
- ));
- return EFI_UNSUPPORTED;
- }
-
- OptionalHeaderPtrUnion.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) (
- (UINTN) Image +
- PeCoffLoaderImageContext->PeCoffHeaderOffset
- );
-
- //
- // Check the PE/COFF Header Signature. Determine if the image is valid and/or a TE image.
- //
- if (OptionalHeaderPtrUnion.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
- DEBUG ((DEBUG_ERROR, "%a %a: The PE signature is not valid for the current image.\n", _DBGMSGID_, __FUNCTION__));
- return EFI_UNSUPPORTED;
- }
-
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
- (UINTN) Image +
- PeCoffLoaderImageContext->PeCoffHeaderOffset +
- sizeof (UINT32) +
- sizeof (EFI_IMAGE_FILE_HEADER) +
- PeCoffLoaderImageContext->SizeOfHeaders
- );
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
- //
- // Use the PE32 offset to get the Export Directory Entry
- //
- NumberOfRvaAndSizes = OptionalHeaderPtrUnion.Pe32->OptionalHeader.NumberOfRvaAndSizes;
- DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHeaderPtrUnion.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT]);
- } else if (OptionalHeaderPtrUnion.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
- //
- // Use the PE32+ offset get the Export Directory Entry
- //
- NumberOfRvaAndSizes = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
- DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT]);
- } else {
- return EFI_UNSUPPORTED;
- }
-
- if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_EXPORT || DirectoryEntry->VirtualAddress == 0) {
- //
- // The export directory is not present
- //
- return EFI_NOT_FOUND;
- } else if (((UINT32) (~0) - DirectoryEntry->VirtualAddress) < DirectoryEntry->Size) {
- //
- // The directory address overflows
- //
- DEBUG ((DEBUG_ERROR, "%a %a: The export directory entry in this image results in overflow.\n", _DBGMSGID_, __FUNCTION__));
- return EFI_UNSUPPORTED;
- } else {
- DEBUG ((DEBUG_INFO, "%a %a: Export Directory Entry found in the image at 0x%x.\n", _DBGMSGID_, __FUNCTION__, (UINTN) OptionalHeaderPtrUnion.Pe32));
- DEBUG ((DEBUG_INFO, " %a %a: Directory Entry Virtual Address = 0x%x.\n", _DBGMSGID_, __FUNCTION__, DirectoryEntry->VirtualAddress));
-
- ExportDirectory = (EFI_IMAGE_EXPORT_DIRECTORY *) ((UINTN) Image + DirectoryEntry->VirtualAddress);
- DEBUG ((
- DEBUG_INFO,
- " %a %a: Export Directory Table found successfully at 0x%x. Name address = 0x%x. Name = %a.\n",
- _DBGMSGID_,
- __FUNCTION__,
- (UINTN) ExportDirectory,
- ((UINTN) Image + ExportDirectory->Name),
- (CHAR8 *) ((UINTN) Image + ExportDirectory->Name)
- ));
- }
- *ImageExportDirectory = ExportDirectory;
-
- return EFI_SUCCESS;
-}
-
-/**
- Returns the image major and image minor version in a given PE/COFF image.
-
- @param[in] Image A pointer to a PE32/COFF image base address that is loaded into memory
- and already relocated to the memory base address. RVAs in the image given
- should be valid.
- @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
- PE/COFF image context for the Image given.
- @param[out] ImageMajorVersion A pointer to a UINT16 buffer to hold the image major version.
- @param[out] ImageMinorVersion A pointer to a UINT16 buffer to hold the image minor version.
-
- @retval EFI_SUCCESS The image version was read successfully.
- @retval EFI_INVALID_PARAMETER A required parameter is NULL.
- @retval EFI_UNSUPPORTED The PE/COFF image given is not supported.
-
-**/
-EFI_STATUS
-GetImageVersionInPeCoffImage (
- IN VOID *Image,
- IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
- OUT UINT16 *ImageMajorVersion,
- OUT UINT16 *ImageMinorVersion
- )
-{
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION OptionalHeaderPtrUnion;
- UINT16 Magic;
-
- DEBUG ((DEBUG_INFO, " %a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
-
- if (Image == NULL || PeCoffLoaderImageContext == NULL || ImageMajorVersion == NULL || ImageMinorVersion == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // NOTE: For backward compatibility, use the Machine field to identify a PE32/PE32+
- // image instead of using the Magic field. Some systems might generate a PE32+
- // image with PE32 magic.
- //
- switch (PeCoffLoaderImageContext->Machine) {
- case EFI_IMAGE_MACHINE_IA32:
- // Todo: Add EFI_IMAGE_MACHINE_ARMT
- //
- // Assume PE32 image with IA32 Machine field.
- //
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
- break;
- case EFI_IMAGE_MACHINE_X64:
- //
- // Assume PE32+ image with X64 Machine field
- //
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
- break;
- default:
- //
- // For unknown Machine field, use Magic in optional header
- //
- DEBUG ((
- DEBUG_WARN,
- "%a %a: The machine type for this image is not valid for a PRM module.\n",
- _DBGMSGID_,
- __FUNCTION__
- ));
- return EFI_UNSUPPORTED;
- }
-
- OptionalHeaderPtrUnion.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) (
- (UINTN) Image +
- PeCoffLoaderImageContext->PeCoffHeaderOffset
- );
- //
- // Check the PE/COFF Header Signature. Determine if the image is valid and/or a TE image.
- //
- if (OptionalHeaderPtrUnion.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
- DEBUG ((DEBUG_ERROR, "%a %a: The PE signature is not valid for the current image.\n", _DBGMSGID_, __FUNCTION__));
- return EFI_UNSUPPORTED;
- }
-
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
- //
- // Use the PE32 offset to get the Export Directory Entry
- //
- *ImageMajorVersion = OptionalHeaderPtrUnion.Pe32->OptionalHeader.MajorImageVersion;
- *ImageMinorVersion = OptionalHeaderPtrUnion.Pe32->OptionalHeader.MinorImageVersion;
- } else {
- //
- // Use the PE32+ offset to get the Export Directory Entry
- //
- *ImageMajorVersion = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.MajorImageVersion;
- *ImageMinorVersion = OptionalHeaderPtrUnion.Pe32Plus->OptionalHeader.MinorImageVersion;
- }
-
- DEBUG ((DEBUG_INFO, " %a %a - Image Major Version: 0x%02x.\n", _DBGMSGID_, __FUNCTION__, *ImageMajorVersion));
- DEBUG ((DEBUG_INFO, " %a %a - Image Minor Version: 0x%02x.\n", _DBGMSGID_, __FUNCTION__, *ImageMinorVersion));
-
- return EFI_SUCCESS;
-}
-
-/**
- Creates a new PRM Module Image Context linked list entry.
-
- @retval PrmModuleImageContextListEntry If successful, a pointer a PRM Module Image Context linked list entry
- otherwise, NULL is returned.
-
-**/
-STATIC
-PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *
-CreateNewPrmModuleImageContextListEntry (
- VOID
- )
-{
- PRM_MODULE_IMAGE_CONTEXT *PrmModuleImageContext;
- PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *PrmModuleImageContextListEntry;
-
- DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
-
- PrmModuleImageContext = AllocateZeroPool (sizeof (*PrmModuleImageContext));
- if (PrmModuleImageContext == NULL) {
- return NULL;
- }
- DEBUG ((
- DEBUG_INFO,
- " %a %a: Allocated PrmModuleImageContext at 0x%x of size 0x%x bytes.\n",
- _DBGMSGID_,
- __FUNCTION__,
- (UINTN) PrmModuleImageContext,
- sizeof (*PrmModuleImageContext)
- ));
-
- PrmModuleImageContextListEntry = AllocateZeroPool (sizeof (*PrmModuleImageContextListEntry));
- if (PrmModuleImageContextListEntry == NULL) {
- FreePool (PrmModuleImageContext);
- return NULL;
- }
- DEBUG ((
- DEBUG_INFO,
- " %a %a: Allocated PrmModuleImageContextListEntry at 0x%x of size 0x%x bytes.\n",
- _DBGMSGID_,
- __FUNCTION__,
- (UINTN) PrmModuleImageContextListEntry,
- sizeof (*PrmModuleImageContextListEntry)
- ));
-
- PrmModuleImageContextListEntry->Signature = PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE;
- PrmModuleImageContextListEntry->Context = PrmModuleImageContext;
-
- return PrmModuleImageContextListEntry;
-}
-
-/**
- Discovers all PRM Modules loaded during the DXE boot phase.
-
- Each PRM Module discovered is placed into a linked list so the list can br processsed in the future.
-
- @retval EFI_SUCCESS All PRM Modules were discovered successfully.
- @retval EFI_NOT_FOUND The gEfiLoadedImageProtocolGuid protocol could not be found.
- @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to allocate the new PRM Context
- linked list nodes.
-
-**/
-EFI_STATUS
-DiscoverPrmModules (
- VOID
- )
-{
- EFI_STATUS Status;
- PRM_MODULE_IMAGE_CONTEXT TempPrmModuleImageContext;
- PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *PrmModuleImageContextListEntry;
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocol;
- EFI_HANDLE *HandleBuffer;
- UINTN HandleCount;
- UINTN Index;
-
- DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
-
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiLoadedImageProtocolGuid,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (EFI_ERROR (Status) && (HandleCount == 0)) {
- DEBUG ((DEBUG_ERROR, "%a %a: No LoadedImageProtocol instances found!\n", _DBGMSGID_, __FUNCTION__));
- return EFI_NOT_FOUND;
- }
-
- for (Index = 0; Index < HandleCount; Index++) {
- Status = gBS->HandleProtocol (
- HandleBuffer[Index],
- &gEfiLoadedImageProtocolGuid,
- (VOID **) &LoadedImageProtocol
- );
- if (EFI_ERROR (Status)) {
- continue;
- }
-
- ZeroMem (&TempPrmModuleImageContext, sizeof (TempPrmModuleImageContext));
- TempPrmModuleImageContext.PeCoffImageContext.Handle = LoadedImageProtocol->ImageBase;
- TempPrmModuleImageContext.PeCoffImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
-
- Status = PeCoffLoaderGetImageInfo (&TempPrmModuleImageContext.PeCoffImageContext);
- if (EFI_ERROR (Status) || TempPrmModuleImageContext.PeCoffImageContext.ImageError != IMAGE_ERROR_SUCCESS) {
- DEBUG ((
- DEBUG_WARN,
- "%a %a: ImageHandle 0x%016lx is not a valid PE/COFF image. It cannot be considered a PRM module.\n",
- _DBGMSGID_,
- __FUNCTION__,
- (EFI_PHYSICAL_ADDRESS) (UINTN) LoadedImageProtocol->ImageBase
- ));
- continue;
- }
- if (TempPrmModuleImageContext.PeCoffImageContext.IsTeImage) {
- // A PRM Module is not allowed to be a TE image
- continue;
- }
-
- // Attempt to find an export table in this image
- Status = GetExportDirectoryInPeCoffImage (
- LoadedImageProtocol->ImageBase,
- &TempPrmModuleImageContext.PeCoffImageContext,
- &TempPrmModuleImageContext.ExportDirectory
- );
- if (EFI_ERROR (Status)) {
- continue;
- }
-
- // Attempt to find the PRM Module Export Descriptor in the export table
- Status = GetPrmModuleExportDescriptorTable (
- TempPrmModuleImageContext.ExportDirectory,
- &TempPrmModuleImageContext.PeCoffImageContext,
- &TempPrmModuleImageContext.ExportDescriptor
- );
- if (EFI_ERROR (Status)) {
- continue;
- }
- // A PRM Module Export Descriptor was successfully found, this is considered a PRM Module.
-
- //
- // Create a new PRM Module image context node
- //
- PrmModuleImageContextListEntry = CreateNewPrmModuleImageContextListEntry ();
- if (PrmModuleImageContextListEntry == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (
- PrmModuleImageContextListEntry->Context,
- &TempPrmModuleImageContext,
- sizeof (*(PrmModuleImageContextListEntry->Context))
- );
- InsertTailList (&mPrmModuleList, &PrmModuleImageContextListEntry->Link);
- mPrmHandlerCount += TempPrmModuleImageContext.ExportDescriptor->Header.NumberPrmHandlers;
- mPrmModuleCount++; // Todo: Match with global variable refactor change in the future
- DEBUG ((DEBUG_INFO, "%a %a: New PRM Module inserted into list to be processed.\n", _DBGMSGID_, __FUNCTION__));
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Gets the address of an entry in an image export table by ASCII name.
-
- @param[in] ExportName A pointer to an ASCII name string of the entry name.
- @param[in] ImageBaseAddress The base address of the PE/COFF image.
- @param[in] ImageExportDirectory A pointer to the export directory in the image.
- @param[out] ExportPhysicalAddress A pointer that will be updated with the address of the address of the
- export entry if found.
-
- @retval EFI_SUCCESS The export entry was found successfully.
- @retval EFI_INVALID_PARAMETER A required pointer argument is NULL.
- @retval EFI_NOT_FOUND An entry with the given ExportName was not found.
-
-**/
-EFI_STATUS
-GetExportEntryAddress (
- IN CONST CHAR8 *ExportName,
- IN EFI_PHYSICAL_ADDRESS ImageBaseAddress,
- IN EFI_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory,
- OUT EFI_PHYSICAL_ADDRESS *ExportPhysicalAddress
- )
-{
- UINTN ExportNameIndex;
- UINT16 CurrentExportOrdinal;
- UINT32 *ExportAddressTable;
- UINT32 *ExportNamePointerTable;
- UINT16 *OrdinalTable;
- CONST CHAR8 *ExportNameTablePointerName;
-
- if (ExportName == NULL || ImageBaseAddress == 0 || ImageExportDirectory == NULL || ExportPhysicalAddress == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- *ExportPhysicalAddress = 0;
-
- ExportAddressTable = (UINT32 *) ((UINTN) ImageBaseAddress + ImageExportDirectory->AddressOfFunctions);
- ExportNamePointerTable = (UINT32 *) ((UINTN) ImageBaseAddress + ImageExportDirectory->AddressOfNames);
- OrdinalTable = (UINT16 *) ((UINTN) ImageBaseAddress + ImageExportDirectory->AddressOfNameOrdinals);
-
- for (ExportNameIndex = 0; ExportNameIndex < ImageExportDirectory->NumberOfNames; ExportNameIndex++) {
- ExportNameTablePointerName = (CONST CHAR8 *) ((UINTN) ImageBaseAddress + ExportNamePointerTable[ExportNameIndex]);
-
- if (AsciiStrnCmp (ExportName, ExportNameTablePointerName, PRM_HANDLER_NAME_MAXIMUM_LENGTH) == 0) {
- CurrentExportOrdinal = OrdinalTable[ExportNameIndex];
-
- ASSERT (CurrentExportOrdinal < ImageExportDirectory->NumberOfFunctions);
- if (CurrentExportOrdinal >= ImageExportDirectory->NumberOfFunctions) {
- DEBUG ((DEBUG_ERROR, " %a %a: The export ordinal value is invalid.\n", _DBGMSGID_, __FUNCTION__));
- break;
- }
-
- *ExportPhysicalAddress = (EFI_PHYSICAL_ADDRESS) ((UINTN) ImageBaseAddress + ExportAddressTable[CurrentExportOrdinal]);
- return EFI_SUCCESS;
- }
- }
-
- return EFI_NOT_FOUND;
-}
+UINTN mPrmHandlerCount;
+UINTN mPrmModuleCount;
/**
Processes a list of PRM context entries to build a PRM ACPI table.
@@ -616,9 +54,8 @@ ProcessPrmModules (
{
EFI_IMAGE_EXPORT_DIRECTORY *CurrentImageExportDirectory;
PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *CurrentExportDescriptorStruct;
- LIST_ENTRY *Link;
PRM_ACPI_DESCRIPTION_TABLE *PrmAcpiTable;
- PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *TempListEntry;
+ PRM_MODULE_IMAGE_CONTEXT *CurrentPrmModuleImageContext;
CONST CHAR8 *CurrentExportDescriptorHandlerName;
ACPI_PARAMETER_BUFFER_DESCRIPTOR *CurrentModuleAcpiParamDescriptors;
@@ -640,13 +77,12 @@ ProcessPrmModules (
if (PrmAcpiDescriptionTable == NULL) {
return EFI_INVALID_PARAMETER;
}
- Link = NULL;
*PrmAcpiDescriptionTable = NULL;
DEBUG ((DEBUG_INFO, " %a %a: %d total PRM modules to process.\n", _DBGMSGID_, __FUNCTION__, mPrmModuleCount));
DEBUG ((DEBUG_INFO, " %a %a: %d total PRM handlers to process.\n", _DBGMSGID_, __FUNCTION__, mPrmHandlerCount));
- PrmAcpiDescriptionTableBufferSize = (OFFSET_OF (PRM_ACPI_DESCRIPTION_TABLE, PrmModuleInfoStructure) +
+ PrmAcpiDescriptionTableBufferSize = (UINT32) (OFFSET_OF (PRM_ACPI_DESCRIPTION_TABLE, PrmModuleInfoStructure) +
(OFFSET_OF (PRM_MODULE_INFORMATION_STRUCT, HandlerInfoStructure) * mPrmModuleCount) +
(sizeof (PRM_HANDLER_INFORMATION_STRUCT) * mPrmHandlerCount)
);
@@ -667,18 +103,20 @@ ProcessPrmModules (
PrmAcpiTable->Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
PrmAcpiTable->Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
PrmAcpiTable->PrmModuleInfoOffset = OFFSET_OF (PRM_ACPI_DESCRIPTION_TABLE, PrmModuleInfoStructure);
- PrmAcpiTable->PrmModuleInfoCount = mPrmModuleCount;
+ PrmAcpiTable->PrmModuleInfoCount = (UINT32) mPrmModuleCount;
//
// Iterate across all PRM Modules on the list
//
CurrentModuleInfoStruct = &PrmAcpiTable->PrmModuleInfoStructure[0];
- EFI_LIST_FOR_EACH(Link, &mPrmModuleList)
- {
- TempListEntry = CR(Link, PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY, Link, PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE);
- CurrentImageAddress = TempListEntry->Context->PeCoffImageContext.ImageAddress;
- CurrentImageExportDirectory = TempListEntry->Context->ExportDirectory;
- CurrentExportDescriptorStruct = TempListEntry->Context->ExportDescriptor;
+ for (
+ CurrentPrmModuleImageContext = NULL, Status = GetNextPrmModuleEntry (&CurrentPrmModuleImageContext);
+ !EFI_ERROR (Status);
+ Status = GetNextPrmModuleEntry (&CurrentPrmModuleImageContext)) {
+
+ CurrentImageAddress = CurrentPrmModuleImageContext->PeCoffImageContext.ImageAddress;
+ CurrentImageExportDirectory = CurrentPrmModuleImageContext->ExportDirectory;
+ CurrentExportDescriptorStruct = CurrentPrmModuleImageContext->ExportDescriptor;
CurrentModuleAcpiParamDescriptors = NULL;
DEBUG ((
@@ -703,7 +141,7 @@ ProcessPrmModules (
CurrentModuleInfoStruct->MinorRevision = 0;
Status = GetImageVersionInPeCoffImage (
(VOID *) (UINTN) CurrentImageAddress,
- &TempListEntry->Context->PeCoffImageContext,
+ &CurrentPrmModuleImageContext->PeCoffImageContext,
&CurrentModuleInfoStruct->MajorRevision,
&CurrentModuleInfoStruct->MinorRevision
);
@@ -863,9 +301,7 @@ PrmLoaderEndOfDxeNotification (
DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));
- InitializeListHead (&mPrmModuleList);
-
- Status = DiscoverPrmModules ();
+ Status = DiscoverPrmModules (&mPrmModuleCount, &mPrmHandlerCount);
ASSERT_EFI_ERROR (Status);
Status = ProcessPrmModules (&PrmAcpiDescriptionTable);
diff --git a/PrmPkg/Include/Library/PrmModuleDiscoveryLib.h b/PrmPkg/Include/Library/PrmModuleDiscoveryLib.h
new file mode 100644
index 000000000000..fe3a42586afa
--- /dev/null
+++ b/PrmPkg/Include/Library/PrmModuleDiscoveryLib.h
@@ -0,0 +1,60 @@
+/** @file
+
+ The PRM Module Discovery library provides functionality to discover PRM modules installed by platform firmware.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PRM_MODULE_DISCOVERY_LIB_H_
+#define PRM_MODULE_DISCOVERY_LIB_H_
+
+#include <Base.h>
+#include <PrmContextBuffer.h>
+#include <PrmModuleImageContext.h>
+#include <Uefi.h>
+
+/**
+ Gets the next PRM module discovered after the given PRM module.
+
+ @param[in,out] ModuleImageContext A pointer to a pointer to a PRM module image context structure.
+
+ @retval EFI_SUCCESS The next PRM module was found successfully.
+ @retval EFI_INVALID_PARAMETER The given ModuleImageContext structure is invalid or the pointer is NULL.
+ @retval EFI_NOT_FOUND The next PRM module was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+GetNextPrmModuleEntry (
+ IN OUT PRM_MODULE_IMAGE_CONTEXT **ModuleImageContext
+ );
+
+/**
+ Discovers all PRM Modules loaded during boot.
+
+ Each PRM Module discovered is placed into a linked list so the list can br processsed in the future.
+
+ @param[out] ModuleCount An optional pointer parameter that, if provided, is set to the number
+ of PRM modules discovered.
+ @param[out] HandlerCount An optional pointer parameter that, if provided, is set to the number
+ of PRM handlers discovered.
+
+ @retval EFI_SUCCESS All PRM Modules were discovered successfully.
+ @retval EFI_INVALID_PARAMETER An actual pointer parameter was passed as NULL.
+ @retval EFI_NOT_FOUND The gEfiLoadedImageProtocolGuid protocol could not be found.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory resources to allocate the new PRM Context
+ linked list nodes.
+ @retval EFI_ALREADY_STARTED The function was called previously and already discovered the PRM modules
+ loaded on this boot.
+
+**/
+EFI_STATUS
+EFIAPI
+DiscoverPrmModules (
+ OUT UINTN *ModuleCount OPTIONAL,
+ OUT UINTN *HandlerCount OPTIONAL
+ );
+
+#endif
diff --git a/PrmPkg/Include/Library/PrmPeCoffLib.h b/PrmPkg/Include/Library/PrmPeCoffLib.h
new file mode 100644
index 000000000000..4698a9477699
--- /dev/null
+++ b/PrmPkg/Include/Library/PrmPeCoffLib.h
@@ -0,0 +1,111 @@
+/** @file
+
+ The PRM PE/COFF library provides functionality to support additional PE/COFF functionality needed to use
+ Platform Runtime Mechanism (PRM) modules.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PRM_PECOFF_LIB_H_
+#define PRM_PECOFF_LIB_H_
+
+#include <Base.h>
+#include <PrmExportDescriptor.h>
+#include <IndustryStandard/PeImage.h>
+#include <Library/PeCoffLib.h>
+
+/**
+ Gets a pointer to the export directory in a given PE/COFF image.
+
+ @param[in] ImageExportDirectory A pointer to an export directory table in a PE/COFF image.
+ @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
+ PE/COFF image context for the Image containing the PRM Module Export
+ Descriptor table.
+ @param[out] ExportDescriptor A pointer to a pointer to the PRM Module Export Descriptor table found
+ in the ImageExportDirectory given.
+
+ @retval EFI_SUCCESS The PRM Module Export Descriptor table was found successfully.
+ @retval EFI_INVALID_PARAMETER A required parameter is NULL.
+ @retval EFI_NOT_FOUND The PRM Module Export Descriptor table was not found in the given
+ ImageExportDirectory.
+
+**/
+EFI_STATUS
+GetPrmModuleExportDescriptorTable (
+ IN EFI_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory,
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
+ OUT PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT **ExportDescriptor
+ );
+
+/**
+ Gets a pointer to the export directory in a given PE/COFF image.
+
+ @param[in] Image A pointer to a PE32/COFF image base address that is loaded into memory
+ and already relocated to the memory base address. RVAs in the image given
+ should be valid.
+ @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
+ PE/COFF image context for the Image given.
+ @param[out] ImageExportDirectory A pointer to a pointer to the export directory found in the Image given.
+
+ @retval EFI_SUCCESS The export directory was found successfully.
+ @retval EFI_INVALID_PARAMETER A required parameter is NULL.
+ @retval EFI_UNSUPPORTED The PE/COFF image given is not supported as a PRM Module.
+ @retval EFI_NOT_FOUND The image export directory could not be found for this image.
+
+**/
+EFI_STATUS
+GetExportDirectoryInPeCoffImage (
+ IN VOID *Image,
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
+ OUT EFI_IMAGE_EXPORT_DIRECTORY **ImageExportDirectory
+ );
+
+/**
+ Returns the image major and image minor version in a given PE/COFF image.
+
+ @param[in] Image A pointer to a PE32/COFF image base address that is loaded into memory
+ and already relocated to the memory base address. RVAs in the image given
+ should be valid.
+ @param[in] PeCoffLoaderImageContext A pointer to a PE_COFF_LOADER_IMAGE_CONTEXT structure that contains the
+ PE/COFF image context for the Image given.
+ @param[out] ImageMajorVersion A pointer to a UINT16 buffer to hold the image major version.
+ @param[out] ImageMinorVersion A pointer to a UINT16 buffer to hold the image minor version.
+
+ @retval EFI_SUCCESS The image version was read successfully.
+ @retval EFI_INVALID_PARAMETER A required parameter is NULL.
+ @retval EFI_UNSUPPORTED The PE/COFF image given is not supported.
+
+**/
+EFI_STATUS
+GetImageVersionInPeCoffImage (
+ IN VOID *Image,
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *PeCoffLoaderImageContext,
+ OUT UINT16 *ImageMajorVersion,
+ OUT UINT16 *ImageMinorVersion
+ );
+
+/**
+ Gets the address of an entry in an image export table by ASCII name.
+
+ @param[in] ExportName A pointer to an ASCII name string of the entry name.
+ @param[in] ImageBaseAddress The base address of the PE/COFF image.
+ @param[in] ImageExportDirectory A pointer to the export directory in the image.
+ @param[out] ExportPhysicalAddress A pointer that will be updated with the address of the address of the
+ export entry if found.
+
+ @retval EFI_SUCCESS The export entry was found successfully.
+ @retval EFI_INVALID_PARAMETER A required pointer argument is NULL.
+ @retval EFI_NOT_FOUND An entry with the given ExportName was not found.
+
+**/
+EFI_STATUS
+GetExportEntryAddress (
+ IN CONST CHAR8 *ExportName,
+ IN EFI_PHYSICAL_ADDRESS ImageBaseAddress,
+ IN EFI_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory,
+ OUT EFI_PHYSICAL_ADDRESS *ExportPhysicalAddress
+ );
+
+#endif
diff --git a/PrmPkg/Include/PrmModuleImageContext.h b/PrmPkg/Include/PrmModuleImageContext.h
new file mode 100644
index 000000000000..10146a272b6f
--- /dev/null
+++ b/PrmPkg/Include/PrmModuleImageContext.h
@@ -0,0 +1,28 @@
+/** @file
+
+ Definitions used internal to the PrmPkg implementation for PRM module image context.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PRM_MODULE_IMAGE_CONTEXT_H_
+#define PRM_MODULE_IMAGE_CONTEXT_H_
+
+#include <IndustryStandard/PeImage.h>
+#include <Library/PeCoffLib.h>
+
+#include <PrmExportDescriptor.h>
+
+#pragma pack(push, 1)
+
+typedef struct {
+ PE_COFF_LOADER_IMAGE_CONTEXT PeCoffImageContext;
+ EFI_IMAGE_EXPORT_DIRECTORY *ExportDirectory;
+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *ExportDescriptor;
+} PRM_MODULE_IMAGE_CONTEXT;
+
+#pragma pack(pop)
+
+#endif
diff --git a/PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf b/PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf
new file mode 100644
index 000000000000..1115df3a3446
--- /dev/null
+++ b/PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf
@@ -0,0 +1,41 @@
+## @file
+# PRM Module Discovery Library
+#
+# Provides functionality to discover PRM modules loaded in the system boot.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxePrmModuleDiscoveryLib
+ FILE_GUID = 95D3893F-4CBA-4C20-92C1-D24BFE3CE7B9
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PrmModuleDiscoveryLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
+ CONSTRUCTOR = PrmModuleDiscoveryLibConstructor
+ DESTRUCTOR = PrmModuleDiscoveryLibDestructor
+
+[Sources]
+ PrmModuleDiscovery.h
+ DxePrmModuleDiscoveryLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ PrmPeCoffLib
+ UefiBootServicesTableLib
+
+[Protocols]
+ gEfiLoadedImageProtocolGuid
+ gEfiMmAccessProtocolGuid
diff --git a/PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h b/PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
new file mode 100644
index 000000000000..79058d15317e
--- /dev/null
+++ b/PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
@@ -0,0 +1,27 @@
+/** @file
+
+ Definitions internally used for Platform Runtime Mechanism (PRM) module discovery.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PRM_MODULE_DISCOVERY_H_
+#define PRM_MODULE_DISCOVERY_H_
+
+#include <PrmModuleImageContext.h>
+
+#define PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE SIGNATURE_32('P','R','M','E')
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link;
+ PRM_MODULE_IMAGE_CONTEXT Context;
+} PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY;
+
+#pragma pack(pop)
+
+#endif
diff --git a/PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf b/PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
new file mode 100644
index 000000000000..f139d5380b98
--- /dev/null
+++ b/PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
@@ -0,0 +1,32 @@
+## @file
+# PRM PE/COFF Library
+#
+# Provides functionality to support additional PE/COFF functionality needed to use Platform Runtime Mechanism (PRM)
+# modules.
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxePrmPeCoffLib
+ FILE_GUID = 0B9AEEAC-D79A-46A5-A784-84BDBC6291B5
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PrmPeCoffLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+[Sources]
+ DxePrmPeCoffLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PrmPkg/PrmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ PeCoffLib
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoader.h b/PrmPkg/PrmLoaderDxe/PrmLoader.h
deleted file mode 100644
index 1356c7a0c923..000000000000
--- a/PrmPkg/PrmLoaderDxe/PrmLoader.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/** @file
-
- Definitions specific to the Platform Runtime Mechanism (PRM) loader.x
-
- Copyright (c) Microsoft Corporation
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef PRM_LOADER_H_
-#define PRM_LOADER_H_
-
-#include <IndustryStandard/PeImage.h>
-#include <Library/PeCoffLib.h>
-
-#include <PrmExportDescriptor.h>
-
-#define _DBGMSGID_ "[PRMLOADER]"
-#define PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE SIGNATURE_32('P','R','M','E')
-
-#pragma pack(push, 1)
-
-typedef struct {
- PE_COFF_LOADER_IMAGE_CONTEXT PeCoffImageContext;
- EFI_IMAGE_EXPORT_DIRECTORY *ExportDirectory;
- PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *ExportDescriptor;
-} PRM_MODULE_IMAGE_CONTEXT;
-
-typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
- PRM_MODULE_IMAGE_CONTEXT *Context;
-} PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY;
-
-#pragma pack(pop)
-
-//
-// Iterate through the double linked list. NOT delete safe.
-//
-#define EFI_LIST_FOR_EACH(Entry, ListHead) \
- for(Entry = (ListHead)->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink)
-
-//
-// Iterate through the double linked list. This is delete-safe.
-// Don't touch NextEntry.
-//
-#define EFI_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead) \
- for(Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink;\
- Entry != (ListHead); Entry = NextEntry, NextEntry = Entry->ForwardLin
-
-#endif
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
index 4d959ccd35a3..554d49685e2a 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
@@ -22,7 +22,6 @@ [Defines]
[Sources]
PrmAcpiTable.h
- PrmLoader.h
PrmLoaderDxe.c
[Packages]
@@ -39,8 +38,9 @@ [LibraryClasses]
DebugLib
MemoryAllocationLib
PcdLib
- PeCoffLib
PrmContextBufferLib
+ PrmModuleDiscoveryLib
+ PrmPeCoffLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
@@ -54,7 +54,6 @@ [Pcd]
[Protocols]
gEfiAcpiTableProtocolGuid
- gEfiLoadedImageProtocolGuid
gPrmConfigProtocolGuid
[Depex]
diff --git a/PrmPkg/PrmPkg.dec b/PrmPkg/PrmPkg.dec
index ff681d423d30..785e2c24c2f9 100644
--- a/PrmPkg/PrmPkg.dec
+++ b/PrmPkg/PrmPkg.dec
@@ -36,6 +36,14 @@ [LibraryClasses]
#
PrmContextBufferLib|Include/Library/PrmContextBufferLib.h
+ ## @libraryclass Provides functionality to discover PRM modules installed by platform firmware
+ #
+ PrmModuleDiscoveryLib|Include/Library/PrmModuleDiscoveryLib.h
+
+ ## @libraryclass Provides additional PE/COFF functionality needed to support the Platform Runtime Mechanism (PRM) loader driver.
+ #
+ PrmPeCoffLib|Include/Library/PrmPeCoffLib.h
+
[Protocols]
## PRM Configuration Protocol
#
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
index 19b996eb3a02..e876f2053a8e 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -55,6 +55,9 @@ [LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER]
# PRM Package
#
PrmContextBufferLib|$(PLATFORM_PACKAGE)/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
+ PrmModuleDiscoveryLib|$(PLATFORM_PACKAGE)/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf
+ PrmPeCoffLib|$(PLATFORM_PACKAGE)/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
+
###################################################################################################
#
@@ -72,6 +75,16 @@ [Components]
$(PLATFORM_PACKAGE)/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf
$(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
+ #
+ # PRM Module Discovery Library
+ #
+ $(PLATFORM_PACKAGE)/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf
+
+ #
+ # PRM PE/COFF Library
+ #
+ $(PLATFORM_PACKAGE)/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
+
#
# PRM Configuration Driver
#
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 26/41] PrmPkg/Application/PrmInfo: Add initial application
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (24 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 25/41] PrmPkg: Refactor some PrmLoaderDxe functionality into libraries Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 27/41] PrmPkg: Enforce stricter types Michael Kubacki
` (14 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a new UEFI application called "PrmInfo" that allows a user
to display and test Platform Runtime Mechanism (PRM) modules.
Execute the application help command for detailed usage
instructions and examples of how to use the application:
"PrmInfo -?"
This application is intended to be helpful during PRM enabling
by allowing the user to:
1. Confirm that their firmware port of the PRM infrastructure
implemented in this package is functioning correctly.
2. Quickly get information about what PRM modules and handlers
are present on a given system.
3. Quickly test PRM handlers without booting to a fully featured
operating system.
4. Develop and exercise PRM handlers prior to the availability of
an operating system that is PRM aware.
Adds a brief section to Readme.md about the PrmInfo UEFI application
with a link to allow the reader to find more information about the
application if interested.
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/Application/PrmInfo/PrmInfo.c | 725 ++++++++++++++++++++
PrmPkg/Application/PrmInfo/PrmInfo.h | 49 ++
PrmPkg/Application/PrmInfo/PrmInfo.inf | 66 ++
PrmPkg/Application/PrmInfo/PrmInfo.uni | 11 +
| 12 +
PrmPkg/Application/PrmInfo/PrmInfoStrings.uni | 132 ++++
PrmPkg/PrmPkg.dec | 10 +
PrmPkg/PrmPkg.dsc | 28 +-
PrmPkg/Readme.md | 19 +
9 files changed, 1050 insertions(+), 2 deletions(-)
diff --git a/PrmPkg/Application/PrmInfo/PrmInfo.c b/PrmPkg/Application/PrmInfo/PrmInfo.c
new file mode 100644
index 000000000000..431a6f206163
--- /dev/null
+++ b/PrmPkg/Application/PrmInfo/PrmInfo.c
@@ -0,0 +1,725 @@
+/** @file
+ Prints information about the PRM configuration loaded by the system firmware.
+
+ This application also provides some additional testing features for PRM configuration. For example,
+ the application can be used to selectively invoke PRM handlers in the UEFI shell environment to
+ provide a quick testing path of the PRM infrastructure on the firmware and the PRM module implementation.
+
+ This can also be useful to prepare a PRM enabled firmware and PRM modules prior to formal OS support to
+ test the PRM code.
+
+ Copyright (C) Microsoft Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/ZeroGuid.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrmContextBufferLib.h>
+#include <Library/PrmModuleDiscoveryLib.h>
+#include <Library/PrmPeCoffLib.h>
+#include <Library/ShellLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiHiiServicesLib.h>
+#include <Library/UefiLib.h>
+
+#include "PrmInfo.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringPrmInfoHelpTokenId = STRING_TOKEN (STR_PRMINFO_HELP);
+//
+// This is the generated String package data for all .UNI files.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 PrmInfoStrings[];
+
+STATIC UINTN mPrmHandlerCount;
+STATIC UINTN mPrmModuleCount;
+
+STATIC EFI_HII_HANDLE mPrmInfoHiiHandle;
+STATIC LIST_ENTRY mPrmHandlerList;
+
+STATIC CONST SHELL_PARAM_ITEM mParamList[] = {
+ {L"-l", TypeFlag},
+ {L"-t", TypeValue},
+ {NULL, TypeMax}
+ };
+
+/**
+ Frees all of the nodes in a linked list.
+
+ @param[in] ListHead A pointer to the head of the list that should be freed.
+
+ **/
+VOID
+EFIAPI
+FreeList (
+ IN LIST_ENTRY *ListHead
+ )
+{
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NextLink;
+ PRM_HANDLER_CONTEXT_LIST_ENTRY *ListEntry;
+
+ if (ListHead == NULL) {
+ return;
+ }
+
+ Link = GetFirstNode (&mPrmHandlerList);
+ while (!IsNull (&mPrmHandlerList, Link)) {
+ ListEntry = CR (Link, PRM_HANDLER_CONTEXT_LIST_ENTRY, Link, PRM_HANDLER_CONTEXT_LIST_ENTRY_SIGNATURE);
+ NextLink = GetNextNode (&mPrmHandlerList, Link);
+
+ RemoveEntryList (Link);
+ FreePool (ListEntry);
+
+ Link = NextLink;
+ }
+}
+
+/**
+ Creates a new PRM Module Image Context linked list entry.
+
+ @retval PrmHandlerContextListEntry If successful, a pointer a PRM Handler Context linked list entry
+ otherwise, NULL is returned.
+
+**/
+PRM_HANDLER_CONTEXT_LIST_ENTRY *
+CreateNewPrmHandlerListEntry (
+ VOID
+ )
+{
+ PRM_HANDLER_CONTEXT_LIST_ENTRY *PrmHandlerContextListEntry;
+
+ PrmHandlerContextListEntry = AllocateZeroPool (sizeof (*PrmHandlerContextListEntry));
+ if (PrmHandlerContextListEntry == NULL) {
+ return NULL;
+ }
+ PrmHandlerContextListEntry->Signature = PRM_HANDLER_CONTEXT_LIST_ENTRY_SIGNATURE;
+
+ return PrmHandlerContextListEntry;
+}
+
+/**
+ Creates a new PRM Module Image Context linked list entry.
+
+ @param[in] RuntimeMmioRanges A pointer to an array of PRM module config runtime MMIO ranges.
+
+**/
+VOID
+PrintMmioRuntimeRangeInfo (
+ IN PRM_RUNTIME_MMIO_RANGES *RuntimeMmioRanges
+ )
+{
+ UINTN RuntimeMmioRangeCount;
+ UINTN RuntimeMmioRangeIndex;
+
+ if (RuntimeMmioRanges == NULL) {
+ return;
+ }
+
+ RuntimeMmioRangeCount = (UINTN) RuntimeMmioRanges->Count;
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_RUNTIME_MMIO_COUNT), mPrmInfoHiiHandle, RuntimeMmioRangeCount);
+
+ for (RuntimeMmioRangeIndex = 0; RuntimeMmioRangeIndex < RuntimeMmioRangeCount; RuntimeMmioRangeIndex++) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_PRMINFO_RUNTIME_MMIO_INFO),
+ mPrmInfoHiiHandle,
+ RuntimeMmioRangeIndex,
+ RuntimeMmioRanges->Range[RuntimeMmioRangeIndex].PhysicalBaseAddress,
+ RuntimeMmioRanges->Range[RuntimeMmioRangeIndex].VirtualBaseAddress,
+ RuntimeMmioRanges->Range[RuntimeMmioRangeIndex].Length
+ );
+ }
+}
+
+/**
+ Gathers the PRM handler (and by extension module) information discovered on this system.
+
+ This function must be called to build up the discovered context for other functions in the application. The
+ function will optionally print results as determed by the value of the PrintInformation parameter.
+
+ @param[in] PrintInformation Indicates whether to print information as discovered in the function.
+
+**/
+VOID
+GatherPrmHandlerInfo (
+ IN BOOLEAN PrintInformation
+ )
+{
+ EFI_STATUS Status;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT16 HandlerCount;
+ UINTN HandlerIndex;
+ EFI_PHYSICAL_ADDRESS CurrentHandlerPhysicalAddress;
+ EFI_PHYSICAL_ADDRESS CurrentImageAddress;
+ PRM_HANDLER_CONTEXT CurrentHandlerContext;
+ EFI_GUID *CurrentModuleGuid;
+ EFI_IMAGE_EXPORT_DIRECTORY *CurrentImageExportDirectory;
+ PRM_CONTEXT_BUFFER *CurrentContextBuffer;
+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *CurrentExportDescriptorStruct;
+ PRM_MODULE_CONTEXT_BUFFERS *CurrentModuleContextBuffers;
+ PRM_HANDLER_CONTEXT_LIST_ENTRY *CurrentHandlerContextListEntry;
+ PRM_MODULE_IMAGE_CONTEXT *CurrentPrmModuleImageContext;
+ PRM_RUNTIME_MMIO_RANGES *CurrentPrmModuleRuntimeMmioRanges;
+
+ ASSERT (mPrmModuleCount <= mPrmHandlerCount);
+
+ if (mPrmHandlerCount == 0) {
+ return;
+ }
+
+ // Iterate across all PRM modules discovered
+ for (
+ CurrentPrmModuleImageContext = NULL, Status = GetNextPrmModuleEntry (&CurrentPrmModuleImageContext);
+ !EFI_ERROR (Status);
+ Status = GetNextPrmModuleEntry (&CurrentPrmModuleImageContext)) {
+
+ CurrentImageAddress = CurrentPrmModuleImageContext->PeCoffImageContext.ImageAddress;
+ CurrentImageExportDirectory = CurrentPrmModuleImageContext->ExportDirectory;
+ CurrentExportDescriptorStruct = CurrentPrmModuleImageContext->ExportDescriptor;
+
+ CurrentModuleGuid = &CurrentExportDescriptorStruct->Header.ModuleGuid;
+ HandlerCount = CurrentExportDescriptorStruct->Header.NumberPrmHandlers;
+
+ MajorVersion = 0;
+ MinorVersion = 0;
+ Status = GetImageVersionInPeCoffImage (
+ (VOID *) (UINTN) CurrentImageAddress,
+ &CurrentPrmModuleImageContext->PeCoffImageContext,
+ &MajorVersion,
+ &MinorVersion
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (PrintInformation) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_PRMINFO_MODULE_NAME),
+ mPrmInfoHiiHandle,
+ (CHAR8 *) ((UINTN) CurrentImageAddress + CurrentImageExportDirectory->Name)
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_MODULE_GUID), mPrmInfoHiiHandle, CurrentModuleGuid);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_MODULE_VERSION), mPrmInfoHiiHandle, MajorVersion, MinorVersion);
+ }
+
+ // It is currently valid for a PRM module not to use a context buffer
+ CurrentPrmModuleRuntimeMmioRanges = NULL;
+ Status = GetModuleContextBuffers (
+ ByModuleGuid,
+ CurrentModuleGuid,
+ &CurrentModuleContextBuffers
+ );
+ ASSERT (!EFI_ERROR (Status) || Status == EFI_NOT_FOUND);
+ if (!EFI_ERROR (Status) && CurrentModuleContextBuffers != NULL) {
+ CurrentPrmModuleRuntimeMmioRanges = CurrentModuleContextBuffers->RuntimeMmioRanges;
+ }
+
+ if (PrintInformation) {
+ if (CurrentPrmModuleRuntimeMmioRanges != NULL) {
+ PrintMmioRuntimeRangeInfo (CurrentPrmModuleRuntimeMmioRanges);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_NO_MMIO_RANGES), mPrmInfoHiiHandle);
+ }
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_LINE_BREAK), mPrmInfoHiiHandle);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLER_COUNT), mPrmInfoHiiHandle, HandlerCount);
+ }
+
+ for (HandlerIndex = 0; HandlerIndex < HandlerCount; HandlerIndex++) {
+ ZeroMem (&CurrentHandlerContext, sizeof (CurrentHandlerContext));
+
+ CurrentHandlerContext.ModuleName = (CHAR8 *) ((UINTN) CurrentImageAddress + CurrentImageExportDirectory->Name);
+ CurrentHandlerContext.Guid = &CurrentExportDescriptorStruct->PrmHandlerExportDescriptors[HandlerIndex].PrmHandlerGuid;
+ CurrentHandlerContext.Name = (CHAR8 *) CurrentExportDescriptorStruct->PrmHandlerExportDescriptors[HandlerIndex].PrmHandlerName;
+
+ if (PrintInformation) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLER_NAME), mPrmInfoHiiHandle, CurrentHandlerContext.Name);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLER_GUID), mPrmInfoHiiHandle, CurrentHandlerContext.Guid);
+ }
+
+ Status = GetExportEntryAddress (
+ CurrentHandlerContext.Name,
+ CurrentImageAddress,
+ CurrentImageExportDirectory,
+ &CurrentHandlerPhysicalAddress
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ CurrentHandlerContext.Handler = (PRM_HANDLER *) (UINTN) CurrentHandlerPhysicalAddress;
+
+ if (PrintInformation) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLER_PA), mPrmInfoHiiHandle, CurrentHandlerPhysicalAddress);
+ }
+ } else {
+ if (PrintInformation) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLER_PA_ERROR), mPrmInfoHiiHandle, Status);
+ }
+ }
+
+ Status = GetContextBuffer (
+ CurrentHandlerContext.Guid,
+ CurrentModuleContextBuffers,
+ &CurrentContextBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ CurrentHandlerContext.StaticDataBuffer = CurrentContextBuffer->StaticDataBuffer;
+ }
+
+ if (PrintInformation) {
+ if (CurrentHandlerContext.StaticDataBuffer != NULL) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_PRMINFO_STATIC_DATA_BUFFER),
+ mPrmInfoHiiHandle,
+ (UINTN) CurrentHandlerContext.StaticDataBuffer
+ );
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_LINE_BREAK), mPrmInfoHiiHandle);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_NO_STATIC_BUFFER), mPrmInfoHiiHandle);
+ }
+ }
+
+ CurrentHandlerContextListEntry = CreateNewPrmHandlerListEntry ();
+ ASSERT (CurrentHandlerContextListEntry != NULL);
+ if (CurrentHandlerContextListEntry != NULL) {
+ CopyMem (
+ &CurrentHandlerContextListEntry->Context,
+ &CurrentHandlerContext,
+ sizeof (CurrentHandlerContextListEntry->Context)
+ );
+ InsertTailList (&mPrmHandlerList, &CurrentHandlerContextListEntry->Link);
+ }
+ }
+ }
+}
+
+/**
+ Populates the given context buffer so it can be passed to a PRM handler.
+
+ @param[in] StaticDataBuffer A pointer to the static data buffer that will be referenced in the context
+ buffer that is populated. This is an optional pointer that, if not provided,
+ by passing NULL will be ignored.
+ @param[in] HandlerGuid A pointer to the GUID of the PRM handler.
+ @param[in] ContextBuffer A pointer to a caller allocated ContextBuffer structure that will be populated
+ by this function.
+
+ @retval EFI_SUCCESS The given ContextBuffer was populated successfully.
+ @retval EFI_INVALID_PARAMETER The HandlerGuid or ContextBuffer actual argument is NULL.
+
+**/
+EFI_STATUS
+PopulateContextBuffer (
+ IN PRM_DATA_BUFFER *StaticDataBuffer OPTIONAL,
+ IN EFI_GUID *HandlerGuid,
+ IN PRM_CONTEXT_BUFFER *ContextBuffer
+ )
+{
+ if (HandlerGuid == NULL || ContextBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ZeroMem (ContextBuffer, sizeof (*ContextBuffer));
+
+ ContextBuffer->Signature = PRM_CONTEXT_BUFFER_SIGNATURE;
+ ContextBuffer->Version = PRM_CONTEXT_BUFFER_INTERFACE_VERSION;
+ CopyGuid (&ContextBuffer->HandlerGuid, HandlerGuid);
+
+ if (StaticDataBuffer != NULL) {
+ ContextBuffer->StaticDataBuffer = StaticDataBuffer;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Prints a given execution time in the appropriate unit.
+
+ @param[in] TimeInNanoSec The time to print in unit of nanoseconds.
+
+**/
+VOID
+PrintExecutionTime (
+ IN UINT64 TimeInNanoSec
+ )
+{
+ UINT64 Sec;
+ UINT64 MilliSec;
+ UINT64 MicroSec;
+ UINT64 NanoSec;
+ UINT64 RemainingTime;
+
+ Sec = 0;
+ MilliSec = 0;
+ MicroSec = 0;
+ NanoSec = 0;
+ RemainingTime = TimeInNanoSec;
+
+ if (RemainingTime > ONE_SECOND) {
+ Sec = DivU64x32 (RemainingTime, ONE_SECOND);
+ RemainingTime -= MultU64x32 (Sec, ONE_SECOND);
+ }
+
+ if (RemainingTime > ONE_MILLISECOND) {
+ MilliSec = DivU64x32 (RemainingTime, ONE_MILLISECOND);
+ RemainingTime -= MultU64x32 (MilliSec, ONE_MILLISECOND);
+ }
+
+ if (RemainingTime > ONE_MICROSECOND) {
+ MicroSec = DivU64x32 (RemainingTime, ONE_MICROSECOND);
+ RemainingTime -= MultU64x32 (MicroSec, ONE_MICROSECOND);
+ }
+
+ if (RemainingTime > 0) {
+ NanoSec = RemainingTime;
+ }
+
+ if (Sec > 0) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_SECS), mPrmInfoHiiHandle, Sec, MilliSec, MicroSec, NanoSec);
+ } else if (MilliSec > 0) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_MILLI_SECS), mPrmInfoHiiHandle, MilliSec, MicroSec, NanoSec);
+ } else if (MicroSec > 0) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_USECS), mPrmInfoHiiHandle, MicroSec, NanoSec);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_NANO_SECS), mPrmInfoHiiHandle, NanoSec);
+ }
+}
+
+/**
+ Executes the PRM handler with the provided GUID.
+
+ @param[in] HandlerGuid A pointer to the GUID of the PRM handler to execute.
+ A zero GUID indicates that all PRM handlers present should be executed.
+
+ @retval EFI_SUCCESS The PRM handler(s) were executed.
+ @retval EFI_INVALID_PARAMETER The HandlerGuid actual argument is NULL.
+ @retval EFI_NOT_FOUND The PRM handler could not be found.
+
+**/
+EFI_STATUS
+ExecutePrmHandlerByGuid (
+ IN EFI_GUID *HandlerGuid
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN ExecuteAllHandlers;
+ BOOLEAN HandlerFound;
+ UINT64 StartTime;
+ UINT64 EndTime;
+ PRM_CONTEXT_BUFFER CurrentContextBuffer;
+ PRM_HANDLER_CONTEXT *HandlerContext;
+ PRM_HANDLER_CONTEXT_LIST_ENTRY *HandlerContextListEntry;
+ LIST_ENTRY *Link;
+
+ Link = NULL;
+ HandlerFound = FALSE;
+
+ if (HandlerGuid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Zero GUID means execute all discovered handlers
+ //
+ ExecuteAllHandlers = CompareGuid (HandlerGuid, &gZeroGuid);
+
+ EFI_LIST_FOR_EACH (Link, &mPrmHandlerList) {
+ HandlerContextListEntry = CR (Link, PRM_HANDLER_CONTEXT_LIST_ENTRY, Link, PRM_HANDLER_CONTEXT_LIST_ENTRY_SIGNATURE);
+ HandlerContext = &HandlerContextListEntry->Context;
+
+ if (!ExecuteAllHandlers && !CompareGuid (HandlerGuid, HandlerContext->Guid)) {
+ continue;
+ }
+
+ HandlerFound = TRUE;
+ Status = PopulateContextBuffer (HandlerContext->StaticDataBuffer, HandlerContext->Guid, &CurrentContextBuffer);
+ if (!EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_LINE_BREAK), mPrmInfoHiiHandle);
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_PRMINFO_MODULE_NAME),
+ mPrmInfoHiiHandle,
+ HandlerContext->ModuleName
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLER_NAME_HL), mPrmInfoHiiHandle, HandlerContext->Name);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLER_GUID), mPrmInfoHiiHandle, HandlerContext->Guid);
+
+ StartTime = 0;
+ EndTime = 0;
+ if (PcdGetBool (PcdPrmInfoPrintHandlerExecutionTime)) {
+ StartTime = GetPerformanceCounter ();
+ }
+ Status = HandlerContext->Handler (NULL, &CurrentContextBuffer);
+ if (PcdGetBool (PcdPrmInfoPrintHandlerExecutionTime)) {
+ EndTime = GetPerformanceCounter ();
+ }
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLER_ERR_STATUS), mPrmInfoHiiHandle, Status);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLER_SUCC_STATUS), mPrmInfoHiiHandle, Status);
+ }
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLER_EXEC_TIME), mPrmInfoHiiHandle);
+ if (StartTime == 0 && EndTime == 0) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_UNKNOWN), mPrmInfoHiiHandle);
+ } else {
+ PrintExecutionTime (GetTimeInNanoSecond (EndTime - StartTime));
+ }
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_LINE_BREAK), mPrmInfoHiiHandle);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_LINE_BREAK), mPrmInfoHiiHandle);
+ } else {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a - %a: An error occurred creating a context buffer for handler %g\n",
+ gEfiCallerBaseName,
+ __FUNCTION__,
+ HandlerContext->Guid
+ ));
+ }
+
+ if (!ExecuteAllHandlers) {
+ break;
+ }
+ }
+
+ if (!HandlerFound) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Parses the application parameter list and performs the appropriate operations based on the results.
+
+ @retval EFI_SUCCESS The parameter list was parsed successfully.
+ @retval EFI_INVALID_PARAMETER An invalid parameter was given to the application.
+ @retval EFI_LOAD_ERROR An error occurred loading the application.
+
+**/
+EFI_STATUS
+ParseParameterList (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ SHELL_STATUS ReturnStatus;
+ UINTN ArgumentCount;
+ EFI_GUID HandlerGuid;
+ BOOLEAN PrintHandlerInfo;
+ LIST_ENTRY *Package;
+ LIST_ENTRY *TempNode;
+ CHAR16 *ProblemParam;
+ CONST CHAR16 *HandlerGuidStr;
+
+ HandlerGuidStr = NULL;
+ Package = NULL;
+ PrintHandlerInfo = FALSE;
+ ReturnStatus = EFI_SUCCESS;
+
+ InitializeListHead (&mPrmHandlerList);
+
+ //
+ // Basic application parameter validation
+ //
+ Status = ShellCommandLineParseEx (mParamList, &Package, &ProblemParam, FALSE, FALSE);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_GEN_PROBLEM), mPrmInfoHiiHandle, APPLICATION_NAME, ProblemParam);
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ FreePool (ProblemParam);
+ } else {
+ ReturnStatus = EFI_LOAD_ERROR;
+ ASSERT (FALSE);
+ }
+
+ goto Done;
+ } else if (Package == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_NO_ARG), mPrmInfoHiiHandle, APPLICATION_NAME);
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ //
+ // Get argument count including flags
+ //
+ for (
+ ArgumentCount = 0, TempNode = Package;
+ GetNextNode (Package, TempNode) != Package;
+ ArgumentCount++, TempNode = GetNextNode (Package, TempNode)
+ );
+
+ if (ArgumentCount == 1) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_NO_ARG), mPrmInfoHiiHandle, APPLICATION_NAME);
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ if (ArgumentCount > 6) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_TOO_MANY), mPrmInfoHiiHandle, APPLICATION_NAME);
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ //
+ // Parse the actual arguments provided
+ //
+ if (ShellCommandLineGetFlag (Package, L"-b")) {
+ if (ArgumentCount <= 2) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_PARAM_INV), mPrmInfoHiiHandle, APPLICATION_NAME, L"-b");
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ goto Done;
+ } else {
+ ShellSetPageBreakMode (TRUE);
+ }
+ }
+
+ if (ShellCommandLineGetFlag (Package, L"-l")) {
+ PrintHandlerInfo = TRUE;
+ }
+
+ if (ShellCommandLineGetFlag (Package, L"-t")) {
+ HandlerGuidStr = ShellCommandLineGetValue (Package, L"-t");
+ if (HandlerGuidStr != NULL) {
+ if (StrnCmp (HandlerGuidStr, L"all", StrLen (HandlerGuidStr)) == 0) {
+ CopyGuid (&HandlerGuid, &gZeroGuid);
+ } else {
+ Status = StrToGuid (HandlerGuidStr, &HandlerGuid);
+ if (EFI_ERROR (Status) || (HandlerGuidStr[GUID_STRING_LENGTH] != L'\0')) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_GUID_INV), mPrmInfoHiiHandle, APPLICATION_NAME, HandlerGuidStr);
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+ }
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_NO_VALUE), mPrmInfoHiiHandle, APPLICATION_NAME, L"-t");
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+ }
+
+ Status = DiscoverPrmModules (&mPrmModuleCount, &mPrmHandlerCount);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_DISCOVERY_FAILED), mPrmInfoHiiHandle, APPLICATION_NAME);
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a - %a: An error occurred during PRM module discovery (%r)\n",
+ gEfiCallerBaseName,
+ __FUNCTION__,
+ Status
+ ));
+ ReturnStatus = Status;
+ goto Done;
+ }
+
+ if (PrintHandlerInfo) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_LIST_TITLE), mPrmInfoHiiHandle);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_MODULES_FOUND), mPrmInfoHiiHandle, mPrmModuleCount);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLERS_FOUND), mPrmInfoHiiHandle, mPrmHandlerCount);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_LINE_BREAK), mPrmInfoHiiHandle);
+ }
+ GatherPrmHandlerInfo (PrintHandlerInfo);
+
+ if (HandlerGuidStr != NULL) {
+ Status = ExecutePrmHandlerByGuid (&HandlerGuid);
+ if (Status == EFI_NOT_FOUND) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PRMINFO_HANDLER_NOT_FOUND), mPrmInfoHiiHandle, APPLICATION_NAME, HandlerGuid);
+ }
+ }
+
+Done:
+ FreeList (&mPrmHandlerList);
+
+ if (Package != NULL) {
+ ShellCommandLineFreeVarList (Package);
+ }
+
+ return ReturnStatus;
+}
+
+/**
+ Entry point of this UEFI application.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;
+
+ //
+ // Retrieve the HII package list from ImageHandle
+ //
+ Status = gBS->OpenProtocol (
+ ImageHandle,
+ &gEfiHiiPackageListProtocolGuid,
+ (VOID **) &PackageList,
+ ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Publish the HII package list to the HII Database
+ //
+ Status = gHiiDatabase->NewPackageList (
+ gHiiDatabase,
+ PackageList,
+ NULL,
+ &mPrmInfoHiiHandle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (mPrmInfoHiiHandle == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ Status = ParseParameterList ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a - %a: An error occurred parsing user-provided arguments (%r)\n",
+ gEfiCallerBaseName,
+ __FUNCTION__,
+ Status
+ ));
+ }
+
+ if (mPrmInfoHiiHandle != NULL) {
+ HiiRemovePackages (mPrmInfoHiiHandle);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/PrmPkg/Application/PrmInfo/PrmInfo.h b/PrmPkg/Application/PrmInfo/PrmInfo.h
new file mode 100644
index 000000000000..c2c3fa2f23fc
--- /dev/null
+++ b/PrmPkg/Application/PrmInfo/PrmInfo.h
@@ -0,0 +1,49 @@
+/** @file
+ Prints information about the PRM configuration loaded by the system firmware.
+
+ Copyright (C) Microsoft Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PRM_INFO_H_
+#define PRM_INFO_H_
+
+#include <Base.h>
+#include <Prm.h>
+#include <PrmDataBuffer.h>
+#include <Uefi.h>
+
+#define APPLICATION_NAME L"PrmInfo"
+
+#define PRM_HANDLER_CONTEXT_LIST_ENTRY_SIGNATURE SIGNATURE_32('P','R','H','E')
+
+#pragma pack(push, 1)
+
+typedef struct {
+ CHAR8 *Name;
+ EFI_GUID *Guid;
+ PRM_DATA_BUFFER *StaticDataBuffer;
+ CHAR8 *ModuleName;
+ PRM_HANDLER *Handler;
+} PRM_HANDLER_CONTEXT;
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link;
+ PRM_HANDLER_CONTEXT Context;
+} PRM_HANDLER_CONTEXT_LIST_ENTRY;
+
+#pragma pack(pop)
+
+//
+// Iterate through the double linked list. NOT delete safe.
+//
+#define EFI_LIST_FOR_EACH(Entry, ListHead) \
+ for(Entry = (ListHead)->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink)
+
+#define ONE_MICROSECOND (1000)
+#define ONE_MILLISECOND (1000 * ONE_MICROSECOND)
+#define ONE_SECOND (1000 * ONE_MILLISECOND)
+
+#endif
diff --git a/PrmPkg/Application/PrmInfo/PrmInfo.inf b/PrmPkg/Application/PrmInfo/PrmInfo.inf
new file mode 100644
index 000000000000..df8fb9ccc0db
--- /dev/null
+++ b/PrmPkg/Application/PrmInfo/PrmInfo.inf
@@ -0,0 +1,66 @@
+## @file
+# PrmInfo.inf
+#
+# Reports information about the PRM configuration currently loaded on the system.
+#
+# Copyright (C) Microsoft Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PrmInfo
+ FILE_GUID = F26C503B-BD8E-4274-A80B-2C4E20FADA6E
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+ UEFI_HII_RESOURCE_SECTION = TRUE
+ MODULE_UNI_FILE = PrmInfo.uni
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ PrmInfoStrings.uni
+ PrmInfo.h
+ PrmInfo.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+ PrmPkg/PrmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ HiiLib
+ MemoryAllocationLib
+ PcdLib
+ PrmContextBufferLib
+ PrmModuleDiscoveryLib
+ PrmPeCoffLib
+ ShellLib
+ TimerLib
+ UefiApplicationEntryPoint
+ UefiBootServicesTableLib
+ UefiHiiServicesLib
+ UefiLib
+
+[Pcd]
+ gPrmPkgTokenSpaceGuid.PcdPrmInfoPrintHandlerExecutionTime
+
+[Protocols]
+ gEfiHiiPackageListProtocolGuid ## CONSUMES
+
+[Guids]
+ gPrmHiiGuid
+ gZeroGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ PrmInfoExtra.uni
diff --git a/PrmPkg/Application/PrmInfo/PrmInfo.uni b/PrmPkg/Application/PrmInfo/PrmInfo.uni
new file mode 100644
index 000000000000..1b65e117e8e2
--- /dev/null
+++ b/PrmPkg/Application/PrmInfo/PrmInfo.uni
@@ -0,0 +1,11 @@
+// /**
+// Platform Runtime Mechanism (PRM) Information UEFI shell application
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// */
+
+#string STR_MODULE_ABSTRACT #language en-US "A shell application that displays information about the PRM configuration loaded by system firmware"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This application displays information about the PRM configuration loaded by system firmware."
--git a/PrmPkg/Application/PrmInfo/PrmInfoExtra.uni b/PrmPkg/Application/PrmInfo/PrmInfoExtra.uni
new file mode 100644
index 000000000000..f50c17903a0a
--- /dev/null
+++ b/PrmPkg/Application/PrmInfo/PrmInfoExtra.uni
@@ -0,0 +1,12 @@
+// /** @file
+// PrmInfo Localized Strings and Content
+//
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Platform Runtime Mechanism (PRM) Information Application"
diff --git a/PrmPkg/Application/PrmInfo/PrmInfoStrings.uni b/PrmPkg/Application/PrmInfo/PrmInfoStrings.uni
new file mode 100644
index 000000000000..9385fd848344
--- /dev/null
+++ b/PrmPkg/Application/PrmInfo/PrmInfoStrings.uni
@@ -0,0 +1,132 @@
+/** @file
+ String definitions for the PRM Information UEFI shell application.
+
+ Copyright (C) Microsoft Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+*/
+
+#langdef en-US "English"
+
+//
+// Parameter error messages
+//
+#string STR_PRMINFO_DISCOVERY_FAILED #language en-US "%H%s%N: PRM module discovery failed.\r\n"
+#string STR_PRMINFO_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'\r\n"
+#string STR_PRMINFO_GUID_INV #language en-US "%H%s%N: Invalid GUID - '%H%s%N'\r\n"
+#string STR_PRMINFO_HANDLER_NOT_FOUND #language en-US "%H%s%N: PRM Handler not found - '%H{%g}%N'\r\n"
+#string STR_PRMINFO_MISSING_OPTION #language en-US "%H%s%N: Missing option '%H%s%N' required by flag - '%H%s%N'\r\n"
+#string STR_PRMINFO_NO_ARG #language en-US "%H%s%N: An argument must be provided, try "-?" for help.\n"
+#string STR_PRMINFO_NO_VALUE #language en-US "%H%s%N: Missing argument for flag - '%H%s%N'\r\n"
+#string STR_PRMINFO_PARAM_INV #language en-US "%H%s%N: Invalid argument - '%H%s%N', try "-?" for help.\r\n"
+#string STR_PRMINFO_TOO_MANY #language en-US "%H%s%N: Too many arguments.\r\n"
+
+//
+// Application informational messages
+//
+#string STR_PRMINFO_HANDLER_COUNT #language en-US " Handler Count: %d\r\n"
+#string STR_PRMINFO_HANDLER_EXEC_TIME #language en-US " Execution Time: "
+#string STR_PRMINFO_HANDLER_GUID #language en-US " Handler GUID: %g\r\n"
+#string STR_PRMINFO_HANDLER_NAME #language en-US " Handler Name: %a\r\n"
+#string STR_PRMINFO_HANDLER_NAME_HL #language en-US " Handler Name: %H%a%N\r\n"
+#string STR_PRMINFO_HANDLER_PA #language en-US " Handler Physical Address: 0x%016x\r\n"
+#string STR_PRMINFO_HANDLER_ERR_STATUS #language en-US " Return Status: %E%r%N\r\n"
+#string STR_PRMINFO_HANDLER_SUCC_STATUS #language en-US " Return Status: %V%r%N\r\n"
+#string STR_PRMINFO_HANDLERS_FOUND #language en-US " %d PRM handlers found.\r\n"
+#string STR_PRMINFO_LINE_BREAK #language en-US "\r\n"
+#string STR_PRMINFO_LIST_TITLE #language en-US "PRM Modules and Handlers:\r\n"
+#string STR_PRMINFO_MODULE_GUID #language en-US "Module GUID: %g\r\n"
+#string STR_PRMINFO_MODULE_NAME #language en-US "Module Name: %a\r\n"
+#string STR_PRMINFO_MODULE_VERSION #language en-US "Module Version: %02d.%02d\r\n\r\n"
+#string STR_PRMINFO_MODULES_FOUND #language en-US " %d PRM modules found.\r\n"
+#string STR_PRMINFO_NO_MMIO_RANGES #language en-US " No runtime MMIO ranges used by this module.\r\n"
+#string STR_PRMINFO_NO_STATIC_BUFFER #language en-US " This handler does not define a static data buffer.\r\n\r\n"
+#string STR_PRMINFO_RUNTIME_MMIO_COUNT #language en-US " Runtime MMIO Range Count: %d\r\n"
+#string STR_PRMINFO_RUNTIME_MMIO_INFO #language en-US " [%d]: Physical Base Address = 0x%016x\r\n Virtual Base Address = 0x%016x\r\n Length = 0x%x\r\n"
+#string STR_PRMINFO_STATIC_DATA_BUFFER #language en-US " Static Data Buffer: 0x%016x\r\n"
+#string STR_PRMINFO_UNKNOWN #language en-US "Unknown"
+#string STR_PRMINFO_USECS #language en-US "%H%ld.%ld microseconds%N"
+#string STR_PRMINFO_NANO_SECS #language en-US "%H%ld nanoseconds%N"
+#string STR_PRMINFO_SECS #language en-US "%H%ld.%ld%ld%ld seconds%N"
+#string STR_PRMINFO_MILLI_SECS #language en-US "%H%ld.%ld%ld milliseconds%N"
+
+//
+// Application error messages
+//
+#string STR_PRMINFO_HANDLER_PA_ERROR #language en-US " An ERROR (%r) occurred determining the handler physical address.\r\n"
+
+#string STR_PRMINFO_HELP #language en-US ""
+".TH PrmInfo 0 "Display and test Platform Runtime Mechanism (PRM) modules."\r\n"
+".SH NAME:\r\n"
+"Display and test Platform Runtime Mechanism (PRM) modules.\r\n"
+".SH SYNOPSIS\r\n"
+"\r\n"
+"PRMINFO [[-?] | [-b] [-l] [-r] [-t (guid | all)]]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -? - Show help.\r\n"
+" -b - Displays one screen of output at a time.\r\n"
+" -l - Display a list of installed PRM modules and handlers.\r\n"
+" -t - Call a given PRM handler by the specified GUID.\r\n"
+" guid - A 32 digit GUID string with hyphen separation with no enclosing\r\n"
+" character such as braces.\r\n"
+" Example: 00000000-0000-0000-0000-000000000000\r\n"
+" all - The string 'all' indicating all PRM handlers should be called\r\n"
+" in order discovered.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+" This program is provided to allow examination of the Platform Runtime\r\n"
+" Mechanism (PRM) configuration present on the current system. In addition,\r\n"
+" the application contains some lightweight tests to verify that the firmware\r\n"
+" set up the PRM information that will be conveyed to the loaded operating\r\n"
+" system correctly.\r\n"
+" \r\n"
+" Default behavior is to display the content of all the PRM modules and\r\n"
+" handlers currently installed (equivalent to the -l argument). To facilitate\r\n"
+" debugging and verifying correct implementation of the PRM infrastructure\r\n"
+" and PRM modules in a given firmware, the application can also call a\r\n"
+" given PRM handler and perform basic validation of the PRMT ACPI table\r\n"
+" to confirm it satisfies the basic constraints required for the table\r\n"
+" in the PRM Specification.\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. Calling PRM handlers from this application:\r\n"
+" - The user should exercise caution when calling PRM handlers in the\r\n"
+" pre-OS environment. The PRM author may have only considered\r\n"
+" execution within the context of OS runtime."
+"\r\n"
+" - The application will not perform any manipulation of PRM handler\r\n"
+" parameter buffers prior to calling the handler.\r\n"
+"\r\n"
+" - This feature is intended to provide a quick method to exercise\r\n"
+" PRM code without loading a full OS that is PRM aware and to perform\r\n"
+" testing of PRM code that is aware it will be executed in such an\r\n"
+" environment. It is not recommended to call PRM handlers on a\r\n"
+" production system if you are not fully aware of how the PRM handler\r\n"
+" behaves and any side effect(s) it might have on the system.\r\n"
+".SH STANDARDS\r\n"
+" \r\n"
+"STANDARDS:\r\n"
+" Platform Runtime Mechanism (PRM) is currently in a draft state and the\r\n"
+" specification is not yet publicly available. A reference to the publicly\r\n"
+" available document will replace this text when it is available.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To display a list of the installed PRM modules and PRM handlers:\r\n"
+" fs0:\> prminfo -l\r\n"
+" \r\n"
+" * To validate the installed PRMT ACPI table:\r\n"
+" fs0:\> prminfo -r\r\n"
+" \r\n"
+" * To call a PRM handler by GUID:\r\n"
+" fs0:\> prminfo -t e1466081-7562-430f-896b-b0e523dc335a\r\n"
+" \r\n"
+" * To call all of the PRM handlers discovered on the system:\r\n"
+" fs0:\> prminfo -t all\r\n"
+".SH RETURNVALUES\r\n"
+" \r\n"
+"RETURN VALUES:\r\n"
+" SHELL_SUCCESS Data was displayed as requested.\r\n"
+" SHELL_INVALID_PARAMETER The operation failed.\r\n"
+" \r\n"
diff --git a/PrmPkg/PrmPkg.dec b/PrmPkg/PrmPkg.dec
index 785e2c24c2f9..94888d1c70a4 100644
--- a/PrmPkg/PrmPkg.dec
+++ b/PrmPkg/PrmPkg.dec
@@ -30,6 +30,7 @@ [Includes]
[Guids]
gPrmPkgTokenSpaceGuid = { 0x46f56acc, 0x600b, 0x450f, { 0xa5, 0x9c, 0x3a, 0x1a, 0x4a, 0xd4, 0x35, 0x3e }}
+ gPrmHiiGuid = { 0xee4cd885, 0xd104, 0x4056, { 0x84, 0xba, 0x46, 0x18, 0x82, 0xa7, 0x2a, 0x18 }}
[LibraryClasses]
## @libraryclass Provides a general abstraction for PRM context buffer management
@@ -55,3 +56,12 @@ [PcdsFixedAtBuild]
## Size in bytes of a PRM firmware volume
gPrmPkgTokenSpaceGuid.PcdFlashFvPrmSize|0x00000000|UINT32|0x00000002
+
+ ## Print PRM handler execution time in PrmInfo
+ #
+ # Provides an option to disable usage of a timer library to record PRM handler
+ # execution time. In most cases, the platform should provide a valid TimerLib
+ # instance that can be used when the application is built with that package to
+ # report PRM handler execution time in the application. If such a TimerLib
+ # instance is not available, set this PCD to FALSE in the package DSC file.
+ gPrmPkgTokenSpaceGuid.PcdPrmInfoPrintHandlerExecutionTime|TRUE|BOOLEAN|0x00000003
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
index e876f2053a8e..5241354cb220 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -36,13 +36,14 @@ [LibraryClasses.common]
RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
-[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER]
+[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
#
# EDK II Packages
#
BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
- DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
@@ -59,6 +60,24 @@ [LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER]
PrmPeCoffLib|$(PLATFORM_PACKAGE)/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
+[LibraryClasses.common.UEFI_APPLICATION]
+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+
+################################################################################
+#
+# Pcd Section - List of PCD entries modified by this package
+#
+################################################################################
+
+[PcdsFixedAtBuild.common]
+ gPrmPkgTokenSpaceGuid.PcdPrmInfoPrintHandlerExecutionTime|FALSE
+
###################################################################################################
#
# Components Section - List of the modules and components that will be processed by compilation
@@ -116,6 +135,11 @@ [Components]
}
$(PLATFORM_PACKAGE)/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf
+ #
+ # PRM Information UEFI Application
+ #
+ $(PLATFORM_PACKAGE)/Application/PrmInfo/PrmInfo.inf
+
#
# The SampleMemoryAllocationModule was used during a time in the POC when the OS
# provided memory allocation services. This module was successful in using those services.
diff --git a/PrmPkg/Readme.md b/PrmPkg/Readme.md
index b79cb66c4790..2a8a40c924c0 100644
--- a/PrmPkg/Readme.md
+++ b/PrmPkg/Readme.md
@@ -118,6 +118,25 @@ maintained in PrmPkg. It is intended to only contain PRM infrastructure code and
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 Information UEFI Application
+A UEFI application is provided in this package called "PrmInfo" that allows a user to display and test PRM
+modules on their system.
+
+[Link to application source code](PrmPkg/Application/PrmInfo).
+
+This application is intended to be helpful during PRM enabling by allowing the user to:
+ 1. Confirm that their firmware port of the PRM infrastructure implemented in this package is functioning correctly.
+ 2. Quickly get information about what PRM modules and handlers that are present on a given system.
+ 3. Quickly test PRM handlers without booting into a full operating system.
+ 4. Develop and exercise PRM handlers prior to the availability of an operating system that is PRM aware.
+
+Execute the application help command for detailed usage instructions and examples of how to use the application: \
+ ``PrmInfo -?``
+
+*Example Usage:*
+
+![](PrmPkg/Application/PrmInfo/PrmInfo_Usage_Example.gif)
+
## PRM Module
> __*Note*__: You can find simple examples of PRM modules in the Samples directory of this package.
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 27/41] PrmPkg: Enforce stricter types
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (25 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 26/41] PrmPkg/Application/PrmInfo: Add initial application Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 28/41] PrmPkg/Test/PrmPkgHostTest.dsc: Add initial file Michael Kubacki
` (13 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Makes the following changes to enforce stricter types:
1. PrmPkg/PrmConfigDxe
The function PrmConfigEndOfDxeNotification () is used as a notify
function (of type EFI_EVENT_NOTIFY), however it has a return type
of EFI_STATUS whereas the return type should actually be VOID.
2. PrmPkg/PrmLoaderDxe
Updates the following types to be more accurate than were allowed
in the VS compiler:
* 3rd actual argument given to GetModuleContextBuffers () is
explicitly marked as CONST PRM_MODULE_CONTEXT_BUFFERS **
* 3rd actual argument given to GetContextBuffer () is
explicitly marked as CONST PRM_CONTEXT_BUFFER **
* PrmLoaderEndOfDxeNotification () return type is changed to VOID
to align with the EFI_EVENT_NOTIFY type
3. PrmPkg/Application/PrmInfo
Updates the following types to be more accurate than were allowed
in the VS compiler:
* SHELL_STATUS in ParseParameterList () is now EFI_STATUS
* 3rd actual argument given to GetModuleContextBuffers () is
explicitly marked as CONST PRM_MODULE_CONTEXT_BUFFERS **
* 3rd actual argument given to GetContextBuffer () is
explicitly marked as CONST PRM_CONTEXT_BUFFER **
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/Application/PrmInfo/PrmInfo.c | 6 +++---
PrmPkg/PrmConfigDxe/PrmConfigDxe.c | 8 ++------
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c | 10 +++-------
3 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/PrmPkg/Application/PrmInfo/PrmInfo.c b/PrmPkg/Application/PrmInfo/PrmInfo.c
index 431a6f206163..e479667ec7eb 100644
--- a/PrmPkg/Application/PrmInfo/PrmInfo.c
+++ b/PrmPkg/Application/PrmInfo/PrmInfo.c
@@ -221,7 +221,7 @@ GatherPrmHandlerInfo (
Status = GetModuleContextBuffers (
ByModuleGuid,
CurrentModuleGuid,
- &CurrentModuleContextBuffers
+ (CONST PRM_MODULE_CONTEXT_BUFFERS **) &CurrentModuleContextBuffers
);
ASSERT (!EFI_ERROR (Status) || Status == EFI_NOT_FOUND);
if (!EFI_ERROR (Status) && CurrentModuleContextBuffers != NULL) {
@@ -272,7 +272,7 @@ GatherPrmHandlerInfo (
Status = GetContextBuffer (
CurrentHandlerContext.Guid,
CurrentModuleContextBuffers,
- &CurrentContextBuffer
+ (CONST PRM_CONTEXT_BUFFER **) &CurrentContextBuffer
);
if (!EFI_ERROR (Status)) {
CurrentHandlerContext.StaticDataBuffer = CurrentContextBuffer->StaticDataBuffer;
@@ -520,7 +520,7 @@ ParseParameterList (
)
{
EFI_STATUS Status;
- SHELL_STATUS ReturnStatus;
+ EFI_STATUS ReturnStatus;
UINTN ArgumentCount;
EFI_GUID HandlerGuid;
BOOLEAN PrintHandlerInfo;
diff --git a/PrmPkg/PrmConfigDxe/PrmConfigDxe.c b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
index c547db3eca5e..f3223d63de0c 100644
--- a/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
+++ b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
@@ -361,10 +361,8 @@ PrmConfigVirtualAddressChangeEvent (
@param[in] Context The pointer to the notification function's context,
which is implementation-dependent.
- @retval EFI_SUCCESS The function executed successfully
-
**/
-EFI_STATUS
+VOID
EFIAPI
PrmConfigEndOfDxeNotification (
IN EFI_EVENT Event,
@@ -446,8 +444,6 @@ PrmConfigEndOfDxeNotification (
gBS->FreePool (HandleBuffer);
}
gBS->CloseEvent(Event);
-
- return EFI_SUCCESS;
}
/**
@@ -476,7 +472,7 @@ PrmConfigEntryPoint (
// Register a notification function to change memory attributes at end of DXE
//
Event = NULL;
- Status = gBS->CreateEventEx(
+ Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
PrmConfigEndOfDxeNotification,
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
index 407c48257432..aa7aab391e8c 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -151,7 +151,7 @@ ProcessPrmModules (
Status = GetModuleContextBuffers (
ByModuleGuid,
&CurrentModuleInfoStruct->Identifier,
- &CurrentModuleContextBuffers
+ (CONST PRM_MODULE_CONTEXT_BUFFERS **) &CurrentModuleContextBuffers
);
ASSERT (!EFI_ERROR (Status) || Status == EFI_NOT_FOUND);
if (!EFI_ERROR (Status) && CurrentModuleContextBuffers != NULL) {
@@ -177,7 +177,7 @@ ProcessPrmModules (
Status = GetContextBuffer (
&CurrentHandlerInfoStruct->Identifier,
CurrentModuleContextBuffers,
- &CurrentContextBuffer
+ (CONST PRM_CONTEXT_BUFFER **) &CurrentContextBuffer
);
if (!EFI_ERROR (Status)) {
CurrentHandlerInfoStruct->StaticDataBuffer = (UINT64) (UINTN) CurrentContextBuffer->StaticDataBuffer;
@@ -286,10 +286,8 @@ PublishPrmAcpiTable (
@param[in] Context The pointer to the notification function's context,
which is implementation-dependent.
- @retval EFI_SUCCESS The function executed successfully
-
**/
-EFI_STATUS
+VOID
EFIAPI
PrmLoaderEndOfDxeNotification (
IN EFI_EVENT Event,
@@ -314,8 +312,6 @@ PrmLoaderEndOfDxeNotification (
FreePool (PrmAcpiDescriptionTable);
}
gBS->CloseEvent (Event);
-
- return EFI_SUCCESS;
}
/**
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 28/41] PrmPkg/Test/PrmPkgHostTest.dsc: Add initial file
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (26 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 27/41] PrmPkg: Enforce stricter types Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 29/41] PrmPkg/Test/UnitTest/Library: Add initial UEFI Boot Services test lib Michael Kubacki
` (12 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a new DSC file that will be used to build host-based unit tests
in PrmPkg.
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/Test/PrmPkgHostTest.dsc | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/PrmPkg/Test/PrmPkgHostTest.dsc b/PrmPkg/Test/PrmPkgHostTest.dsc
new file mode 100644
index 000000000000..41f3c32b8d19
--- /dev/null
+++ b/PrmPkg/Test/PrmPkgHostTest.dsc
@@ -0,0 +1,17 @@
+## @file
+# PrmPkg DSC file used to build host-based unit tests.
+#
+# Copyright (c) Microsoft Corporation.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ PLATFORM_NAME = PrmPkgHostTest
+ PLATFORM_GUID = 5BCCFC54-2162-42FB-ABCA-5B8D0DC4013C
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME)/HostTest
+ SUPPORTED_ARCHITECTURES = IA32|X64
+ BUILD_TARGETS = NOOPT
+ SKUID_IDENTIFIER = DEFAULT
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 29/41] PrmPkg/Test/UnitTest/Library: Add initial UEFI Boot Services test lib
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (27 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 28/41] PrmPkg/Test/PrmPkgHostTest.dsc: Add initial file Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 30/41] PrmPkg/Library/DxePrmContextBufferLib: Add host-based unit tests Michael Kubacki
` (11 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a host-based specific implementation of UefiBootServicesTableLib.
This library implements relatively simple versions of the functionality
in the actual boot services implementation and does not depend on
dynamic linking to the boot services table.
Most unit tests can install the dependencies their code under test
depends on prior to invocation and uninstall those dependencies after
the test to test code that directly depends on boot services.
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/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.c | 119 ++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestEventTimer.c | 180 +++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestImage.c | 163 ++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMemory.c | 145 ++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMisc.c | 198 +++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.c | 1633 ++++++++++++++++++++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestTpl.c | 43 +
PrmPkg/PrmPkg.dsc | 1 +
PrmPkg/Test/PrmPkgHostTest.dsc | 11 +
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibTest.uni | 12 +
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.h | 1046 +++++++++++++
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf | 46 +
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.h | 123 ++
13 files changed, 3720 insertions(+)
diff --git a/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.c b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.c
new file mode 100644
index 000000000000..d41cba3fea0e
--- /dev/null
+++ b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.c
@@ -0,0 +1,119 @@
+/** @file
+ This library supports a Boot Services table library implementation that allows code dependent
+ upon UefiBootServicesTableLib to operate in an isolated execution environment such as within
+ the context of a host-based unit test framework.
+
+ The unit test should initialize the Boot Services database with any required elements
+ (e.g. protocols, events, handles, etc.) prior to the services being invoked by code under test.
+
+ It is strongly recommended to clean any global databases (e.g. protocol, event, handles, etc.) after
+ every unit test so the tests execute in a predictable manner from a clean state.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiBootServicesTableLibUnitTest.h"
+
+EFI_HANDLE gImageHandle = NULL;
+EFI_SYSTEM_TABLE *gST = NULL;
+
+STATIC EFI_BOOT_SERVICES mBootServices = {
+ {
+ EFI_BOOT_SERVICES_SIGNATURE, // Signature
+ EFI_BOOT_SERVICES_REVISION, // Revision
+ sizeof (EFI_BOOT_SERVICES), // HeaderSize
+ 0, // CRC32
+ 0 // Reserved
+ },
+ (EFI_RAISE_TPL) UnitTestRaiseTpl, // RaiseTPL
+ (EFI_RESTORE_TPL) UnitTestRestoreTpl, // RestoreTPL
+ (EFI_ALLOCATE_PAGES) UnitTestAllocatePages, // AllocatePages
+ (EFI_FREE_PAGES) UnitTestFreePages, // FreePages
+ (EFI_GET_MEMORY_MAP) UnitTestGetMemoryMap, // GetMemoryMap
+ (EFI_ALLOCATE_POOL) UnitTestAllocatePool, // AllocatePool
+ (EFI_FREE_POOL) UnitTestFreePool, // FreePool
+ (EFI_CREATE_EVENT) UnitTestCreateEvent, // CreateEvent
+ (EFI_SET_TIMER) UnitTestSetTimer, // SetTimer
+ (EFI_WAIT_FOR_EVENT) UnitTestWaitForEvent, // WaitForEvent
+ (EFI_SIGNAL_EVENT) UnitTestSignalEvent, // SignalEvent
+ (EFI_CLOSE_EVENT) UnitTestCloseEvent, // CloseEvent
+ (EFI_CHECK_EVENT) UnitTestCheckEvent, // CheckEvent
+ (EFI_INSTALL_PROTOCOL_INTERFACE) UnitTestInstallProtocolInterface, // InstallProtocolInterface
+ (EFI_REINSTALL_PROTOCOL_INTERFACE) UnitTestReinstallProtocolInterface, // ReinstallProtocolInterface
+ (EFI_UNINSTALL_PROTOCOL_INTERFACE) UnitTestUninstallProtocolInterface, // UninstallProtocolInterface
+ (EFI_HANDLE_PROTOCOL) UnitTestHandleProtocol, // HandleProtocol
+ (VOID *) NULL, // Reserved
+ (EFI_REGISTER_PROTOCOL_NOTIFY) UnitTestRegisterProtocolNotify, // RegisterProtocolNotify
+ (EFI_LOCATE_HANDLE) UnitTestLocateHandle, // LocateHandle
+ (EFI_LOCATE_DEVICE_PATH) UnitTestLocateDevicePath, // LocateDevicePath
+ (EFI_INSTALL_CONFIGURATION_TABLE) UnitTestInstallConfigurationTable, // InstallConfigurationTable
+ (EFI_IMAGE_LOAD) UnitTestLoadImage, // LoadImage
+ (EFI_IMAGE_START) UnitTestStartImage, // StartImage
+ (EFI_EXIT) UnitTestExit, // Exit
+ (EFI_IMAGE_UNLOAD) UnitTestUnloadImage, // UnloadImage
+ (EFI_EXIT_BOOT_SERVICES) UnitTestExitBootServices, // ExitBootServices
+ (EFI_GET_NEXT_MONOTONIC_COUNT) UnitTestGetNextMonotonicCount, // GetNextMonotonicCount
+ (EFI_STALL) UnitTestStall, // Stall
+ (EFI_SET_WATCHDOG_TIMER) UnitTestSetWatchdogTimer, // SetWatchdogTimer
+ (EFI_CONNECT_CONTROLLER) UnitTestConnectController, // ConnectController
+ (EFI_DISCONNECT_CONTROLLER) UnitTestDisconnectController, // DisconnectController
+ (EFI_OPEN_PROTOCOL) UnitTestOpenProtocol, // OpenProtocol
+ (EFI_CLOSE_PROTOCOL) UnitTestCloseProtocol, // CloseProtocol
+ (EFI_OPEN_PROTOCOL_INFORMATION) UnitTestOpenProtocolInformation, // OpenProtocolInformation
+ (EFI_PROTOCOLS_PER_HANDLE) UnitTestProtocolsPerHandle, // ProtocolsPerHandle
+ (EFI_LOCATE_HANDLE_BUFFER) UnitTestLocateHandleBuffer, // LocateHandleBuffer
+ (EFI_LOCATE_PROTOCOL) UnitTestLocateProtocol, // LocateProtocol
+ (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) UnitTestInstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces
+ (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) UnitTestUninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces
+ (EFI_CALCULATE_CRC32) UnitTestCalculateCrc32, // CalculateCrc32
+ (EFI_COPY_MEM) CopyMem, // CopyMem
+ (EFI_SET_MEM) SetMem, // SetMem
+ (EFI_CREATE_EVENT_EX) UnitTestCreateEventEx // CreateEventEx
+};
+
+EFI_BOOT_SERVICES *gBS = &mBootServices;
+
+/**
+ The constructor function caches the pointer of Boot Services Table.
+
+ The constructor function caches the pointer of Boot Services Table through System Table.
+ It will ASSERT() if the pointer of System Table is NULL.
+ It will ASSERT() if the pointer of Boot Services Table is NULL.
+ It will always return EFI_SUCCESS.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiBootServicesTableLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ //
+ // Cache the Image Handle
+ //
+ gImageHandle = ImageHandle;
+ ASSERT (gImageHandle != NULL);
+
+ //
+ // Cache pointer to the EFI System Table
+ //
+
+ // Note: The system table is not implemented
+ gST = NULL;
+
+ //
+ // Cache pointer to the EFI Boot Services Table
+ //
+ gBS = SystemTable->BootServices;
+ ASSERT (gBS != NULL);
+
+ return EFI_SUCCESS;
+}
diff --git a/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestEventTimer.c b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestEventTimer.c
new file mode 100644
index 000000000000..16bd3f4c547d
--- /dev/null
+++ b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestEventTimer.c
@@ -0,0 +1,180 @@
+/** @file
+ Implementation of event and timer related services in the UEFI Boot Services table for use in unit tests.
+
+Copyright (c) Microsoft Corporation
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiBootServicesTableLibUnitTest.h"
+
+/**
+ Creates an event.
+
+ @param Type The type of event to create and its mode and
+ attributes
+ @param NotifyTpl The task priority level of event notifications
+ @param NotifyFunction Pointer to the events notification function
+ @param NotifyContext Pointer to the notification functions context
+ corresponds to parameter "Context" in the
+ notification function
+ @param Event Pointer to the newly created event if the call
+ succeeds undefined otherwise
+
+ @retval EFI_SUCCESS The event structure was created
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
+ @retval EFI_OUT_OF_RESOURCES The event could not be allocated
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCreateEvent (
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
+ IN VOID *NotifyContext, OPTIONAL
+ OUT EFI_EVENT *Event
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Sets the type of timer and the trigger time for a timer event.
+
+ @param UserEvent The timer event that is to be signaled at the
+ specified time
+ @param Type The type of time that is specified in
+ TriggerTime
+ @param TriggerTime The number of 100ns units until the timer
+ expires
+
+ @retval EFI_SUCCESS The event has been set to be signaled at the
+ requested time
+ @retval EFI_INVALID_PARAMETER Event or Type is not valid
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestSetTimer (
+ IN EFI_EVENT UserEvent,
+ IN EFI_TIMER_DELAY Type,
+ IN UINT64 TriggerTime
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Stops execution until an event is signaled.
+
+ @param NumberOfEvents The number of events in the UserEvents array
+ @param UserEvents An array of EFI_EVENT
+ @param UserIndex Pointer to the index of the event which
+ satisfied the wait condition
+
+ @retval EFI_SUCCESS The event indicated by Index was signaled.
+ @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification
+ function or Event was not a valid type
+ @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestWaitForEvent (
+ IN UINTN NumberOfEvents,
+ IN EFI_EVENT *UserEvents,
+ OUT UINTN *UserIndex
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Signals the event. Queues the event to be notified if needed.
+
+ @param UserEvent The event to signal .
+
+ @retval EFI_INVALID_PARAMETER Parameters are not valid.
+ @retval EFI_SUCCESS The event was signaled.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestSignalEvent (
+ IN EFI_EVENT UserEvent
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Closes an event and frees the event structure.
+
+ @param UserEvent Event to close
+
+ @retval EFI_INVALID_PARAMETER Parameters are not valid.
+ @retval EFI_SUCCESS The event has been closed
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCloseEvent (
+ IN EFI_EVENT UserEvent
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Check the status of an event.
+
+ @param UserEvent The event to check
+
+ @retval EFI_SUCCESS The event is in the signaled state
+ @retval EFI_NOT_READY The event is not in the signaled state
+ @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCheckEvent (
+ IN EFI_EVENT UserEvent
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Creates an event in a group.
+
+ @param Type The type of event to create and its mode and
+ attributes
+ @param NotifyTpl The task priority level of event notifications
+ @param NotifyFunction Pointer to the events notification function
+ @param NotifyContext Pointer to the notification functions context
+ corresponds to parameter "Context" in the
+ notification function
+ @param EventGroup GUID for EventGroup if NULL act the same as
+ gBS->CreateEvent().
+ @param Event Pointer to the newly created event if the call
+ succeeds undefined otherwise
+
+ @retval EFI_SUCCESS The event structure was created
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
+ @retval EFI_OUT_OF_RESOURCES The event could not be allocated
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCreateEventEx (
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
+ IN CONST VOID *NotifyContext, OPTIONAL
+ IN CONST EFI_GUID *EventGroup, OPTIONAL
+ OUT EFI_EVENT *Event
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
diff --git a/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestImage.c b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestImage.c
new file mode 100644
index 000000000000..b6083a4c3f27
--- /dev/null
+++ b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestImage.c
@@ -0,0 +1,163 @@
+/** @file
+ Implementation of image related services in the UEFI Boot Services table for use in unit tests.
+
+Copyright (c) Microsoft Corporation
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiBootServicesTableLibUnitTest.h"
+
+/**
+ Loads an EFI image into memory and returns a handle to the image.
+
+ @param BootPolicy If TRUE, indicates that the request originates
+ from the boot manager, and that the boot
+ manager is attempting to load FilePath as a
+ boot selection.
+ @param ParentImageHandle The caller's image handle.
+ @param FilePath The specific file path from which the image is
+ loaded.
+ @param SourceBuffer If not NULL, a pointer to the memory location
+ containing a copy of the image to be loaded.
+ @param SourceSize The size in bytes of SourceBuffer.
+ @param ImageHandle Pointer to the returned image handle that is
+ created when the image is successfully loaded.
+
+ @retval EFI_SUCCESS The image was loaded into memory.
+ @retval EFI_NOT_FOUND The FilePath was not found.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+ @retval EFI_UNSUPPORTED The image type is not supported, or the device
+ path cannot be parsed to locate the proper
+ protocol for loading the file.
+ @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient
+ resources.
+ @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not
+ understood.
+ @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error.
+ @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the
+ image from being loaded. NULL is returned in *ImageHandle.
+ @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a
+ valid EFI_LOADED_IMAGE_PROTOCOL. However, the current
+ platform policy specifies that the image should not be started.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestLoadImage (
+ IN BOOLEAN BootPolicy,
+ IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Transfer control to a loaded image's entry point.
+
+ @param ImageHandle Handle of image to be started.
+ @param ExitDataSize Pointer of the size to ExitData
+ @param ExitData Pointer to a pointer to a data buffer that
+ includes a Null-terminated string,
+ optionally followed by additional binary data.
+ The string is a description that the caller may
+ use to further indicate the reason for the
+ image's exit.
+
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
+ @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started.
+ @retval EFI_SUCCESS Successfully transfer control to the image's
+ entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestStartImage (
+ IN EFI_HANDLE ImageHandle,
+ OUT UINTN *ExitDataSize,
+ OUT CHAR16 **ExitData OPTIONAL
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Terminates the currently loaded EFI image and returns control to boot services.
+
+ @param ImageHandle Handle that identifies the image. This
+ parameter is passed to the image on entry.
+ @param Status The image's exit code.
+ @param ExitDataSize The size, in bytes, of ExitData. Ignored if
+ ExitStatus is EFI_SUCCESS.
+ @param ExitData Pointer to a data buffer that includes a
+ Null-terminated Unicode string, optionally
+ followed by additional binary data. The string
+ is a description that the caller may use to
+ further indicate the reason for the image's
+ exit.
+
+ @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current
+ image.
+ @retval EFI_SUCCESS Successfully terminates the currently loaded
+ EFI image.
+ @retval EFI_ACCESS_DENIED Should never reach there.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate pool
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestExit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_STATUS Status,
+ IN UINTN ExitDataSize,
+ IN CHAR16 *ExitData OPTIONAL
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Unloads an image.
+
+ @param ImageHandle Handle that identifies the image to be
+ unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_UNSUPPORTED The image has been started, and does not support
+ unload.
+ @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestUnloadImage (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Terminates all boot services.
+
+ @param ImageHandle Handle that identifies the exiting image.
+ @param MapKey Key to the latest memory map.
+
+ @retval EFI_SUCCESS Boot Services terminated
+ @retval EFI_INVALID_PARAMETER MapKey is incorrect.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestExitBootServices (
+ IN EFI_HANDLE ImageHandle,
+ IN UINTN MapKey
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
diff --git a/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMemory.c b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMemory.c
new file mode 100644
index 000000000000..48da39d0c359
--- /dev/null
+++ b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMemory.c
@@ -0,0 +1,145 @@
+/** @file
+ Implementation of memory related services in the UEFI Boot Services table for use in unit tests.
+
+Copyright (c) Microsoft Corporation
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiBootServicesTableLibUnitTest.h"
+
+/**
+ Allocates pages from the memory map.
+
+ @param Type The type of allocation to perform
+ @param MemoryType The type of memory to turn the allocated pages
+ into
+ @param NumberOfPages The number of pages to allocate
+ @param Memory A pointer to receive the base allocated memory
+ address
+
+ @return Status. On success, Memory is filled in with the base address allocated
+ @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in
+ spec.
+ @retval EFI_NOT_FOUND Could not allocate pages match the requirement.
+ @retval EFI_OUT_OF_RESOURCES No enough pages to allocate.
+ @retval EFI_SUCCESS Pages successfully allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestAllocatePages (
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN NumberOfPages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Frees previous allocated pages.
+
+ @param Memory Base address of memory being freed
+ @param NumberOfPages The number of pages to free
+
+ @retval EFI_NOT_FOUND Could not find the entry that covers the range
+ @retval EFI_INVALID_PARAMETER Address not aligned
+ @return EFI_SUCCESS -Pages successfully freed.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestFreePages (
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ This function returns a copy of the current memory map. The map is an array of
+ memory descriptors, each of which describes a contiguous block of memory.
+
+ @param MemoryMapSize A pointer to the size, in bytes, of the
+ MemoryMap buffer. On input, this is the size of
+ the buffer allocated by the caller. On output,
+ it is the size of the buffer returned by the
+ firmware if the buffer was large enough, or the
+ size of the buffer needed to contain the map if
+ the buffer was too small.
+ @param MemoryMap A pointer to the buffer in which firmware places
+ the current memory map.
+ @param MapKey A pointer to the location in which firmware
+ returns the key for the current memory map.
+ @param DescriptorSize A pointer to the location in which firmware
+ returns the size, in bytes, of an individual
+ EFI_MEMORY_DESCRIPTOR.
+ @param DescriptorVersion A pointer to the location in which firmware
+ returns the version number associated with the
+ EFI_MEMORY_DESCRIPTOR.
+
+ @retval EFI_SUCCESS The memory map was returned in the MemoryMap
+ buffer.
+ @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current
+ buffer size needed to hold the memory map is
+ returned in MemoryMapSize.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestGetMemoryMap (
+ IN OUT UINTN *MemoryMapSize,
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ OUT UINTN *MapKey,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *DescriptorVersion
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Allocate pool of a particular type.
+
+ @param PoolType Type of pool to allocate
+ @param Size The amount of pool to allocate
+ @param Buffer The address to return a pointer to the allocated
+ pool
+
+ @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL
+ @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed.
+ @retval EFI_SUCCESS Pool successfully allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestAllocatePool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Frees pool.
+
+ @param Buffer The allocated pool entry to free
+
+ @retval EFI_INVALID_PARAMETER Buffer is not a valid value.
+ @retval EFI_SUCCESS Pool successfully freed.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestFreePool (
+ IN VOID *Buffer
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
diff --git a/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMisc.c b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMisc.c
new file mode 100644
index 000000000000..dbe3e76b549f
--- /dev/null
+++ b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestMisc.c
@@ -0,0 +1,198 @@
+/** @file
+ Implementation of miscellaneous services in the UEFI Boot Services table for use in unit tests.
+
+Copyright (c) Microsoft Corporation
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiBootServicesTableLibUnitTest.h"
+
+/**
+ Returns a monotonically increasing count for the platform.
+
+ @param[out] Count The pointer to returned value.
+
+ @retval EFI_SUCCESS The next monotonic count was returned.
+ @retval EFI_INVALID_PARAMETER Count is NULL.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestGetNextMonotonicCount (
+ OUT UINT64 *Count
+ )
+{
+ STATIC UINT64 StaticCount = 0;
+
+ *Count = StaticCount++;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Introduces a fine-grained stall.
+
+ @param Microseconds The number of microseconds to stall execution.
+
+ @retval EFI_SUCCESS Execution was stalled for at least the requested
+ amount of microseconds.
+ @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestStall (
+ IN UINTN Microseconds
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Sets the system's watchdog timer.
+
+ @param Timeout The number of seconds to set the watchdog timer to.
+ A value of zero disables the timer.
+ @param WatchdogCode The numeric code to log on a watchdog timer timeout
+ event. The firmware reserves codes 0x0000 to 0xFFFF.
+ Loaders and operating systems may use other timeout
+ codes.
+ @param DataSize The size, in bytes, of WatchdogData.
+ @param WatchdogData A data buffer that includes a Null-terminated Unicode
+ string, optionally followed by additional binary data.
+ The string is a description that the call may use to
+ further indicate the reason to be logged with a
+ watchdog event.
+
+ @return EFI_SUCCESS Timeout has been set
+ @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet
+ @return EFI_UNSUPPORTED System does not have a timer (currently not used)
+ @return EFI_DEVICE_ERROR Could not complete due to hardware error
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestSetWatchdogTimer (
+ IN UINTN Timeout,
+ IN UINT64 WatchdogCode,
+ IN UINTN DataSize,
+ IN CHAR16 *WatchdogData OPTIONAL
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Connects one or more drivers to a controller.
+
+ @param ControllerHandle The handle of the controller to which driver(s) are to be connected.
+ @param DriverImageHandle A pointer to an ordered list handles that support the
+ EFI_DRIVER_BINDING_PROTOCOL.
+ @param RemainingDevicePath A pointer to the device path that specifies a child of the
+ controller specified by ControllerHandle.
+ @param Recursive If TRUE, then ConnectController() is called recursively
+ until the entire tree of controllers below the controller specified
+ by ControllerHandle have been created. If FALSE, then
+ the tree of controllers is only expanded one level.
+
+ @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle.
+ 2) No drivers were connected to ControllerHandle, but
+ RemainingDevicePath is not NULL, and it is an End Device
+ Path Node.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+ @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances
+ present in the system.
+ 2) No drivers were connected to ControllerHandle.
+ @retval EFI_SECURITY_VIOLATION
+ The user has no permission to start UEFI device drivers on the device path
+ associated with the ControllerHandle or specified by the RemainingDevicePath.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestConnectController (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE *DriverImageHandle OPTIONAL,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
+ IN BOOLEAN Recursive
+ )
+{
+ return EFI_SUCCESS; // Return success for now
+}
+
+/**
+ Disconnects a controller from a driver
+
+ @param ControllerHandle ControllerHandle The handle of
+ the controller from which
+ driver(s) are to be
+ disconnected.
+ @param DriverImageHandle DriverImageHandle The driver to
+ disconnect from ControllerHandle.
+ @param ChildHandle ChildHandle The handle of the
+ child to destroy.
+
+ @retval EFI_SUCCESS One or more drivers were
+ disconnected from the controller.
+ @retval EFI_SUCCESS On entry, no drivers are managing
+ ControllerHandle.
+ @retval EFI_SUCCESS DriverImageHandle is not NULL,
+ and on entry DriverImageHandle is
+ not managing ControllerHandle.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+ @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
+ and it is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
+ is not a valid EFI_HANDLE.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources
+ available to disconnect any
+ drivers from ControllerHandle.
+ @retval EFI_DEVICE_ERROR The controller could not be
+ disconnected because of a device
+ error.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestDisconnectController (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE DriverImageHandle OPTIONAL,
+ IN EFI_HANDLE ChildHandle OPTIONAL
+ )
+{
+ return EFI_SUCCESS; // Return success for now
+}
+
+/**
+ Computes and returns a 32-bit CRC for a data buffer.
+
+ @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed.
+ @param[in] DataSize The number of bytes in the buffer Data.
+ @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data
+ and DataSize.
+
+ @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in
+ Crc32.
+ @retval EFI_INVALID_PARAMETER Data is NULL.
+ @retval EFI_INVALID_PARAMETER Crc32 is NULL.
+ @retval EFI_INVALID_PARAMETER DataSize is 0.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCalculateCrc32 (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT32 *Crc32
+ )
+{
+ if (Data == NULL || Crc32 == NULL || DataSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Crc32 = CalculateCrc32 (Data, DataSize);
+
+ return EFI_SUCCESS;
+}
diff --git a/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.c b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.c
new file mode 100644
index 000000000000..65e69ecc3d94
--- /dev/null
+++ b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.c
@@ -0,0 +1,1633 @@
+/** @file
+ Implementation of protocol related services in the UEFI Boot Services table for use in unit tests.
+
+Copyright (c) Microsoft Corporation
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiBootServicesTableLibUnitTestProtocol.h"
+
+STATIC LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);
+STATIC LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
+STATIC UINT64 gHandleDatabaseKey = 0;
+STATIC UINTN mEfiLocateHandleRequest = 0;
+
+//
+// Helper Functions
+//
+
+/**
+ Check whether a handle is a valid EFI_HANDLE
+
+ @param UserHandle The handle to check
+
+ @retval EFI_INVALID_PARAMETER The handle is NULL or not a valid EFI_HANDLE.
+ @retval EFI_SUCCESS The handle is valid EFI_HANDLE.
+
+**/
+EFI_STATUS
+ UnitTestValidateHandle (
+ IN EFI_HANDLE UserHandle
+ )
+{
+ IHANDLE *Handle;
+ LIST_ENTRY *Link;
+
+ if (UserHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) {
+ Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
+ if (Handle == (IHANDLE *) UserHandle) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Finds the protocol entry for the requested protocol.
+
+ @param Protocol The ID of the protocol
+ @param Create Create a new entry if not found
+
+ @return Protocol entry
+
+**/
+PROTOCOL_ENTRY *
+UnitTestFindProtocolEntry (
+ IN EFI_GUID *Protocol,
+ IN BOOLEAN Create
+ )
+{
+ LIST_ENTRY *Link;
+ PROTOCOL_ENTRY *Item;
+ PROTOCOL_ENTRY *ProtEntry;
+
+ //
+ // Search the database for the matching GUID
+ //
+
+ ProtEntry = NULL;
+ for (Link = mProtocolDatabase.ForwardLink;
+ Link != &mProtocolDatabase;
+ Link = Link->ForwardLink) {
+
+ Item = CR (Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);
+ if (CompareGuid (&Item->ProtocolID, Protocol)) {
+
+ //
+ // This is the protocol entry
+ //
+
+ ProtEntry = Item;
+ break;
+ }
+ }
+
+ //
+ // If the protocol entry was not found and Create is TRUE, then
+ // allocate a new entry
+ //
+ if ((ProtEntry == NULL) && Create) {
+ ProtEntry = AllocatePool (sizeof (PROTOCOL_ENTRY));
+
+ if (ProtEntry != NULL) {
+ //
+ // Initialize new protocol entry structure
+ //
+ ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE;
+ CopyGuid ((VOID *) &ProtEntry->ProtocolID, Protocol);
+ InitializeListHead (&ProtEntry->Protocols);
+ InitializeListHead (&ProtEntry->Notify);
+
+ //
+ // Add it to protocol database
+ //
+ InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries);
+ }
+ }
+
+ return ProtEntry;
+}
+
+/**
+ Finds the protocol instance for the requested handle and protocol.
+ Note: This function doesn't do parameters checking, it's caller's responsibility
+ to pass in valid parameters.
+
+ @param Handle The handle to search the protocol on
+ @param Protocol GUID of the protocol
+ @param Interface The interface for the protocol being searched
+
+ @return Protocol instance (NULL: Not found)
+
+**/
+PROTOCOL_INTERFACE *
+UnitTestFindProtocolInterface (
+ IN IHANDLE *Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ )
+{
+ PROTOCOL_INTERFACE *Prot;
+ PROTOCOL_ENTRY *ProtEntry;
+ LIST_ENTRY *Link;
+
+ Prot = NULL;
+
+ //
+ // Lookup the protocol entry for this protocol ID
+ //
+
+ ProtEntry = UnitTestFindProtocolEntry (Protocol, FALSE);
+ if (ProtEntry != NULL) {
+
+ //
+ // Look at each protocol interface for any matches
+ //
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link=Link->ForwardLink) {
+
+ //
+ // If this protocol interface matches, remove it
+ //
+ Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
+ if (Prot->Interface == Interface && Prot->Protocol == ProtEntry) {
+ break;
+ }
+
+ Prot = NULL;
+ }
+ }
+
+ return Prot;
+}
+
+/**
+ Signal event for every protocol in protocol entry.
+
+ @param ProtEntry Protocol entry
+
+**/
+VOID
+UnitTestNotifyProtocolEntry (
+ IN PROTOCOL_ENTRY *ProtEntry
+ )
+{
+ PROTOCOL_NOTIFY *ProtNotify;
+ LIST_ENTRY *Link;
+
+ for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
+ ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
+ UnitTestSignalEvent (ProtNotify->Event);
+ }
+}
+
+/**
+ Routine to get the next Handle, when you are searching for all handles.
+
+ @param Position Information about which Handle to seach for.
+ @param Interface Return the interface structure for the matching
+ protocol.
+
+ @return An pointer to IHANDLE if the next Position is not the end of the list.
+ Otherwise,NULL is returned.
+
+**/
+IHANDLE *
+UnitTestGetNextLocateAllHandles (
+ IN OUT LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ )
+{
+ IHANDLE *Handle;
+
+ //
+ // Next handle
+ //
+ Position->Position = Position->Position->ForwardLink;
+
+ //
+ // If not at the end of the list, get the handle
+ //
+ Handle = NULL;
+ *Interface = NULL;
+ if (Position->Position != &gHandleList) {
+ Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
+ }
+
+ return Handle;
+}
+
+/**
+ Routine to get the next Handle, when you are searching for register protocol
+ notifies.
+
+ @param Position Information about which Handle to seach for.
+ @param Interface Return the interface structure for the matching
+ protocol.
+
+ @return An pointer to IHANDLE if the next Position is not the end of the list.
+ Otherwise,NULL is returned.
+
+**/
+IHANDLE *
+UnitTestGetNextLocateByRegisterNotify (
+ IN OUT LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ )
+{
+ IHANDLE *Handle;
+ PROTOCOL_NOTIFY *ProtNotify;
+ PROTOCOL_INTERFACE *Prot;
+ LIST_ENTRY *Link;
+
+ Handle = NULL;
+ *Interface = NULL;
+ ProtNotify = Position->SearchKey;
+
+ //
+ // If this is the first request, get the next handle
+ //
+ if (ProtNotify != NULL) {
+ ASSERT (ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);
+ Position->SearchKey = NULL;
+
+ //
+ // If not at the end of the list, get the next handle
+ //
+ Link = ProtNotify->Position->ForwardLink;
+ if (Link != &ProtNotify->Protocol->Protocols) {
+ Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
+ Handle = Prot->Handle;
+ *Interface = Prot->Interface;
+ }
+ }
+
+ return Handle;
+}
+
+
+/**
+ Routine to get the next Handle, when you are searching for a given protocol.
+
+ @param Position Information about which Handle to seach for.
+ @param Interface Return the interface structure for the matching
+ protocol.
+
+ @return An pointer to IHANDLE if the next Position is not the end of the list.
+ Otherwise,NULL is returned.
+
+**/
+IHANDLE *
+UnitTestGetNextLocateByProtocol (
+ IN OUT LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ )
+{
+ IHANDLE *Handle;
+ LIST_ENTRY *Link;
+ PROTOCOL_INTERFACE *Prot;
+
+ Handle = NULL;
+ *Interface = NULL;
+ for (; ;) {
+ //
+ // Next entry
+ //
+ Link = Position->Position->ForwardLink;
+ Position->Position = Link;
+
+ //
+ // If not at the end, return the handle
+ //
+ if (Link == &Position->ProtEntry->Protocols) {
+ Handle = NULL;
+ break;
+ }
+
+ //
+ // Get the handle
+ //
+ Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
+ Handle = Prot->Handle;
+ *Interface = Prot->Interface;
+
+ //
+ // If this handle has not been returned this request, then
+ // return it now
+ //
+ if (Handle->LocateRequest != mEfiLocateHandleRequest) {
+ Handle->LocateRequest = mEfiLocateHandleRequest;
+ break;
+ }
+ }
+
+ return Handle;
+}
+
+/**
+ Attempts to disconnect all drivers that are using the protocol interface being queried.
+ If failed, reconnect all drivers disconnected.
+ Note: This function doesn't do parameters checking, it's caller's responsibility
+ to pass in valid parameters.
+
+ @param UserHandle The handle on which the protocol is installed
+ @param Prot The protocol to disconnect drivers from
+
+ @retval EFI_SUCCESS Drivers using the protocol interface are all
+ disconnected
+ @retval EFI_ACCESS_DENIED Failed to disconnect one or all of the drivers
+
+**/
+EFI_STATUS
+UnitTestDisconnectControllersUsingProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN PROTOCOL_INTERFACE *Prot
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN ItemFound;
+ LIST_ENTRY *Link;
+ OPEN_PROTOCOL_DATA *OpenData;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Attempt to disconnect all drivers from this protocol interface
+ //
+ do {
+ ItemFound = FALSE;
+ for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
+ Status = UnitTestDisconnectController (UserHandle, OpenData->AgentHandle, NULL);
+ if (!EFI_ERROR (Status)) {
+ ItemFound = TRUE;
+ }
+ break;
+ }
+ }
+ } while (ItemFound);
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Attempt to remove BY_HANDLE_PROTOCOL and GET_PROTOCOL and TEST_PROTOCOL Open List items
+ //
+ for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList;) {
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if ((OpenData->Attributes &
+ (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0) {
+ Link = RemoveEntryList (&OpenData->Link);
+ Prot->OpenListCount--;
+ FreePool (OpenData);
+ } else {
+ Link = Link->ForwardLink;
+ }
+ }
+ }
+
+ //
+ // If there are errors or still has open items in the list, then reconnect all the drivers and return an error
+ //
+ if (EFI_ERROR (Status) || (Prot->OpenListCount > 0)) {
+ UnitTestConnectController (UserHandle, NULL, NULL, TRUE);
+ Status = EFI_ACCESS_DENIED;
+ }
+
+ return Status;
+}
+
+/**
+ Removes Protocol from the protocol list (but not the handle list).
+
+ @param Handle The handle to remove protocol on.
+ @param Protocol GUID of the protocol to be moved
+ @param Interface The interface of the protocol
+
+ @return Protocol Entry
+
+**/
+PROTOCOL_INTERFACE *
+UnitTestRemoveInterfaceFromProtocol (
+ IN IHANDLE *Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ )
+{
+ PROTOCOL_INTERFACE *Prot;
+ PROTOCOL_NOTIFY *ProtNotify;
+ PROTOCOL_ENTRY *ProtEntry;
+ LIST_ENTRY *Link;
+
+ Prot = UnitTestFindProtocolInterface (Handle, Protocol, Interface);
+ if (Prot != NULL) {
+
+ ProtEntry = Prot->Protocol;
+
+ //
+ // If there's a protocol notify location pointing to this entry, back it up one
+ //
+ for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
+ ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
+
+ if (ProtNotify->Position == &Prot->ByProtocol) {
+ ProtNotify->Position = Prot->ByProtocol.BackLink;
+ }
+ }
+
+ //
+ // Remove the protocol interface entry
+ //
+ RemoveEntryList (&Prot->ByProtocol);
+ }
+
+ return Prot;
+}
+
+//
+// Boot Services Function Implementation
+//
+
+/**
+ Locate a certain GUID protocol interface in a Handle's protocols.
+
+ @param UserHandle The handle to obtain the protocol interface on
+ @param Protocol The GUID of the protocol
+
+ @return The requested protocol interface for the handle
+
+**/
+PROTOCOL_INTERFACE *
+UnitTestGetProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol
+ )
+{
+ EFI_STATUS Status;
+ PROTOCOL_ENTRY *ProtEntry;
+ PROTOCOL_INTERFACE *Prot;
+ IHANDLE *Handle;
+ LIST_ENTRY *Link;
+
+ Status = UnitTestValidateHandle (UserHandle);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ Handle = (IHANDLE *) UserHandle;
+
+ //
+ // Look at each protocol interface for a match
+ //
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
+ Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
+ ProtEntry = Prot->Protocol;
+ if (CompareGuid (&ProtEntry->ProtocolID, Protocol)) {
+ return Prot;
+ }
+ }
+ return NULL;
+}
+
+/**
+ Installs a protocol interface into the boot services environment.
+
+ @param UserHandle The handle to install the protocol handler on,
+ or NULL if a new handle is to be allocated
+ @param Protocol The protocol to add to the handle
+ @param InterfaceType Indicates whether Interface is supplied in
+ native form.
+ @param Interface The interface for the protocol being added
+ @param Notify indicates whether notify the notification list
+ for this protocol
+
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
+ @retval EFI_SUCCESS Protocol interface successfully installed
+
+**/
+EFI_STATUS
+UnitTestInstallProtocolInterfaceNotify (
+ IN OUT EFI_HANDLE *UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface,
+ IN BOOLEAN Notify
+ )
+{
+ PROTOCOL_INTERFACE *Prot;
+ PROTOCOL_ENTRY *ProtEntry;
+ IHANDLE *Handle;
+ EFI_STATUS Status;
+ VOID *ExistingInterface;
+
+ //
+ // returns EFI_INVALID_PARAMETER if InterfaceType is invalid.
+ // Also added check for invalid UserHandle and Protocol pointers.
+ //
+ if (UserHandle == NULL || Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (InterfaceType != EFI_NATIVE_INTERFACE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Print debug message
+ //
+ UT_LOG_INFO ("InstallProtocolInterface: %g %p\n", Protocol, Interface);
+
+ Status = EFI_OUT_OF_RESOURCES;
+ Prot = NULL;
+ Handle = NULL;
+
+ if (*UserHandle != NULL) {
+ Status = UnitTestHandleProtocol (*UserHandle, Protocol, (VOID **) &ExistingInterface);
+ if (!EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Lookup the Protocol Entry for the requested protocol
+ //
+ ProtEntry = UnitTestFindProtocolEntry (Protocol, TRUE);
+ if (ProtEntry == NULL) {
+ goto Done;
+ }
+
+ //
+ // Allocate a new protocol interface structure
+ //
+ Prot = AllocateZeroPool (sizeof (PROTOCOL_INTERFACE));
+ if (Prot == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // If caller didn't supply a handle, allocate a new one
+ //
+ Handle = (IHANDLE *) *UserHandle;
+ if (Handle == NULL) {
+ Handle = AllocateZeroPool (sizeof (IHANDLE));
+ if (Handle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // Initialize new handler structure
+ //
+ Handle->Signature = EFI_HANDLE_SIGNATURE;
+ InitializeListHead (&Handle->Protocols);
+
+ //
+ // Initialize the Key to show that the handle has been created/modified
+ //
+ gHandleDatabaseKey++;
+ Handle->Key = gHandleDatabaseKey;
+
+ //
+ // Add this handle to the list global list of all handles
+ // in the system
+ //
+ InsertTailList (&gHandleList, &Handle->AllHandles);
+ } else {
+ Status = UnitTestValidateHandle (Handle);
+ if (EFI_ERROR (Status)) {
+ DEBUG((DEBUG_ERROR, "InstallProtocolInterface: input handle at 0x%x is invalid\n", Handle));
+ goto Done;
+ }
+ }
+
+ //
+ // Each interface that is added must be unique
+ //
+ ASSERT (UnitTestFindProtocolInterface (Handle, Protocol, Interface) == NULL);
+
+ //
+ // Initialize the protocol interface structure
+ //
+ Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE;
+ Prot->Handle = Handle;
+ Prot->Protocol = ProtEntry;
+ Prot->Interface = Interface;
+
+ //
+ // Initialize OpenProtocol Data base
+ //
+ InitializeListHead (&Prot->OpenList);
+ Prot->OpenListCount = 0;
+
+ //
+ // Add this protocol interface to the head of the supported
+ // protocol list for this handle
+ //
+ InsertHeadList (&Handle->Protocols, &Prot->Link);
+
+ //
+ // Add this protocol interface to the tail of the
+ // protocol entry
+ //
+ InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);
+
+ //
+ // Notify the notification list for this protocol
+ //
+ if (Notify) {
+ UnitTestNotifyProtocolEntry (ProtEntry);
+ }
+ Status = EFI_SUCCESS;
+
+Done:
+ if (!EFI_ERROR (Status)) {
+ //
+ // Return the new handle back to the caller
+ //
+ *UserHandle = Handle;
+ } else {
+ //
+ // There was an error, clean up
+ //
+ if (Prot != NULL) {
+ UnitTestFreePool (Prot);
+ }
+ DEBUG ((DEBUG_ERROR, "InstallProtocolInterface: %g %p failed with %r\n", Protocol, Interface, Status));
+ }
+
+ return Status;
+}
+
+/**
+ Wrapper function to UnitTestInstallProtocolInterfaceNotify. This is the public API which
+ Calls the private one which contains a BOOLEAN parameter for notifications
+
+ @param UserHandle The handle to install the protocol handler on,
+ or NULL if a new handle is to be allocated
+ @param Protocol The protocol to add to the handle
+ @param InterfaceType Indicates whether Interface is supplied in
+ native form.
+ @param Interface The interface for the protocol being added
+
+ @return Status code
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestInstallProtocolInterface (
+ IN OUT EFI_HANDLE *UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface
+ )
+{
+ return UnitTestInstallProtocolInterfaceNotify (
+ UserHandle,
+ Protocol,
+ InterfaceType,
+ Interface,
+ TRUE
+ );
+}
+
+/**
+ Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
+
+ @param UserHandle Handle on which the interface is to be
+ reinstalled
+ @param Protocol The numeric ID of the interface
+ @param OldInterface A pointer to the old interface
+ @param NewInterface A pointer to the new interface
+
+ @retval EFI_SUCCESS The protocol interface was installed
+ @retval EFI_NOT_FOUND The OldInterface on the handle was not found
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestReinstallProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN VOID *OldInterface,
+ IN VOID *NewInterface
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Uninstalls all instances of a protocol:interfacer from a handle.
+ If the last protocol interface is remove from the handle, the
+ handle is freed.
+
+ @param UserHandle The handle to remove the protocol handler from
+ @param Protocol The protocol, of protocol:interface, to remove
+ @param Interface The interface, of protocol:interface, to remove
+
+ @retval EFI_INVALID_PARAMETER Protocol is NULL.
+ @retval EFI_SUCCESS Protocol interface successfully uninstalled.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestUninstallProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ )
+{
+ EFI_STATUS Status;
+ IHANDLE *Handle;
+ PROTOCOL_INTERFACE *Prot;
+
+ //
+ // Check that Protocol is valid
+ //
+ if (Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check that UserHandle is a valid handle
+ //
+ Status = UnitTestValidateHandle (UserHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
+ //
+ Prot = UnitTestFindProtocolInterface (UserHandle, Protocol, Interface);
+ if (Prot == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+
+ //
+ // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed
+ //
+ Status = UnitTestDisconnectControllersUsingProtocolInterface (
+ UserHandle,
+ Prot
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // One or more drivers refused to release, so return the error
+ //
+ goto Done;
+ }
+
+ //
+ // Remove the protocol interface from the protocol
+ //
+ Status = EFI_NOT_FOUND;
+ Handle = (IHANDLE *) UserHandle;
+ Prot = UnitTestRemoveInterfaceFromProtocol (Handle, Protocol, Interface);
+
+ if (Prot != NULL) {
+ //
+ // Update the Key to show that the handle has been created/modified
+ //
+ gHandleDatabaseKey++;
+ Handle->Key = gHandleDatabaseKey;
+
+ //
+ // Remove the protocol interface from the handle
+ //
+ RemoveEntryList (&Prot->Link);
+
+ //
+ // Free the memory
+ //
+ Prot->Signature = 0;
+ FreePool (Prot);
+ Status = EFI_SUCCESS;
+ }
+
+ //
+ // If there are no more handlers for the handle, free the handle
+ //
+ if (IsListEmpty (&Handle->Protocols)) {
+ Handle->Signature = 0;
+ RemoveEntryList (&Handle->AllHandles);
+ FreePool (Handle);
+ }
+
+Done:
+ return Status;
+}
+
+/**
+ Queries a handle to determine if it supports a specified protocol.
+
+ @param UserHandle The handle being queried.
+ @param Protocol The published unique identifier of the protocol.
+ @param Interface Supplies the address where a pointer to the
+ corresponding Protocol Interface is returned.
+
+ @return The requested protocol interface for the handle
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestHandleProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface
+ )
+{
+ return UnitTestOpenProtocol (
+ UserHandle,
+ Protocol,
+ Interface,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ );
+}
+
+/**
+ Add a new protocol notification record for the request protocol.
+
+ @param Protocol The requested protocol to add the notify
+ registration
+ @param Event The event to signal
+ @param Registration Returns the registration record
+
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_SUCCESS Successfully returned the registration record
+ that has been added
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestRegisterProtocolNotify (
+ IN EFI_GUID *Protocol,
+ IN EFI_EVENT Event,
+ OUT VOID **Registration
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Locates the requested handle(s) and returns them in Buffer.
+
+ @param SearchType The type of search to perform to locate the
+ handles
+ @param Protocol The protocol to search for
+ @param SearchKey Dependant on SearchType
+ @param BufferSize On input the size of Buffer. On output the
+ size of data returned.
+ @param Buffer The buffer to return the results in
+
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is
+ returned in BufferSize.
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_SUCCESS Successfully found the requested handle(s) and
+ returns them in Buffer.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestLocateHandle (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HANDLE *Buffer
+ )
+{
+ EFI_STATUS Status;
+ LOCATE_POSITION Position;
+ PROTOCOL_NOTIFY *ProtNotify;
+ UNIT_TEST_GET_NEXT GetNext;
+ UINTN ResultSize;
+ IHANDLE *Handle;
+ IHANDLE **ResultBuffer;
+ VOID *Interface;
+
+ if (BufferSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((*BufferSize > 0) && (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ GetNext = NULL;
+
+ //
+ // Set initial position
+ //
+ Position.Protocol = Protocol;
+ Position.SearchKey = SearchKey;
+ Position.Position = &gHandleList;
+
+ ResultSize = 0;
+ ResultBuffer = (IHANDLE **) Buffer;
+ Status = EFI_SUCCESS;
+
+ //
+ // Get the search function based on type
+ //
+ switch (SearchType) {
+ case AllHandles:
+ GetNext = UnitTestGetNextLocateAllHandles;
+ break;
+
+ case ByRegisterNotify:
+ //
+ // Must have SearchKey for locate ByRegisterNotify
+ //
+ if (SearchKey == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+ GetNext = UnitTestGetNextLocateByRegisterNotify;
+ break;
+
+ case ByProtocol:
+ GetNext = UnitTestGetNextLocateByProtocol;
+ if (Protocol == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+ //
+ // Look up the protocol entry and set the head pointer
+ //
+ Position.ProtEntry = UnitTestFindProtocolEntry (Protocol, FALSE);
+ if (Position.ProtEntry == NULL) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+ Position.Position = &Position.ProtEntry->Protocols;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (GetNext != NULL);
+ //
+ // Enumerate out the matching handles
+ //
+ mEfiLocateHandleRequest += 1;
+ for (; ;) {
+ //
+ // Get the next handle. If no more handles, stop
+ //
+ Handle = GetNext (&Position, &Interface);
+ if (NULL == Handle) {
+ break;
+ }
+
+ //
+ // Increase the resulting buffer size, and if this handle
+ // fits return it
+ //
+ ResultSize += sizeof (Handle);
+ if (ResultSize <= *BufferSize) {
+ *ResultBuffer = Handle;
+ ResultBuffer += 1;
+ }
+ }
+
+ //
+ // If the result is a zero length buffer, then there were no
+ // matching handles
+ //
+ if (ResultSize == 0) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ //
+ // Return the resulting buffer size. If it's larger than what
+ // was passed, then set the error code
+ //
+ if (ResultSize > *BufferSize) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *BufferSize = ResultSize;
+
+ if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) {
+ //
+ // If this is a search by register notify and a handle was
+ // returned, update the register notification position
+ //
+ ASSERT (SearchKey != NULL);
+ ProtNotify = SearchKey;
+ ProtNotify->Position = ProtNotify->Position->ForwardLink;
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Locates the handle to a device on the device path that best matches the specified protocol.
+
+ @param Protocol The protocol to search for.
+ @param DevicePath On input, a pointer to a pointer to the device
+ path. On output, the device path pointer is
+ modified to point to the remaining part of the
+ devicepath.
+ @param Device A pointer to the returned device handle.
+
+ @retval EFI_SUCCESS The resulting handle was returned.
+ @retval EFI_NOT_FOUND No handles matched the search.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestLocateDevicePath (
+ IN EFI_GUID *Protocol,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT EFI_HANDLE *Device
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Boot Service called to add, modify, or remove a system configuration table from
+ the EFI System Table.
+
+ @param Guid Pointer to the GUID for the entry to add, update, or
+ remove
+ @param Table Pointer to the configuration table for the entry to add,
+ update, or remove, may be NULL.
+
+ @return EFI_SUCCESS Guid, Table pair added, updated, or removed.
+ @return EFI_INVALID_PARAMETER Input GUID not valid.
+ @return EFI_NOT_FOUND Attempted to delete non-existant entry
+ @return EFI_OUT_OF_RESOURCES Not enough memory available
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestInstallConfigurationTable (
+ IN EFI_GUID *Guid,
+ IN VOID *Table
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Locates the installed protocol handler for the handle, and
+ invokes it to obtain the protocol interface. Usage information
+ is registered in the protocol data base.
+
+ @param UserHandle The handle to obtain the protocol interface on
+ @param Protocol The ID of the protocol
+ @param Interface The location to return the protocol interface
+ @param ImageHandle The handle of the Image that is opening the
+ protocol interface specified by Protocol and
+ Interface.
+ @param ControllerHandle The controller handle that is requiring this
+ interface.
+ @param Attributes The open mode of the protocol interface
+ specified by Handle and Protocol.
+
+ @retval EFI_INVALID_PARAMETER Protocol is NULL.
+ @retval EFI_SUCCESS Get the protocol interface.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestOpenProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface OPTIONAL,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT32 Attributes
+ )
+{
+ EFI_STATUS Status;
+ PROTOCOL_INTERFACE *Prot;
+ LIST_ENTRY *Link;
+ OPEN_PROTOCOL_DATA *OpenData;
+ BOOLEAN ByDriver;
+ BOOLEAN Exclusive;
+ BOOLEAN Disconnect;
+ BOOLEAN ExactMatch;
+
+ //
+ // Check for invalid Protocol
+ //
+ if (Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check for invalid Interface
+ //
+ if ((Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) && (Interface == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check for invalid UserHandle
+ //
+ Status = UnitTestValidateHandle (UserHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Check for invalid Attributes
+ //
+ switch (Attributes) {
+ case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER :
+ Status = UnitTestValidateHandle (ImageHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = UnitTestValidateHandle (ControllerHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if (UserHandle == ControllerHandle) {
+ return EFI_INVALID_PARAMETER;
+ }
+ break;
+ case EFI_OPEN_PROTOCOL_BY_DRIVER :
+ case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE :
+ Status = UnitTestValidateHandle (ImageHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = UnitTestValidateHandle (ControllerHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ break;
+ case EFI_OPEN_PROTOCOL_EXCLUSIVE :
+ Status = UnitTestValidateHandle (ImageHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ break;
+ case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL :
+ case EFI_OPEN_PROTOCOL_GET_PROTOCOL :
+ case EFI_OPEN_PROTOCOL_TEST_PROTOCOL :
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Look at each protocol interface for a match
+ //
+ Prot = UnitTestGetProtocolInterface (UserHandle, Protocol);
+ if (Prot == NULL) {
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ Status = EFI_SUCCESS;
+
+ ByDriver = FALSE;
+ Exclusive = FALSE;
+ for ( Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ ExactMatch = (BOOLEAN)((OpenData->AgentHandle == ImageHandle) &&
+ (OpenData->Attributes == Attributes) &&
+ (OpenData->ControllerHandle == ControllerHandle));
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
+ ByDriver = TRUE;
+ if (ExactMatch) {
+ Status = EFI_ALREADY_STARTED;
+ goto Done;
+ }
+ }
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) != 0) {
+ Exclusive = TRUE;
+ } else if (ExactMatch) {
+ OpenData->OpenCount++;
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+ }
+
+ //
+ // ByDriver TRUE -> A driver is managing (UserHandle, Protocol)
+ // ByDriver FALSE -> There are no drivers managing (UserHandle, Protocol)
+ // Exclusive TRUE -> Something has exclusive access to (UserHandle, Protocol)
+ // Exclusive FALSE -> Nothing has exclusive access to (UserHandle, Protocol)
+ //
+
+ switch (Attributes) {
+ case EFI_OPEN_PROTOCOL_BY_DRIVER :
+ if (Exclusive || ByDriver) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+ break;
+ case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE :
+ case EFI_OPEN_PROTOCOL_EXCLUSIVE :
+ if (Exclusive) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+ if (ByDriver) {
+ do {
+ Disconnect = FALSE;
+ for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
+ Disconnect = TRUE;
+ Status = UnitTestDisconnectController (UserHandle, OpenData->AgentHandle, NULL);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ } else {
+ break;
+ }
+ }
+ }
+ } while (Disconnect);
+ }
+ break;
+ case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER :
+ case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL :
+ case EFI_OPEN_PROTOCOL_GET_PROTOCOL :
+ case EFI_OPEN_PROTOCOL_TEST_PROTOCOL :
+ break;
+ }
+
+ if (ImageHandle == NULL) {
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+ //
+ // Create new entry
+ //
+ OpenData = AllocatePool (sizeof(OPEN_PROTOCOL_DATA));
+ if (OpenData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ OpenData->Signature = OPEN_PROTOCOL_DATA_SIGNATURE;
+ OpenData->AgentHandle = ImageHandle;
+ OpenData->ControllerHandle = ControllerHandle;
+ OpenData->Attributes = Attributes;
+ OpenData->OpenCount = 1;
+ InsertTailList (&Prot->OpenList, &OpenData->Link);
+ Prot->OpenListCount++;
+ Status = EFI_SUCCESS;
+ }
+
+Done:
+
+ if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
+ //
+ // Keep Interface unmodified in case of any Error
+ // except EFI_ALREADY_STARTED and EFI_UNSUPPORTED.
+ //
+ if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {
+ //
+ // According to above logic, if 'Prot' is NULL, then the 'Status' must be
+ // EFI_UNSUPPORTED. Here the 'Status' is not EFI_UNSUPPORTED, so 'Prot'
+ // must be not NULL.
+ //
+ // The ASSERT here is for addressing a false positive NULL pointer
+ // dereference issue raised from static analysis.
+ //
+ ASSERT (Prot != NULL);
+ //
+ // EFI_ALREADY_STARTED is not an error for bus driver.
+ // Return the corresponding protocol interface.
+ //
+ *Interface = Prot->Interface;
+ } else if (Status == EFI_UNSUPPORTED) {
+ //
+ // Return NULL Interface if Unsupported Protocol.
+ //
+ *Interface = NULL;
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Closes a protocol on a handle that was opened using OpenProtocol().
+
+ @param UserHandle The handle for the protocol interface that was
+ previously opened with OpenProtocol(), and is
+ now being closed.
+ @param Protocol The published unique identifier of the protocol.
+ It is the caller's responsibility to pass in a
+ valid GUID.
+ @param AgentHandle The handle of the agent that is closing the
+ protocol interface.
+ @param ControllerHandle If the agent that opened a protocol is a driver
+ that follows the EFI Driver Model, then this
+ parameter is the controller handle that required
+ the protocol interface. If the agent does not
+ follow the EFI Driver Model, then this parameter
+ is optional and may be NULL.
+
+ @retval EFI_SUCCESS The protocol instance was closed.
+ @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a
+ valid EFI_HANDLE.
+ @retval EFI_NOT_FOUND Can not find the specified protocol or
+ AgentHandle.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCloseProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_HANDLE AgentHandle,
+ IN EFI_HANDLE ControllerHandle
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Return information about Opened protocols in the system
+
+ @param UserHandle The handle to close the protocol interface on
+ @param Protocol The ID of the protocol
+ @param EntryBuffer A pointer to a buffer of open protocol
+ information in the form of
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
+ @param EntryCount Number of EntryBuffer entries
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestOpenProtocolInformation (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
+ OUT UINTN *EntryCount
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
+ from pool.
+
+ @param UserHandle The handle from which to retrieve the list of
+ protocol interface GUIDs.
+ @param ProtocolBuffer A pointer to the list of protocol interface GUID
+ pointers that are installed on Handle.
+ @param ProtocolBufferCount A pointer to the number of GUID pointers present
+ in ProtocolBuffer.
+
+ @retval EFI_SUCCESS The list of protocol interface GUIDs installed
+ on Handle was returned in ProtocolBuffer. The
+ number of protocol interface GUIDs was returned
+ in ProtocolBufferCount.
+ @retval EFI_INVALID_PARAMETER Handle is NULL.
+ @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL.
+ @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL.
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the
+ results.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestProtocolsPerHandle (
+ IN EFI_HANDLE UserHandle,
+ OUT EFI_GUID ***ProtocolBuffer,
+ OUT UINTN *ProtocolBufferCount
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Function returns an array of handles that support the requested protocol
+ in a buffer allocated from pool. This is a version of UnitTestLocateHandle()
+ that allocates a buffer for the caller.
+
+ @param SearchType Specifies which handle(s) are to be returned.
+ @param Protocol Provides the protocol to search by. This
+ parameter is only valid for SearchType
+ ByProtocol.
+ @param SearchKey Supplies the search key depending on the
+ SearchType.
+ @param NumberHandles The number of handles returned in Buffer.
+ @param Buffer A pointer to the buffer to return the requested
+ array of handles that support Protocol.
+
+ @retval EFI_SUCCESS The result array of handles was returned.
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the
+ matching results.
+ @retval EFI_INVALID_PARAMETER One or more parameters are not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestLocateHandleBuffer (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *NumberHandles,
+ OUT EFI_HANDLE **Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+
+ if (NumberHandles == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BufferSize = 0;
+ *NumberHandles = 0;
+ *Buffer = NULL;
+ Status = UnitTestLocateHandle (
+ SearchType,
+ Protocol,
+ SearchKey,
+ &BufferSize,
+ *Buffer
+ );
+ //
+ // LocateHandleBuffer() returns incorrect status code if SearchType is
+ // invalid.
+ //
+ // Add code to correctly handle expected errors from UnitTestLocateHandle().
+ //
+ if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
+ if (Status != EFI_INVALID_PARAMETER) {
+ Status = EFI_NOT_FOUND;
+ }
+ return Status;
+ }
+
+ *Buffer = AllocatePool (BufferSize);
+ if (*Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = UnitTestLocateHandle (
+ SearchType,
+ Protocol,
+ SearchKey,
+ &BufferSize,
+ *Buffer
+ );
+
+ *NumberHandles = BufferSize / sizeof (EFI_HANDLE);
+ if (EFI_ERROR (Status)) {
+ *NumberHandles = 0;
+ }
+
+ return Status;
+}
+
+/**
+ Return the first Protocol Interface that matches the Protocol GUID. If
+ Registration is passed in, return a Protocol Instance that was just add
+ to the system. If Registration is NULL return the first Protocol Interface
+ you find.
+
+ @param Protocol The protocol to search for
+ @param Registration Optional Registration Key returned from
+ RegisterProtocolNotify()
+ @param Interface Return the Protocol interface (instance).
+
+ @retval EFI_SUCCESS If a valid Interface is returned
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_NOT_FOUND Protocol interface not found
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestLocateProtocol (
+ IN EFI_GUID *Protocol,
+ IN VOID *Registration OPTIONAL,
+ OUT VOID **Interface
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Installs a list of protocol interface into the boot services environment.
+ This function calls InstallProtocolInterface() in a loop. If any error
+ occurs all the protocols added by this function are removed. This is
+ basically a lib function to save space.
+
+ @param Handle The handle to install the protocol handlers on,
+ or NULL if a new handle is to be allocated
+ @param ... EFI_GUID followed by protocol instance. A NULL
+ terminates the list. The pairs are the
+ arguments to InstallProtocolInterface(). All the
+ protocols are added to Handle.
+
+ @retval EFI_SUCCESS All the protocol interface was installed.
+ @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols.
+ @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in
+ the handle database.
+ @retval EFI_INVALID_PARAMETER Handle is NULL.
+ @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestInstallMultipleProtocolInterfaces (
+ IN OUT EFI_HANDLE *Handle,
+ ...
+ )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+/**
+ Uninstalls a list of protocol interface in the boot services environment.
+ This function calls UninstallProtocolInterface() in a loop. This is
+ basically a lib function to save space.
+
+ @param Handle The handle to uninstall the protocol
+ @param ... EFI_GUID followed by protocol instance. A NULL
+ terminates the list. The pairs are the
+ arguments to UninstallProtocolInterface(). All
+ the protocols are added to Handle.
+
+ @return Status code
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestUninstallMultipleProtocolInterfaces (
+ IN EFI_HANDLE Handle,
+ ...
+ )
+{
+ EFI_STATUS Status;
+ VA_LIST Args;
+ EFI_GUID *Protocol;
+ VOID *Interface;
+ UINTN Index;
+
+ VA_START (Args, Handle);
+ for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
+ //
+ // If protocol is NULL, then it's the end of the list
+ //
+ Protocol = VA_ARG (Args, EFI_GUID *);
+ if (Protocol == NULL) {
+ break;
+ }
+
+ Interface = VA_ARG (Args, VOID *);
+
+ //
+ // Uninstall it
+ //
+ Status = UnitTestUninstallProtocolInterface (Handle, Protocol, Interface);
+ }
+ VA_END (Args);
+
+ //
+ // If there was an error, add all the interfaces that were
+ // uninstalled without any errors
+ //
+ if (EFI_ERROR (Status)) {
+ //
+ // Reset the va_arg back to the first argument.
+ //
+ VA_START (Args, Handle);
+ for (; Index > 1; Index--) {
+ Protocol = VA_ARG(Args, EFI_GUID *);
+ Interface = VA_ARG(Args, VOID *);
+ UnitTestInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
+ }
+ VA_END (Args);
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ return Status;
+}
diff --git a/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestTpl.c b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestTpl.c
new file mode 100644
index 000000000000..7e1849fbd4a9
--- /dev/null
+++ b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestTpl.c
@@ -0,0 +1,43 @@
+/** @file
+ Implementation of Task Priority Level (TPL) related services in the UEFI Boot Services table for use in unit tests.
+
+Copyright (c) Microsoft Corporation
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiBootServicesTableLibUnitTest.h"
+
+/**
+ Raise the task priority level to the new level.
+ High level is implemented by disabling processor interrupts.
+
+ @param NewTpl New task priority level
+
+ @return The previous task priority level
+
+**/
+EFI_TPL
+EFIAPI
+UnitTestRaiseTpl (
+ IN EFI_TPL NewTpl
+ )
+{
+ return TPL_APPLICATION;
+}
+
+/**
+ Lowers the task priority to the previous value. If the new
+ priority unmasks events at a higher priority, they are dispatched.
+
+ @param NewTpl New, lower, task priority
+
+**/
+VOID
+EFIAPI
+UnitTestRestoreTpl (
+ IN EFI_TPL NewTpl
+ )
+{
+ return;
+}
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
index 5241354cb220..911158302404 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -93,6 +93,7 @@ [Components]
$(PLATFORM_PACKAGE)/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiParameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf
$(PLATFORM_PACKAGE)/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf
$(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareAccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
+ $(PLATFORM_PACKAGE)/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf
#
# PRM Module Discovery Library
diff --git a/PrmPkg/Test/PrmPkgHostTest.dsc b/PrmPkg/Test/PrmPkgHostTest.dsc
index 41f3c32b8d19..2d718f8888b8 100644
--- a/PrmPkg/Test/PrmPkgHostTest.dsc
+++ b/PrmPkg/Test/PrmPkgHostTest.dsc
@@ -15,3 +15,14 @@ [Defines]
SUPPORTED_ARCHITECTURES = IA32|X64
BUILD_TARGETS = NOOPT
SKUID_IDENTIFIER = DEFAULT
+
+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+
+[LibraryClasses]
+ UefiBootServicesTableLib|PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf
+
+[Components]
+ #
+ # Unit test helper libraries
+ #
+ PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf
diff --git a/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibTest.uni b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibTest.uni
new file mode 100644
index 000000000000..1f742bb6d8e9
--- /dev/null
+++ b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibTest.uni
@@ -0,0 +1,12 @@
+// /** @file
+// UEFI Boot Services Table Library for unit tests implementation.
+//
+// Copyright (c) Microsoft Corporation
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "UEFI Boot Services Table Library for unit tests"
+
+#string STR_MODULE_DESCRIPTION #language en-US "UEFI Boot Services Table Library for unit tests."
diff --git a/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.h b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.h
new file mode 100644
index 000000000000..687508cf1faf
--- /dev/null
+++ b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.h
@@ -0,0 +1,1046 @@
+/** @file
+ An internal header file for the Unit Test instance of the UEFI Boot Services Table Library.
+
+ This file includes common header files, defines internal structure and functions used by
+ the library implementation.
+
+Copyright (c) Microsoft Corporation
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_H_
+#define UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_H_
+
+#include <Uefi.h>
+
+#include <Pi/PiMultiPhase.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UnitTestLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ Raise the task priority level to the new level.
+ High level is implemented by disabling processor interrupts.
+
+ @param NewTpl New task priority level
+
+ @return The previous task priority level
+
+**/
+EFI_TPL
+EFIAPI
+UnitTestRaiseTpl (
+ IN EFI_TPL NewTpl
+ );
+
+
+
+/**
+ Lowers the task priority to the previous value. If the new
+ priority unmasks events at a higher priority, they are dispatched.
+
+ @param NewTpl New, lower, task priority
+
+**/
+VOID
+EFIAPI
+UnitTestRestoreTpl (
+ IN EFI_TPL NewTpl
+ );
+
+/**
+ Allocates pages from the memory map.
+
+ @param Type The type of allocation to perform
+ @param MemoryType The type of memory to turn the allocated pages
+ into
+ @param NumberOfPages The number of pages to allocate
+ @param Memory A pointer to receive the base allocated memory
+ address
+
+ @return Status. On success, Memory is filled in with the base address allocated
+ @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in
+ spec.
+ @retval EFI_NOT_FOUND Could not allocate pages match the requirement.
+ @retval EFI_OUT_OF_RESOURCES No enough pages to allocate.
+ @retval EFI_SUCCESS Pages successfully allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestAllocatePages (
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN NumberOfPages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+ );
+
+/**
+ Frees previous allocated pages.
+
+ @param Memory Base address of memory being freed
+ @param NumberOfPages The number of pages to free
+
+ @retval EFI_NOT_FOUND Could not find the entry that covers the range
+ @retval EFI_INVALID_PARAMETER Address not aligned
+ @return EFI_SUCCESS -Pages successfully freed.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestFreePages (
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+ );
+
+/**
+ This function returns a copy of the current memory map. The map is an array of
+ memory descriptors, each of which describes a contiguous block of memory.
+
+ @param MemoryMapSize A pointer to the size, in bytes, of the
+ MemoryMap buffer. On input, this is the size of
+ the buffer allocated by the caller. On output,
+ it is the size of the buffer returned by the
+ firmware if the buffer was large enough, or the
+ size of the buffer needed to contain the map if
+ the buffer was too small.
+ @param MemoryMap A pointer to the buffer in which firmware places
+ the current memory map.
+ @param MapKey A pointer to the location in which firmware
+ returns the key for the current memory map.
+ @param DescriptorSize A pointer to the location in which firmware
+ returns the size, in bytes, of an individual
+ EFI_MEMORY_DESCRIPTOR.
+ @param DescriptorVersion A pointer to the location in which firmware
+ returns the version number associated with the
+ EFI_MEMORY_DESCRIPTOR.
+
+ @retval EFI_SUCCESS The memory map was returned in the MemoryMap
+ buffer.
+ @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current
+ buffer size needed to hold the memory map is
+ returned in MemoryMapSize.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestGetMemoryMap (
+ IN OUT UINTN *MemoryMapSize,
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ OUT UINTN *MapKey,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *DescriptorVersion
+ );
+
+
+
+/**
+ Allocate pool of a particular type.
+
+ @param PoolType Type of pool to allocate
+ @param Size The amount of pool to allocate
+ @param Buffer The address to return a pointer to the allocated
+ pool
+
+ @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL
+ @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed.
+ @retval EFI_SUCCESS Pool successfully allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestAllocatePool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ );
+
+/**
+ Frees pool.
+
+ @param Buffer The allocated pool entry to free
+
+ @retval EFI_INVALID_PARAMETER Buffer is not a valid value.
+ @retval EFI_SUCCESS Pool successfully freed.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestFreePool (
+ IN VOID *Buffer
+ );
+
+/**
+ Frees pool.
+
+ @param Buffer The allocated pool entry to free
+ @param PoolType Pointer to pool type
+
+ @retval EFI_INVALID_PARAMETER Buffer is not a valid value.
+ @retval EFI_SUCCESS Pool successfully freed.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestInternalFreePool (
+ IN VOID *Buffer,
+ OUT EFI_MEMORY_TYPE *PoolType OPTIONAL
+ );
+
+/**
+ Creates an event.
+
+ @param Type The type of event to create and its mode and
+ attributes
+ @param NotifyTpl The task priority level of event notifications
+ @param NotifyFunction Pointer to the events notification function
+ @param NotifyContext Pointer to the notification functions context;
+ corresponds to parameter "Context" in the
+ notification function
+ @param Event Pointer to the newly created event if the call
+ succeeds; undefined otherwise
+
+ @retval EFI_SUCCESS The event structure was created
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
+ @retval EFI_OUT_OF_RESOURCES The event could not be allocated
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCreateEvent (
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
+ IN VOID *NotifyContext, OPTIONAL
+ OUT EFI_EVENT *Event
+ );
+
+/**
+ Sets the type of timer and the trigger time for a timer event.
+
+ @param UserEvent The timer event that is to be signaled at the
+ specified time
+ @param Type The type of time that is specified in
+ TriggerTime
+ @param TriggerTime The number of 100ns units until the timer
+ expires
+
+ @retval EFI_SUCCESS The event has been set to be signaled at the
+ requested time
+ @retval EFI_INVALID_PARAMETER Event or Type is not valid
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestSetTimer (
+ IN EFI_EVENT UserEvent,
+ IN EFI_TIMER_DELAY Type,
+ IN UINT64 TriggerTime
+ );
+
+/**
+ Stops execution until an event is signaled.
+
+ @param NumberOfEvents The number of events in the UserEvents array
+ @param UserEvents An array of EFI_EVENT
+ @param UserIndex Pointer to the index of the event which
+ satisfied the wait condition
+
+ @retval EFI_SUCCESS The event indicated by Index was signaled.
+ @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification
+ function or Event was not a valid type
+ @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestWaitForEvent (
+ IN UINTN NumberOfEvents,
+ IN EFI_EVENT *UserEvents,
+ OUT UINTN *UserIndex
+ );
+
+/**
+ Signals the event. Queues the event to be notified if needed.
+
+ @param UserEvent The event to signal .
+
+ @retval EFI_INVALID_PARAMETER Parameters are not valid.
+ @retval EFI_SUCCESS The event was signaled.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestSignalEvent (
+ IN EFI_EVENT UserEvent
+ );
+
+/**
+ Closes an event and frees the event structure.
+
+ @param UserEvent Event to close
+
+ @retval EFI_INVALID_PARAMETER Parameters are not valid.
+ @retval EFI_SUCCESS The event has been closed
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCloseEvent (
+ IN EFI_EVENT UserEvent
+ );
+
+/**
+ Check the status of an event.
+
+ @param UserEvent The event to check
+
+ @retval EFI_SUCCESS The event is in the signaled state
+ @retval EFI_NOT_READY The event is not in the signaled state
+ @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCheckEvent (
+ IN EFI_EVENT UserEvent
+ );
+
+/**
+ Wrapper function to UnitTestInstallProtocolInterfaceNotify. This is the public API which
+ Calls the private one which contains a BOOLEAN parameter for notifications
+
+ @param UserHandle The handle to install the protocol handler on,
+ or NULL if a new handle is to be allocated
+ @param Protocol The protocol to add to the handle
+ @param InterfaceType Indicates whether Interface is supplied in
+ native form.
+ @param Interface The interface for the protocol being added
+
+ @return Status code
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestInstallProtocolInterface (
+ IN OUT EFI_HANDLE *UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface
+ );
+
+/**
+ Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
+
+ @param UserHandle Handle on which the interface is to be
+ reinstalled
+ @param Protocol The numeric ID of the interface
+ @param OldInterface A pointer to the old interface
+ @param NewInterface A pointer to the new interface
+
+ @retval EFI_SUCCESS The protocol interface was installed
+ @retval EFI_NOT_FOUND The OldInterface on the handle was not found
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestReinstallProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN VOID *OldInterface,
+ IN VOID *NewInterface
+ );
+
+/**
+ Uninstalls all instances of a protocol:interfacer from a handle.
+ If the last protocol interface is remove from the handle, the
+ handle is freed.
+
+ @param UserHandle The handle to remove the protocol handler from
+ @param Protocol The protocol, of protocol:interface, to remove
+ @param Interface The interface, of protocol:interface, to remove
+
+ @retval EFI_INVALID_PARAMETER Protocol is NULL.
+ @retval EFI_SUCCESS Protocol interface successfully uninstalled.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestUninstallProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ );
+
+/**
+ Queries a handle to determine if it supports a specified protocol.
+
+ @param UserHandle The handle being queried.
+ @param Protocol The published unique identifier of the protocol.
+ @param Interface Supplies the address where a pointer to the
+ corresponding Protocol Interface is returned.
+
+ @return The requested protocol interface for the handle
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestHandleProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface
+ );
+
+/**
+ Add a new protocol notification record for the request protocol.
+
+ @param Protocol The requested protocol to add the notify
+ registration
+ @param Event The event to signal
+ @param Registration Returns the registration record
+
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_SUCCESS Successfully returned the registration record
+ that has been added
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestRegisterProtocolNotify (
+ IN EFI_GUID *Protocol,
+ IN EFI_EVENT Event,
+ OUT VOID **Registration
+ );
+
+/**
+ Locates the requested handle(s) and returns them in Buffer.
+
+ @param SearchType The type of search to perform to locate the
+ handles
+ @param Protocol The protocol to search for
+ @param SearchKey Dependant on SearchType
+ @param BufferSize On input the size of Buffer. On output the
+ size of data returned.
+ @param Buffer The buffer to return the results in
+
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is
+ returned in BufferSize.
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_SUCCESS Successfully found the requested handle(s) and
+ returns them in Buffer.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestLocateHandle (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HANDLE *Buffer
+ );
+
+/**
+ Locates the handle to a device on the device path that best matches the specified protocol.
+
+ @param Protocol The protocol to search for.
+ @param DevicePath On input, a pointer to a pointer to the device
+ path. On output, the device path pointer is
+ modified to point to the remaining part of the
+ devicepath.
+ @param Device A pointer to the returned device handle.
+
+ @retval EFI_SUCCESS The resulting handle was returned.
+ @retval EFI_NOT_FOUND No handles matched the search.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestLocateDevicePath (
+ IN EFI_GUID *Protocol,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT EFI_HANDLE *Device
+ );
+
+/**
+ Boot Service called to add, modify, or remove a system configuration table from
+ the EFI System Table.
+
+ @param Guid Pointer to the GUID for the entry to add, update, or
+ remove
+ @param Table Pointer to the configuration table for the entry to add,
+ update, or remove, may be NULL.
+
+ @return EFI_SUCCESS Guid, Table pair added, updated, or removed.
+ @return EFI_INVALID_PARAMETER Input GUID not valid.
+ @return EFI_NOT_FOUND Attempted to delete non-existant entry
+ @return EFI_OUT_OF_RESOURCES Not enough memory available
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestInstallConfigurationTable (
+ IN EFI_GUID *Guid,
+ IN VOID *Table
+ );
+
+/**
+ Loads an EFI image into memory and returns a handle to the image.
+
+ @param BootPolicy If TRUE, indicates that the request originates
+ from the boot manager, and that the boot
+ manager is attempting to load FilePath as a
+ boot selection.
+ @param ParentImageHandle The caller's image handle.
+ @param FilePath The specific file path from which the image is
+ loaded.
+ @param SourceBuffer If not NULL, a pointer to the memory location
+ containing a copy of the image to be loaded.
+ @param SourceSize The size in bytes of SourceBuffer.
+ @param ImageHandle Pointer to the returned image handle that is
+ created when the image is successfully loaded.
+
+ @retval EFI_SUCCESS The image was loaded into memory.
+ @retval EFI_NOT_FOUND The FilePath was not found.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+ @retval EFI_UNSUPPORTED The image type is not supported, or the device
+ path cannot be parsed to locate the proper
+ protocol for loading the file.
+ @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient
+ resources.
+ @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not
+ understood.
+ @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error.
+ @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the
+ image from being loaded. NULL is returned in *ImageHandle.
+ @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a
+ valid EFI_LOADED_IMAGE_PROTOCOL. However, the current
+ platform policy specifies that the image should not be started.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestLoadImage (
+ IN BOOLEAN BootPolicy,
+ IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle
+ );
+
+/**
+ Transfer control to a loaded image's entry point.
+
+ @param ImageHandle Handle of image to be started.
+ @param ExitDataSize Pointer of the size to ExitData
+ @param ExitData Pointer to a pointer to a data buffer that
+ includes a Null-terminated string,
+ optionally followed by additional binary data.
+ The string is a description that the caller may
+ use to further indicate the reason for the
+ image's exit.
+
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
+ @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started.
+ @retval EFI_SUCCESS Successfully transfer control to the image's
+ entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestStartImage (
+ IN EFI_HANDLE ImageHandle,
+ OUT UINTN *ExitDataSize,
+ OUT CHAR16 **ExitData OPTIONAL
+ );
+
+/**
+ Terminates the currently loaded EFI image and returns control to boot services.
+
+ @param ImageHandle Handle that identifies the image. This
+ parameter is passed to the image on entry.
+ @param Status The image's exit code.
+ @param ExitDataSize The size, in bytes, of ExitData. Ignored if
+ ExitStatus is EFI_SUCCESS.
+ @param ExitData Pointer to a data buffer that includes a
+ Null-terminated Unicode string, optionally
+ followed by additional binary data. The string
+ is a description that the caller may use to
+ further indicate the reason for the image's
+ exit.
+
+ @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current
+ image.
+ @retval EFI_SUCCESS Successfully terminates the currently loaded
+ EFI image.
+ @retval EFI_ACCESS_DENIED Should never reach there.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate pool
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestExit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_STATUS Status,
+ IN UINTN ExitDataSize,
+ IN CHAR16 *ExitData OPTIONAL
+ );
+
+/**
+ Unloads an image.
+
+ @param ImageHandle Handle that identifies the image to be
+ unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_UNSUPPORTED The image has been started, and does not support
+ unload.
+ @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestUnloadImage (
+ IN EFI_HANDLE ImageHandle
+ );
+
+/**
+ Terminates all boot services.
+
+ @param ImageHandle Handle that identifies the exiting image.
+ @param MapKey Key to the latest memory map.
+
+ @retval EFI_SUCCESS Boot Services terminated
+ @retval EFI_INVALID_PARAMETER MapKey is incorrect.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestExitBootServices (
+ IN EFI_HANDLE ImageHandle,
+ IN UINTN MapKey
+ );
+
+/**
+ Returns a monotonically increasing count for the platform.
+
+ @param[out] Count The pointer to returned value.
+
+ @retval EFI_SUCCESS The next monotonic count was returned.
+ @retval EFI_INVALID_PARAMETER Count is NULL.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestGetNextMonotonicCount (
+ OUT UINT64 *Count
+ );
+
+/**
+ Introduces a fine-grained stall.
+
+ @param Microseconds The number of microseconds to stall execution.
+
+ @retval EFI_SUCCESS Execution was stalled for at least the requested
+ amount of microseconds.
+ @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestStall (
+ IN UINTN Microseconds
+ );
+
+/**
+ Sets the system's watchdog timer.
+
+ @param Timeout The number of seconds to set the watchdog timer to.
+ A value of zero disables the timer.
+ @param WatchdogCode The numeric code to log on a watchdog timer timeout
+ event. The firmware reserves codes 0x0000 to 0xFFFF.
+ Loaders and operating systems may use other timeout
+ codes.
+ @param DataSize The size, in bytes, of WatchdogData.
+ @param WatchdogData A data buffer that includes a Null-terminated Unicode
+ string, optionally followed by additional binary data.
+ The string is a description that the call may use to
+ further indicate the reason to be logged with a
+ watchdog event.
+
+ @return EFI_SUCCESS Timeout has been set
+ @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet
+ @return EFI_UNSUPPORTED System does not have a timer (currently not used)
+ @return EFI_DEVICE_ERROR Could not complete due to hardware error
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestSetWatchdogTimer (
+ IN UINTN Timeout,
+ IN UINT64 WatchdogCode,
+ IN UINTN DataSize,
+ IN CHAR16 *WatchdogData OPTIONAL
+ );
+
+/**
+ Connects one or more drivers to a controller.
+
+ @param ControllerHandle The handle of the controller to which driver(s) are to be connected.
+ @param DriverImageHandle A pointer to an ordered list handles that support the
+ EFI_DRIVER_BINDING_PROTOCOL.
+ @param RemainingDevicePath A pointer to the device path that specifies a child of the
+ controller specified by ControllerHandle.
+ @param Recursive If TRUE, then ConnectController() is called recursively
+ until the entire tree of controllers below the controller specified
+ by ControllerHandle have been created. If FALSE, then
+ the tree of controllers is only expanded one level.
+
+ @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle.
+ 2) No drivers were connected to ControllerHandle, but
+ RemainingDevicePath is not NULL, and it is an End Device
+ Path Node.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+ @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances
+ present in the system.
+ 2) No drivers were connected to ControllerHandle.
+ @retval EFI_SECURITY_VIOLATION
+ The user has no permission to start UEFI device drivers on the device path
+ associated with the ControllerHandle or specified by the RemainingDevicePath.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestConnectController (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE *DriverImageHandle OPTIONAL,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
+ IN BOOLEAN Recursive
+ );
+
+/**
+ Disconnects a controller from a driver
+
+ @param ControllerHandle ControllerHandle The handle of
+ the controller from which
+ driver(s) are to be
+ disconnected.
+ @param DriverImageHandle DriverImageHandle The driver to
+ disconnect from ControllerHandle.
+ @param ChildHandle ChildHandle The handle of the
+ child to destroy.
+
+ @retval EFI_SUCCESS One or more drivers were
+ disconnected from the controller.
+ @retval EFI_SUCCESS On entry, no drivers are managing
+ ControllerHandle.
+ @retval EFI_SUCCESS DriverImageHandle is not NULL,
+ and on entry DriverImageHandle is
+ not managing ControllerHandle.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+ @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
+ and it is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
+ is not a valid EFI_HANDLE.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources
+ available to disconnect any
+ drivers from ControllerHandle.
+ @retval EFI_DEVICE_ERROR The controller could not be
+ disconnected because of a device
+ error.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestDisconnectController (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE DriverImageHandle OPTIONAL,
+ IN EFI_HANDLE ChildHandle OPTIONAL
+ );
+
+/**
+ Locates the installed protocol handler for the handle, and
+ invokes it to obtain the protocol interface. Usage information
+ is registered in the protocol data base.
+
+ @param UserHandle The handle to obtain the protocol interface on
+ @param Protocol The ID of the protocol
+ @param Interface The location to return the protocol interface
+ @param ImageHandle The handle of the Image that is opening the
+ protocol interface specified by Protocol and
+ Interface.
+ @param ControllerHandle The controller handle that is requiring this
+ interface.
+ @param Attributes The open mode of the protocol interface
+ specified by Handle and Protocol.
+
+ @retval EFI_INVALID_PARAMETER Protocol is NULL.
+ @retval EFI_SUCCESS Get the protocol interface.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestOpenProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface OPTIONAL,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT32 Attributes
+ );
+
+/**
+ Closes a protocol on a handle that was opened using OpenProtocol().
+
+ @param UserHandle The handle for the protocol interface that was
+ previously opened with OpenProtocol(), and is
+ now being closed.
+ @param Protocol The published unique identifier of the protocol.
+ It is the caller's responsibility to pass in a
+ valid GUID.
+ @param AgentHandle The handle of the agent that is closing the
+ protocol interface.
+ @param ControllerHandle If the agent that opened a protocol is a driver
+ that follows the EFI Driver Model, then this
+ parameter is the controller handle that required
+ the protocol interface. If the agent does not
+ follow the EFI Driver Model, then this parameter
+ is optional and may be NULL.
+
+ @retval EFI_SUCCESS The protocol instance was closed.
+ @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a
+ valid EFI_HANDLE.
+ @retval EFI_NOT_FOUND Can not find the specified protocol or
+ AgentHandle.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCloseProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_HANDLE AgentHandle,
+ IN EFI_HANDLE ControllerHandle
+ );
+
+/**
+ Return information about Opened protocols in the system
+
+ @param UserHandle The handle to close the protocol interface on
+ @param Protocol The ID of the protocol
+ @param EntryBuffer A pointer to a buffer of open protocol
+ information in the form of
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
+ @param EntryCount Number of EntryBuffer entries
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestOpenProtocolInformation (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
+ OUT UINTN *EntryCount
+ );
+
+/**
+ Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
+ from pool.
+
+ @param UserHandle The handle from which to retrieve the list of
+ protocol interface GUIDs.
+ @param ProtocolBuffer A pointer to the list of protocol interface GUID
+ pointers that are installed on Handle.
+ @param ProtocolBufferCount A pointer to the number of GUID pointers present
+ in ProtocolBuffer.
+
+ @retval EFI_SUCCESS The list of protocol interface GUIDs installed
+ on Handle was returned in ProtocolBuffer. The
+ number of protocol interface GUIDs was returned
+ in ProtocolBufferCount.
+ @retval EFI_INVALID_PARAMETER Handle is NULL.
+ @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL.
+ @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL.
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the
+ results.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestProtocolsPerHandle (
+ IN EFI_HANDLE UserHandle,
+ OUT EFI_GUID ***ProtocolBuffer,
+ OUT UINTN *ProtocolBufferCount
+ );
+
+/**
+ Function returns an array of handles that support the requested protocol
+ in a buffer allocated from pool. This is a version of UnitTestLocateHandle()
+ that allocates a buffer for the caller.
+
+ @param SearchType Specifies which handle(s) are to be returned.
+ @param Protocol Provides the protocol to search by. This
+ parameter is only valid for SearchType
+ ByProtocol.
+ @param SearchKey Supplies the search key depending on the
+ SearchType.
+ @param NumberHandles The number of handles returned in Buffer.
+ @param Buffer A pointer to the buffer to return the requested
+ array of handles that support Protocol.
+
+ @retval EFI_SUCCESS The result array of handles was returned.
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the
+ matching results.
+ @retval EFI_INVALID_PARAMETER One or more parameters are not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestLocateHandleBuffer (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *NumberHandles,
+ OUT EFI_HANDLE **Buffer
+ );
+
+/**
+ Return the first Protocol Interface that matches the Protocol GUID. If
+ Registration is passed in, return a Protocol Instance that was just add
+ to the system. If Registration is NULL return the first Protocol Interface
+ you find.
+
+ @param Protocol The protocol to search for
+ @param Registration Optional Registration Key returned from
+ RegisterProtocolNotify()
+ @param Interface Return the Protocol interface (instance).
+
+ @retval EFI_SUCCESS If a valid Interface is returned
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_NOT_FOUND Protocol interface not found
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestLocateProtocol (
+ IN EFI_GUID *Protocol,
+ IN VOID *Registration OPTIONAL,
+ OUT VOID **Interface
+ );
+
+/**
+ Installs a list of protocol interface into the boot services environment.
+ This function calls InstallProtocolInterface() in a loop. If any error
+ occurs all the protocols added by this function are removed. This is
+ basically a lib function to save space.
+
+ @param Handle The handle to install the protocol handlers on,
+ or NULL if a new handle is to be allocated
+ @param ... EFI_GUID followed by protocol instance. A NULL
+ terminates the list. The pairs are the
+ arguments to InstallProtocolInterface(). All the
+ protocols are added to Handle.
+
+ @retval EFI_SUCCESS All the protocol interface was installed.
+ @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols.
+ @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in
+ the handle database.
+ @retval EFI_INVALID_PARAMETER Handle is NULL.
+ @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestInstallMultipleProtocolInterfaces (
+ IN OUT EFI_HANDLE *Handle,
+ ...
+ );
+
+/**
+ Uninstalls a list of protocol interface in the boot services environment.
+ This function calls UninstallProtocolInterface() in a loop. This is
+ basically a lib function to save space.
+
+ @param Handle The handle to uninstall the protocol
+ @param ... EFI_GUID followed by protocol instance. A NULL
+ terminates the list. The pairs are the
+ arguments to UninstallProtocolInterface(). All
+ the protocols are added to Handle.
+
+ @return Status code
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestUninstallMultipleProtocolInterfaces (
+ IN EFI_HANDLE Handle,
+ ...
+ );
+
+/**
+ Computes and returns a 32-bit CRC for a data buffer.
+
+ @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed.
+ @param[in] DataSize The number of bytes in the buffer Data.
+ @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data
+ and DataSize.
+
+ @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in
+ Crc32.
+ @retval EFI_INVALID_PARAMETER Data is NULL.
+ @retval EFI_INVALID_PARAMETER Crc32 is NULL.
+ @retval EFI_INVALID_PARAMETER DataSize is 0.
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCalculateCrc32 (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT32 *Crc32
+ );
+
+/**
+ Creates an event in a group.
+
+ @param Type The type of event to create and its mode and
+ attributes
+ @param NotifyTpl The task priority level of event notifications
+ @param NotifyFunction Pointer to the events notification function
+ @param NotifyContext Pointer to the notification functions context;
+ corresponds to parameter "Context" in the
+ notification function
+ @param EventGroup GUID for EventGroup if NULL act the same as
+ gBS->CreateEvent().
+ @param Event Pointer to the newly created event if the call
+ succeeds; undefined otherwise
+
+ @retval EFI_SUCCESS The event structure was created
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
+ @retval EFI_OUT_OF_RESOURCES The event could not be allocated
+
+**/
+EFI_STATUS
+EFIAPI
+UnitTestCreateEventEx (
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
+ IN CONST VOID *NotifyContext, OPTIONAL
+ IN CONST EFI_GUID *EventGroup, OPTIONAL
+ OUT EFI_EVENT *Event
+ );
+
+#endif
diff --git a/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf
new file mode 100644
index 000000000000..3b85dbb1b715
--- /dev/null
+++ b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf
@@ -0,0 +1,46 @@
+## @file
+# UEFI Boot Services Table Library for unit tests implementation.
+#
+# Copyright (c) Microsoft Corporation
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = UefiBootServicesTableLibUnitTest
+ MODULE_UNI_FILE = UefiBootServicesTableLibTest.uni
+ FILE_GUID = 725E1CCD-07F1-4964-9A3E-9AA6DCC51DE6
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UefiBootServicesTableLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE
+
+ CONSTRUCTOR = UefiBootServicesTableLibUnitTestConstructor
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ UefiBootServicesTableLibUnitTest.h
+ UefiBootServicesTableLibUnitTest.c
+ UefiBootServicesTableLibUnitTestEventTimer.c
+ UefiBootServicesTableLibUnitTestImage.c
+ UefiBootServicesTableLibUnitTestMemory.c
+ UefiBootServicesTableLibUnitTestProtocol.h
+ UefiBootServicesTableLibUnitTestProtocol.c
+ UefiBootServicesTableLibUnitTestMisc.c
+ UefiBootServicesTableLibUnitTestTpl.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ UnitTestLib
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ TimerExtra.uni
diff --git a/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.h b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.h
new file mode 100644
index 000000000000..2857db2b2c7f
--- /dev/null
+++ b/PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTestProtocol.h
@@ -0,0 +1,123 @@
+/** @file
+ An internal header file for the Unit Test instance of the UEFI Boot Services Table Library.
+
+ This file includes common header files, defines internal structure and functions used by
+ the library implementation.
+
+Copyright (c) Microsoft Corporation
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_PROTOCOL_H_
+#define UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_PROTOCOL_H_
+
+#include "UefiBootServicesTableLibUnitTest.h"
+
+#define EFI_HANDLE_SIGNATURE SIGNATURE_32('h','n','d','l')
+
+///
+/// IHANDLE - contains a list of protocol handles
+///
+typedef struct {
+ UINTN Signature;
+ /// All handles list of IHANDLE
+ LIST_ENTRY AllHandles;
+ /// List of PROTOCOL_INTERFACE's for this handle
+ LIST_ENTRY Protocols;
+ UINTN LocateRequest;
+ /// The Handle Database Key value when this handle was last created or modified
+ UINT64 Key;
+} IHANDLE;
+
+#define ASSERT_IS_HANDLE(a) ASSERT((a)->Signature == EFI_HANDLE_SIGNATURE)
+
+#define PROTOCOL_ENTRY_SIGNATURE SIGNATURE_32('p','r','t','e')
+
+///
+/// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol
+/// database. Each handler that supports this protocol is listed, along
+/// with a list of registered notifies.
+///
+typedef struct {
+ UINTN Signature;
+ /// Link Entry inserted to mProtocolDatabase
+ LIST_ENTRY AllEntries;
+ /// ID of the protocol
+ EFI_GUID ProtocolID;
+ /// All protocol interfaces
+ LIST_ENTRY Protocols;
+ /// Registered notification handlers
+ LIST_ENTRY Notify;
+} PROTOCOL_ENTRY;
+
+
+#define PROTOCOL_INTERFACE_SIGNATURE SIGNATURE_32('p','i','f','c')
+
+///
+/// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked
+/// with a protocol interface structure
+///
+typedef struct {
+ UINTN Signature;
+ /// Link on IHANDLE.Protocols
+ LIST_ENTRY Link;
+ /// Back pointer
+ IHANDLE *Handle;
+ /// Link on PROTOCOL_ENTRY.Protocols
+ LIST_ENTRY ByProtocol;
+ /// The protocol ID
+ PROTOCOL_ENTRY *Protocol;
+ /// The interface value
+ VOID *Interface;
+ /// OPEN_PROTOCOL_DATA list
+ LIST_ENTRY OpenList;
+ UINTN OpenListCount;
+
+} PROTOCOL_INTERFACE;
+
+#define OPEN_PROTOCOL_DATA_SIGNATURE SIGNATURE_32('p','o','d','l')
+
+typedef struct {
+ UINTN Signature;
+ ///Link on PROTOCOL_INTERFACE.OpenList
+ LIST_ENTRY Link;
+
+ EFI_HANDLE AgentHandle;
+ EFI_HANDLE ControllerHandle;
+ UINT32 Attributes;
+ UINT32 OpenCount;
+} OPEN_PROTOCOL_DATA;
+
+
+#define PROTOCOL_NOTIFY_SIGNATURE SIGNATURE_32('p','r','t','n')
+
+///
+/// PROTOCOL_NOTIFY - used for each register notification for a protocol
+///
+typedef struct {
+ UINTN Signature;
+ PROTOCOL_ENTRY *Protocol;
+ /// All notifications for this protocol
+ LIST_ENTRY Link;
+ /// Event to notify
+ EFI_EVENT Event;
+ /// Last position notified
+ LIST_ENTRY *Position;
+} PROTOCOL_NOTIFY;
+
+typedef struct {
+ EFI_GUID *Protocol;
+ VOID *SearchKey;
+ LIST_ENTRY *Position;
+ PROTOCOL_ENTRY *ProtEntry;
+} LOCATE_POSITION;
+
+typedef
+IHANDLE *
+(* UNIT_TEST_GET_NEXT) (
+ IN OUT LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ );
+
+#endif
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 30/41] PrmPkg/Library/DxePrmContextBufferLib: Add host-based unit tests
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (28 preceding siblings ...)
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 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 31/41] PrmPkg/DxePrmModuleDiscoveryLib: Add initial " Michael Kubacki
` (10 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds host-based unit tests for DxePrmContextBufferLib. This tests
each function in DxePrmContextBufferLib.
Any changes to DxePrmContextBufferLib moving forward must pass the unit
tests. The unit tests should be updated as needed if the library API
changes.
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/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTest.c | 649 ++++++++++++++++++++
PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf | 46 ++
PrmPkg/Test/PrmPkgHostTest.dsc | 6 +
3 files changed, 701 insertions(+)
diff --git a/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTest.c b/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTest.c
new file mode 100644
index 000000000000..07e247305880
--- /dev/null
+++ b/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTest.c
@@ -0,0 +1,649 @@
+/** @file
+
+ Unit tests for the PRM Context Buffer Library.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <Uefi.h>
+
+#include <Guid/ZeroGuid.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PrmContextBufferLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UnitTestLib.h>
+#include <Protocol/PrmConfig.h>
+
+#define UNIT_TEST_NAME "PRM Context Buffer Library Unit Test"
+#define UNIT_TEST_VERSION "0.1"
+
+///=== TEST DATA ==================================================================================
+
+EFI_HANDLE mTestProtocolHandle;
+
+//*----------------------------------------------------------------------------------*
+//* Context Structures *
+//*----------------------------------------------------------------------------------*
+typedef struct {
+ PRM_MODULE_CONTEXT_BUFFERS *InstallationStructure;
+ EFI_HANDLE Handle;
+ PRM_GUID_SEARCH_TYPE GuidSearchType;
+ EFI_GUID *Guid;
+ EFI_GUID *ExpectedModuleGuid;
+ EFI_STATUS ExpectedStatus;
+} PRM_CONTEXT_BUFFERS_TEST_CONTEXT;
+
+typedef struct {
+ EFI_GUID *HandlerGuid;
+ PRM_MODULE_CONTEXT_BUFFERS *ContextBuffers;
+ PRM_CONTEXT_BUFFER *ExpectedContextBuffer;
+ EFI_STATUS ExpectedStatus;
+} PRM_CONTEXT_BUFFER_TEST_CONTEXT;
+
+//*----------------------------------------------------------------------------------*
+//* Test GUIDs *
+//*----------------------------------------------------------------------------------*
+
+// {52960b90-2f3a-4917-b91a-ed5f599a8809}
+#define HANDLER_TEST_GUID_1 {0x52960b90, 0x2f3a, 0x4917, { 0xb9, 0x1a, 0xed, 0x5f, 0x59, 0x9a, 0x88, 0x09 }}
+EFI_GUID mHandlerTestGuid1 = HANDLER_TEST_GUID_1;
+
+// {9316a80d-06dc-417b-b21d-6b3c2ae4ed6f}
+#define HANDLER_TEST_GUID_2 {0x9316a80d, 0x06dc, 0x417b, { 0xb2, 0x1d, 0x6b, 0x3c, 0x2a, 0xe4, 0xed, 0x6f }}
+EFI_GUID mHandlerTestGuid2 = HANDLER_TEST_GUID_2;
+
+// {d32ac8ba-6cc6-456f-9ed9-9233fa310434}
+#define HANDLER_TEST_GUID_3 {0xd32ac8ba, 0x6cc6, 0x456f, { 0x9e, 0xd9, 0x92, 0x33, 0xfa, 0x31, 0x04, 0x34 }}
+EFI_GUID mHandlerTestGuid3 = HANDLER_TEST_GUID_3;
+
+// {faadaa95-070b-4a34-a919-18305dc07370}
+#define MODULE_TEST_GUID_1 {0xfaadaa95, 0x070b, 0x4a34, { 0xa9, 0x19, 0x18, 0x30, 0x5d, 0xc0, 0x73, 0x70 }}
+EFI_GUID mModuleTestGuid1 = MODULE_TEST_GUID_1;
+
+// {0ea24584-731c-4863-9100-75780af509a7}
+#define MODULE_TEST_GUID_2 {0x0ea24584, 0x731c, 0x4863, { 0x91, 0x00, 0x75, 0x78, 0x0a, 0xf5, 0x09, 0xa7 }}
+EFI_GUID mModuleTestGuid2 = MODULE_TEST_GUID_2;
+
+// {f456b7a1-82a6-4427-8486-87e3a602df43}
+#define MODULE_TEST_GUID_3 {0xf456b7a1, 0x82a6, 0x4427, { 0x84, 0x86, 0x87, 0xe3, 0xa6, 0x02, 0xdf, 0x43 }}
+EFI_GUID mModuleTestGuid3 = MODULE_TEST_GUID_3;
+
+// {4a941a9c-9dcf-471b-94b5-d9e2d8c64a1b}
+#define NEGATIVE_TEST_GUID {0x4a941a9c, 0x9dcf, 0x471b, {0x94, 0xb5, 0xd9, 0xe2, 0xd8, 0xc6, 0x4a, 0x1b }}
+EFI_GUID mNegativeTestGuid = NEGATIVE_TEST_GUID;
+
+//*----------------------------------------------------------------------------------*
+//* PRM Static Test Structures *
+//*----------------------------------------------------------------------------------*
+
+PRM_DATA_BUFFER mTestStaticDataBuffer1 = {
+ {
+ PRM_DATA_BUFFER_HEADER_SIGNATURE,
+ sizeof (PRM_DATA_BUFFER)
+ }
+ // No data in the buffer (only a header)
+};
+
+PRM_CONTEXT_BUFFER mTestPrmContextBuffer1 = {
+ PRM_CONTEXT_BUFFER_SIGNATURE, // Signature
+ PRM_CONTEXT_BUFFER_INTERFACE_VERSION, // Version
+ 0, // Reserved
+ HANDLER_TEST_GUID_1, // HandlerGuid
+ &mTestStaticDataBuffer1 // StaticDataBuffer
+};
+
+PRM_CONTEXT_BUFFER mTestPrmContextBuffer2[2] = {
+ // Context buffer #1
+ {
+ PRM_CONTEXT_BUFFER_SIGNATURE, // Signature
+ PRM_CONTEXT_BUFFER_INTERFACE_VERSION, // Version
+ 0, // Reserved
+ HANDLER_TEST_GUID_2, // HandlerGuid
+ NULL // StaticDataBuffer
+ },
+ // Context buffer #2
+ {
+ PRM_CONTEXT_BUFFER_SIGNATURE, // Signature
+ PRM_CONTEXT_BUFFER_INTERFACE_VERSION, // Version
+ 0, // Reserved
+ HANDLER_TEST_GUID_3, // HandlerGuid
+ &mTestStaticDataBuffer1 // StaticDataBuffer (reuse buffer StaticDataBuffer1)
+ }
+};
+
+PRM_MODULE_CONTEXT_BUFFERS mTestPrmModuleContextBuffers1 = {
+ MODULE_TEST_GUID_1,
+ 1,
+ &mTestPrmContextBuffer1,
+ NULL
+};
+
+PRM_MODULE_CONTEXT_BUFFERS mTestPrmModuleContextBuffers2 = {
+ MODULE_TEST_GUID_2,
+ 1,
+ &mTestPrmContextBuffer1,
+ NULL
+};
+
+PRM_MODULE_CONTEXT_BUFFERS mTestPrmModuleContextBuffers3 = {
+ MODULE_TEST_GUID_3,
+ 2,
+ &mTestPrmContextBuffer2[0],
+ NULL
+};
+
+
+//*----------------------------------------------------------------------------------*
+//* Test Contexts *
+//*----------------------------------------------------------------------------------*
+
+//* Searches by module GUID *
+// +--------------------------------+--------+----------------+--------------------+--------------------+--------------------+
+// + InstallationStructure | Handle | GuidSearchType | Guid | ExpectedModuleGuid | ExpectedStatus |
+// +--------------------------------+--------+----------------+--------------------+--------------------+--------------------+
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers00 = { &mTestPrmModuleContextBuffers1, NULL, ByModuleGuid, &mModuleTestGuid1, &mModuleTestGuid1, EFI_SUCCESS };
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers01 = { &mTestPrmModuleContextBuffers2, NULL, ByModuleGuid, &mModuleTestGuid2, &mModuleTestGuid2, EFI_SUCCESS };
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers02 = { &mTestPrmModuleContextBuffers3, NULL, ByModuleGuid, &mModuleTestGuid3, &mModuleTestGuid3, EFI_SUCCESS };
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers03 = { &mTestPrmModuleContextBuffers3, NULL, ByModuleGuid, &mNegativeTestGuid, &gZeroGuid, EFI_NOT_FOUND };
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers04 = { &mTestPrmModuleContextBuffers1, NULL, ByModuleGuid, &gZeroGuid, &gZeroGuid, EFI_NOT_FOUND };
+
+//* Searches by handler GUID *
+// +--------------------------------+--------+----------------+--------------------+--------------------+--------------------+
+// + InstallationStructure | Handle | GuidSearchType | Guid | ExpectedModuleGuid | ExpectedStatus |
+// +--------------------------------+--------+----------------+--------------------+--------------------+--------------------+
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers05 = { &mTestPrmModuleContextBuffers1, NULL, ByHandlerGuid, &mHandlerTestGuid1, &mModuleTestGuid1, EFI_SUCCESS };
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers06 = { &mTestPrmModuleContextBuffers1, NULL, ByHandlerGuid, &gZeroGuid, &gZeroGuid, EFI_NOT_FOUND };
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers07 = { &mTestPrmModuleContextBuffers2, NULL, ByHandlerGuid, &mHandlerTestGuid1, &mModuleTestGuid2, EFI_SUCCESS };
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers08 = { &mTestPrmModuleContextBuffers2, NULL, ByHandlerGuid, &mNegativeTestGuid, &gZeroGuid, EFI_NOT_FOUND };
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers09 = { &mTestPrmModuleContextBuffers3, NULL, ByHandlerGuid, &mHandlerTestGuid1, &gZeroGuid, EFI_NOT_FOUND };
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers10 = { &mTestPrmModuleContextBuffers3, NULL, ByHandlerGuid, &mHandlerTestGuid2, &mModuleTestGuid3, EFI_SUCCESS };
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers11 = { &mTestPrmModuleContextBuffers3, NULL, ByHandlerGuid, &mHandlerTestGuid3, &mModuleTestGuid3, EFI_SUCCESS };
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT mContextBuffers12 = { &mTestPrmModuleContextBuffers3, NULL, ByHandlerGuid, &gZeroGuid, &gZeroGuid, EFI_NOT_FOUND };
+
+PRM_CONTEXT_BUFFERS_TEST_CONTEXT *mContextBuffersArray[] = {
+ &mContextBuffers00,
+ &mContextBuffers01,
+ &mContextBuffers02,
+ &mContextBuffers03,
+ &mContextBuffers04,
+ &mContextBuffers05,
+ &mContextBuffers06,
+ &mContextBuffers07,
+ &mContextBuffers08,
+ &mContextBuffers09,
+ &mContextBuffers10,
+ &mContextBuffers11,
+ &mContextBuffers12
+};
+
+// +----------------------+----------------------------------+------------------------------------------+--------------------+
+// + HandlerGuid | ContextBuffers | ExpectedContextBuffer | ExpectedStatus |
+// +----------------------+----------------------------------+------------------------------------------+--------------------+
+PRM_CONTEXT_BUFFER_TEST_CONTEXT mContextBuffer00 = { &mHandlerTestGuid1, &mTestPrmModuleContextBuffers1, &mTestPrmContextBuffer1, EFI_SUCCESS };
+PRM_CONTEXT_BUFFER_TEST_CONTEXT mContextBuffer01 = { &mHandlerTestGuid1, &mTestPrmModuleContextBuffers2, &mTestPrmContextBuffer1, EFI_SUCCESS };
+PRM_CONTEXT_BUFFER_TEST_CONTEXT mContextBuffer02 = { &mHandlerTestGuid2, &mTestPrmModuleContextBuffers3, &mTestPrmContextBuffer2[0], EFI_SUCCESS };
+PRM_CONTEXT_BUFFER_TEST_CONTEXT mContextBuffer03 = { &mHandlerTestGuid3, &mTestPrmModuleContextBuffers3, &mTestPrmContextBuffer2[1], EFI_SUCCESS };
+PRM_CONTEXT_BUFFER_TEST_CONTEXT mContextBuffer04 = { &mNegativeTestGuid, &mTestPrmModuleContextBuffers1, NULL, EFI_NOT_FOUND };
+PRM_CONTEXT_BUFFER_TEST_CONTEXT mContextBuffer05 = { &gZeroGuid, &mTestPrmModuleContextBuffers3, NULL, EFI_NOT_FOUND };
+
+PRM_CONTEXT_BUFFER_TEST_CONTEXT *mContextBufferArray[] = {
+ &mContextBuffer00,
+ &mContextBuffer01,
+ &mContextBuffer02,
+ &mContextBuffer03,
+ &mContextBuffer04,
+ &mContextBuffer05
+};
+
+///=== HELPER FUNCTIONS ===========================================================================
+
+// None
+
+///=== TEST CASES =================================================================================
+
+///===== BASIC SUITE ==================================================
+
+/**
+ Verifies that passing NULL arguments to all library functions fails with EFI_INVALID_PARAMETER.
+
+ @param[in] Context [Optional] An optional context parameter.
+ Not used in this unit test.
+
+ @retval UNIT_TEST_PASSED Unit test case prerequisites are met.
+ @retval UNIT_TEST_ERROR_PREREQUISITE_NOT_MET Test case should be skipped..
+
+**/
+UNIT_TEST_STATUS
+EFIAPI
+NullPointerArgumentsShouldFailGracefully (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ EFI_GUID Guid;
+ PRM_CONTEXT_BUFFER *ContextBufferPtr;
+ PRM_MODULE_CONTEXT_BUFFERS ModuleContextBuffers;
+ PRM_MODULE_CONTEXT_BUFFERS *ModuleContextBuffersPtr;
+
+ UT_ASSERT_EQUAL (FindContextBufferInModuleBuffers (NULL, NULL, NULL), EFI_INVALID_PARAMETER);
+ UT_ASSERT_EQUAL (FindContextBufferInModuleBuffers (NULL, &ModuleContextBuffers, &ContextBufferPtr), EFI_INVALID_PARAMETER);
+ UT_ASSERT_EQUAL (FindContextBufferInModuleBuffers (&Guid, NULL, &ContextBufferPtr), EFI_INVALID_PARAMETER);
+ UT_ASSERT_EQUAL (FindContextBufferInModuleBuffers (&Guid, &ModuleContextBuffers, NULL), EFI_INVALID_PARAMETER);
+
+ UT_ASSERT_EQUAL (GetModuleContextBuffers (ByModuleGuid, NULL, NULL), EFI_INVALID_PARAMETER);
+ UT_ASSERT_EQUAL (GetModuleContextBuffers (ByModuleGuid, NULL, &ModuleContextBuffersPtr), EFI_INVALID_PARAMETER);
+ UT_ASSERT_EQUAL (GetModuleContextBuffers (ByModuleGuid, &Guid, NULL), EFI_INVALID_PARAMETER);
+
+ UT_ASSERT_EQUAL (GetContextBuffer (NULL, NULL, NULL), EFI_INVALID_PARAMETER);
+ UT_ASSERT_EQUAL (GetContextBuffer (NULL, &ModuleContextBuffers, &ContextBufferPtr), EFI_INVALID_PARAMETER);
+ UT_ASSERT_EQUAL (GetContextBuffer (&Guid, NULL, &ContextBufferPtr), EFI_NOT_FOUND);
+ UT_ASSERT_EQUAL (GetContextBuffer (&Guid, &ModuleContextBuffers, NULL), EFI_INVALID_PARAMETER);
+
+ return UNIT_TEST_PASSED;
+}
+
+///===== FUNCTIONAL CORRECTNESS SUITE ==================================================
+
+/**
+ Functional Correctness pre-requisite function.
+
+ Installs a gPrmConfigProtocolGuid protocol instance as specified by the provided
+ context in preparation for unit test execution
+
+ @param[in] Context [Optional] An optional parameter that enables:
+ A pointer to a PRM_CONTEXT_BUFFERS_TEST_CONTEXT structure with
+ context information for this unit test.
+
+ @retval UNIT_TEST_PASSED Unit test case prerequisites
+ are met.
+ @retval UNIT_TEST_ERROR_PREREQUISITE_NOT_MET Test case should be skipped.
+
+**/
+STATIC
+UNIT_TEST_STATUS
+EFIAPI
+InitializeFunctionalCorrectness (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ EFI_STATUS Status;
+ PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
+ PRM_MODULE_CONTEXT_BUFFERS *ModuleContextBuffers;
+ PRM_CONTEXT_BUFFERS_TEST_CONTEXT *TestContext;
+
+ UT_ASSERT_NOT_NULL (Context);
+ TestContext = (PRM_CONTEXT_BUFFERS_TEST_CONTEXT *) Context;
+ ModuleContextBuffers = TestContext->InstallationStructure;
+
+ PrmConfigProtocol = AllocateZeroPool (sizeof (*PrmConfigProtocol));
+ if (PrmConfigProtocol == NULL) {
+ return UNIT_TEST_ERROR_PREREQUISITE_NOT_MET;
+ }
+
+ CopyGuid (&PrmConfigProtocol->ModuleContextBuffers.ModuleGuid, &ModuleContextBuffers->ModuleGuid);
+ PrmConfigProtocol->ModuleContextBuffers.BufferCount = ModuleContextBuffers->BufferCount;
+ PrmConfigProtocol->ModuleContextBuffers.Buffer = ModuleContextBuffers->Buffer;
+
+ Status = gBS->InstallProtocolInterface (
+ &TestContext->Handle,
+ &gPrmConfigProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID *) PrmConfigProtocol
+ );
+ UT_ASSERT_NOT_EFI_ERROR (Status);
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ Functional Correctness cleanup function.
+
+ Uninstalls the gPrmConfigProtocolGuid protocol instance as specified by the
+ provided context. This is used to clean up the mocked protocol database after
+ unit test execution.
+
+ @param[in] Context [Optional] An optional parameter that enables:
+ A pointer to a PRM_CONTEXT_BUFFERS_TEST_CONTEXT structure with
+ context information for this unit test.
+
+ @retval UNIT_TEST_PASSED Test case cleanup succeeded.
+ @retval UNIT_TEST_ERROR_CLEANUP_FAILED Test case cleanup failed.
+
+**/
+STATIC
+UNIT_TEST_STATUS
+EFIAPI
+DeInitializeFunctionalCorrectness (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ EFI_STATUS Status;
+ PRM_CONFIG_PROTOCOL *PrmConfigProtocol;
+ PRM_CONTEXT_BUFFERS_TEST_CONTEXT *TestContext;
+
+ UT_ASSERT_NOT_NULL (Context);
+ TestContext = (PRM_CONTEXT_BUFFERS_TEST_CONTEXT *) Context;
+
+ Status = gBS->HandleProtocol (
+ TestContext->Handle,
+ &gPrmConfigProtocolGuid,
+ (VOID **) &PrmConfigProtocol
+ );
+ UT_ASSERT_NOT_EFI_ERROR (Status);
+
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->UninstallProtocolInterface (
+ TestContext->Handle,
+ &gPrmConfigProtocolGuid,
+ PrmConfigProtocol
+ );
+ UT_ASSERT_NOT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ FreePool (PrmConfigProtocol);
+ }
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ Verifies that the correct PRM_MODULE_CONTEXT_BUFFERS structure instance is found
+ for a given PRM module or PRM handler GUID.
+
+ @param[in] Context [Optional] An optional context parameter.
+ A pointer to a PRM_CONTEXT_BUFFERS_TEST_CONTEXT structure with
+ context information for this unit test.
+
+ @retval UNIT_TEST_PASSED Unit test case prerequisites are met.
+ @retval UNIT_TEST_ERROR_PREREQUISITE_NOT_MET Test case should be skipped..
+
+**/
+UNIT_TEST_STATUS
+EFIAPI
+VerifyGetModuleContextBuffers (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ EFI_STATUS Status;
+ PRM_MODULE_CONTEXT_BUFFERS *ContextBuffers;
+ PRM_CONTEXT_BUFFERS_TEST_CONTEXT *TestContext;
+
+ ContextBuffers = NULL;
+ TestContext = (PRM_CONTEXT_BUFFERS_TEST_CONTEXT *) Context;
+
+ Status = GetModuleContextBuffers (TestContext->GuidSearchType, TestContext->Guid, &ContextBuffers);
+ UT_ASSERT_STATUS_EQUAL (Status, TestContext->ExpectedStatus);
+
+ if (!EFI_ERROR (TestContext->ExpectedStatus)) {
+ UT_ASSERT_TRUE (CompareGuid (TestContext->ExpectedModuleGuid, &ContextBuffers->ModuleGuid));
+ UT_LOG_INFO (
+ "%a: Searching by %a GUID ({%g}) returned ContextBuffers at 0x%x\n",
+ __FUNCTION__,
+ ((TestContext->GuidSearchType == ByModuleGuid) ? "module" : "handler"),
+ TestContext->Guid,
+ (UINTN) ContextBuffers
+ );
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ Verifies that the expected PRM_CONTEXT_BUFFER instance is found for the given HandlerGuid
+ in the provided PRM_MODULE_CONTEXT_BUFFERS structure.
+
+ @param[in] Context [Optional] An optional context parameter.
+ A pointer to a PRM_CONTEXT_BUFFERS_TEST_CONTEXT structure with
+ context information for this unit test.
+
+ @retval UNIT_TEST_PASSED Unit test case prerequisites are met.
+ @retval UNIT_TEST_ERROR_PREREQUISITE_NOT_MET Test case should be skipped..
+
+**/
+UNIT_TEST_STATUS
+EFIAPI
+VerifyFindContextBufferInModuleBuffers (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ EFI_STATUS Status;
+ PRM_CONTEXT_BUFFER *FoundContextBuffer;
+ PRM_MODULE_CONTEXT_BUFFERS *ContextBuffers;
+ PRM_CONTEXT_BUFFER_TEST_CONTEXT *TestContext;
+
+ ContextBuffers = NULL;
+ FoundContextBuffer = NULL;
+ TestContext = (PRM_CONTEXT_BUFFER_TEST_CONTEXT *) Context;
+
+ Status = FindContextBufferInModuleBuffers (TestContext->HandlerGuid, TestContext->ContextBuffers, &FoundContextBuffer);
+ UT_ASSERT_STATUS_EQUAL (Status, TestContext->ExpectedStatus);
+
+ if (!EFI_ERROR (TestContext->ExpectedStatus)) {
+ UT_ASSERT_NOT_NULL (FoundContextBuffer);
+ UT_ASSERT_TRUE (FoundContextBuffer == TestContext->ExpectedContextBuffer);
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ Verifies that the expected PRM_CONTEXT_BUFFER instance is found for the given HandlerGuid.
+
+ This function checks both the case when a PRM_MODULE_CONTEXT_BUFFERS structure pointer is provided and
+ not provided.
+
+ NOTES:
+ - In the future, this function should mock the internal calls to other library functions but the direct
+ calls are left in place for now.
+ - The PrmModuleContextBuffers being NULL is not actually tested at the moment. In the future, that case
+ should also be added.
+
+ @param[in] Context [Optional] An optional context parameter.
+ A pointer to a PRM_CONTEXT_BUFFERS_TEST_CONTEXT structure with
+ context information for this unit test.
+
+ @retval UNIT_TEST_PASSED Unit test case prerequisites are met.
+ @retval UNIT_TEST_ERROR_PREREQUISITE_NOT_MET Test case should be skipped..
+
+**/
+UNIT_TEST_STATUS
+EFIAPI
+VerifyGetContextBuffer (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ EFI_STATUS Status;
+ PRM_CONTEXT_BUFFER *FoundContextBuffer;
+ PRM_MODULE_CONTEXT_BUFFERS *ContextBuffers;
+ PRM_CONTEXT_BUFFER_TEST_CONTEXT *TestContext;
+
+ ContextBuffers = NULL;
+ FoundContextBuffer = NULL;
+ TestContext = (PRM_CONTEXT_BUFFER_TEST_CONTEXT *) Context;
+
+ Status = GetContextBuffer (TestContext->HandlerGuid, TestContext->ContextBuffers, &FoundContextBuffer);
+ UT_ASSERT_STATUS_EQUAL (Status, TestContext->ExpectedStatus);
+
+ if (!EFI_ERROR (TestContext->ExpectedStatus)) {
+ UT_ASSERT_NOT_NULL (FoundContextBuffer);
+ UT_ASSERT_TRUE (FoundContextBuffer == TestContext->ExpectedContextBuffer);
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
+///=== TEST ENGINE ================================================================================
+
+/**
+ Entry point for the PRM Context Buffer Library unit tests.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point executed successfully.
+ @retval other Some error occurred when executing this entry point.
+
+**/
+int main ()
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UNIT_TEST_FRAMEWORK_HANDLE Framework;
+ UNIT_TEST_SUITE_HANDLE BasicTests;
+ UNIT_TEST_SUITE_HANDLE FunctionalCorrectnessTests;
+ CHAR8 TestCaseClassNameString[256];
+ CHAR8 TestCaseDescriptionString[256];
+
+ Framework = NULL;
+
+ DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION));
+
+ //
+ // Start setting up the test framework for running the tests.
+ //
+ Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
+ goto EXIT;
+ }
+
+ //
+ // Add all test suites and tests.
+ //
+ Status = CreateUnitTestSuite (&BasicTests, Framework, "Basic Context Buffer Tests", "PrmContextBufferLib.Basic", NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for PrmContextBufferLib.Basic\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ AddTestCase (
+ BasicTests,
+ "",
+ "PrmContextBufferLib.Basic.NullPointerGracefulFailure",
+ NullPointerArgumentsShouldFailGracefully,
+ NULL,
+ NULL,
+ NULL
+ );
+
+ Status = CreateUnitTestSuite (&FunctionalCorrectnessTests, Framework, "Functional Correctness Tests", "PrmContextBufferLib.Functional", NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for PrmContextBufferLib.Functional\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ //
+ // Add Functional Correctness unit tests
+ //
+ for (Index = 0; Index < ARRAY_SIZE (mContextBuffersArray); Index++) {
+ ZeroMem (&TestCaseClassNameString[0], ARRAY_SIZE (TestCaseClassNameString));
+ ZeroMem (&TestCaseDescriptionString[0], ARRAY_SIZE (TestCaseDescriptionString));
+
+ AsciiSPrint (
+ &TestCaseClassNameString[0],
+ ARRAY_SIZE (TestCaseClassNameString),
+ "PrmContextBufferLib.Functional.VerifyGetModuleContextBuffers%d",
+ Index + 1
+ );
+ AsciiSPrint (
+ &TestCaseDescriptionString[0],
+ ARRAY_SIZE (TestCaseDescriptionString),
+ "Verify Get PRM Module Context Buffers Structure by %a GUID %d\n",
+ ((mContextBuffersArray[Index]->GuidSearchType == ByModuleGuid) ? "module" : "handler"),
+ Index + 1
+ );
+
+ AddTestCase (
+ FunctionalCorrectnessTests,
+ &TestCaseDescriptionString[0],
+ &TestCaseClassNameString[0],
+ VerifyGetModuleContextBuffers,
+ InitializeFunctionalCorrectness,
+ DeInitializeFunctionalCorrectness,
+ mContextBuffersArray[Index]
+ );
+ }
+
+ for (Index = 0; Index < ARRAY_SIZE (mContextBufferArray); Index++) {
+ ZeroMem (&TestCaseClassNameString[0], ARRAY_SIZE (TestCaseClassNameString));
+ ZeroMem (&TestCaseDescriptionString[0], ARRAY_SIZE (TestCaseDescriptionString));
+
+ AsciiSPrint (
+ &TestCaseClassNameString[0],
+ ARRAY_SIZE (TestCaseClassNameString),
+ "PrmContextBufferLib.Functional.VerifyFindContextBufferInModuleBuffers%d",
+ Index + 1
+ );
+ AsciiSPrint (
+ &TestCaseDescriptionString[0],
+ ARRAY_SIZE (TestCaseDescriptionString),
+ "Verify Find PRM Context Buffer by Handler GUID %d\n",
+ Index + 1
+ );
+
+ AddTestCase (
+ FunctionalCorrectnessTests,
+ &TestCaseDescriptionString[0],
+ &TestCaseClassNameString[0],
+ VerifyFindContextBufferInModuleBuffers,
+ NULL,
+ NULL,
+ mContextBufferArray[Index]
+ );
+ }
+
+ for (Index = 0; Index < ARRAY_SIZE (mContextBufferArray); Index++) {
+ ZeroMem (&TestCaseClassNameString[0], ARRAY_SIZE (TestCaseClassNameString));
+ ZeroMem (&TestCaseDescriptionString[0], ARRAY_SIZE (TestCaseDescriptionString));
+
+ AsciiSPrint (
+ &TestCaseClassNameString[0],
+ ARRAY_SIZE (TestCaseClassNameString),
+ "PrmContextBufferLib.Functional.VerifyGetContextBuffer%d",
+ Index + 1
+ );
+ AsciiSPrint (
+ &TestCaseDescriptionString[0],
+ ARRAY_SIZE (TestCaseDescriptionString),
+ "Verify Get PRM Context Buffer by Handler GUID %d\n",
+ Index + 1
+ );
+
+ AddTestCase (
+ FunctionalCorrectnessTests,
+ &TestCaseDescriptionString[0],
+ &TestCaseClassNameString[0],
+ VerifyGetContextBuffer,
+ NULL,
+ NULL,
+ mContextBufferArray[Index]
+ );
+ }
+
+ //
+ // Execute the tests.
+ //
+ Status = RunAllTestSuites (Framework);
+
+EXIT:
+ if (Framework)
+ {
+ FreeUnitTestFramework (Framework);
+ }
+
+ return Status;
+}
diff --git a/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf b/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf
new file mode 100644
index 000000000000..7cf6a16867d4
--- /dev/null
+++ b/PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf
@@ -0,0 +1,46 @@
+## @file
+# PRM Context Buffer Library Host-Based Unit Tests
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = PrmContextBufferLibUnitTestHost
+ FILE_GUID = F1FB5F32-BDB5-4391-BD6D-979E90EE2DC3
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ DxePrmContextBufferLibUnitTest.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+ PrmPkg/PrmPkg.dec
+
+[Guids]
+ gZeroGuid
+
+[Protocols]
+ gPrmConfigProtocolGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ PrintLib
+ PrmContextBufferLib
+ UefiBootServicesTableLib
+ UnitTestLib
diff --git a/PrmPkg/Test/PrmPkgHostTest.dsc b/PrmPkg/Test/PrmPkgHostTest.dsc
index 2d718f8888b8..1f44037d0102 100644
--- a/PrmPkg/Test/PrmPkgHostTest.dsc
+++ b/PrmPkg/Test/PrmPkgHostTest.dsc
@@ -19,6 +19,7 @@ [Defines]
!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
[LibraryClasses]
+ PrmContextBufferLib|PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
UefiBootServicesTableLib|PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf
[Components]
@@ -26,3 +27,8 @@ [Components]
# Unit test helper libraries
#
PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf
+
+ #
+ # Unit test host applications
+ #
+ PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 31/41] PrmPkg/DxePrmModuleDiscoveryLib: Add initial host-based unit tests
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (29 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 30/41] PrmPkg/Library/DxePrmContextBufferLib: Add host-based unit tests Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 32/41] PrmPkg: Add PlatformGuid Michael Kubacki
` (9 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds host-based unit tests for DxePrmModuleDiscoveryLib. This is
an initial set of support, more tests should be added in the
future.
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/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c | 1 -
PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTest.c | 209 ++++++++++++++++++++
PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h | 12 ++
PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf | 39 ++++
PrmPkg/Test/PrmPkgHostTest.dsc | 5 +
5 files changed, 265 insertions(+), 1 deletion(-)
diff --git a/PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c b/PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
index 6977799aa8f3..0dd6a76be4d7 100644
--- a/PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
+++ b/PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
@@ -87,7 +87,6 @@ GetNextPrmModuleEntry (
otherwise, NULL is returned.
**/
-STATIC
PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *
CreateNewPrmModuleImageContextListEntry (
VOID
diff --git a/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTest.c b/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTest.c
new file mode 100644
index 000000000000..ef8abe397cd4
--- /dev/null
+++ b/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTest.c
@@ -0,0 +1,209 @@
+/** @file
+
+ Unit tests for the PRM Module Discovery Library.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrmModuleDiscoveryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UnitTestLib.h>
+
+#include "../PrmModuleDiscovery.h"
+
+#define UNIT_TEST_NAME "PRM Module Discovery Library Unit Test"
+#define UNIT_TEST_VERSION "0.1"
+
+///=== TEST CASES =================================================================================
+
+///===== CREATE NEW PRM MODULE IMAGE CONTEXT LIST ENTRY TESTS SUITE ==================================================
+
+/**
+ Verifies that the buffer returned can be deallocated.
+
+ @param[in] Context [Optional] An optional context parameter.
+ Not used in this unit test.
+
+ @retval UNIT_TEST_PASSED Unit test case prerequisites are met.
+ @retval UNIT_TEST_ERROR_PREREQUISITE_NOT_MET Test case should be skipped..
+
+**/
+UNIT_TEST_STATUS
+EFIAPI
+PrmModuleImageContextListEntryShouldDeallocate (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *ListEntry;
+
+ ListEntry = CreateNewPrmModuleImageContextListEntry ();
+
+ UT_ASSERT_NOT_NULL (ListEntry);
+ if (ListEntry != NULL) {
+ FreePool (ListEntry);
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ Verifies that the list entry signature is set to the appropriate value.
+
+ @param[in] Context [Optional] An optional context parameter.
+ Not used in this unit test.
+
+ @retval UNIT_TEST_PASSED Unit test case prerequisites are met.
+ @retval UNIT_TEST_ERROR_PREREQUISITE_NOT_MET Test case should be skipped..
+
+**/
+UNIT_TEST_STATUS
+EFIAPI
+PrmModuleImageContextListEntrySignatureShouldBeValid (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *ListEntry;
+
+ ListEntry = CreateNewPrmModuleImageContextListEntry ();
+
+ UT_ASSERT_TRUE (ListEntry->Signature == PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY_SIGNATURE);
+
+ if (ListEntry != NULL) {
+ FreePool (ListEntry);
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ Verifies that the Context buffer in the list entry is initialized to zero.
+
+ @param[in] Context [Optional] An optional context parameter.
+ Not used in this unit test.
+
+ @retval UNIT_TEST_PASSED Unit test case prerequisites are met.
+ @retval UNIT_TEST_ERROR_PREREQUISITE_NOT_MET Test case should be skipped..
+
+**/
+UNIT_TEST_STATUS
+EFIAPI
+PrmModuleImageContextListEntryImageContextShouldBeZeroed (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *ListEntry;
+ PRM_MODULE_IMAGE_CONTEXT ImageContext;
+
+ ListEntry = CreateNewPrmModuleImageContextListEntry ();
+
+ ZeroMem (&ImageContext, sizeof (ImageContext));
+ UT_ASSERT_MEM_EQUAL (&ListEntry->Context, &ImageContext, sizeof (ImageContext));
+
+ if (ListEntry != NULL) {
+ FreePool (ListEntry);
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
+///=== TEST ENGINE ================================================================================
+
+/**
+ Entry point for the PRM Context Buffer Library unit tests.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point executed successfully.
+ @retval other Some error occurred when executing this entry point.
+
+**/
+int main ()
+{
+ EFI_STATUS Status;
+ UNIT_TEST_FRAMEWORK_HANDLE Framework;
+ UNIT_TEST_SUITE_HANDLE CreateNewPrmModuleImageContextListEntryTests;
+
+ Framework = NULL;
+
+ DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION));
+
+ //
+ // Start setting up the test framework for running the tests.
+ //
+ Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
+ goto EXIT;
+ }
+
+ Status = CreateUnitTestSuite (
+ &CreateNewPrmModuleImageContextListEntryTests,
+ Framework,
+ "Create New PRM Module Image Context List Entry Tests",
+ "PrmModuleDiscoveryLib.CreateNewPrmModuleImageContextListEntry",
+ NULL,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for PrmModuleDiscoveryLib.CreateNewPrmModuleImageContextListEntry\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ AddTestCase (
+ CreateNewPrmModuleImageContextListEntryTests,
+ "",
+ "PrmModuleDiscoveryLib.CreateNewPrmModuleImageContextListEntry.ListEntryShouldDeallocate",
+ PrmModuleImageContextListEntryShouldDeallocate,
+ NULL,
+ NULL,
+ NULL
+ );
+
+ AddTestCase (
+ CreateNewPrmModuleImageContextListEntryTests,
+ "",
+ "PrmModuleDiscoveryLib.CreateNewPrmModuleImageContextListEntry.ListEntrySignatureShouldBeValid",
+ PrmModuleImageContextListEntrySignatureShouldBeValid,
+ NULL,
+ NULL,
+ NULL
+ );
+
+ AddTestCase (
+ CreateNewPrmModuleImageContextListEntryTests,
+ "",
+ "PrmModuleDiscoveryLib.CreateNewPrmModuleImageContextListEntry.ListEntryImageContextShouldBeZeroed",
+ PrmModuleImageContextListEntryImageContextShouldBeZeroed,
+ NULL,
+ NULL,
+ NULL
+ );
+
+ //
+ // Execute the tests.
+ //
+ Status = RunAllTestSuites (Framework);
+
+EXIT:
+ if (Framework)
+ {
+ FreeUnitTestFramework (Framework);
+ }
+
+ return Status;
+}
diff --git a/PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h b/PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
index 79058d15317e..ea42cf272550 100644
--- a/PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
+++ b/PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
@@ -24,4 +24,16 @@ typedef struct {
#pragma pack(pop)
+/**
+ Creates a new PRM Module Image Context linked list entry.
+
+ @retval PrmModuleImageContextListEntry If successful, a pointer a PRM Module Image Context linked list entry
+ otherwise, NULL is returned.
+
+**/
+PRM_MODULE_IMAGE_CONTEXT_LIST_ENTRY *
+CreateNewPrmModuleImageContextListEntry (
+ VOID
+ );
+
#endif
diff --git a/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf b/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf
new file mode 100644
index 000000000000..8aae1f7cd78a
--- /dev/null
+++ b/PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf
@@ -0,0 +1,39 @@
+## @file
+# PRM Module Discovery Library Host-Based Unit Tests
+#
+# Copyright (c) Microsoft Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = PrmModuleDiscoveryLibUnitTestHost
+ FILE_GUID = 864886C5-5458-4FF5-A160-4D5B2EAEC558
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ DxePrmModuleDiscoveryLibUnitTest.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+ PrmPkg/PrmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ PrmModuleDiscoveryLib
+ UefiBootServicesTableLib
+ UnitTestLib
diff --git a/PrmPkg/Test/PrmPkgHostTest.dsc b/PrmPkg/Test/PrmPkgHostTest.dsc
index 1f44037d0102..67fb4f5bd0d2 100644
--- a/PrmPkg/Test/PrmPkgHostTest.dsc
+++ b/PrmPkg/Test/PrmPkgHostTest.dsc
@@ -19,7 +19,11 @@ [Defines]
!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
[LibraryClasses]
+ PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PrmContextBufferLib|PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
+ PrmModuleDiscoveryLib|PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf
+ PrmPeCoffLib|PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
UefiBootServicesTableLib|PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootServicesTableLibUnitTest.inf
[Components]
@@ -32,3 +36,4 @@ [Components]
# Unit test host applications
#
PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibUnitTestHost.inf
+ PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscoveryLibUnitTestHost.inf
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 32/41] PrmPkg: Add PlatformGuid
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (30 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 31/41] PrmPkg/DxePrmModuleDiscoveryLib: Add initial " Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 33/41] PrmPkg: Update PRM OpRegion Michael Kubacki
` (8 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <mikuback@microsoft.com>
Adds a "platform GUID" field to the PRM ACPI table. This field
is used by a platform to uniquely identify itself such that it
can be targeted by runtime PRM module updates for that platform.
Platforms using PRM are currently required to set a unique value
for gPrmPkgTokenSpaceGuid.PcdPrmPlatformGuid in their platform
DSC.
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/PrmLoaderDxe/PrmLoaderDxe.c | 17 +++++++++++++++++
PrmPkg/PrmLoaderDxe/PrmAcpiTable.h | 3 +++
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf | 2 ++
PrmPkg/PrmPkg.dec | 10 ++++++++++
PrmPkg/Readme.md | 12 ++++++++++++
5 files changed, 44 insertions(+)
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
index aa7aab391e8c..f78c682a654b 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -11,6 +11,7 @@
#include "PrmAcpiTable.h"
+#include <Guid/ZeroGuid.h>
#include <IndustryStandard/Acpi.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
@@ -52,6 +53,7 @@ ProcessPrmModules (
OUT PRM_ACPI_DESCRIPTION_TABLE **PrmAcpiDescriptionTable
)
{
+ EFI_GUID *PlatformGuid;
EFI_IMAGE_EXPORT_DIRECTORY *CurrentImageExportDirectory;
PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *CurrentExportDescriptorStruct;
PRM_ACPI_DESCRIPTION_TABLE *PrmAcpiTable;
@@ -79,6 +81,20 @@ ProcessPrmModules (
}
*PrmAcpiDescriptionTable = NULL;
+ PlatformGuid = (EFI_GUID *) PcdGetPtr (PcdPrmPlatformGuid);
+ //
+ // The platform should set PcdPrmPlatformGuid to a non-zero value
+ //
+ if (CompareGuid (PlatformGuid, &gZeroGuid)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ " %a %a: PcdPrmPlatformGuid must be set to a unique value in the platform DSC file.\n",
+ _DBGMSGID_,
+ __FUNCTION__
+ ));
+ ASSERT (!CompareGuid (PlatformGuid, &gZeroGuid));
+ }
+
DEBUG ((DEBUG_INFO, " %a %a: %d total PRM modules to process.\n", _DBGMSGID_, __FUNCTION__, mPrmModuleCount));
DEBUG ((DEBUG_INFO, " %a %a: %d total PRM handlers to process.\n", _DBGMSGID_, __FUNCTION__, mPrmHandlerCount));
@@ -102,6 +118,7 @@ ProcessPrmModules (
PrmAcpiTable->Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
PrmAcpiTable->Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
PrmAcpiTable->Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+ CopyGuid (&PrmAcpiTable->PrmPlatformGuid, PlatformGuid);
PrmAcpiTable->PrmModuleInfoOffset = OFFSET_OF (PRM_ACPI_DESCRIPTION_TABLE, PrmModuleInfoStructure);
PrmAcpiTable->PrmModuleInfoCount = (UINT32) mPrmModuleCount;
diff --git a/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h b/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
index ec3be529d119..6f9ba8f77724 100644
--- a/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
+++ b/PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
@@ -56,6 +56,9 @@ typedef struct {
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header; ///< Standard ACPI description header
+ GUID PrmPlatformGuid; ///< A GUID that uniquely identifies this platform.
+ ///< Used to check for compatibility in PRM module
+ ///< runtime updates.
UINT32 PrmModuleInfoOffset; ///< Offset in bytes from the beginning of this
///< structure to the PRM Module Info array
UINT32 PrmModuleInfoCount; ///< Number of entries in the PRM Module Info array
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
index 554d49685e2a..7efefdae960f 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
@@ -31,6 +31,7 @@ [Packages]
[Guids]
gEfiEndOfDxeEventGroupGuid
+ gZeroGuid
[LibraryClasses]
BaseLib
@@ -51,6 +52,7 @@ [Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## CONSUMES
+ gPrmPkgTokenSpaceGuid.PcdPrmPlatformGuid ## CONSUMES
[Protocols]
gEfiAcpiTableProtocolGuid
diff --git a/PrmPkg/PrmPkg.dec b/PrmPkg/PrmPkg.dec
index 94888d1c70a4..6753ac624444 100644
--- a/PrmPkg/PrmPkg.dec
+++ b/PrmPkg/PrmPkg.dec
@@ -65,3 +65,13 @@ [PcdsFixedAtBuild]
# report PRM handler execution time in the application. If such a TimerLib
# instance is not available, set this PCD to FALSE in the package DSC file.
gPrmPkgTokenSpaceGuid.PcdPrmInfoPrintHandlerExecutionTime|TRUE|BOOLEAN|0x00000003
+
+ ## PRM Platform GUID
+ #
+ # Uniquely identifies a specific platform targeted for PRM module updates. Each
+ # platform MUST provide a new GUID. This GUID is checked against the platform
+ # GUID in the PRM module export descriptor during PRM runtime updates to determine
+ # if a given PRM module update is valid for a given system. Even if PRM runtime
+ # updates are not planned for a given platform, this value should still be given
+ # a unique value in the platform DSC.
+ gPrmPkgTokenSpaceGuid.PcdPrmPlatformGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}|VOID*|0x00000004
diff --git a/PrmPkg/Readme.md b/PrmPkg/Readme.md
index 2a8a40c924c0..40df8f00a0c8 100644
--- a/PrmPkg/Readme.md
+++ b/PrmPkg/Readme.md
@@ -74,6 +74,18 @@ The following list are the currently defined build flags (if any) that may be pa
This structure is passed as the context buffer to PRM handlers. The structure actually passed to PRM handlers is
allocated and populated by the OS where it gets all the information to populate the context buffer from other structures.
+### PRM Platform GUID
+**IMPORTANT**
+
+A configuration item that requires user attention is the PRM platform GUID. Each platform that uses PRM must be
+uniquely identifiable so that various instances of a PRM module can target the correct platform in PRM module updates.
+
+To apply a unique platform GUID set the following PCD to a unique value in your platform DSC file.
+ ``gPrmPkgTokenSpaceGuid.PcdPrmPlatformGuid``
+
+The default value assigned in [PrmPkg.dec](PrmPkg/PrmPkg.dec) is zero. By design, this is an invalid value that will
+cause an ASSERT if it is not updated.
+
## Overview
At a high-level, PRM can be viewed from three levels of granularity:
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 33/41] PrmPkg: Update PRM OpRegion
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (31 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 32/41] PrmPkg: Add PlatformGuid Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 34/41] Readme.md: Add iASL note and QEMU sample link Michael Kubacki
` (7 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Liu Yun Y <yun.y.liu@intel.com>
1. Enable new PRM OpRegion structure
2. Add PRM Handler Update Lock/Unlock support
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: Liu Yun <yun.y.liu@intel.com>
---
PrmPkg/PrmSsdtInstallDxe/Prm.asl | 131 +++++++++++++-------
1 file changed, 88 insertions(+), 43 deletions(-)
diff --git a/PrmPkg/PrmSsdtInstallDxe/Prm.asl b/PrmPkg/PrmSsdtInstallDxe/Prm.asl
index 0457d09e6954..20a6fef9be7b 100644
--- a/PrmPkg/PrmSsdtInstallDxe/Prm.asl
+++ b/PrmPkg/PrmSsdtInstallDxe/Prm.asl
@@ -1,7 +1,7 @@
/** @file
The definition block in ACPI table for PRM Operation Region
- Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020-2021, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -16,60 +16,105 @@ DefinitionBlock (
{
Scope (\_SB)
{
- //
- // PRM Bridge Device
- //
-
- Device (PRMB)
- {
- Name (_HID, "80860222")
- Name (_CID, "80860222")
- Name (_DDN, "PRM Bridge Device")
- Name (_STA, 0xF)
- OperationRegion (OPR1, 0x80, 0, 16)
- Field (OPR1, DWordAcc, NoLock, Preserve) //Make it ByteAcc for parameter validation
- {
- Var0, 128
- }
- Method (SETV, 1, Serialized)
- {
- CopyObject (Arg0, \_SB.PRMB.Var0)
- }
- }
-
//
// PRM Test Device
//
-
Device (PRMT)
{
Name (_HID, "80860223")
Name (_CID, "80860223")
Name (_DDN, "PRM Test Device")
- Name (_STA, 0xF)
- Name (BUF1, Buffer(16)
+
+ // PrmSamplePrintModule handler GUIDs
+ Name (BUF1, ToUUID("d5f2ad5f-a347-4d3e-87bc-c2ce63029cc8"))
+ Name (BUF2, ToUUID("a9e7adc3-8cd0-429a-8915-10946ebde318"))
+ Name (BUFN, ToUUID("b688c214-4081-4eeb-8d26-1eb5a3bcf11a"))
+
+ //PRM operation region format
+ OperationRegion (PRMR, PlatformRtMechanism, 0, 1)
+ Field (PRMR, BufferAcc, NoLock, Preserve) //Make it ByteAcc for parameter validation
{
- 0x5F, 0xAD, 0xF2, 0xD5, 0x47, 0xA3, 0x3E, 0x4D, //Guid_0
- 0x87, 0xBC, 0xC2, 0xCE, 0x63, 0x02, 0x9C, 0xC8, //Guid_1
- })
- Name (BUF2, Buffer(16)
+ PRMF, 8
+ }
+
+ /*
+ * Control method to invoke PRM OperationRegion handler
+ * Arg0 contains a buffer representing a _DSM GUID
+ */
+ Method (RUNS, 1)
{
- 0xC3, 0xAD, 0xE7, 0xA9, 0xD0, 0x8C, 0x9A, 0x42, //Guid_0
- 0x89, 0x15, 0x10, 0x94, 0x6E, 0xBD, 0xE3, 0x18, //Guid_1
- })
- Name (BUF3, Buffer(16)
+ /* Local0 is the PRM data buffer */
+ Local0 = buffer (26){}
+
+ /* Create byte fields over the buffer */
+ CreateByteField (Local0, 0x0, PSTA)
+ CreateQWordField (Local0, 0x1, USTA)
+ CreateByteField (Local0, 0x9, CMD)
+ CreateField (Local0, 0x50, 0x80, GUID)
+
+ /* Fill in the command and data fields of the data buffer */
+ CMD = 0 // run command
+ GUID = Arg0
+
+ /* Invoke PRM OperationRegion Handler and store the result into Local0 */
+ Local0 = (PRMF = Local0)
+
+ /* Return status */
+ Return (PSTA)
+ }
+
+ /*
+ * Control method to lock a PRM transaction
+ * Arg0 contains a buffer representing a _DSM GUID
+ */
+ Method (LCKH, 1)
{
- 0x14, 0xC2, 0x88, 0xB6, 0x81, 0x40, 0xEB, 0x4E, //Guid_0
- 0x8D, 0x26, 0x1E, 0xB5, 0xA3, 0xBC, 0xF1, 0x1A, //Guid_1
- })
- Method (NTST)
+ /* Local0 is the PRM data buffer */
+ Local0 = buffer (26){}
+
+ /* Create byte fields over the buffer */
+ CreateByteField (Local0, 0x0, STAT)
+ CreateByteField (Local0, 0x9, CMD)
+ CreateField (Local0, 0x50, 0x80, GUID)
+ CMD = 1 // Lock command
+ GUID = Arg0
+ Local0 = (PRMF = Local0)
+
+ /* Note STAT contains the return status */
+ Return (STAT)
+ }
+
+ /*
+ * Control method to unlock a PRM transaction
+ * Arg0 contains a buffer representing a _DSM GUID
+ */
+ Method (ULCK, 1)
{
- \_SB.PRMB.SETV (BUF1)
+ /* Local0 is the PRM data buffer */
+ Local0 = buffer (26){}
+
+ /* Create byte fields over the buffer */
+ CreateByteField (Local0, 0x0, STAT)
+ CreateByteField (Local0, 0x9, CMD)
+ CreateField (Local0, 0x50, 0x80, GUID)
+ CMD = 2 // Unlock command
+ GUID = Arg0
+ Local0 = (PRMF = Local0)
+
+ /* Note STAT contains the return status */
+ Return (STAT)
+ }
+
+ /*
+ *Bit [0] Set if the device is present.
+ *Bit [1] Set if the device is enabled and decoding its resources.
+ *Bit [2] Set if the device should be shown in the UI.
+ *Bit [3] Set if the device is functioning properly (cleared if device failed its diagnostics).
+ */
+ Method (_STA, 0, NotSerialized)
+ {
+ Return (0x0B) // Device present, but not shown
}
}
}
-
-} // End of Definition Block
-
-
-
+}
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 34/41] Readme.md: Add iASL note and QEMU sample link
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (32 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 33/41] PrmPkg: Update PRM OpRegion Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 35/41] PrmPkg: Replace PcdPrmPlatformGuid with EDKII_DSC_PLATFORM_GUID Michael Kubacki
` (6 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a note that the build now depends on an ASL compiler supporting
PlatformRtMechanism by default. The minimum iASL version supported
is noted in addition to an alternative to remove the code that
requires the new OperationRegion.
Also, a link is provided to an example of how to integrate the
package into a platform using QEMU/OvmfPkg as the sample platform
and firmware.
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 | 23 ++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/PrmPkg/Readme.md b/PrmPkg/Readme.md
index 40df8f00a0c8..f340eeb64258 100644
--- a/PrmPkg/Readme.md
+++ b/PrmPkg/Readme.md
@@ -13,6 +13,14 @@ to be leveraged by platform firmware with minimal overhead to integrate PRM func
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.
+> By default, the build makes use of a new ACPI OperationRegion type specifically introduced for PRM called
+`PlatformRtMechanism`. Support for this OperationRegion is planned for the next release of the ACPI specification.
+However, support for `PlatformRtMechanism` is already included in the iASL Compiler/Disassembler for early prototyping
+(i.e. this package). If you would like the default build to work and/or to use PRM handlers that are invoked
+through ACPI, iASL compiler [20200528](https://acpica.org/node/181) or greater must be used. If you are only
+interested in compiling the code and/or using direct call style PRM handlers, you can simply remove
+`PrmSsdtInstallDxe` from `PrmPkg.dsc`.
+
## 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
@@ -60,6 +68,21 @@ To build `PrmPkg` as a standalone package:
> __*Note*__: Due to the way PRM modules are compiled with exports, **only building on Visual Studio compiler tool
chains is currently supported**.
+In the future, each new terminal session can start at step #4. Within a terminal session, start at step #8.
+
+> __*Note*__: \
+> This package has been used without modification in several environments including client, server,
+> and virtual systems.
+>
+> A functional example of how to integrate this code into a platform is available here:
+> https://github.com/makubacki/edk2/tree/sample_ovmfpkg_prmpkg_integration
+>
+> That build will load the drivers and PRM sample modules provided in this package in the open source emulator
+> [QEMU](https://www.qemu.org/) by including it in the [`OvmfPkg`](https://github.com/tianocore/edk2/tree/master/OvmfPkg) build.
+>
+> You can add your own PRM modules into the build and check them with the `PrmInfo` UEFI application described
+> later in this document and dump the PRMT table in the OS to check if your PRM module is represented as expected.
+
### 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
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 35/41] PrmPkg: Replace PcdPrmPlatformGuid with EDKII_DSC_PLATFORM_GUID
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (33 preceding siblings ...)
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 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 36/41] PrmPkg/Samples: Remove PrmSampleMemoryAllocationModule Michael Kubacki
` (5 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Bugzilla request https://bugzilla.tianocore.org/show_bug.cgi?id=2969
was recently completed which causes the PLATFORM_GUID value from the
DSC file to be placed into Autogen file .c & .h files. With this
change, the PRM Platform GUID can be directly matched to the DSC
PLATFORM_GUID value.
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/PrmLoaderDxe/PrmLoaderDxe.c | 12 +++++-----
PrmPkg/Include/PrmExportDescriptor.h | 2 ++
PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf | 1 -
PrmPkg/PrmPkg.dec | 10 ---------
PrmPkg/Readme.md | 23 +++++++++++++++-----
5 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
index f78c682a654b..e2779f5c1786 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
@@ -53,7 +53,6 @@ ProcessPrmModules (
OUT PRM_ACPI_DESCRIPTION_TABLE **PrmAcpiDescriptionTable
)
{
- EFI_GUID *PlatformGuid;
EFI_IMAGE_EXPORT_DIRECTORY *CurrentImageExportDirectory;
PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT *CurrentExportDescriptorStruct;
PRM_ACPI_DESCRIPTION_TABLE *PrmAcpiTable;
@@ -81,18 +80,17 @@ ProcessPrmModules (
}
*PrmAcpiDescriptionTable = NULL;
- PlatformGuid = (EFI_GUID *) PcdGetPtr (PcdPrmPlatformGuid);
//
- // The platform should set PcdPrmPlatformGuid to a non-zero value
+ // The platform DSC GUID must be set to a non-zero value
//
- if (CompareGuid (PlatformGuid, &gZeroGuid)) {
+ if (CompareGuid (&gEdkiiDscPlatformGuid, &gZeroGuid)) {
DEBUG ((
DEBUG_ERROR,
- " %a %a: PcdPrmPlatformGuid must be set to a unique value in the platform DSC file.\n",
+ " %a %a: The Platform GUID in the DSC file must be set to a unique non-zero value.\n",
_DBGMSGID_,
__FUNCTION__
));
- ASSERT (!CompareGuid (PlatformGuid, &gZeroGuid));
+ ASSERT (!CompareGuid (&gEdkiiDscPlatformGuid, &gZeroGuid));
}
DEBUG ((DEBUG_INFO, " %a %a: %d total PRM modules to process.\n", _DBGMSGID_, __FUNCTION__, mPrmModuleCount));
@@ -118,7 +116,7 @@ ProcessPrmModules (
PrmAcpiTable->Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
PrmAcpiTable->Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
PrmAcpiTable->Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
- CopyGuid (&PrmAcpiTable->PrmPlatformGuid, PlatformGuid);
+ CopyGuid (&PrmAcpiTable->PrmPlatformGuid, &gEdkiiDscPlatformGuid);
PrmAcpiTable->PrmModuleInfoOffset = OFFSET_OF (PRM_ACPI_DESCRIPTION_TABLE, PrmModuleInfoStructure);
PrmAcpiTable->PrmModuleInfoCount = (UINT32) mPrmModuleCount;
diff --git a/PrmPkg/Include/PrmExportDescriptor.h b/PrmPkg/Include/PrmExportDescriptor.h
index fc313fd1acc7..76b67a05458a 100644
--- a/PrmPkg/Include/PrmExportDescriptor.h
+++ b/PrmPkg/Include/PrmExportDescriptor.h
@@ -30,6 +30,7 @@ typedef struct {
UINT64 Signature;
UINT16 Revision;
UINT16 NumberPrmHandlers;
+ GUID PlatformGuid;
GUID ModuleGuid;
} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;
@@ -98,6 +99,7 @@ typedef struct {
PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE, \
PRM_MODULE_EXPORT_REVISION, \
VA_ARG_COUNT(__VA_ARGS__), \
+ EDKII_DSC_PLATFORM_GUID, \
EFI_CALLER_ID_GUID \
}, \
{ __VA_ARGS__ } \
diff --git a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
index 7efefdae960f..26e7cc169897 100644
--- a/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
+++ b/PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
@@ -52,7 +52,6 @@ [Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## CONSUMES
- gPrmPkgTokenSpaceGuid.PcdPrmPlatformGuid ## CONSUMES
[Protocols]
gEfiAcpiTableProtocolGuid
diff --git a/PrmPkg/PrmPkg.dec b/PrmPkg/PrmPkg.dec
index 6753ac624444..94888d1c70a4 100644
--- a/PrmPkg/PrmPkg.dec
+++ b/PrmPkg/PrmPkg.dec
@@ -65,13 +65,3 @@ [PcdsFixedAtBuild]
# report PRM handler execution time in the application. If such a TimerLib
# instance is not available, set this PCD to FALSE in the package DSC file.
gPrmPkgTokenSpaceGuid.PcdPrmInfoPrintHandlerExecutionTime|TRUE|BOOLEAN|0x00000003
-
- ## PRM Platform GUID
- #
- # Uniquely identifies a specific platform targeted for PRM module updates. Each
- # platform MUST provide a new GUID. This GUID is checked against the platform
- # GUID in the PRM module export descriptor during PRM runtime updates to determine
- # if a given PRM module update is valid for a given system. Even if PRM runtime
- # updates are not planned for a given platform, this value should still be given
- # a unique value in the platform DSC.
- gPrmPkgTokenSpaceGuid.PcdPrmPlatformGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}|VOID*|0x00000004
diff --git a/PrmPkg/Readme.md b/PrmPkg/Readme.md
index f340eeb64258..4aec5982af54 100644
--- a/PrmPkg/Readme.md
+++ b/PrmPkg/Readme.md
@@ -13,6 +13,10 @@ to be leveraged by platform firmware with minimal overhead to integrate PRM func
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.
+> **Use recent edk2/master** - This code makes use of a very recent change in edk2 BaseTools. Specifically, commit
+[b65afdd](https://github.com/tianocore/edk2/commit/b65afdde74d6c1fac1cdbd2efdad23ba26295808). Ensure you have that
+change to build the code in this repo as-is.
+
> By default, the build makes use of a new ACPI OperationRegion type specifically introduced for PRM called
`PlatformRtMechanism`. Support for this OperationRegion is planned for the next release of the ACPI specification.
However, support for `PlatformRtMechanism` is already included in the iASL Compiler/Disassembler for early prototyping
@@ -100,14 +104,21 @@ The following list are the currently defined build flags (if any) that may be pa
### PRM Platform GUID
**IMPORTANT**
-A configuration item that requires user attention is the PRM platform GUID. Each platform that uses PRM must be
-uniquely identifiable so that various instances of a PRM module can target the correct platform in PRM module updates.
+PRM has a concept of a "Platform GUID" which associates a specific platform with a set of PRM modules built for
+that platform. This GUID is used to ensure system compatibility for a given collection of PRM modules.
-To apply a unique platform GUID set the following PCD to a unique value in your platform DSC file.
- ``gPrmPkgTokenSpaceGuid.PcdPrmPlatformGuid``
+Therefore, each PRM module must only target a single platform and each platform must have a unique GUID. Even if a
+PRM module is unchanged between two different platforms now, there is no guarantee that will remain the case so always
+assign a unique Platform GUID for each platform.
-The default value assigned in [PrmPkg.dec](PrmPkg/PrmPkg.dec) is zero. By design, this is an invalid value that will
-cause an ASSERT if it is not updated.
+The PRM Platform GUID is primarily used during PRM module runtime updates in the OS to ensure that the Platform GUID
+in the system's ACPI table (PRMT) matches the Platform GUID of the module requested for update. Even if runtime
+updates are not a planned feature for a given platform, still assign a unique Platform GUID for binary module
+identification (the Platform GUID is in the module's export descriptor) and to ensure such updates can be seamlessly
+supported in the future if needed.
+
+In the `PrmPkg` implementation, the Platform GUID is automatically derived from the PLATFORM_GUID in the DSC file of
+the package being built.
## Overview
At a high-level, PRM can be viewed from three levels of granularity:
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 36/41] PrmPkg/Samples: Remove PrmSampleMemoryAllocationModule
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (34 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 35/41] PrmPkg: Replace PcdPrmPlatformGuid with EDKII_DSC_PLATFORM_GUID Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 37/41] PrmPkg/Samples: Remove PrmSamplePrintModule Michael Kubacki
` (4 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Removes PrmSampleMemoryAllocationModule since the module depends
upon the deprecated concept of OS services.
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/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.c | 115 --------------------
PrmPkg/PrmPkg.dsc | 8 --
PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf | 43 --------
3 files changed, 166 deletions(-)
diff --git a/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.c b/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.c
deleted file mode 100644
index f1245664ab9c..000000000000
--- a/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/** @file
-
- A sample PRM Module implementation. This PRM Module provides 3 PRM handlers that simply take a DEBUG print
- function from the OS and invoke it with a debug message internal the PRM handler.
-
- Copyright (c) Microsoft Corporation
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <PrmModule.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-
-//
-// PRM Handler GUIDs
-//
-
-// {149a5cb3-6a9c-403f-940a-156abf63938a}
-#define PRM_HANDLER_1_GUID {0x149a5cb3, 0x6a9c, 0x403f, {0x94, 0x0a, 0x15, 0x6a, 0xbf, 0x63, 0x93, 0x8a}}
-
-// Note: If the signature size is modified, the PRM Handler test code in this module needs to be updated.
-#define MEMORY_ALLOCATION_TEST_DATA_SIGNATURE SIGNATURE_32('T','E','S','T')
-#define MEMORY_ALLOCATION_TEST_DATA_SIZE sizeof(UINT32)
-#define MEMORY_ALLOCATION_TEST_DATA_BUFFER_SIZE 256
-
-/**
- A sample Platform Runtime Mechanism (PRM) handler.
-
- This sample handler currently uses the OS_SERVICES to write a debug message
- indicating this is PRM handler 1.
-
- @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
-PrmHandler1 (
- IN VOID *ParameterBuffer,
- IN PRM_CONTEXT_BUFFER *ContextBUffer
- )
-{
- EFI_STATUS Status;
- UINTN Index;
- VOID *NonPagedPool;
- CHAR8 DebugMessage[256];
-
- if (OsServices == NULL || OsServices->DebugPrint == NULL || OsServices->AllocateMemory == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- OsServices->DebugPrint ("Memory Allocation PrmHandler1 entry.\n");
- OsServices->DebugPrint (" Requesting allocation of a 256 byte non-paged pool...\n");
-
- NonPagedPool = NULL;
- NonPagedPool = OsServices->AllocateMemory (MEMORY_ALLOCATION_TEST_DATA_BUFFER_SIZE, FALSE);
- if (NonPagedPool == NULL) {
- OsServices->DebugPrint (" NULL was returned from AllocateMemory()...\n");
- return EFI_OUT_OF_RESOURCES;
- }
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " Buffer address returned from AllocateMemory() = 0x%016lx.\n",
- (UINTN) NonPagedPool
- );
- OsServices->DebugPrint (&DebugMessage[0]);
-
- // Write the test data
- OsServices->DebugPrint (" Beginning memory buffer write and read back test...\n");
- SetMem32 (NonPagedPool, MEMORY_ALLOCATION_TEST_DATA_BUFFER_SIZE, MEMORY_ALLOCATION_TEST_DATA_SIGNATURE);
-
- // Read back and verify the test data is valid
- for (Index = 0, Status = EFI_SUCCESS; Index < (MEMORY_ALLOCATION_TEST_DATA_BUFFER_SIZE / MEMORY_ALLOCATION_TEST_DATA_SIZE); Index++) {
- if (((UINT32 *) NonPagedPool)[Index] != MEMORY_ALLOCATION_TEST_DATA_SIGNATURE) {
- Status = EFI_DEVICE_ERROR;
- break;
- }
- }
- if (EFI_ERROR (Status)) {
- OsServices->DebugPrint (" Memory write & read test failed.\n");
- } else {
- OsServices->DebugPrint (" Memory write & read test passed.\n");
- }
-
- OsServices->DebugPrint ("Memory Allocation PrmHandler1 exit.\n");
-
- return EFI_SUCCESS;
-}
-
-//
-// Register the PRM export information for this PRM Module
-//
-PRM_MODULE_EXPORT (
- PRM_HANDLER_EXPORT_ENTRY (PRM_HANDLER_1_GUID, PrmHandler1)
- );
-
-EFI_STATUS
-EFIAPI
-PrmSampleMemoryAllocationModuleInit (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- return EFI_SUCCESS;
-}
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
index 911158302404..c6e5a151eeca 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -141,14 +141,6 @@ [Components]
#
$(PLATFORM_PACKAGE)/Application/PrmInfo/PrmInfo.inf
- #
- # The SampleMemoryAllocationModule was used during a time in the POC when the OS
- # provided memory allocation services. This module was successful in using those services.
- # Since OS services have been removed (aside from debug prints), this module is no longer
- # relevant but kept around for archival purposes.
- #
- #$(PLATFORM_PACKAGE)/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf
-
[BuildOptions]
# Force deprecated interfaces off
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf b/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf
deleted file mode 100644
index 06be8f40f4ec..000000000000
--- a/PrmPkg/Samples/PrmSampleMemoryAllocationModule/PrmSampleMemoryAllocationModule.inf
+++ /dev/null
@@ -1,43 +0,0 @@
-## @file
-# Sample PRM Driver
-#
-# This driver simply uses an OS-provided debug message print service to write
-# a debug message. Three PRM handlers are provided that each print a unique
-# debug message.
-#
-# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-# Copyright (c) Microsoft Corporation
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = PrmSampleMemoryAllocationModule
- FILE_GUID = C6B3E74A-12E3-4364-8FB4-8C8B34DD153B
- MODULE_TYPE = DXE_RUNTIME_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = PrmSampleMemoryAllocationModuleInit
-
-[Sources]
- PrmSampleMemoryAllocationModule.c
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- PrmPkg/PrmPkg.dec
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- PrintLib
- UefiDriverEntryPoint
- UefiLib
-
-[Depex]
- TRUE
-
-[BuildOptions.common]
- MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE /VERSION:1.0
- MSFT:*_*_*_GENFW_FLAGS = --keepoptionalheader
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 37/41] PrmPkg/Samples: Remove PrmSamplePrintModule
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (35 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 36/41] PrmPkg/Samples: Remove PrmSampleMemoryAllocationModule Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 38/41] PrmPkg: Remove the concept of OS services Michael Kubacki
` (3 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
This sample module is removed since it directly depends on OS
services which are no longer supported as of the current PRM
design.
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/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c | 157 --------------------
PrmPkg/PrmPkg.dsc | 1 -
PrmPkg/PrmSsdtInstallDxe/Prm.asl | 5 -
PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf | 41 -----
PrmPkg/Samples/Readme.md | 73 +--------
5 files changed, 1 insertion(+), 276 deletions(-)
diff --git a/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c
deleted file mode 100644
index 85e8eb28a231..000000000000
--- a/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/** @file
-
- A sample PRM Module implementation. This PRM Module provides 3 PRM handlers that simply take a DEBUG print
- function from the OS and invoke it with a debug message internal the PRM handler.
-
- Copyright (c) Microsoft Corporation
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <PrmModule.h>
-
-#include <Library/BaseLib.h>
-#include <Library/UefiLib.h>
-
-//
-// PRM Handler GUIDs
-//
-
-// {d5f2ad5f-a347-4d3e-87bc-c2ce63029cc8}
-#define PRM_HANDLER_1_GUID {0xd5f2ad5f, 0xa347, 0x4d3e, {0x87, 0xbc, 0xc2, 0xce, 0x63, 0x02, 0x9c, 0xc8}}
-
-// {a9e7adc3-8cd0-429a-8915-10946ebde318}
-#define PRM_HANDLER_2_GUID {0xa9e7adc3, 0x8cd0, 0x429a, {0x89, 0x15, 0x10, 0x94, 0x6e, 0xbd, 0xe3, 0x18}}
-
-// {b688c214-4081-4eeb-8d26-1eb5a3bcf11a}
-#define PRM_HANDLER_N_GUID {0xb688c214, 0x4081, 0x4eeb, {0x8d, 0x26, 0x1e, 0xb5, 0xa3, 0xbc, 0xf1, 0x1a}}
-
-/**
- A sample Platform Runtime Mechanism (PRM) handler.
-
- This sample handler currently uses the OS_SERVICES to write a debug message
- indicating this is PRM handler 1.
-
- @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
-PrmHandler1 (
- IN VOID *ParameterBuffer,
- IN PRM_CONTEXT_BUFFER *ContextBUffer
- )
-{
- PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
-
- if (ParameterBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
- OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
- if (OsServiceDebugPrint == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- OsServiceDebugPrint ("PRM1 handler sample message!\n");
-
- return EFI_SUCCESS;
-}
-
-/**
- A sample Platform Runtime Mechanism (PRM) handler.
-
- This sample handler currently uses the OS_SERVICES to write a debug message
- indicating this is PRM handler 2.
-
- @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
-PrmHandler2 (
- IN VOID *ParameterBuffer,
- IN PRM_CONTEXT_BUFFER *ContextBUffer
- )
-{
- PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
-
- if (ParameterBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
- OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
- if (OsServiceDebugPrint == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- OsServiceDebugPrint ("PRM2 handler sample message!\n");
-
- return EFI_SUCCESS;
-}
-
-/**
- A sample Platform Runtime Mechanism (PRM) handler.
-
- This sample handler currently uses the OS_SERVICES to write a debug message
- indicating this is PRM handler N.
-
- @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
-PrmHandlerN (
- IN VOID *ParameterBuffer,
- IN PRM_CONTEXT_BUFFER *ContextBUffer
- )
-{
- PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
-
- if (ParameterBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
- OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
- if (OsServiceDebugPrint == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- OsServiceDebugPrint ("PRMN handler sample message!\n");
-
- return EFI_SUCCESS;
-}
-
-//
-// 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)
- );
-
-EFI_STATUS
-EFIAPI
-PrmSamplePrintModuleInit (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- return EFI_SUCCESS;
-}
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
index c6e5a151eeca..68768c87f276 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -128,7 +128,6 @@ [Components]
#
# PRM Sample Modules
#
- $(PLATFORM_PACKAGE)/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
$(PLATFORM_PACKAGE)/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf
$(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf {
<LibraryClasses>
diff --git a/PrmPkg/PrmSsdtInstallDxe/Prm.asl b/PrmPkg/PrmSsdtInstallDxe/Prm.asl
index 20a6fef9be7b..e34336b4eee6 100644
--- a/PrmPkg/PrmSsdtInstallDxe/Prm.asl
+++ b/PrmPkg/PrmSsdtInstallDxe/Prm.asl
@@ -25,11 +25,6 @@ DefinitionBlock (
Name (_CID, "80860223")
Name (_DDN, "PRM Test Device")
- // PrmSamplePrintModule handler GUIDs
- Name (BUF1, ToUUID("d5f2ad5f-a347-4d3e-87bc-c2ce63029cc8"))
- Name (BUF2, ToUUID("a9e7adc3-8cd0-429a-8915-10946ebde318"))
- Name (BUFN, ToUUID("b688c214-4081-4eeb-8d26-1eb5a3bcf11a"))
-
//PRM operation region format
OperationRegion (PRMR, PlatformRtMechanism, 0, 1)
Field (PRMR, BufferAcc, NoLock, Preserve) //Make it ByteAcc for parameter validation
diff --git a/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf b/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
deleted file mode 100644
index 7ac291bc6e8a..000000000000
--- a/PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf
+++ /dev/null
@@ -1,41 +0,0 @@
-## @file
-# Sample PRM Driver
-#
-# This driver simply uses an OS-provided debug message print service to write
-# a debug message. Three PRM handlers are provided that each print a unique
-# debug message.
-#
-# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-# Copyright (c) Microsoft Corporation
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = PrmSamplePrintModule
- FILE_GUID = 1652B3C2-A7A1-46AC-AF93-DD6DEE446669
- MODULE_TYPE = DXE_RUNTIME_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = PrmSamplePrintModuleInit
-
-[Sources]
- PrmSamplePrintModule.c
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- PrmPkg/PrmPkg.dec
-
-[LibraryClasses]
- BaseLib
- UefiDriverEntryPoint
- UefiLib
-
-[Depex]
- TRUE
-
-[BuildOptions.common]
- MSFT:*_*_*_DLINK_FLAGS = /DLL /SUBSYSTEM:CONSOLE /VERSION:1.0
- MSFT:*_*_*_GENFW_FLAGS = --keepoptionalheader
diff --git a/PrmPkg/Samples/Readme.md b/PrmPkg/Samples/Readme.md
index 4926be243018..d9f06f8b87de 100644
--- a/PrmPkg/Samples/Readme.md
+++ b/PrmPkg/Samples/Readme.md
@@ -21,7 +21,7 @@ Note that the build command does provide the option to build a specific module i
faster build time. If you would like to just build a single PRM module that can be done by specifying the path to
the module INF file with the "-m" argument to `build`. For example, this command builds 32-bit and 64-bit binaries
with Visual Studio 2019: \
-``build -p PrmPkg/PrmPkg.dsc -m PrmPkg/Samples/PrmSamplePrintModule/PrmSamplePrintModule.inf -a IA32 -a X64 -t VS2019``
+``build -p PrmPkg/PrmPkg.dsc -m PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf -a IA32 -a X64 -t VS2019``
## PRM Sample Module User's Guide
@@ -33,77 +33,6 @@ It is recommended that all PRM authors write a similar set of documentation for
and interact with their PRM modules.
---
-### Module: PRM Sample Print Module
->* Name: `PrmSamplePrintModule`
->* GUID: `1652b3c2-a7a1-46ac-af93-dd6dee446669`
-> * Purpose:
-> * Simplest PRM module example
-> * Example of a PRM module with multiple PRM handlers
-
-**Handlers:**
-#### Handler: PRM Handler 1
-* Name: `PrmHandler1`
-* GUID: `d5f2ad5f-a347-4d3e-87bc-c2ce63029cc8`
-* Actions:
- * Use an OS-provided function pointer (pointer at the beginning of the parameter buffer) to write the message
- “PRM1 handler sample message!”
-
-* Parameter Buffer Required: Yes
-* Parameter Buffer Contents:
- ```c
- typedef struct {
-
- PRM_OS_SERVICE_DEBUG_PRINT *
-
- } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
- ```
-
-* Context Buffer Required: No
-
-* Runtime MMIO Range(s) Required: No
-
-#### Handler: PRM Handler 2
-* Name: `PrmHandler2`
-* GUID: `a9e7adc3-8cd0-429a-8915-10946ebde318`
-* Actions:
- * Use an OS-provided function pointer (pointer at the beginning of the parameter buffer) to write the message
- “PRM2 handler sample message!”
-
-* Parameter Buffer Required: Yes
-* Parameter Buffer Contents:
- ```c
- typedef struct {
-
- PRM_OS_SERVICE_DEBUG_PRINT *
-
- } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
- ```
-
-* Context Buffer Required: No
-
-* Runtime MMIO Range(s) Required: No
-
-#### Handler: PRM Handler N
-* Name: `PrmHandlerN`
-* GUID: `b688c214-4081-4eeb-8d26-1eb5a3bcf11a`
-* Actions:
- * Use an OS-provided function pointer (pointer at the beginning of the parameter buffer) to write the message
- “PRMN handler sample message!”
-
-* Parameter Buffer Required: Yes
-* Parameter Buffer Contents:
- ```c
- typedef struct {
-
- PRM_OS_SERVICE_DEBUG_PRINT *
-
- } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
- ```
-
-* Context Buffer Required: No
-
-* Runtime MMIO Range(s) Required: No
-
### Module: PRM Sample ACPI Parameter Buffer
>* Name: `PrmSampleAcpiParameterBufferModule`
>* GUID: `dc2a58a6-5927-4776-b995-d118a27335a2`
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 38/41] PrmPkg: Remove the concept of OS services
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (36 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 37/41] PrmPkg/Samples: Remove PrmSamplePrintModule Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-22 16:19 ` [PATCH v1 39/41] Readme.md: Add a link to PRM Specification Michael Kubacki
` (2 subsequent siblings)
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
OS services are no longer supported as of the current PRM design.
1. Removes OS services from PrmSampleHardwareAccessModule
2. Removes the PrmOsServices.h file
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/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c | 328 +-------------------
PrmPkg/Include/PrmModule.h | 1 -
PrmPkg/Include/PrmOsServices.h | 45 ---
PrmPkg/PrmPkg.dsc | 5 +-
PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf | 1 -
PrmPkg/Samples/Readme.md | 62 ----
6 files changed, 8 insertions(+), 434 deletions(-)
diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
index 35da1fcf5f17..14d1e56ab88a 100644
--- a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
+++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
@@ -12,7 +12,6 @@
#include <Library/BaseLib.h>
#include <Library/MtrrLib.h>
-#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include <Register/Intel/ArchitecturalMsr.h>
@@ -27,21 +26,12 @@
// {2120cd3c-848b-4d8f-abbb-4b74ce64ac89}
#define MSR_ACCESS_MICROCODE_SIGNATURE_PRM_HANDLER_GUID {0x2120cd3c, 0x848b, 0x4d8f, {0xab, 0xbb, 0x4b, 0x74, 0xce, 0x64, 0xac, 0x89}}
-// {5d28b4e7-3867-4aee-aa09-51fc282c3b22}
-#define MSR_PRINT_MICROCODE_SIGNATURE_PRM_HANDLER_GUID {0x5d28b4e7, 0x3867, 0x4aee, {0xaa, 0x09, 0x51, 0xfc, 0x28, 0x2c, 0x3b, 0x22}}
-
// {ea0935a7-506b-4159-bbbb-48deeecb6f58}
#define MSR_ACCESS_MTRR_DUMP_PRM_HANDLER_GUID {0xea0935a7, 0x506b, 0x4159, {0xbb, 0xbb, 0x48, 0xde, 0xee, 0xcb, 0x6f, 0x58}}
-// {4b64b702-4d2b-4dfe-ac5a-0b4110a2ca47}
-#define MSR_PRINT_MTRR_DUMP_PRM_HANDLER_GUID {0x4b64b702, 0x4d2b, 0x4dfe, {0xac, 0x5a, 0x0b, 0x41, 0x10, 0xa2, 0xca, 0x47}}
-
// {1bd1bda9-909a-4614-9699-25ec0c2783f7}
#define MMIO_ACCESS_HPET_PRM_HANDLER_GUID {0x1bd1bda9, 0x909a, 0x4614, {0x96, 0x99, 0x25, 0xec, 0x0c, 0x27, 0x83, 0xf7}}
-// {8a0efdde-78d0-45f0-aea0-c28245c7e1db}
-#define MMIO_PRINT_HPET_PRM_HANDLER_GUID {0x8a0efdde, 0x78d0, 0x45f0, {0xae, 0xa0, 0xc2, 0x82, 0x45, 0xc7, 0xe1, 0xdb}}
-
//
// BEGIN: MtrrLib internal library globals and function prototypes here for testing
//
@@ -133,27 +123,19 @@ MtrrLibApplyVariableMtrrs (
/**
Accesses MTRR values including architectural and variable MTRRs.
- If the optional OsServiceDebugPrint function pointer is provided that function is
- used to print the MTRR settings.
-
- @param[in] OsServiceDebugPrint A pointer to an OS-provided debug print function.
-
**/
VOID
EFIAPI
AccessAllMtrrs (
- IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint OPTIONAL
+ VOID
)
{
MTRR_SETTINGS LocalMtrrs;
MTRR_SETTINGS *Mtrrs;
- UINTN Index;
UINTN RangeCount;
UINT64 MtrrValidBitsMask;
UINT64 MtrrValidAddressMask;
UINT32 VariableMtrrCount;
- BOOLEAN ContainVariableMtrr;
- CHAR8 DebugMessage[256];
MTRR_MEMORY_RANGE Ranges[
MTRR_NUMBER_OF_FIXED_MTRR * sizeof (UINT64) + 2 * ARRAY_SIZE (Mtrrs->Variables.Mtrr) + 1
@@ -169,66 +151,6 @@ AccessAllMtrrs (
MtrrGetAllMtrrs (&LocalMtrrs);
Mtrrs = &LocalMtrrs;
- //
- // Dump RAW MTRR contents
- //
- if (OsServiceDebugPrint != NULL) {
- OsServiceDebugPrint (" MTRR Settings:\n");
- OsServiceDebugPrint (" =============\n");
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " MTRR Default Type: %016lx\n",
- Mtrrs->MtrrDefType
- );
- OsServiceDebugPrint (&DebugMessage[0]);
- }
-
- if (OsServiceDebugPrint != NULL) {
- for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " Fixed MTRR[%02d] : %016lx\n",
- Index,
- Mtrrs->Fixed.Mtrr[Index]
- );
- OsServiceDebugPrint (&DebugMessage[0]);
- }
-
- ContainVariableMtrr = FALSE;
- for (Index = 0; Index < VariableMtrrCount; Index++) {
- if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) {
- //
- // If mask is not valid, then do not display range
- //
- continue;
- }
- ContainVariableMtrr = TRUE;
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",
- Index,
- Mtrrs->Variables.Mtrr[Index].Base,
- Mtrrs->Variables.Mtrr[Index].Mask
- );
- OsServiceDebugPrint (&DebugMessage[0]);
- }
- if (!ContainVariableMtrr) {
- OsServiceDebugPrint (" Variable MTRR : None.\n");
- }
- OsServiceDebugPrint ("\n");
- }
-
- //
- // Dump MTRR setting in ranges
- //
- if (OsServiceDebugPrint != NULL) {
- OsServiceDebugPrint (" Memory Ranges:\n");
- OsServiceDebugPrint (" ====================================\n");
- }
MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
Ranges[0].BaseAddress = 0;
Ranges[0].Length = MtrrValidBitsMask + 1;
@@ -245,19 +167,6 @@ AccessAllMtrrs (
);
MtrrLibApplyFixedMtrrs (&Mtrrs->Fixed, Ranges, ARRAY_SIZE (Ranges), &RangeCount);
-
- if (OsServiceDebugPrint != NULL) {
- for (Index = 0; Index < RangeCount; Index++) {
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " %a:%016lx-%016lx\n",
- mMtrrMemoryCacheTypeShortName[Ranges[Index].Type],
- Ranges[Index].BaseAddress, Ranges[Index].BaseAddress + Ranges[Index].Length - 1
- );
- OsServiceDebugPrint (&DebugMessage[0]);
- }
- }
}
/**
@@ -300,104 +209,15 @@ HpetRead (
/**
Accesses HPET configuration information.
- If the optional OsServiceDebugPrint function pointer is provided that function is
- used to print HPET settings.
-
- @param[in] OsServiceDebugPrint A pointer to an OS-provided debug print function
-
**/
VOID
EFIAPI
AccessHpetConfiguration (
- IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint
+ VOID
)
{
- UINTN TimerIndex;
- HPET_GENERAL_CAPABILITIES_ID_REGISTER HpetGeneralCapabilities;
- HPET_GENERAL_CONFIGURATION_REGISTER HpetGeneralConfiguration;
- CHAR8 DebugMessage[256];
-
- HpetGeneralCapabilities.Uint64 = HpetRead (HPET_GENERAL_CAPABILITIES_ID_OFFSET);
- HpetGeneralConfiguration.Uint64 = HpetRead (HPET_GENERAL_CONFIGURATION_OFFSET);
-
- if (OsServiceDebugPrint != NULL) {
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET Base Address = 0x%08x\n",
- HPET_BASE_ADDRESS
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET_GENERAL_CAPABILITIES_ID = 0x%016lx\n",
- HpetGeneralCapabilities
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET_GENERAL_CONFIGURATION = 0x%016lx\n",
- HpetGeneralConfiguration.Uint64
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET_GENERAL_INTERRUPT_STATUS = 0x%016lx\n",
- HpetRead (HPET_GENERAL_INTERRUPT_STATUS_OFFSET)
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET_MAIN_COUNTER = 0x%016lx\n",
- HpetRead (HPET_MAIN_COUNTER_OFFSET)
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET Main Counter Period = %d (fs)\n",
- HpetGeneralCapabilities.Bits.CounterClockPeriod
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- for (TimerIndex = 0; TimerIndex <= HpetGeneralCapabilities.Bits.NumberOfTimers; TimerIndex++) {
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET_TIMER%d_CONFIGURATION = 0x%016lx\n",
- TimerIndex,
- HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET_TIMER%d_COMPARATOR = 0x%016lx\n",
- TimerIndex,
- HpetRead (HPET_TIMER_COMPARATOR_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " HPET_TIMER%d_MSI_ROUTE = 0x%016lx\n",
- TimerIndex,
- HpetRead (HPET_TIMER_MSI_ROUTE_OFFSET + TimerIndex * HPET_TIMER_STRIDE)
- );
- OsServiceDebugPrint (&DebugMessage[0]);
- }
- }
+ HpetRead (HPET_GENERAL_CAPABILITIES_ID_OFFSET);
+ HpetRead (HPET_GENERAL_CONFIGURATION_OFFSET);
}
/**
@@ -419,34 +239,6 @@ GetMicrocodeSignature (
return BiosSignIdMsr.Bits.MicrocodeUpdateSignature;
}
-/**
- Prints the microcode update signature as read from architectural MSR 0x8B.
-
-**/
-VOID
-EFIAPI
-PrintMicrocodeUpdateSignature (
- IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint
- )
-{
- UINT32 MicrocodeSignature;
- CHAR8 DebugMessage[256];
-
- if (OsServiceDebugPrint == NULL) {
- return;
- }
-
- MicrocodeSignature = GetMicrocodeSignature ();
-
- AsciiSPrint (
- &DebugMessage[0],
- ARRAY_SIZE (DebugMessage),
- " Signature read = 0x%x.\n",
- MicrocodeSignature
- );
- OsServiceDebugPrint (&DebugMessage[0]);
-}
-
/**
A sample Platform Runtime Mechanism (PRM) handler.
@@ -473,40 +265,6 @@ PRM_HANDLER_EXPORT (MsrAccessMicrocodeSignaturePrmHandler)
return EFI_SUCCESS;
}
-/**
- A sample Platform Runtime Mechanism (PRM) handler.
-
- This sample handler attempts to read the microcode update signature MSR and print the result to a debug message.
-
- @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.
-
-**/
-PRM_HANDLER_EXPORT (MsrPrintMicrocodeSignaturePrmHandler)
-{
- PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
-
- if (ParameterBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- // The OS debug print service is assumed to be at the beginning of ParameterBuffer
- OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
- if (OsServiceDebugPrint == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- OsServiceDebugPrint ("Hardware Access MsrAccessMicrocodeSignaturePrmHandler entry.\n");
- OsServiceDebugPrint (" Attempting to read the Microcode Update Signature MSR (0x8B)...\n");
- PrintMicrocodeUpdateSignature (OsServiceDebugPrint);
- OsServiceDebugPrint ("Hardware Access MsrAccessMicrocodeSignaturePrmHandler exit.\n");
-
- return EFI_SUCCESS;
-}
-
/**
A sample Platform Runtime Mechanism (PRM) handler.
@@ -521,46 +279,11 @@ PRM_HANDLER_EXPORT (MsrPrintMicrocodeSignaturePrmHandler)
**/
PRM_HANDLER_EXPORT (MsrAccessMtrrDumpPrmHandler)
{
- AccessAllMtrrs (NULL);
+ AccessAllMtrrs ();
return EFI_SUCCESS;
}
-/**
- A sample Platform Runtime Mechanism (PRM) handler.
-
- This sample handler attempts to read the current MTRR settings and print the result to a debug message.
-
- @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.
-
-**/
-PRM_HANDLER_EXPORT (MsrPrintMtrrDumpPrmHandler)
-{
- PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
-
- if (ParameterBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- // In the POC, the OS debug print service is assumed to be at the beginning of ParameterBuffer
- OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
- if (OsServiceDebugPrint == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- OsServiceDebugPrint ("Hardware Access MsrAccessMtrrDumpPrmHandler entry.\n");
- OsServiceDebugPrint (" Attempting to dump MTRR values:\n");
- AccessAllMtrrs (OsServiceDebugPrint);
- OsServiceDebugPrint ("Hardware Access MsrAccessMtrrDumpPrmHandler exit.\n");
-
- return EFI_SUCCESS;
-}
-
-
/**
A sample Platform Runtime Mechanism (PRM) handler.
@@ -575,41 +298,7 @@ PRM_HANDLER_EXPORT (MsrPrintMtrrDumpPrmHandler)
**/
PRM_HANDLER_EXPORT (MmioAccessHpetPrmHandler)
{
- AccessHpetConfiguration (NULL);
-
- return EFI_SUCCESS;
-}
-
-/**
- A sample Platform Runtime Mechanism (PRM) handler.
-
- This sample handler attempts to read from a HPET MMIO resource and print the result to a debug message.
-
- @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.
-
-**/
-PRM_HANDLER_EXPORT (MmioPrintHpetPrmHandler)
-{
- PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint;
-
- if (ParameterBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- // An OS debug print service is assumed to be at the beginning of ParameterBuffer
- OsServiceDebugPrint = *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuffer);
- if (OsServiceDebugPrint == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- OsServiceDebugPrint ("Hardware Access MmioPrintHpetPrmHandler entry.\n");
- OsServiceDebugPrint (" Attempting to read HPET configuration...\n");
- AccessHpetConfiguration (OsServiceDebugPrint);
- OsServiceDebugPrint ("Hardware Access MmioPrintHpetPrmHandler exit.\n");
+ AccessHpetConfiguration ();
return EFI_SUCCESS;
}
@@ -620,10 +309,7 @@ PRM_HANDLER_EXPORT (MmioPrintHpetPrmHandler)
PRM_MODULE_EXPORT (
PRM_HANDLER_EXPORT_ENTRY (MSR_ACCESS_MICROCODE_SIGNATURE_PRM_HANDLER_GUID, MsrAccessMicrocodeSignaturePrmHandler),
PRM_HANDLER_EXPORT_ENTRY (MSR_ACCESS_MTRR_DUMP_PRM_HANDLER_GUID, MsrAccessMtrrDumpPrmHandler),
- PRM_HANDLER_EXPORT_ENTRY (MMIO_ACCESS_HPET_PRM_HANDLER_GUID, MmioAccessHpetPrmHandler),
- PRM_HANDLER_EXPORT_ENTRY (MSR_PRINT_MICROCODE_SIGNATURE_PRM_HANDLER_GUID, MsrPrintMicrocodeSignaturePrmHandler),
- PRM_HANDLER_EXPORT_ENTRY (MSR_PRINT_MTRR_DUMP_PRM_HANDLER_GUID, MsrPrintMtrrDumpPrmHandler),
- PRM_HANDLER_EXPORT_ENTRY (MMIO_PRINT_HPET_PRM_HANDLER_GUID, MmioPrintHpetPrmHandler)
+ PRM_HANDLER_EXPORT_ENTRY (MMIO_ACCESS_HPET_PRM_HANDLER_GUID, MmioAccessHpetPrmHandler)
);
/**
diff --git a/PrmPkg/Include/PrmModule.h b/PrmPkg/Include/PrmModule.h
index d7047d8eec58..1369adda1aa7 100644
--- a/PrmPkg/Include/PrmModule.h
+++ b/PrmPkg/Include/PrmModule.h
@@ -15,7 +15,6 @@
#include <PrmDataBuffer.h>
#include <PrmExportDescriptor.h>
#include <PrmMmio.h>
-#include <PrmOsServices.h>
/**
Macro that provides a condensed form of a PRM Handler.
diff --git a/PrmPkg/Include/PrmOsServices.h b/PrmPkg/Include/PrmOsServices.h
deleted file mode 100644
index 62dfa0018787..000000000000
--- a/PrmPkg/Include/PrmOsServices.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/** @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 <Uefi.h>
-
-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.dsc b/PrmPkg/PrmPkg.dsc
index 68768c87f276..d10aa3d547ce 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -129,10 +129,7 @@ [Components]
# PRM Sample Modules
#
$(PLATFORM_PACKAGE)/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiParameterBufferModule.inf
- $(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf {
- <LibraryClasses>
- DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
- }
+ $(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf
$(PLATFORM_PACKAGE)/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule.inf
#
diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf
index 369d1eb1e86d..46d4a88185a9 100644
--- a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf
+++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf
@@ -32,7 +32,6 @@ [Packages]
[LibraryClasses]
BaseLib
MtrrLib
- PrintLib
UefiDriverEntryPoint
UefiLib
diff --git a/PrmPkg/Samples/Readme.md b/PrmPkg/Samples/Readme.md
index d9f06f8b87de..590b81c349b4 100644
--- a/PrmPkg/Samples/Readme.md
+++ b/PrmPkg/Samples/Readme.md
@@ -128,65 +128,3 @@ and interact with their PRM modules.
* Runtime MMIO Range(s) Required: Yes
* Physical Base Address: 0xFED00000
* Length: 0x1000
-
-#### Handler: MSR Print Microcode Signature PRM Handler
-* Name: `MsrPrintMicrocodeSignaturePrmHandler`
-* GUID: `5d28b4e7-3867-4aee-aa09-51fc282c3b22`
-* Actions:
- * Use the provided print function to print the loaded microcode signature at MSR 0x8B.
-
-* Parameter Buffer Required: Yes
-* Parameter Buffer Contents:
- ```c
- typedef struct {
-
- PRM_OS_SERVICE_DEBUG_PRINT *
-
- } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
- ```
-
-* Context Buffer Required: No
-
-* Runtime MMIO Range(s) Required: No
-
-#### Handler: MSR Print MTRR Dump PRM Handler
-* Name: `MsrPrintMtrrDumpPrmHandler`
-* GUID: `4b64b702-4d2b-4dfe-ac5a-0b4110a2ca47`
-* Actions:
- * Use the provided print function to print the fixed and variable MTRR values using MSRs.
-
-* Parameter Buffer Required: Yes
-* Parameter Buffer Contents:
- ```c
- typedef struct {
-
- PRM_OS_SERVICE_DEBUG_PRINT *
-
- } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
- ```
-
-* Context Buffer Required: No
-
-* Runtime MMIO Range(s) Required: No
-
-#### Handler: HPET MMIO Print PRM Handler
-* Name: `MmioPrintHpetPrmHandler`
-* GUID: `8a0efdde-78d0-45f0-aea0-c28245c7e1db`
-* Actions:
- * Use the provided print function to print some HPET registers using MMIO at 0xFED00000.
-
-* Parameter Buffer Required: Yes
-* Parameter Buffer Contents:
- ```c
- typedef struct {
-
- PRM_OS_SERVICE_DEBUG_PRINT *
-
- } SAMPLE_OSDEBUGPRINT_PARAMETER_BUFFER;
- ```
-
-* Context Buffer Required: No
-
-* Runtime MMIO Range(s) Required: Yes
- * Physical Base Address: 0xFED00000
- * Length: 0x1000
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH v1 39/41] Readme.md: Add a link to PRM Specification
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (37 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 38/41] PrmPkg: Remove the concept of OS services Michael Kubacki
@ 2022-03-22 16:19 ` Michael Kubacki
2022-03-28 8:48 ` 回复: [edk2-devel] [PATCH v1 00/41] Add PrmPkg gaoliming
2022-03-29 16:28 ` Sinha, Ankit
40 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-22 16:19 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Kang Gao, Michael D Kinney, Michael Kubacki,
Leif Lindholm, Benjamin You, Liu Yun, Ankit Sinha, Nate DeSimone
From: Michael Kubacki <michael.kubacki@microsoft.com>
Adds a link to the PRM Specification now that it is available on uefi.org.
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 | 2 ++
1 file changed, 2 insertions(+)
diff --git a/PrmPkg/Readme.md b/PrmPkg/Readme.md
index 4aec5982af54..848f898ab6d3 100644
--- a/PrmPkg/Readme.md
+++ b/PrmPkg/Readme.md
@@ -5,6 +5,8 @@ code module that executes within the OS context. Moving this firmware to the OS
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.
+For 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).
+
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.
--
2.28.0.windows.1
^ permalink raw reply related [flat|nested] 44+ messages in thread
* 回复: [edk2-devel] [PATCH v1 00/41] Add PrmPkg
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (38 preceding siblings ...)
2022-03-22 16:19 ` [PATCH v1 39/41] Readme.md: Add a link to PRM Specification Michael Kubacki
@ 2022-03-28 8:48 ` gaoliming
2022-03-28 14:05 ` Michael Kubacki
2022-03-29 16:28 ` Sinha, Ankit
40 siblings, 1 reply; 44+ messages in thread
From: gaoliming @ 2022-03-28 8:48 UTC (permalink / raw)
To: devel, mikuback
Cc: 'Andrew Fish', 'Kang Gao',
'Michael D Kinney', 'Michael Kubacki',
'Leif Lindholm', 'Benjamin You',
'Liu Yun', 'Ankit Sinha', 'Nate DeSimone'
Michael:
Please also update Maintainers.txt to specify maintainer for new PrmPkg.
Thanks
Liming
> -----邮件原件-----
> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Michael
> Kubacki
> 发送时间: 2022年3月23日 0:19
> 收件人: devel@edk2.groups.io
> 抄送: 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>
> 主题: [edk2-devel] [PATCH v1 00/41] Add PrmPkg
>
> From: Michael Kubacki <michael.kubacki@microsoft.com>
>
> This patch series adds a new package called PrmPkg. An RFC was sent
> to the edk2 mailing list on January 28, 2022 detailing the proposal,
> see https://edk2.groups.io/g/devel/message/86181.
>
> Platform Runtime Mechanism (PRM) is a new firmware solution that has
> been developed in edk2-staging/PlatformRuntimeMechanism.
>
> This patch series has been organized to greatly condense the history
> from the edk2-staging branch but to preserve important decisions and
> changes in history that help establish context of changes and will
> serve as valuable references for future development.
>
> Interest in PRM has increased across various vendors and we believe
> it is beneficial to make the source code more widely available for
> the following reasons:
>
> 1. PRM specification adoption
> 2. Feature completeness
> 3. Overall validation coverage
> 4. Interest from the community and future collaboration
>
> The technical details of PRM are covered in the PRM Specification
> in addition to the Readme.md file located in the root of PrmPkg
> in this patch series.
>
> 1. PRM specification adoption
>
> Intel and Microsoft have worked together to standardize PRM in the
> ACPI Specification and the PRM Specification hosted on uefi.org.
>
> * ACPI 6.4 Specification:
> https://uefi.org/node/4149
>
> * PRM Specification:
>
> https://uefi.org/sites/default/files/resources/Platform%20Runtime%20Mech
> anism%20-%20with%20legal%20notice.pdf
>
> 2. Feature completeness
>
> PrmPkg implements the full firmware functionality described in the
> PRM Specification and there are no significant changes to
> functionality planned at this time.
>
> Though we are very much interested in evolving PRM based on
> feedback.
>
> 3. Overall validation coverage
>
> PrmPkg has been integrated and tested on client and server systems
> in addition to virtual platforms (OvmfPkg/QEMU).
>
> Platform integration is simple and a demonstration of this
> integration for OvmfPkg is available in the following branch:
> https://github.com/makubacki/edk2/tree/ovmf_prmpkg_integration
>
> The code has been built with:
> * MSFT VS2015, VS2017, and VS2019
> * GCC5 (see https://bugzilla.tianocore.org/show_bug.cgi?id=3802)
> * iASL compiler (20200528 - https://acpica.org/node/181)
>
> The Linux kernel currently includes the following PRM support:
> * _OSC PRM bit - allows FW to know determine the OS is
> PRM-capable and can redirect _DSM method from alternate
> triggers (such as SMI) to PRM.
> * PRM invocation via _DSM, includes PRM module and handler parsing
> from ACPI PRMT table, and also the PRM operation region handler
> for runtime PRM service invocation.
> * An OS configuration for PRM enabling, PRM support can be
> disabled during OS image build.
>
> Note that upstream Linux does not currently support the following:
> * Ability for the OS driver to call a PRM handler directly,
> it has to be via ACPI _DSM.
> * Run time update PRM module and handler via PE/COFF PRM image.
>
> This commit provides additional context of the changes in Linux:
> https://github.com/torvalds/linux/commit/cefc7ca46235f01d5233e3abd4b79
> 452af01d9e9
>
> Windows 11 (https://www.microsoft.com/software-download/windows11)
> and Windows Server 2022
> (https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the
> -wdk)
> include the PRM functionality noted above in addition to PRM direct
> call and PRM runtime updates.
>
> PRM has been tested on IA32, X64, and AARCH64 targets.
>
> 4. Interest from the community and future collaboration
>
> PRM has been presented at several industry conferences:
>
> * OSFC 2020 - "PRM: SMM Goes on a Diet"
> https://cfp.osfc.io/osfc2020/talk/MCJASB/
>
> * OCP Summit 2019 - "Case Study Alternatives for SMM Usage in
> Intel Platforms"
> https://www.youtube.com/watch?v=mu3DRLM1dPA
>
> In addition, Microsoft plans to publish the Windows PRM driver
> interface and a WDF sample driver that uses the interface to the
> Windows Driver Samples GitHub repository
> (https://github.com/microsoft/Windows-driver-samples).
>
> We believe a PrmPkg in edk2 can increase accessibility to PRM and
> ease collaboration.
>
> PrmPkg
> ------
> PrmPkg contains the common functionality needed to enable PRM on
> any system. It does not contain platform-specific code such as PRM
> modules (and by extension PRM handlers). Other than sample modules,
> PrmPkg will only contain code needed to provide PRM feature
> functionality as defined in the PRM Specification.
>
> PrmPkg is scoped to continue to only contain platform-agnostic
> functionality in the future.
>
> The proposed maintainers of PrmPkg are:
> * Michael Kubacki <mikuback@linux.microsoft.com>
> * Nate DeSimone <nathaniel.l.desimone@intel.com>
>
> The proposed reviewers of PrmPkg are:
> * Ankit Sinha <ankit.sinha@intel.com>
>
> 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>
>
> Liu (2):
> PrmPkg: Publish PRM operation region to support PRM ACPI _DSM
> invocation
> PrmPkg: Export major/minor version in PRM module PE COFF header
>
> Liu Yun Y (1):
> PrmPkg: Update PRM OpRegion
>
> Michael Kubacki (38):
> PrmPkg: Add package and include headers
> PrmPkg: Add PrmConfig protocol interface
> PrmPkg/PrmContextBufferLib: Add initial library instance
> PrmPkg/PrmConfigDxe: Add initial driver
> PrmPkg: Add initial PrmSamplePrintModule
> PrmPkg: Add initial PrmSampleMemoryAllocationModule
> PrmPkg: Add initial PrmSampleHardwareAccessModule
> PrmPkg: Add initial PrmSampleContextBufferModule
> PrmPkg: Add initial package DSC file
> Readme.md: Add initial content
> PrmPkg: Add ALLOCATE_CONTEXT_BUFFER_IN_FW build option
> PrmPkg: Enable variable growth for the PRM_MODULE_EXPORT macro
> PrmPkg: Add initial PrmSsdtInstallDxe module
> PrmPkg: Remove PRM Module Update Lock
> PrmPkg: Remove ALLOCATE_CONTEXT_BUFFER_IN_FW build flag
> PrmPkg/PrmContextBuffer.h: Add ACPI parameter support structures
> PrmPkg/PrmLoaderDxe: Add ACPI parameter buffer support
> PrmPkg/PrmSampleContextBufferModule: Remove OS debug print
> requirement
> PrmPkg/PrmSampleHardwareAccessModule: Add non-print PRM handlers
> PrmPkg/SampleAcpiParameterBufferModule: Add initial module
> PrmPkg/HardwareAccessModuleConfigLib: Add initial library
> PrmPkg/Samples/Readme.md: Add initial file
> PrmPkg: Refactor some PrmLoaderDxe functionality into libraries
> PrmPkg/Application/PrmInfo: Add initial application
> PrmPkg: Enforce stricter types
> PrmPkg/Test/PrmPkgHostTest.dsc: Add initial file
> PrmPkg/Test/UnitTest/Library: Add initial UEFI Boot Services test lib
> PrmPkg/Library/DxePrmContextBufferLib: Add host-based unit tests
> PrmPkg/DxePrmModuleDiscoveryLib: Add initial host-based unit tests
> PrmPkg: Add PlatformGuid
> Readme.md: Add iASL note and QEMU sample link
> PrmPkg: Replace PcdPrmPlatformGuid with EDKII_DSC_PLATFORM_GUID
> PrmPkg/Samples: Remove PrmSampleMemoryAllocationModule
> PrmPkg/Samples: Remove PrmSamplePrintModule
> PrmPkg: Remove the concept of OS services
> Readme.md: Add a link to PRM Specification
> PrmPkg: Changes for edk2 repo transition
> PrmPkg: Apply uncrustify changes
>
> PrmPkg/Application/PrmInfo/PrmInfo.c
> | 732 +++++++++
> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
> | 199 +++
>
> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibU
> nitTest.c
> | 649 ++++++++
> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
> | 386 +++++
>
> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscove
> ryLibUnitTest.c
> | 210 +++
> PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c
> | 417 +++++
> PrmPkg/PrmConfigDxe/PrmConfigDxe.c
> | 512 ++++++
> PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
> | 377 +++++
> PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
> | 110 ++
>
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiPa
> rameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.c
> | 127 ++
>
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiPa
> rameterBufferModule.c
> | 78 +
>
> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuffer
> ModuleConfigLib/DxeContextBufferModuleConfigLib.c
> | 218 +++
>
> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuffer
> Module.c
> | 84 +
>
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareA
> ccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c
> | 108 ++
>
> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareA
> ccessModule.c
> | 335 ++++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTest.c |
> 119 ++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestEventTimer.c |
> 180 +++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestImage.c |
> 163 ++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestMemory.c |
> 145 ++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestMisc.c |
> 198 +++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestProtocol.c |
> 1650 ++++++++++++++++++++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestTpl.c |
> 43 +
> .azurepipelines/templates/pr-gate-build-job.yml
> | 2 +-
> .pytool/CISettings.py
> | 1 +
> Maintainers.txt
> | 8 +
> PrmPkg/Application/PrmInfo/PrmInfo.h
> | 49 +
> PrmPkg/Application/PrmInfo/PrmInfo.inf
> | 66 +
> PrmPkg/Application/PrmInfo/PrmInfo.uni
> | 11 +
> PrmPkg/Application/PrmInfo/PrmInfoExtra.uni
> | 12 +
> PrmPkg/Application/PrmInfo/PrmInfoStrings.uni
> | 132 ++
> PrmPkg/Include/Library/PrmContextBufferLib.h
> | 99 ++
> PrmPkg/Include/Library/PrmModuleDiscoveryLib.h
> | 60 +
> PrmPkg/Include/Library/PrmPeCoffLib.h
> | 111 ++
> PrmPkg/Include/Prm.h
> | 46 +
> PrmPkg/Include/PrmContextBuffer.h
> | 171 ++
> PrmPkg/Include/PrmDataBuffer.h
> | 50 +
> PrmPkg/Include/PrmExportDescriptor.h
> | 109 ++
> PrmPkg/Include/PrmMmio.h
> | 45 +
> PrmPkg/Include/PrmModule.h
> | 47 +
> PrmPkg/Include/PrmModuleImageContext.h
> | 28 +
> PrmPkg/Include/Protocol/PrmConfig.h
> | 31 +
> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
> | 35 +
>
> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibU
> nitTestHost.inf
> | 46 +
> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf
> | 41 +
> PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
> | 39 +
>
> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscove
> ryLibUnitTestHost.inf
> | 39 +
> PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
> | 32 +
> PrmPkg/PrmConfigDxe/PrmConfigDxe.inf
> | 48 +
> PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
> | 96 ++
> PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
> | 61 +
> PrmPkg/PrmPkg.ci.yaml
> | 110 ++
> PrmPkg/PrmPkg.dec
> | 67 +
> PrmPkg/PrmPkg.dsc
> | 142 ++
> PrmPkg/PrmPkg.uni
> | 10 +
> PrmPkg/PrmSsdtInstallDxe/Prm.asl
> | 115 ++
> PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
> | 52 +
> PrmPkg/Readme.md
> | 264 ++++
>
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiPa
> rameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf
> | 39 +
>
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiPa
> rameterBufferModule.inf
> | 41 +
> PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h
> | 24 +
>
> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuffer
> ModuleConfigLib/DxeContextBufferModuleConfigLib.inf
> | 39 +
>
> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuffer
> Module.inf
> | 44 +
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
> | 108 ++
>
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareA
> ccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
> | 39 +
>
> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareA
> ccessModule.inf
> | 43 +
> PrmPkg/Samples/Readme.md
> | 146 ++
> PrmPkg/Test/PrmPkgHostTest.dsc
> | 39 +
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibTest.uni |
> 12 +
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTest.h |
> 1042 ++++++++++++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTest.inf |
> 46 +
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestProtocol.h |
> 120 ++
> 71 files changed, 11096 insertions(+), 1 deletion(-)
> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.c
> create mode 100644
> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
> create mode 100644
> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibU
> nitTest.c
> create mode 100644
> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
> create mode 100644
> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscove
> ryLibUnitTest.c
> create mode 100644 PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c
> create mode 100644 PrmPkg/PrmConfigDxe/PrmConfigDxe.c
> create mode 100644 PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
> create mode 100644 PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
> create mode 100644
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiPa
> rameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.c
> create mode 100644
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiPa
> rameterBufferModule.c
> create mode 100644
> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuffer
> ModuleConfigLib/DxeContextBufferModuleConfigLib.c
> create mode 100644
> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuffer
> Module.c
> create mode 100644
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareA
> ccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c
> create mode 100644
> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareA
> ccessModule.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTest.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestEventTimer.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestImage.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestMemory.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestMisc.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestProtocol.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestTpl.c
> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.h
> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.inf
> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.uni
> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfoExtra.uni
> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfoStrings.uni
> create mode 100644 PrmPkg/Include/Library/PrmContextBufferLib.h
> create mode 100644 PrmPkg/Include/Library/PrmModuleDiscoveryLib.h
> create mode 100644 PrmPkg/Include/Library/PrmPeCoffLib.h
> 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/PrmModuleImageContext.h
> create mode 100644 PrmPkg/Include/Protocol/PrmConfig.h
> create mode 100644
> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
> create mode 100644
> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibU
> nitTestHost.inf
> create mode 100644
> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf
> create mode 100644
> PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
> create mode 100644
> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscove
> ryLibUnitTestHost.inf
> create mode 100644 PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
> create mode 100644 PrmPkg/PrmConfigDxe/PrmConfigDxe.inf
> create mode 100644 PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
> create mode 100644 PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
> create mode 100644 PrmPkg/PrmPkg.ci.yaml
> create mode 100644 PrmPkg/PrmPkg.dec
> create mode 100644 PrmPkg/PrmPkg.dsc
> create mode 100644 PrmPkg/PrmPkg.uni
> create mode 100644 PrmPkg/PrmSsdtInstallDxe/Prm.asl
> create mode 100644 PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
> create mode 100644 PrmPkg/Readme.md
> create mode 100644
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiPa
> rameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf
> create mode 100644
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiPa
> rameterBufferModule.inf
> create mode 100644
> PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h
> create mode 100644
> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuffer
> ModuleConfigLib/DxeContextBufferModuleConfigLib.inf
> create mode 100644
> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuffer
> Module.inf
> create mode 100644
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
> create mode 100644
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareA
> ccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
> create mode 100644
> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareA
> ccessModule.inf
> create mode 100644 PrmPkg/Samples/Readme.md
> create mode 100644 PrmPkg/Test/PrmPkgHostTest.dsc
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibTest.uni
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTest.h
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTest.inf
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
> vicesTableLibUnitTestProtocol.h
>
> --
> 2.28.0.windows.1
>
>
>
> -=-=-=-=-=-=
> Groups.io Links: You receive all messages sent to this group.
> View/Reply Online (#87842): https://edk2.groups.io/g/devel/message/87842
> Mute This Topic: https://groups.io/mt/89955942/4905953
> Group Owner: devel+owner@edk2.groups.io
> Unsubscribe: https://edk2.groups.io/g/devel/unsub
> [gaoliming@byosoft.com.cn]
> -=-=-=-=-=-=
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: 回复: [edk2-devel] [PATCH v1 00/41] Add PrmPkg
2022-03-28 8:48 ` 回复: [edk2-devel] [PATCH v1 00/41] Add PrmPkg gaoliming
@ 2022-03-28 14:05 ` Michael Kubacki
0 siblings, 0 replies; 44+ messages in thread
From: Michael Kubacki @ 2022-03-28 14:05 UTC (permalink / raw)
To: devel, gaoliming
Cc: 'Andrew Fish', 'Kang Gao',
'Michael D Kinney', 'Michael Kubacki',
'Leif Lindholm', 'Benjamin You',
'Liu Yun', 'Ankit Sinha', 'Nate DeSimone'
Hi Liming,
I updated Maintainers.txt in patch [40/41].
https://edk2.groups.io/g/devel/message/87882
Due to the email limit on the mailing list the last few patches had to
be sent shortly after the initial series.
Regards,
Michael
On 3/28/2022 4:48 AM, gaoliming wrote:
> Michael:
> Please also update Maintainers.txt to specify maintainer for new PrmPkg.
>
> Thanks
> Liming
>> -----邮件原件-----
>> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Michael
>> Kubacki
>> 发送时间: 2022年3月23日 0:19
>> 收件人: devel@edk2.groups.io
>> 抄送: 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>
>> 主题: [edk2-devel] [PATCH v1 00/41] Add PrmPkg
>>
>> From: Michael Kubacki <michael.kubacki@microsoft.com>
>>
>> This patch series adds a new package called PrmPkg. An RFC was sent
>> to the edk2 mailing list on January 28, 2022 detailing the proposal,
>> see https://edk2.groups.io/g/devel/message/86181.
>>
>> Platform Runtime Mechanism (PRM) is a new firmware solution that has
>> been developed in edk2-staging/PlatformRuntimeMechanism.
>>
>> This patch series has been organized to greatly condense the history
>> from the edk2-staging branch but to preserve important decisions and
>> changes in history that help establish context of changes and will
>> serve as valuable references for future development.
>>
>> Interest in PRM has increased across various vendors and we believe
>> it is beneficial to make the source code more widely available for
>> the following reasons:
>>
>> 1. PRM specification adoption
>> 2. Feature completeness
>> 3. Overall validation coverage
>> 4. Interest from the community and future collaboration
>>
>> The technical details of PRM are covered in the PRM Specification
>> in addition to the Readme.md file located in the root of PrmPkg
>> in this patch series.
>>
>> 1. PRM specification adoption
>>
>> Intel and Microsoft have worked together to standardize PRM in the
>> ACPI Specification and the PRM Specification hosted on uefi.org.
>>
>> * ACPI 6.4 Specification:
>> https://uefi.org/node/4149
>>
>> * PRM Specification:
>>
>> https://uefi.org/sites/default/files/resources/Platform%20Runtime%20Mech
>> anism%20-%20with%20legal%20notice.pdf
>>
>> 2. Feature completeness
>>
>> PrmPkg implements the full firmware functionality described in the
>> PRM Specification and there are no significant changes to
>> functionality planned at this time.
>>
>> Though we are very much interested in evolving PRM based on
>> feedback.
>>
>> 3. Overall validation coverage
>>
>> PrmPkg has been integrated and tested on client and server systems
>> in addition to virtual platforms (OvmfPkg/QEMU).
>>
>> Platform integration is simple and a demonstration of this
>> integration for OvmfPkg is available in the following branch:
>> https://github.com/makubacki/edk2/tree/ovmf_prmpkg_integration
>>
>> The code has been built with:
>> * MSFT VS2015, VS2017, and VS2019
>> * GCC5 (see https://bugzilla.tianocore.org/show_bug.cgi?id=3802)
>> * iASL compiler (20200528 - https://acpica.org/node/181)
>>
>> The Linux kernel currently includes the following PRM support:
>> * _OSC PRM bit - allows FW to know determine the OS is
>> PRM-capable and can redirect _DSM method from alternate
>> triggers (such as SMI) to PRM.
>> * PRM invocation via _DSM, includes PRM module and handler parsing
>> from ACPI PRMT table, and also the PRM operation region handler
>> for runtime PRM service invocation.
>> * An OS configuration for PRM enabling, PRM support can be
>> disabled during OS image build.
>>
>> Note that upstream Linux does not currently support the following:
>> * Ability for the OS driver to call a PRM handler directly,
>> it has to be via ACPI _DSM.
>> * Run time update PRM module and handler via PE/COFF PRM image.
>>
>> This commit provides additional context of the changes in Linux:
>> https://github.com/torvalds/linux/commit/cefc7ca46235f01d5233e3abd4b79
>> 452af01d9e9
>>
>> Windows 11 (https://www.microsoft.com/software-download/windows11)
>> and Windows Server 2022
>> (https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the
>> -wdk)
>> include the PRM functionality noted above in addition to PRM direct
>> call and PRM runtime updates.
>>
>> PRM has been tested on IA32, X64, and AARCH64 targets.
>>
>> 4. Interest from the community and future collaboration
>>
>> PRM has been presented at several industry conferences:
>>
>> * OSFC 2020 - "PRM: SMM Goes on a Diet"
>> https://cfp.osfc.io/osfc2020/talk/MCJASB/
>>
>> * OCP Summit 2019 - "Case Study Alternatives for SMM Usage in
>> Intel Platforms"
>> https://www.youtube.com/watch?v=mu3DRLM1dPA
>>
>> In addition, Microsoft plans to publish the Windows PRM driver
>> interface and a WDF sample driver that uses the interface to the
>> Windows Driver Samples GitHub repository
>> (https://github.com/microsoft/Windows-driver-samples).
>>
>> We believe a PrmPkg in edk2 can increase accessibility to PRM and
>> ease collaboration.
>>
>> PrmPkg
>> ------
>> PrmPkg contains the common functionality needed to enable PRM on
>> any system. It does not contain platform-specific code such as PRM
>> modules (and by extension PRM handlers). Other than sample modules,
>> PrmPkg will only contain code needed to provide PRM feature
>> functionality as defined in the PRM Specification.
>>
>> PrmPkg is scoped to continue to only contain platform-agnostic
>> functionality in the future.
>>
>> The proposed maintainers of PrmPkg are:
>> * Michael Kubacki <mikuback@linux.microsoft.com>
>> * Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> The proposed reviewers of PrmPkg are:
>> * Ankit Sinha <ankit.sinha@intel.com>
>>
>> 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>
>>
>> Liu (2):
>> PrmPkg: Publish PRM operation region to support PRM ACPI _DSM
>> invocation
>> PrmPkg: Export major/minor version in PRM module PE COFF header
>>
>> Liu Yun Y (1):
>> PrmPkg: Update PRM OpRegion
>>
>> Michael Kubacki (38):
>> PrmPkg: Add package and include headers
>> PrmPkg: Add PrmConfig protocol interface
>> PrmPkg/PrmContextBufferLib: Add initial library instance
>> PrmPkg/PrmConfigDxe: Add initial driver
>> PrmPkg: Add initial PrmSamplePrintModule
>> PrmPkg: Add initial PrmSampleMemoryAllocationModule
>> PrmPkg: Add initial PrmSampleHardwareAccessModule
>> PrmPkg: Add initial PrmSampleContextBufferModule
>> PrmPkg: Add initial package DSC file
>> Readme.md: Add initial content
>> PrmPkg: Add ALLOCATE_CONTEXT_BUFFER_IN_FW build option
>> PrmPkg: Enable variable growth for the PRM_MODULE_EXPORT macro
>> PrmPkg: Add initial PrmSsdtInstallDxe module
>> PrmPkg: Remove PRM Module Update Lock
>> PrmPkg: Remove ALLOCATE_CONTEXT_BUFFER_IN_FW build flag
>> PrmPkg/PrmContextBuffer.h: Add ACPI parameter support structures
>> PrmPkg/PrmLoaderDxe: Add ACPI parameter buffer support
>> PrmPkg/PrmSampleContextBufferModule: Remove OS debug print
>> requirement
>> PrmPkg/PrmSampleHardwareAccessModule: Add non-print PRM handlers
>> PrmPkg/SampleAcpiParameterBufferModule: Add initial module
>> PrmPkg/HardwareAccessModuleConfigLib: Add initial library
>> PrmPkg/Samples/Readme.md: Add initial file
>> PrmPkg: Refactor some PrmLoaderDxe functionality into libraries
>> PrmPkg/Application/PrmInfo: Add initial application
>> PrmPkg: Enforce stricter types
>> PrmPkg/Test/PrmPkgHostTest.dsc: Add initial file
>> PrmPkg/Test/UnitTest/Library: Add initial UEFI Boot Services test lib
>> PrmPkg/Library/DxePrmContextBufferLib: Add host-based unit tests
>> PrmPkg/DxePrmModuleDiscoveryLib: Add initial host-based unit tests
>> PrmPkg: Add PlatformGuid
>> Readme.md: Add iASL note and QEMU sample link
>> PrmPkg: Replace PcdPrmPlatformGuid with EDKII_DSC_PLATFORM_GUID
>> PrmPkg/Samples: Remove PrmSampleMemoryAllocationModule
>> PrmPkg/Samples: Remove PrmSamplePrintModule
>> PrmPkg: Remove the concept of OS services
>> Readme.md: Add a link to PRM Specification
>> PrmPkg: Changes for edk2 repo transition
>> PrmPkg: Apply uncrustify changes
>>
>> PrmPkg/Application/PrmInfo/PrmInfo.c
>> | 732 +++++++++
>> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
>> | 199 +++
>>
>> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibU
>> nitTest.c
>> | 649 ++++++++
>> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
>> | 386 +++++
>>
>> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscove
>> ryLibUnitTest.c
>> | 210 +++
>> PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c
>> | 417 +++++
>> PrmPkg/PrmConfigDxe/PrmConfigDxe.c
>> | 512 ++++++
>> PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
>> | 377 +++++
>> PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
>> | 110 ++
>>
>> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiPa
>> rameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.c
>> | 127 ++
>>
>> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiPa
>> rameterBufferModule.c
>> | 78 +
>>
>> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuffer
>> ModuleConfigLib/DxeContextBufferModuleConfigLib.c
>> | 218 +++
>>
>> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuffer
>> Module.c
>> | 84 +
>>
>> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareA
>> ccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c
>> | 108 ++
>>
>> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareA
>> ccessModule.c
>> | 335 ++++
>>
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTest.c |
>> 119 ++
>>
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestEventTimer.c |
>> 180 +++
>>
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestImage.c |
>> 163 ++
>>
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestMemory.c |
>> 145 ++
>>
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestMisc.c |
>> 198 +++
>>
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestProtocol.c |
>> 1650 ++++++++++++++++++++
>>
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestTpl.c |
>> 43 +
>> .azurepipelines/templates/pr-gate-build-job.yml
>> | 2 +-
>> .pytool/CISettings.py
>> | 1 +
>> Maintainers.txt
>> | 8 +
>> PrmPkg/Application/PrmInfo/PrmInfo.h
>> | 49 +
>> PrmPkg/Application/PrmInfo/PrmInfo.inf
>> | 66 +
>> PrmPkg/Application/PrmInfo/PrmInfo.uni
>> | 11 +
>> PrmPkg/Application/PrmInfo/PrmInfoExtra.uni
>> | 12 +
>> PrmPkg/Application/PrmInfo/PrmInfoStrings.uni
>> | 132 ++
>> PrmPkg/Include/Library/PrmContextBufferLib.h
>> | 99 ++
>> PrmPkg/Include/Library/PrmModuleDiscoveryLib.h
>> | 60 +
>> PrmPkg/Include/Library/PrmPeCoffLib.h
>> | 111 ++
>> PrmPkg/Include/Prm.h
>> | 46 +
>> PrmPkg/Include/PrmContextBuffer.h
>> | 171 ++
>> PrmPkg/Include/PrmDataBuffer.h
>> | 50 +
>> PrmPkg/Include/PrmExportDescriptor.h
>> | 109 ++
>> PrmPkg/Include/PrmMmio.h
>> | 45 +
>> PrmPkg/Include/PrmModule.h
>> | 47 +
>> PrmPkg/Include/PrmModuleImageContext.h
>> | 28 +
>> PrmPkg/Include/Protocol/PrmConfig.h
>> | 31 +
>> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
>> | 35 +
>>
>> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibU
>> nitTestHost.inf
>> | 46 +
>> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf
>> | 41 +
>> PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
>> | 39 +
>>
>> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscove
>> ryLibUnitTestHost.inf
>> | 39 +
>> PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
>> | 32 +
>> PrmPkg/PrmConfigDxe/PrmConfigDxe.inf
>> | 48 +
>> PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
>> | 96 ++
>> PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
>> | 61 +
>> PrmPkg/PrmPkg.ci.yaml
>> | 110 ++
>> PrmPkg/PrmPkg.dec
>> | 67 +
>> PrmPkg/PrmPkg.dsc
>> | 142 ++
>> PrmPkg/PrmPkg.uni
>> | 10 +
>> PrmPkg/PrmSsdtInstallDxe/Prm.asl
>> | 115 ++
>> PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
>> | 52 +
>> PrmPkg/Readme.md
>> | 264 ++++
>>
>> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiPa
>> rameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf
>> | 39 +
>>
>> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiPa
>> rameterBufferModule.inf
>> | 41 +
>> PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h
>> | 24 +
>>
>> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuffer
>> ModuleConfigLib/DxeContextBufferModuleConfigLib.inf
>> | 39 +
>>
>> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuffer
>> Module.inf
>> | 44 +
>> PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
>> | 108 ++
>>
>> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareA
>> ccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
>> | 39 +
>>
>> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareA
>> ccessModule.inf
>> | 43 +
>> PrmPkg/Samples/Readme.md
>> | 146 ++
>> PrmPkg/Test/PrmPkgHostTest.dsc
>> | 39 +
>>
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibTest.uni |
>> 12 +
>>
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTest.h |
>> 1042 ++++++++++++
>>
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTest.inf |
>> 46 +
>>
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestProtocol.h |
>> 120 ++
>> 71 files changed, 11096 insertions(+), 1 deletion(-)
>> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.c
>> create mode 100644
>> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
>> create mode 100644
>> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibU
>> nitTest.c
>> create mode 100644
>> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
>> create mode 100644
>> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscove
>> ryLibUnitTest.c
>> create mode 100644 PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c
>> create mode 100644 PrmPkg/PrmConfigDxe/PrmConfigDxe.c
>> create mode 100644 PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
>> create mode 100644 PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
>> create mode 100644
>> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiPa
>> rameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.c
>> create mode 100644
>> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiPa
>> rameterBufferModule.c
>> create mode 100644
>> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuffer
>> ModuleConfigLib/DxeContextBufferModuleConfigLib.c
>> create mode 100644
>> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuffer
>> Module.c
>> create mode 100644
>> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareA
>> ccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c
>> create mode 100644
>> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareA
>> ccessModule.c
>> create mode 100644
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTest.c
>> create mode 100644
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestEventTimer.c
>> create mode 100644
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestImage.c
>> create mode 100644
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestMemory.c
>> create mode 100644
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestMisc.c
>> create mode 100644
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestProtocol.c
>> create mode 100644
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestTpl.c
>> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.h
>> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.inf
>> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.uni
>> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfoExtra.uni
>> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfoStrings.uni
>> create mode 100644 PrmPkg/Include/Library/PrmContextBufferLib.h
>> create mode 100644 PrmPkg/Include/Library/PrmModuleDiscoveryLib.h
>> create mode 100644 PrmPkg/Include/Library/PrmPeCoffLib.h
>> 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/PrmModuleImageContext.h
>> create mode 100644 PrmPkg/Include/Protocol/PrmConfig.h
>> create mode 100644
>> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
>> create mode 100644
>> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLibU
>> nitTestHost.inf
>> create mode 100644
>> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.inf
>> create mode 100644
>> PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
>> create mode 100644
>> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDiscove
>> ryLibUnitTestHost.inf
>> create mode 100644 PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
>> create mode 100644 PrmPkg/PrmConfigDxe/PrmConfigDxe.inf
>> create mode 100644 PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
>> create mode 100644 PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
>> create mode 100644 PrmPkg/PrmPkg.ci.yaml
>> create mode 100644 PrmPkg/PrmPkg.dec
>> create mode 100644 PrmPkg/PrmPkg.dsc
>> create mode 100644 PrmPkg/PrmPkg.uni
>> create mode 100644 PrmPkg/PrmSsdtInstallDxe/Prm.asl
>> create mode 100644 PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
>> create mode 100644 PrmPkg/Readme.md
>> create mode 100644
>> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiPa
>> rameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.inf
>> create mode 100644
>> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiPa
>> rameterBufferModule.inf
>> create mode 100644
>> PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h
>> create mode 100644
>> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuffer
>> ModuleConfigLib/DxeContextBufferModuleConfigLib.inf
>> create mode 100644
>> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuffer
>> Module.inf
>> create mode 100644
>> PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
>> create mode 100644
>> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardwareA
>> ccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
>> create mode 100644
>> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareA
>> ccessModule.inf
>> create mode 100644 PrmPkg/Samples/Readme.md
>> create mode 100644 PrmPkg/Test/PrmPkgHostTest.dsc
>> create mode 100644
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibTest.uni
>> create mode 100644
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTest.h
>> create mode 100644
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTest.inf
>> create mode 100644
>> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootSer
>> vicesTableLibUnitTestProtocol.h
>>
>> --
>> 2.28.0.windows.1
>>
>>
>>
>> -=-=-=-=-=-=
>> Groups.io Links: You receive all messages sent to this group.
>> View/Reply Online (#87842): https://edk2.groups.io/g/devel/message/87842
>> Mute This Topic: https://groups.io/mt/89955942/4905953
>> Group Owner: devel+owner@edk2.groups.io
>> Unsubscribe: https://edk2.groups.io/g/devel/unsub
>> [gaoliming@byosoft.com.cn]
>> -=-=-=-=-=-=
>>
>
>
>
>
>
>
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [edk2-devel] [PATCH v1 00/41] Add PrmPkg
2022-03-22 16:19 [PATCH v1 00/41] Add PrmPkg Michael Kubacki
` (39 preceding siblings ...)
2022-03-28 8:48 ` 回复: [edk2-devel] [PATCH v1 00/41] Add PrmPkg gaoliming
@ 2022-03-29 16:28 ` Sinha, Ankit
2022-03-31 0:52 ` 回复: " gaoliming
40 siblings, 1 reply; 44+ messages in thread
From: Sinha, Ankit @ 2022-03-29 16:28 UTC (permalink / raw)
To: devel@edk2.groups.io, mikuback@linux.microsoft.com
Cc: Andrew Fish, Gao, Kang, Kinney, Michael D, Kubacki, Michael,
Leif Lindholm, You, Benjamin, Liu, Yun Y, Desimone, Nathaniel L
Reviewed-by: Ankit Sinha <ankit.sinha@intel.com>
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Michael
> Kubacki
> Sent: Tuesday, March 22, 2022 9:19 AM
> To: devel@edk2.groups.io
> Cc: Andrew Fish <afish@apple.com>; Gao, Kang <kang.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Kubacki, Michael
> <michael.kubacki@microsoft.com>; Leif Lindholm <leif@nuviainc.com>; You,
> Benjamin <benjamin.you@intel.com>; Liu, Yun Y <yun.y.liu@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>
> Subject: [edk2-devel] [PATCH v1 00/41] Add PrmPkg
>
> From: Michael Kubacki <michael.kubacki@microsoft.com>
>
> This patch series adds a new package called PrmPkg. An RFC was sent to the
> edk2 mailing list on January 28, 2022 detailing the proposal, see
> https://edk2.groups.io/g/devel/message/86181.
>
> Platform Runtime Mechanism (PRM) is a new firmware solution that has
> been developed in edk2-staging/PlatformRuntimeMechanism.
>
> This patch series has been organized to greatly condense the history from
> the edk2-staging branch but to preserve important decisions and changes in
> history that help establish context of changes and will serve as valuable
> references for future development.
>
> Interest in PRM has increased across various vendors and we believe it is
> beneficial to make the source code more widely available for the following
> reasons:
>
> 1. PRM specification adoption
> 2. Feature completeness
> 3. Overall validation coverage
> 4. Interest from the community and future collaboration
>
> The technical details of PRM are covered in the PRM Specification in addition
> to the Readme.md file located in the root of PrmPkg in this patch series.
>
> 1. PRM specification adoption
>
> Intel and Microsoft have worked together to standardize PRM in the ACPI
> Specification and the PRM Specification hosted on uefi.org.
>
> * ACPI 6.4 Specification:
> https://uefi.org/node/4149
>
> * PRM Specification:
>
> https://uefi.org/sites/default/files/resources/Platform%20Runtime%20Mec
> hanism%20-%20with%20legal%20notice.pdf
>
> 2. Feature completeness
>
> PrmPkg implements the full firmware functionality described in the PRM
> Specification and there are no significant changes to functionality planned at
> this time.
>
> Though we are very much interested in evolving PRM based on feedback.
>
> 3. Overall validation coverage
>
> PrmPkg has been integrated and tested on client and server systems in
> addition to virtual platforms (OvmfPkg/QEMU).
>
> Platform integration is simple and a demonstration of this integration for
> OvmfPkg is available in the following branch:
> https://github.com/makubacki/edk2/tree/ovmf_prmpkg_integration
>
> The code has been built with:
> * MSFT VS2015, VS2017, and VS2019
> * GCC5 (see https://bugzilla.tianocore.org/show_bug.cgi?id=3802)
> * iASL compiler (20200528 - https://acpica.org/node/181)
>
> The Linux kernel currently includes the following PRM support:
> * _OSC PRM bit - allows FW to know determine the OS is
> PRM-capable and can redirect _DSM method from alternate
> triggers (such as SMI) to PRM.
> * PRM invocation via _DSM, includes PRM module and handler parsing
> from ACPI PRMT table, and also the PRM operation region handler
> for runtime PRM service invocation.
> * An OS configuration for PRM enabling, PRM support can be
> disabled during OS image build.
>
> Note that upstream Linux does not currently support the following:
> * Ability for the OS driver to call a PRM handler directly,
> it has to be via ACPI _DSM.
> * Run time update PRM module and handler via PE/COFF PRM image.
>
> This commit provides additional context of the changes in Linux:
> https://github.com/torvalds/linux/commit/cefc7ca46235f01d5233e3abd4b79
> 452af01d9e9
>
> Windows 11 (https://www.microsoft.com/software-download/windows11)
> and Windows Server 2022 (https://docs.microsoft.com/en-us/windows-
> hardware/drivers/download-the-wdk)
> include the PRM functionality noted above in addition to PRM direct call and
> PRM runtime updates.
>
> PRM has been tested on IA32, X64, and AARCH64 targets.
>
> 4. Interest from the community and future collaboration
>
> PRM has been presented at several industry conferences:
>
> * OSFC 2020 - "PRM: SMM Goes on a Diet"
> https://cfp.osfc.io/osfc2020/talk/MCJASB/
>
> * OCP Summit 2019 - "Case Study Alternatives for SMM Usage in
> Intel Platforms"
> https://www.youtube.com/watch?v=mu3DRLM1dPA
>
> In addition, Microsoft plans to publish the Windows PRM driver interface and
> a WDF sample driver that uses the interface to the Windows Driver Samples
> GitHub repository (https://github.com/microsoft/Windows-driver-samples).
>
> We believe a PrmPkg in edk2 can increase accessibility to PRM and ease
> collaboration.
>
> PrmPkg
> ------
> PrmPkg contains the common functionality needed to enable PRM on any
> system. It does not contain platform-specific code such as PRM modules (and
> by extension PRM handlers). Other than sample modules, PrmPkg will only
> contain code needed to provide PRM feature functionality as defined in the
> PRM Specification.
>
> PrmPkg is scoped to continue to only contain platform-agnostic functionality
> in the future.
>
> The proposed maintainers of PrmPkg are:
> * Michael Kubacki <mikuback@linux.microsoft.com>
> * Nate DeSimone <nathaniel.l.desimone@intel.com>
>
> The proposed reviewers of PrmPkg are:
> * Ankit Sinha <ankit.sinha@intel.com>
>
> 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>
>
> Liu (2):
> PrmPkg: Publish PRM operation region to support PRM ACPI _DSM
> invocation
> PrmPkg: Export major/minor version in PRM module PE COFF header
>
> Liu Yun Y (1):
> PrmPkg: Update PRM OpRegion
>
> Michael Kubacki (38):
> PrmPkg: Add package and include headers
> PrmPkg: Add PrmConfig protocol interface
> PrmPkg/PrmContextBufferLib: Add initial library instance
> PrmPkg/PrmConfigDxe: Add initial driver
> PrmPkg: Add initial PrmSamplePrintModule
> PrmPkg: Add initial PrmSampleMemoryAllocationModule
> PrmPkg: Add initial PrmSampleHardwareAccessModule
> PrmPkg: Add initial PrmSampleContextBufferModule
> PrmPkg: Add initial package DSC file
> Readme.md: Add initial content
> PrmPkg: Add ALLOCATE_CONTEXT_BUFFER_IN_FW build option
> PrmPkg: Enable variable growth for the PRM_MODULE_EXPORT macro
> PrmPkg: Add initial PrmSsdtInstallDxe module
> PrmPkg: Remove PRM Module Update Lock
> PrmPkg: Remove ALLOCATE_CONTEXT_BUFFER_IN_FW build flag
> PrmPkg/PrmContextBuffer.h: Add ACPI parameter support structures
> PrmPkg/PrmLoaderDxe: Add ACPI parameter buffer support
> PrmPkg/PrmSampleContextBufferModule: Remove OS debug print
> requirement
> PrmPkg/PrmSampleHardwareAccessModule: Add non-print PRM handlers
> PrmPkg/SampleAcpiParameterBufferModule: Add initial module
> PrmPkg/HardwareAccessModuleConfigLib: Add initial library
> PrmPkg/Samples/Readme.md: Add initial file
> PrmPkg: Refactor some PrmLoaderDxe functionality into libraries
> PrmPkg/Application/PrmInfo: Add initial application
> PrmPkg: Enforce stricter types
> PrmPkg/Test/PrmPkgHostTest.dsc: Add initial file
> PrmPkg/Test/UnitTest/Library: Add initial UEFI Boot Services test lib
> PrmPkg/Library/DxePrmContextBufferLib: Add host-based unit tests
> PrmPkg/DxePrmModuleDiscoveryLib: Add initial host-based unit tests
> PrmPkg: Add PlatformGuid
> Readme.md: Add iASL note and QEMU sample link
> PrmPkg: Replace PcdPrmPlatformGuid with EDKII_DSC_PLATFORM_GUID
> PrmPkg/Samples: Remove PrmSampleMemoryAllocationModule
> PrmPkg/Samples: Remove PrmSamplePrintModule
> PrmPkg: Remove the concept of OS services
> Readme.md: Add a link to PRM Specification
> PrmPkg: Changes for edk2 repo transition
> PrmPkg: Apply uncrustify changes
>
> PrmPkg/Application/PrmInfo/PrmInfo.c
> | 732 +++++++++
> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
> | 199 +++
>
> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLi
> bUnitTest.c | 649 ++++++++
> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
> | 386 +++++
>
> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDisco
> veryLibUnitTest.c | 210 +++
> PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c
> | 417 +++++
> PrmPkg/PrmConfigDxe/PrmConfigDxe.c
> | 512 ++++++
> PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
> | 377 +++++
> PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
> | 110 ++
>
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiP
> arameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.
> c | 127 ++
>
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiP
> arameterBufferModule.c | 78 +
>
> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuff
> erModuleConfigLib/DxeContextBufferModuleConfigLib.c | 218
> +++
>
> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuff
> erModule.c | 84 +
>
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardware
> AccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c |
> 108 ++
>
> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardware
> AccessModule.c | 335 ++++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTest.c | 119 ++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestEventTimer.c | 180 +++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestImage.c | 163 ++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestMemory.c | 145 ++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestMisc.c | 198 +++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestProtocol.c | 1650
> ++++++++++++++++++++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestTpl.c | 43 +
> .azurepipelines/templates/pr-gate-build-job.yml
> | 2 +-
> .pytool/CISettings.py
> | 1 +
> Maintainers.txt
> | 8 +
> PrmPkg/Application/PrmInfo/PrmInfo.h
> | 49 +
> PrmPkg/Application/PrmInfo/PrmInfo.inf
> | 66 +
> PrmPkg/Application/PrmInfo/PrmInfo.uni
> | 11 +
> PrmPkg/Application/PrmInfo/PrmInfoExtra.uni
> | 12 +
> PrmPkg/Application/PrmInfo/PrmInfoStrings.uni
> | 132 ++
> PrmPkg/Include/Library/PrmContextBufferLib.h
> | 99 ++
> PrmPkg/Include/Library/PrmModuleDiscoveryLib.h
> | 60 +
> PrmPkg/Include/Library/PrmPeCoffLib.h
> | 111 ++
> PrmPkg/Include/Prm.h
> | 46 +
> PrmPkg/Include/PrmContextBuffer.h
> | 171 ++
> PrmPkg/Include/PrmDataBuffer.h
> | 50 +
> PrmPkg/Include/PrmExportDescriptor.h
> | 109 ++
> PrmPkg/Include/PrmMmio.h
> | 45 +
> PrmPkg/Include/PrmModule.h
> | 47 +
> PrmPkg/Include/PrmModuleImageContext.h
> | 28 +
> PrmPkg/Include/Protocol/PrmConfig.h
> | 31 +
> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
> | 35 +
>
> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLi
> bUnitTestHost.inf | 46 +
>
> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.in
> f | 41 +
> PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
> | 39 +
>
> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDisco
> veryLibUnitTestHost.inf | 39 +
> PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
> | 32 +
> PrmPkg/PrmConfigDxe/PrmConfigDxe.inf
> | 48 +
> PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
> | 96 ++
> PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
> | 61 +
> PrmPkg/PrmPkg.ci.yaml
> | 110 ++
> PrmPkg/PrmPkg.dec
> | 67 +
> PrmPkg/PrmPkg.dsc
> | 142 ++
> PrmPkg/PrmPkg.uni
> | 10 +
> PrmPkg/PrmSsdtInstallDxe/Prm.asl
> | 115 ++
> PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
> | 52 +
> PrmPkg/Readme.md
> | 264 ++++
>
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiP
> arameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.
> inf | 39 +
>
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiP
> arameterBufferModule.inf | 41 +
> PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h
> | 24 +
>
> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuff
> erModuleConfigLib/DxeContextBufferModuleConfigLib.inf | 39 +
>
> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuff
> erModule.inf | 44 +
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
> | 108 ++
>
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardware
> AccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf |
> 39 +
>
> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardware
> AccessModule.inf | 43 +
> PrmPkg/Samples/Readme.md
> | 146 ++
> PrmPkg/Test/PrmPkgHostTest.dsc
> | 39 +
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibTest.uni | 12 +
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTest.h | 1042 ++++++++++++
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTest.inf | 46 +
>
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestProtocol.h | 120 ++
> 71 files changed, 11096 insertions(+), 1 deletion(-) create mode 100644
> PrmPkg/Application/PrmInfo/PrmInfo.c
> create mode 100644
> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
> create mode 100644
> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLi
> bUnitTest.c
> create mode 100644
> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
> create mode 100644
> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDisco
> veryLibUnitTest.c
> create mode 100644 PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c
> create mode 100644 PrmPkg/PrmConfigDxe/PrmConfigDxe.c
> create mode 100644 PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
> create mode 100644 PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
> create mode 100644
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiP
> arameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.
> c
> create mode 100644
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiP
> arameterBufferModule.c
> create mode 100644
> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuff
> erModuleConfigLib/DxeContextBufferModuleConfigLib.c
> create mode 100644
> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuff
> erModule.c
> create mode 100644
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardware
> AccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c
> create mode 100644
> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardware
> AccessModule.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTest.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestEventTimer.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestImage.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestMemory.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestMisc.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestProtocol.c
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestTpl.c
> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.h
> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.inf
> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.uni
> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfoExtra.uni
> create mode 100644 PrmPkg/Application/PrmInfo/PrmInfoStrings.uni
> create mode 100644 PrmPkg/Include/Library/PrmContextBufferLib.h
> create mode 100644 PrmPkg/Include/Library/PrmModuleDiscoveryLib.h
> create mode 100644 PrmPkg/Include/Library/PrmPeCoffLib.h
> 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/PrmModuleImageContext.h
> create mode 100644 PrmPkg/Include/Protocol/PrmConfig.h
> create mode 100644
> PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
> create mode 100644
> PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLi
> bUnitTestHost.inf
> create mode 100644
> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.in
> f
> create mode 100644
> PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
> create mode 100644
> PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDisco
> veryLibUnitTestHost.inf
> create mode 100644
> PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
> create mode 100644 PrmPkg/PrmConfigDxe/PrmConfigDxe.inf
> create mode 100644 PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
> create mode 100644 PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
> create mode 100644 PrmPkg/PrmPkg.ci.yaml create mode 100644
> PrmPkg/PrmPkg.dec create mode 100644 PrmPkg/PrmPkg.dsc create mode
> 100644 PrmPkg/PrmPkg.uni create mode 100644
> PrmPkg/PrmSsdtInstallDxe/Prm.asl create mode 100644
> PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
> create mode 100644 PrmPkg/Readme.md
> create mode 100644
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiP
> arameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.
> inf
> create mode 100644
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiP
> arameterBufferModule.inf
> create mode 100644
> PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h
> create mode 100644
> PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuff
> erModuleConfigLib/DxeContextBufferModuleConfigLib.inf
> create mode 100644
> PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuff
> erModule.inf
> create mode 100644
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
> create mode 100644
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardware
> AccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
> create mode 100644
> PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardware
> AccessModule.inf
> create mode 100644 PrmPkg/Samples/Readme.md create mode 100644
> PrmPkg/Test/PrmPkgHostTest.dsc create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibTest.uni
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTest.h
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTest.inf
> create mode 100644
> PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> ervicesTableLibUnitTestProtocol.h
>
> --
> 2.28.0.windows.1
>
>
>
> -=-=-=-=-=-=
> Groups.io Links: You receive all messages sent to this group.
> View/Reply Online (#87842): https://edk2.groups.io/g/devel/message/87842
> Mute This Topic: https://groups.io/mt/89955942/1772825
> Group Owner: devel+owner@edk2.groups.io
> Unsubscribe: https://edk2.groups.io/g/devel/unsub [ankit.sinha@intel.com]
> -=-=-=-=-=-=
>
^ permalink raw reply [flat|nested] 44+ messages in thread
* 回复: [edk2-devel] [PATCH v1 00/41] Add PrmPkg
2022-03-29 16:28 ` Sinha, Ankit
@ 2022-03-31 0:52 ` gaoliming
0 siblings, 0 replies; 44+ messages in thread
From: gaoliming @ 2022-03-31 0:52 UTC (permalink / raw)
To: devel, ankit.sinha, mikuback
Cc: 'Andrew Fish', 'Gao, Kang',
'Kinney, Michael D', 'Kubacki, Michael',
'Leif Lindholm', 'You, Benjamin',
'Liu, Yun Y', 'Desimone, Nathaniel L'
Acked-by: Liming Gao <gaoliming@byosoft.com.cn>
> -----邮件原件-----
> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Sinha, Ankit
> 发送时间: 2022年3月30日 0:29
> 收件人: devel@edk2.groups.io; mikuback@linux.microsoft.com
> 抄送: Andrew Fish <afish@apple.com>; Gao, Kang <kang.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Kubacki, Michael
> <michael.kubacki@microsoft.com>; Leif Lindholm <leif@nuviainc.com>; You,
> Benjamin <benjamin.you@intel.com>; Liu, Yun Y <yun.y.liu@intel.com>;
> Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>
> 主题: Re: [edk2-devel] [PATCH v1 00/41] Add PrmPkg
>
> Reviewed-by: Ankit Sinha <ankit.sinha@intel.com>
>
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Michael
> > Kubacki
> > Sent: Tuesday, March 22, 2022 9:19 AM
> > To: devel@edk2.groups.io
> > Cc: Andrew Fish <afish@apple.com>; Gao, Kang <kang.gao@intel.com>;
> > Kinney, Michael D <michael.d.kinney@intel.com>; Kubacki, Michael
> > <michael.kubacki@microsoft.com>; Leif Lindholm <leif@nuviainc.com>;
> You,
> > Benjamin <benjamin.you@intel.com>; Liu, Yun Y <yun.y.liu@intel.com>;
> > Sinha, Ankit <ankit.sinha@intel.com>; Desimone, Nathaniel L
> > <nathaniel.l.desimone@intel.com>
> > Subject: [edk2-devel] [PATCH v1 00/41] Add PrmPkg
> >
> > From: Michael Kubacki <michael.kubacki@microsoft.com>
> >
> > This patch series adds a new package called PrmPkg. An RFC was sent to
the
> > edk2 mailing list on January 28, 2022 detailing the proposal, see
> > https://edk2.groups.io/g/devel/message/86181.
> >
> > Platform Runtime Mechanism (PRM) is a new firmware solution that has
> > been developed in edk2-staging/PlatformRuntimeMechanism.
> >
> > This patch series has been organized to greatly condense the history
from
> > the edk2-staging branch but to preserve important decisions and changes
in
> > history that help establish context of changes and will serve as
valuable
> > references for future development.
> >
> > Interest in PRM has increased across various vendors and we believe it
is
> > beneficial to make the source code more widely available for the
following
> > reasons:
> >
> > 1. PRM specification adoption
> > 2. Feature completeness
> > 3. Overall validation coverage
> > 4. Interest from the community and future collaboration
> >
> > The technical details of PRM are covered in the PRM Specification in
> addition
> > to the Readme.md file located in the root of PrmPkg in this patch
series.
> >
> > 1. PRM specification adoption
> >
> > Intel and Microsoft have worked together to standardize PRM in the ACPI
> > Specification and the PRM Specification hosted on uefi.org.
> >
> > * ACPI 6.4 Specification:
> > https://uefi.org/node/4149
> >
> > * PRM Specification:
> >
> > https://uefi.org/sites/default/files/resources/Platform%20Runtime%20Mec
> > hanism%20-%20with%20legal%20notice.pdf
> >
> > 2. Feature completeness
> >
> > PrmPkg implements the full firmware functionality described in the PRM
> > Specification and there are no significant changes to functionality
planned at
> > this time.
> >
> > Though we are very much interested in evolving PRM based on feedback.
> >
> > 3. Overall validation coverage
> >
> > PrmPkg has been integrated and tested on client and server systems in
> > addition to virtual platforms (OvmfPkg/QEMU).
> >
> > Platform integration is simple and a demonstration of this integration
for
> > OvmfPkg is available in the following branch:
> > https://github.com/makubacki/edk2/tree/ovmf_prmpkg_integration
> >
> > The code has been built with:
> > * MSFT VS2015, VS2017, and VS2019
> > * GCC5 (see https://bugzilla.tianocore.org/show_bug.cgi?id=3802)
> > * iASL compiler (20200528 - https://acpica.org/node/181)
> >
> > The Linux kernel currently includes the following PRM support:
> > * _OSC PRM bit - allows FW to know determine the OS is
> > PRM-capable and can redirect _DSM method from alternate
> > triggers (such as SMI) to PRM.
> > * PRM invocation via _DSM, includes PRM module and handler parsing
> > from ACPI PRMT table, and also the PRM operation region handler
> > for runtime PRM service invocation.
> > * An OS configuration for PRM enabling, PRM support can be
> > disabled during OS image build.
> >
> > Note that upstream Linux does not currently support the following:
> > * Ability for the OS driver to call a PRM handler directly,
> > it has to be via ACPI _DSM.
> > * Run time update PRM module and handler via PE/COFF PRM image.
> >
> > This commit provides additional context of the changes in Linux:
> >
> https://github.com/torvalds/linux/commit/cefc7ca46235f01d5233e3abd4b79
> > 452af01d9e9
> >
> > Windows 11 (https://www.microsoft.com/software-download/windows11)
> > and Windows Server 2022 (https://docs.microsoft.com/en-us/windows-
> > hardware/drivers/download-the-wdk)
> > include the PRM functionality noted above in addition to PRM direct call
and
> > PRM runtime updates.
> >
> > PRM has been tested on IA32, X64, and AARCH64 targets.
> >
> > 4. Interest from the community and future collaboration
> >
> > PRM has been presented at several industry conferences:
> >
> > * OSFC 2020 - "PRM: SMM Goes on a Diet"
> > https://cfp.osfc.io/osfc2020/talk/MCJASB/
> >
> > * OCP Summit 2019 - "Case Study Alternatives for SMM Usage in
> > Intel Platforms"
> > https://www.youtube.com/watch?v=mu3DRLM1dPA
> >
> > In addition, Microsoft plans to publish the Windows PRM driver interface
> and
> > a WDF sample driver that uses the interface to the Windows Driver
Samples
> > GitHub repository (https://github.com/microsoft/Windows-driver-samples).
> >
> > We believe a PrmPkg in edk2 can increase accessibility to PRM and ease
> > collaboration.
> >
> > PrmPkg
> > ------
> > PrmPkg contains the common functionality needed to enable PRM on any
> > system. It does not contain platform-specific code such as PRM modules
> (and
> > by extension PRM handlers). Other than sample modules, PrmPkg will only
> > contain code needed to provide PRM feature functionality as defined in
the
> > PRM Specification.
> >
> > PrmPkg is scoped to continue to only contain platform-agnostic
functionality
> > in the future.
> >
> > The proposed maintainers of PrmPkg are:
> > * Michael Kubacki <mikuback@linux.microsoft.com>
> > * Nate DeSimone <nathaniel.l.desimone@intel.com>
> >
> > The proposed reviewers of PrmPkg are:
> > * Ankit Sinha <ankit.sinha@intel.com>
> >
> > 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>
> >
> > Liu (2):
> > PrmPkg: Publish PRM operation region to support PRM ACPI _DSM
> > invocation
> > PrmPkg: Export major/minor version in PRM module PE COFF header
> >
> > Liu Yun Y (1):
> > PrmPkg: Update PRM OpRegion
> >
> > Michael Kubacki (38):
> > PrmPkg: Add package and include headers
> > PrmPkg: Add PrmConfig protocol interface
> > PrmPkg/PrmContextBufferLib: Add initial library instance
> > PrmPkg/PrmConfigDxe: Add initial driver
> > PrmPkg: Add initial PrmSamplePrintModule
> > PrmPkg: Add initial PrmSampleMemoryAllocationModule
> > PrmPkg: Add initial PrmSampleHardwareAccessModule
> > PrmPkg: Add initial PrmSampleContextBufferModule
> > PrmPkg: Add initial package DSC file
> > Readme.md: Add initial content
> > PrmPkg: Add ALLOCATE_CONTEXT_BUFFER_IN_FW build option
> > PrmPkg: Enable variable growth for the PRM_MODULE_EXPORT macro
> > PrmPkg: Add initial PrmSsdtInstallDxe module
> > PrmPkg: Remove PRM Module Update Lock
> > PrmPkg: Remove ALLOCATE_CONTEXT_BUFFER_IN_FW build flag
> > PrmPkg/PrmContextBuffer.h: Add ACPI parameter support structures
> > PrmPkg/PrmLoaderDxe: Add ACPI parameter buffer support
> > PrmPkg/PrmSampleContextBufferModule: Remove OS debug print
> > requirement
> > PrmPkg/PrmSampleHardwareAccessModule: Add non-print PRM
> handlers
> > PrmPkg/SampleAcpiParameterBufferModule: Add initial module
> > PrmPkg/HardwareAccessModuleConfigLib: Add initial library
> > PrmPkg/Samples/Readme.md: Add initial file
> > PrmPkg: Refactor some PrmLoaderDxe functionality into libraries
> > PrmPkg/Application/PrmInfo: Add initial application
> > PrmPkg: Enforce stricter types
> > PrmPkg/Test/PrmPkgHostTest.dsc: Add initial file
> > PrmPkg/Test/UnitTest/Library: Add initial UEFI Boot Services test lib
> > PrmPkg/Library/DxePrmContextBufferLib: Add host-based unit tests
> > PrmPkg/DxePrmModuleDiscoveryLib: Add initial host-based unit tests
> > PrmPkg: Add PlatformGuid
> > Readme.md: Add iASL note and QEMU sample link
> > PrmPkg: Replace PcdPrmPlatformGuid with
> EDKII_DSC_PLATFORM_GUID
> > PrmPkg/Samples: Remove PrmSampleMemoryAllocationModule
> > PrmPkg/Samples: Remove PrmSamplePrintModule
> > PrmPkg: Remove the concept of OS services
> > Readme.md: Add a link to PRM Specification
> > PrmPkg: Changes for edk2 repo transition
> > PrmPkg: Apply uncrustify changes
> >
> > PrmPkg/Application/PrmInfo/PrmInfo.c
> > | 732 +++++++++
> > PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
> > | 199 +++
> >
> > PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLi
> > bUnitTest.c
> | 649 ++++++++
> >
> PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
> > | 386 +++++
> >
> > PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDisco
> > veryLibUnitTest.c
> | 210 +++
> > PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c
> > | 417 +++++
> > PrmPkg/PrmConfigDxe/PrmConfigDxe.c
> > | 512 ++++++
> > PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
> > | 377 +++++
> > PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
> > | 110 ++
> >
> >
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiP
> > arameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.
> > c | 127 ++
> >
> > PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiP
> > arameterBufferModule.c
> | 78 +
> >
> > PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuff
> > erModuleConfigLib/DxeContextBufferModuleConfigLib.c
> | 218
> > +++
> >
> > PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuff
> > erModule.c
> | 84 +
> >
> >
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardware
> > AccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c
> |
> > 108 ++
> >
> > PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardware
> > AccessModule.c
> | 335 ++++
> >
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTest.c
> | 119 ++
> >
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestEventTimer.c
> | 180 +++
> >
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestImage.c
> | 163 ++
> >
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestMemory.c
> | 145 ++
> >
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestMisc.c
> | 198 +++
> >
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestProtocol.c
> | 1650
> > ++++++++++++++++++++
> >
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestTpl.c
> | 43 +
> > .azurepipelines/templates/pr-gate-build-job.yml
> > | 2 +-
> > .pytool/CISettings.py
> > | 1 +
> > Maintainers.txt
> > | 8 +
> > PrmPkg/Application/PrmInfo/PrmInfo.h
> > | 49 +
> > PrmPkg/Application/PrmInfo/PrmInfo.inf
> > | 66 +
> > PrmPkg/Application/PrmInfo/PrmInfo.uni
> > | 11 +
> > PrmPkg/Application/PrmInfo/PrmInfoExtra.uni
> > | 12 +
> > PrmPkg/Application/PrmInfo/PrmInfoStrings.uni
> > | 132 ++
> > PrmPkg/Include/Library/PrmContextBufferLib.h
> > | 99 ++
> > PrmPkg/Include/Library/PrmModuleDiscoveryLib.h
> > | 60 +
> > PrmPkg/Include/Library/PrmPeCoffLib.h
> > | 111 ++
> > PrmPkg/Include/Prm.h
> > | 46 +
> > PrmPkg/Include/PrmContextBuffer.h
> > | 171 ++
> > PrmPkg/Include/PrmDataBuffer.h
> > | 50 +
> > PrmPkg/Include/PrmExportDescriptor.h
> > | 109 ++
> > PrmPkg/Include/PrmMmio.h
> > | 45 +
> > PrmPkg/Include/PrmModule.h
> > | 47 +
> > PrmPkg/Include/PrmModuleImageContext.h
> > | 28 +
> > PrmPkg/Include/Protocol/PrmConfig.h
> > | 31 +
> > PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
> > | 35 +
> >
> > PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLi
> > bUnitTestHost.inf
> | 46 +
> >
> > PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.in
> > f
> | 41 +
> > PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
> > | 39 +
> >
> > PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDisco
> > veryLibUnitTestHost.inf
> | 39 +
> > PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
> > | 32 +
> > PrmPkg/PrmConfigDxe/PrmConfigDxe.inf
> > | 48 +
> > PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
> > | 96 ++
> > PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
> > | 61 +
> > PrmPkg/PrmPkg.ci.yaml
> > | 110 ++
> > PrmPkg/PrmPkg.dec
> > | 67 +
> > PrmPkg/PrmPkg.dsc
> > | 142 ++
> > PrmPkg/PrmPkg.uni
> > | 10 +
> > PrmPkg/PrmSsdtInstallDxe/Prm.asl
> > | 115 ++
> > PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
> > | 52 +
> > PrmPkg/Readme.md
> > | 264 ++++
> >
> >
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiP
> > arameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.
> > inf | 39 +
> >
> > PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiP
> > arameterBufferModule.inf
> | 41 +
> > PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h
> > | 24 +
> >
> > PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuff
> > erModuleConfigLib/DxeContextBufferModuleConfigLib.inf
> | 39 +
> >
> > PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuff
> > erModule.inf
> | 44 +
> > PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
> > | 108 ++
> >
> >
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardware
> > AccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
> |
> > 39 +
> >
> > PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardware
> > AccessModule.inf
> | 43 +
> > PrmPkg/Samples/Readme.md
> > | 146 ++
> > PrmPkg/Test/PrmPkgHostTest.dsc
> > | 39 +
> >
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibTest.uni
> | 12 +
> >
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTest.h
> | 1042 ++++++++++++
> >
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTest.inf
> | 46 +
> >
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestProtocol.h
> | 120 ++
> > 71 files changed, 11096 insertions(+), 1 deletion(-) create mode
100644
> > PrmPkg/Application/PrmInfo/PrmInfo.c
> > create mode 100644
> > PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.c
> > create mode 100644
> > PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLi
> > bUnitTest.c
> > create mode 100644
> > PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.c
> > create mode 100644
> > PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDisco
> > veryLibUnitTest.c
> > create mode 100644
> PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c
> > create mode 100644 PrmPkg/PrmConfigDxe/PrmConfigDxe.c
> > create mode 100644 PrmPkg/PrmLoaderDxe/PrmLoaderDxe.c
> > create mode 100644 PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.c
> > create mode 100644
> >
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiP
> > arameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.
> > c
> > create mode 100644
> > PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiP
> > arameterBufferModule.c
> > create mode 100644
> > PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuff
> > erModuleConfigLib/DxeContextBufferModuleConfigLib.c
> > create mode 100644
> > PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuff
> > erModule.c
> > create mode 100644
> >
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardware
> > AccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.c
> > create mode 100644
> > PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardware
> > AccessModule.c
> > create mode 100644
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTest.c
> > create mode 100644
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestEventTimer.c
> > create mode 100644
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestImage.c
> > create mode 100644
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestMemory.c
> > create mode 100644
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestMisc.c
> > create mode 100644
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestProtocol.c
> > create mode 100644
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestTpl.c
> > create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.h
> > create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.inf
> > create mode 100644 PrmPkg/Application/PrmInfo/PrmInfo.uni
> > create mode 100644 PrmPkg/Application/PrmInfo/PrmInfoExtra.uni
> > create mode 100644 PrmPkg/Application/PrmInfo/PrmInfoStrings.uni
> > create mode 100644 PrmPkg/Include/Library/PrmContextBufferLib.h
> > create mode 100644 PrmPkg/Include/Library/PrmModuleDiscoveryLib.h
> > create mode 100644 PrmPkg/Include/Library/PrmPeCoffLib.h
> > 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/PrmModuleImageContext.h
> > create mode 100644 PrmPkg/Include/Protocol/PrmConfig.h
> > create mode 100644
> > PrmPkg/Library/DxePrmContextBufferLib/DxePrmContextBufferLib.inf
> > create mode 100644
> > PrmPkg/Library/DxePrmContextBufferLib/UnitTest/DxePrmContextBufferLi
> > bUnitTestHost.inf
> > create mode 100644
> > PrmPkg/Library/DxePrmModuleDiscoveryLib/DxePrmModuleDiscoveryLib.in
> > f
> > create mode 100644
> > PrmPkg/Library/DxePrmModuleDiscoveryLib/PrmModuleDiscovery.h
> > create mode 100644
> > PrmPkg/Library/DxePrmModuleDiscoveryLib/UnitTest/DxePrmModuleDisco
> > veryLibUnitTestHost.inf
> > create mode 100644
> > PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.inf
> > create mode 100644 PrmPkg/PrmConfigDxe/PrmConfigDxe.inf
> > create mode 100644 PrmPkg/PrmLoaderDxe/PrmAcpiTable.h
> > create mode 100644 PrmPkg/PrmLoaderDxe/PrmLoaderDxe.inf
> > create mode 100644 PrmPkg/PrmPkg.ci.yaml create mode 100644
> > PrmPkg/PrmPkg.dec create mode 100644 PrmPkg/PrmPkg.dsc create
> mode
> > 100644 PrmPkg/PrmPkg.uni create mode 100644
> > PrmPkg/PrmSsdtInstallDxe/Prm.asl create mode 100644
> > PrmPkg/PrmSsdtInstallDxe/PrmSsdtInstallDxe.inf
> > create mode 100644 PrmPkg/Readme.md
> > create mode 100644
> >
> PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/Library/DxeAcpiP
> > arameterBufferModuleConfigLib/DxeAcpiParameterBufferModuleConfigLib.
> > inf
> > create mode 100644
> > PrmPkg/Samples/PrmSampleAcpiParameterBufferModule/PrmSampleAcpiP
> > arameterBufferModule.inf
> > create mode 100644
> > PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h
> > create mode 100644
> > PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuff
> > erModuleConfigLib/DxeContextBufferModuleConfigLib.inf
> > create mode 100644
> > PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBuff
> > erModule.inf
> > create mode 100644
> > PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h
> > create mode 100644
> >
> PrmPkg/Samples/PrmSampleHardwareAccessModule/Library/DxeHardware
> > AccessModuleConfigLib/DxeHardwareAccessModuleConfigLib.inf
> > create mode 100644
> > PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardware
> > AccessModule.inf
> > create mode 100644 PrmPkg/Samples/Readme.md create mode
> 100644
> > PrmPkg/Test/PrmPkgHostTest.dsc create mode 100644
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibTest.uni
> > create mode 100644
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTest.h
> > create mode 100644
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTest.inf
> > create mode 100644
> > PrmPkg/Test/UnitTest/Library/UefiBootServicesTableLibUnitTest/UefiBootS
> > ervicesTableLibUnitTestProtocol.h
> >
> > --
> > 2.28.0.windows.1
> >
> >
> >
> > -=-=-=-=-=-=
> > Groups.io Links: You receive all messages sent to this group.
> > View/Reply Online (#87842):
> https://edk2.groups.io/g/devel/message/87842
> > Mute This Topic: https://groups.io/mt/89955942/1772825
> > Group Owner: devel+owner@edk2.groups.io
> > Unsubscribe: https://edk2.groups.io/g/devel/unsub
> [ankit.sinha@intel.com]
> > -=-=-=-=-=-=
> >
>
>
>
>
>
^ permalink raw reply [flat|nested] 44+ messages in thread
end of thread, other threads:[~2022-03-31 0:52 UTC | newest]
Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH v1 10/41] Readme.md: Add initial content Michael Kubacki
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox