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:
committed by
mergify[bot]
parent
27b1a840e4
commit
7c41ec47ca
@ -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
|
Reference in New Issue
Block a user