mirror of https://github.com/acidanthera/audk.git
PrmPkg: Add initial PrmSampleContextBufferModule
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> Acked-by: Michael D Kinney <michael.d.kinney@intel.com> Acked-by: Liming Gao <gaoliming@byosoft.com.cn> Acked-by: Leif Lindholm <quic_llindhol@quicinc.com> Reviewed-by: Ankit Sinha <ankit.sinha@intel.com>
This commit is contained in:
parent
27b1a840e4
commit
7c41ec47ca
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue