From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mx.groups.io with SMTP id smtpd.web08.12131.1647966050522955682 for ; Tue, 22 Mar 2022 09:20:50 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@linux.microsoft.com header.s=default header.b=kfgXc/sH; spf=pass (domain: linux.microsoft.com, ip: 13.77.154.182, mailfrom: mikuback@linux.microsoft.com) Received: from localhost.localdomain (unknown [47.202.59.224]) by linux.microsoft.com (Postfix) with ESMTPSA id 3E2AE20DE498; Tue, 22 Mar 2022 09:20:49 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 3E2AE20DE498 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1647966050; bh=Ye+YZgzDsVm/2qkxKHwxurVJ48OYYbxAMI7xGuyTK2A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kfgXc/sHqRSA8bzREjZXFa4PNh4IZwY0AXFZ1bHtlgK4w8bbgjXf83LGvZ0vBaW7j XO23dMhVVHQOkf1WU9HqWcaLr0gU4Dl5gQiTQppaCBScQvkYj0Q3vd1ShYr+Gn7eZg /QIJIrU8FWfjG0oi0GIoi+pZkwdgTF73uvdOkF/s= From: "Michael Kubacki" To: devel@edk2.groups.io Cc: Andrew Fish , Kang Gao , Michael D Kinney , Michael Kubacki , Leif Lindholm , Benjamin You , Liu Yun , Ankit Sinha , Nate DeSimone Subject: [PATCH v1 08/41] PrmPkg: Add initial PrmSampleContextBufferModule Date: Tue, 22 Mar 2022 12:19:14 -0400 Message-Id: <20220322161947.9319-9-mikuback@linux.microsoft.com> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20220322161947.9319-1-mikuback@linux.microsoft.com> References: <20220322161947.9319-1-mikuback@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Michael Kubacki REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D3812 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 Cc: Kang Gao Cc: Michael D Kinney Cc: Michael Kubacki Cc: Leif Lindholm Cc: Benjamin You Cc: Liu Yun Cc: Ankit Sinha Cc: Nate DeSimone Signed-off-by: Michael Kubacki --- PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModu= leConfigLib/DxeContextBufferModuleConfigLib.c | 203 +++++++++++++++++++= + PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule= .c | 182 ++++++++++++++++++ PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticData.h = | 24 +++ PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBufferModu= leConfigLib/DxeContextBufferModuleConfigLib.inf | 39 ++++ PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferModule= .inf | 42 ++++ 5 files changed, 490 insertions(+) diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeConte= xtBufferModuleConfigLib/DxeContextBufferModuleConfigLib.c b/PrmPkg/Sample= s/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/Dx= eContextBufferModuleConfigLib.c new file mode 100644 index 000000000000..3bf5beba7d4a --- /dev/null +++ b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuffe= rModuleConfigLib/DxeContextBufferModuleConfigLib.c @@ -0,0 +1,203 @@ +/** @file + + The boot services environment configuration library for the Context Bu= ffer Sample PRM module. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +STATIC EFI_HANDLE mPrmConfigProtocolHandle; + +// {5a6cf42b-8bb4-472c-a233-5c4dc4033dc7} +STATIC CONST EFI_GUID mPrmModuleGuid =3D {0x5a6cf42b, 0x8bb4, 0x472c, {0= xa2, 0x33, 0x5c, 0x4d, 0xc4, 0x03, 0x3d, 0xc7}}; + +// {e1466081-7562-430f-896b-b0e523dc335a} +STATIC CONST EFI_GUID mDumpStaticDataBufferPrmHandlerGuid =3D {0xe146608= 1, 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 suc= cessfully. + @retval EFI_INVALID_PARAMETER The StaticDataBuffer pointer argument is= NULL. + +**/ +EFI_STATUS +PopulateStaticDataBuffer ( + OUT STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE *StaticDataBuffer + ) +{ + if (StaticDataBuffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Note: In a real-world module these values would likely come from so= mewhere + // like a Setup menu option, PCD, binary data, runtime device info, et= c. 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 =3D TRUE; + StaticDataBuffer->Policy2Enabled =3D 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 dat= a 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 allocat= e the static data buffer. + +**/ +EFI_STATUS +GetStaticDataBuffer ( + OUT PRM_DATA_BUFFER **StaticDataBuffer + ) +{ + EFI_STATUS Status; + PRM_DATA_BUFFER *DataBuffer; + UINTN DataBufferLength; + + if (StaticDataBuffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + *StaticDataBuffer =3D NULL; + + // + // Length of the data buffer =3D Buffer Header Size + Buffer Data Size + // + DataBufferLength =3D sizeof (PRM_DATA_BUFFER_HEADER) + sizeof (STATIC_= DATA_SAMPLE_CONTEXT_BUFFER_MODULE); + + DataBuffer =3D AllocateRuntimeZeroPool (DataBufferLength); + if (DataBuffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Initialize the data buffer header + // + DataBuffer->Header.Signature =3D PRM_DATA_BUFFER_HEADER_SIGNATURE; + DataBuffer->Header.Length =3D (UINT32) DataBufferLength; + + Status =3D PopulateStaticDataBuffer ((STATIC_DATA_SAMPLE_CONTEXT_BUFFE= R_MODULE *) &DataBuffer->Data[0]); + ASSERT_EFI_ERROR (Status); + + *StaticDataBuffer =3D 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 installe= d 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 =3D NULL; + StaticDataBuffer =3D NULL; + PrmConfigProtocol =3D NULL; + + /* + In this sample PRM module, the protocol describing this sample modul= e'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 comm= unicate 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 =3D GetStaticDataBuffer (&StaticDataBuffer); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status) || StaticDataBuffer =3D=3D NULL) { + goto Done; + } + + // + // Allocate and populate the context buffer + // + // This sample module uses a single context buffer for all the handler= s + // Todo: This can be done more elegantly in the future. Likely though = a library service. + // + PrmContextBuffer =3D AllocateRuntimeZeroPool (sizeof (*PrmContextBuffe= r)); + ASSERT (PrmContextBuffer !=3D NULL); + if (PrmContextBuffer =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto Done; + } + CopyGuid (&PrmContextBuffer->HandlerGuid, &mDumpStaticDataBufferPrmHan= dlerGuid); + PrmContextBuffer->Signature =3D PRM_CONTEXT_BUFFER_SIGNATURE; + PrmContextBuffer->Version =3D PRM_CONTEXT_BUFFER_INTERFACE_VERSION; + PrmContextBuffer->StaticDataBuffer =3D StaticDataBuffer; + + PrmConfigProtocol =3D AllocateZeroPool (sizeof (*PrmConfigProtocol)); + ASSERT (PrmConfigProtocol !=3D NULL); + if (PrmConfigProtocol =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto Done; + } + CopyGuid (&PrmConfigProtocol->ModuleContextBuffers.ModuleGuid, &mPrmMo= duleGuid); + PrmConfigProtocol->ModuleContextBuffers.BufferCount =3D 1; + PrmConfigProtocol->ModuleContextBuffers.Buffer =3D PrmContextBuffer; + + // + // Install the PRM Configuration Protocol for this module. This indica= tes the configuration + // library has completed resource initialization for the PRM module. + // + Status =3D gBS->InstallProtocolInterface ( + &mPrmConfigProtocolHandle, + &gPrmConfigProtocolGuid, + EFI_NATIVE_INTERFACE, + (VOID *) PrmConfigProtocol + ); + +Done: + if (EFI_ERROR (Status)) { + if (StaticDataBuffer !=3D NULL) { + FreePool (StaticDataBuffer); + } + if (PrmContextBuffer !=3D NULL) { + FreePool (PrmContextBuffer); + } + if (PrmConfigProtocol !=3D NULL) { + FreePool (PrmConfigProtocol); + } + } + + return Status; +} diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContext= BufferModule.c b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleCon= textBufferModule.c new file mode 100644 index 000000000000..074552d0c07e --- /dev/null +++ b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferM= odule.c @@ -0,0 +1,182 @@ +/** @file + + This PRM Module demonstrates how to configure the module data resource= s 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 + +#include +#include +#include + +#include + +// +// PRM Handler GUIDs +// + +// {e1466081-7562-430f-896b-b0e523dc335a} +#define DUMP_STATIC_DATA_BUFFER_PRM_HANDLER_GUID {0xe1466081, 0x7562, 0x= 430f, {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 serv= ice. + @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 =3D Buffer; + CHAR8 DebugMessage[16]; + + if (OsServiceDebugPrint =3D=3D NULL || Buffer =3D=3D NULL) { + return; + } + + OsServiceDebugPrint (" "); + for (Count =3D 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 serv= ice. + @param[in] StaticDataBuffer A pointer to the static buffer. + +**/ +VOID +EFIAPI +PrintStaticDataBuffer ( + IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrin= t, + IN CONST STATIC_DATA_SAMPLE_CONTEXT_BUFFER_MODULE *StaticDataBuffer + ) +{ + CHAR8 DebugMessage[256]; + + if (OsServiceDebugPrint =3D=3D NULL || StaticDataBuffer =3D=3D NULL) { + return; + } + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " Policy1Enabled =3D 0x%x.\n", + StaticDataBuffer->Policy1Enabled + ); + OsServiceDebugPrint (&DebugMessage[0]); + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " Policy2Enabled =3D 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 b= uffer that were configured + during the firmware boot environment and print those contents at OS ru= ntime. + + @param[in] OsServices An array of pointers to OS provided se= rvices 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 =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // In the POC, the OS debug print service is assumed to be at the begi= nning of ParameterBuffer + OsServiceDebugPrint =3D *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuff= er); + if (OsServiceDebugPrint =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + OsServiceDebugPrint ("Context Buffer DumpStaticDataBufferPrmHandler en= try.\n"); + + if (ContextBuffer->StaticDataBuffer =3D=3D NULL) { + OsServiceDebugPrint ("The static buffer is not allocated!\n"); + return EFI_INVALID_PARAMETER; + } + + OsServiceDebugPrint (" Printing the contents of the static data buffe= r:\n"); + + // + // Verify PRM data buffer signature is valid + // + if ( + ContextBuffer->Signature !=3D PRM_CONTEXT_BUFFER_SIGNATURE || + ContextBuffer->StaticDataBuffer->Header.Signature !=3D PRM_DATA_BUFF= ER_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 ex= it.\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, Du= mpStaticDataBufferPrmHandler) + ); + +EFI_STATUS +EFIAPI +PrmSampleContextBufferModuleInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EFI_SUCCESS; +} diff --git a/PrmPkg/Samples/PrmSampleContextBufferModule/Include/StaticDa= ta.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 Con= text 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 + +#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/DxeConte= xtBufferModuleConfigLib/DxeContextBufferModuleConfigLib.inf b/PrmPkg/Samp= les/PrmSampleContextBufferModule/Library/DxeContextBufferModuleConfigLib/= DxeContextBufferModuleConfigLib.inf new file mode 100644 index 000000000000..db604680e91e --- /dev/null +++ b/PrmPkg/Samples/PrmSampleContextBufferModule/Library/DxeContextBuffe= rModuleConfigLib/DxeContextBufferModuleConfigLib.inf @@ -0,0 +1,39 @@ +## @file +# Sample PRM Configuration Library Instance +# +# The PRM configuration library instance is responsible for initializin= g 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 =3D 0x00010005 + BASE_NAME =3D DxeContextBufferModuleConfigLib + FILE_GUID =3D FFB56F09-65E3-4462-A799-2F0D1930D38C + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D NULL |DXE_DRIVER + CONSTRUCTOR =3D 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/PrmSampleContext= BufferModule.inf b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleC= ontextBufferModule.inf new file mode 100644 index 000000000000..4dd77f526116 --- /dev/null +++ b/PrmPkg/Samples/PrmSampleContextBufferModule/PrmSampleContextBufferM= odule.inf @@ -0,0 +1,42 @@ +## @file +# Sample PRM Driver +# +# A sample PRM Module implementation. This PRM Module includes a PRM Mo= dule configuration library instance +# that applies the configuration for the PRM context data in the boot e= nvironment. A PRM handler +# is provided that accesses the context buffer resources and prints the= ir value at OS runtime. +# +# Copyright (c) Microsoft Corporation +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PrmSampleContextBufferModule + FILE_GUID =3D 5A6CF42B-8BB4-472C-A233-5C4DC4033DC7 + MODULE_TYPE =3D DXE_RUNTIME_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D 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 =3D /DLL /SUBSYSTEM:CONSOLE /VERSION:1.0 --=20 2.28.0.windows.1