From: Michael Kubacki Date: Wed, 10 Jun 2020 18:06:07 +0000 (-0700) Subject: PrmPkg/Application/PrmInfo: Add initial application X-Git-Tag: edk2-stable202205~142 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=4348c72ad0328fcf8ef37930cf51a5dbc2388038 PrmPkg/Application/PrmInfo: Add initial application 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 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 Acked-by: Michael D Kinney Acked-by: Liming Gao Acked-by: Leif Lindholm Reviewed-by: Ankit Sinha --- diff --git a/PrmPkg/Application/PrmInfo/PrmInfo.c b/PrmPkg/Application/PrmInfo/PrmInfo.c new file mode 100644 index 0000000000..431a6f2061 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 0000000000..c2c3fa2f23 --- /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 +#include +#include +#include + +#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 0000000000..df8fb9ccc0 --- /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 0000000000..1b65e117e8 --- /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." diff --git a/PrmPkg/Application/PrmInfo/PrmInfoExtra.uni b/PrmPkg/Application/PrmInfo/PrmInfoExtra.uni new file mode 100644 index 0000000000..f50c17903a --- /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 0000000000..9385fd8483 --- /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 785e2c24c2..94888d1c70 100644 --- a/PrmPkg/PrmPkg.dec +++ b/PrmPkg/PrmPkg.dec @@ -30,6 +30,7 @@ [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 @@ ## 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 e876f2053a..5241354cb2 100644 --- a/PrmPkg/PrmPkg.dsc +++ b/PrmPkg/PrmPkg.dsc @@ -36,13 +36,14 @@ 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 @@ 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 @@ } $(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 b79cb66c47..2a8a40c924 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.