STATIC UINTN mMaxRuntimeMmioRangeCount;\r
STATIC UINTN mMaxStaticDataBufferCount;\r
\r
-STATIC PRM_RUNTIME_MMIO_RANGES **mRuntimeMmioRanges;\r
-STATIC PRM_DATA_BUFFER ***mStaticDataBuffers;\r
+GLOBAL_REMOVE_IF_UNREFERENCED STATIC PRM_RUNTIME_MMIO_RANGES **mRuntimeMmioRanges;\r
+GLOBAL_REMOVE_IF_UNREFERENCED STATIC PRM_DATA_BUFFER ***mStaticDataBuffers;\r
\r
/**\r
Converts the runtime memory range physical addresses to virtual addresses.\r
)\r
{\r
EFI_STATUS Status;\r
- UINTN BufferIndex;\r
UINTN HandleCount;\r
UINTN HandleIndex;\r
UINTN RangeIndex;\r
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW\r
+ UINTN BufferIndex;\r
UINTN StaticDataBufferIndex;\r
+ PRM_CONTEXT_BUFFER *CurrentContextBuffer;\r
+#endif\r
EFI_HANDLE *HandleBuffer;\r
PRM_CONFIG_PROTOCOL *PrmConfigProtocol;\r
- PRM_CONTEXT_BUFFER *CurrentContextBuffer;\r
\r
DEBUG ((DEBUG_INFO, "%a %a - Entry.\n", _DBGMSGID_, __FUNCTION__));\r
\r
RangeIndex = 0;\r
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW\r
StaticDataBufferIndex = 0;\r
\r
- mRuntimeMmioRanges = AllocateRuntimeZeroPool (sizeof (*mRuntimeMmioRanges) * mMaxRuntimeMmioRangeCount);\r
- if (mRuntimeMmioRanges == NULL && mMaxRuntimeMmioRangeCount > 0) {\r
+ mStaticDataBuffers = AllocateRuntimeZeroPool (sizeof (*mStaticDataBuffers) * mMaxStaticDataBufferCount);\r
+ if (mStaticDataBuffers == NULL && mMaxStaticDataBufferCount > 0) {\r
DEBUG ((\r
DEBUG_ERROR,\r
- " %a %a: Memory allocation for runtime MMIO pointer array failed.\n",\r
+ " %a %a: Memory allocation for PRM static data buffer pointer array failed.\n",\r
_DBGMSGID_,\r
__FUNCTION__\r
));\r
ASSERT (FALSE);\r
return;\r
}\r
+#endif\r
\r
- mStaticDataBuffers = AllocateRuntimeZeroPool (sizeof (*mStaticDataBuffers) * mMaxStaticDataBufferCount);\r
- if (mStaticDataBuffers == NULL && mMaxStaticDataBufferCount > 0) {\r
+ mRuntimeMmioRanges = AllocateRuntimeZeroPool (sizeof (*mRuntimeMmioRanges) * mMaxRuntimeMmioRangeCount);\r
+ if (mRuntimeMmioRanges == NULL && mMaxRuntimeMmioRangeCount > 0) {\r
DEBUG ((\r
DEBUG_ERROR,\r
- " %a %a: Memory allocation for PRM static data buffer pointer array failed.\n",\r
+ " %a %a: Memory allocation for runtime MMIO pointer array failed.\n",\r
_DBGMSGID_,\r
__FUNCTION__\r
));\r
continue;\r
}\r
\r
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW\r
for (BufferIndex = 0; BufferIndex < PrmConfigProtocol->ModuleContextBuffers.BufferCount; BufferIndex++) {\r
CurrentContextBuffer = &(PrmConfigProtocol->ModuleContextBuffers.Buffer[BufferIndex]);\r
\r
mStaticDataBuffers[StaticDataBufferIndex++] = &CurrentContextBuffer->StaticDataBuffer;\r
}\r
}\r
+#endif\r
if (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges != NULL) {\r
if (RangeIndex >= mMaxRuntimeMmioRangeCount) {\r
Status = EFI_BUFFER_TOO_SMALL;\r
__FUNCTION__,\r
RangeIndex\r
));\r
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW\r
DEBUG ((\r
DEBUG_INFO,\r
" %a %a: %d static buffers saved for future virtual memory conversion.\n",\r
__FUNCTION__,\r
StaticDataBufferIndex\r
));\r
+#endif\r
}\r
}\r
\r
{\r
UINTN Index;\r
\r
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW\r
//\r
// Convert static data buffer pointers\r
//\r
for (Index = 0; Index < mMaxStaticDataBufferCount; Index++) {\r
gRT->ConvertPointer (0x0, (VOID **) mStaticDataBuffers[Index]);\r
}\r
+#endif\r
\r
//\r
// Convert runtime MMIO ranges\r
if (PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges != NULL) {\r
DEBUG ((\r
DEBUG_INFO,\r
- " %a %a: Found %d PRM runtime MMIO ranges to convert.\n",\r
+ " %a %a: Found %d PRM runtime MMIO ranges.\n",\r
_DBGMSGID_,\r
__FUNCTION__,\r
PrmConfigProtocol->ModuleContextBuffers.RuntimeMmioRanges->Count\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ DEBUG ((DEBUG_INFO, " %a %a: Context buffers will be allocated in ", _DBGMSGID_, __FUNCTION__));\r
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW\r
+ DEBUG ((DEBUG_INFO, "firmware.\n"));\r
+#else\r
+ DEBUG ((DEBUG_INFO, "the operating system.\n"));\r
+#endif\r
+\r
//\r
// Register a notification function for virtual address change\r
//\r
UINT16 StructureLength; ///< Length in bytes of this structure\r
GUID Identifier; ///< GUID of the PRM handler for this structure\r
UINT64 PhysicalAddress; ///< Physical address of this PRM handler\r
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW\r
UINT64 PrmContextBuffer; ///< Physical address of the context buffer for this\r
///< PRM handler (PRM_CONTEXT_BUFFER *)\r
+#else\r
UINT64 StaticDataBuffer; ///< Physical address of the static data buffer for\r
///< this PRM handler (PRM_DATA_BUFFER *)\r
UINT64 AcpiParameterBuffer; ///< Physical address of the parameter buffer\r
///< that is only used in the case of _DSM invocation.\r
///< If _DSM invocation is not used, this value is\r
///< ignored.\r
+#endif\r
+\r
} PRM_HANDLER_INFORMATION_STRUCT;\r
\r
typedef struct {\r
The following list are the currently defined build flags (if any) that may be passed to the `build` command\r
(e.g. -D FLAG=VALUE).\r
\r
+* `ALLOCATE_CONTEXT_BUFFER_IN_FW` - Allocates the context buffer for each PRM handler in the firmware instead of\r
+ the operating system (OS).\r
+\r
+ Additional detail: The context buffer structure is defined in [PrmContextBuffer.h](PrmPkg/Include/PrmContextBuffer.h).\r
+ This structure can be instantiated by either firmware with a physical pointer to the buffer placed in the\r
+ `PRM_HANDLER_INFORMATION_STRUCT` for each handler wherein the OS would convert that physical pointer and pass it\r
+ as a virtual address pointer to each PRM handler. Alternatively, the context buffer can be allocated and populated\r
+ by the OS where it would get all the information to populate the context buffer from other structures.\r
+\r
+ The default is for the OS to allocate and populate the buffer. The alternative option of the firmware doing this\r
+ work is kept in the source code until broader OS testing is completed.\r
+\r
## Overview\r
At a high-level, PRM can be viewed from three levels of granularity:\r
\r
//\r
// Allocate and populate the context buffer\r
//\r
+#ifdef ALLOCATE_CONTEXT_BUFFER_IN_FW\r
+ //\r
+ // The context buffer allocated in FW will continue being used at OS runtime so it must\r
+ // be a runtime services data buffer.\r
+ //\r
// This sample module uses a single context buffer for all the handlers\r
// Todo: This can be done more elegantly in the future. Likely though a library service.\r
//\r
PrmContextBuffer = AllocateRuntimeZeroPool (sizeof (*PrmContextBuffer));\r
+#else\r
+ //\r
+ // This context buffer is not actually used by PRM handler at OS runtime. The OS will allocate\r
+ // the actual context buffer passed to the PRM handler.\r
+ //\r
+ // This context buffer is used internally in the firmware to associate a PRM handler with a\r
+ // a static data buffer and a runtime MMIO ranges array so those can be placed into the\r
+ // PRM_HANDLER_INFORMATION_STRUCT and PRM_MODULE_INFORMATION_STRUCT respectively for the PRM handler.\r
+ //\r
+ PrmContextBuffer = AllocateZeroPool (sizeof (*PrmContextBuffer));\r
+#endif\r
ASSERT (PrmContextBuffer != NULL);\r
if (PrmContextBuffer == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r