/** @file\r
Intel Processor Trace feature.\r
\r
- Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2017 - 2023, Intel Corporation. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
UINTN *TopaMemArray;\r
\r
+ BOOLEAN EnableOnBspOnly;\r
+\r
PROC_TRACE_PROCESSOR_DATA *ProcessorData;\r
} PROC_TRACE_DATA;\r
\r
ConfigData->NumberOfProcessors = (UINT32)NumberOfProcessors;\r
ConfigData->ProcTraceMemSize = PcdGet32 (PcdCpuProcTraceMemSize);\r
ConfigData->ProcTraceOutputScheme = PcdGet8 (PcdCpuProcTraceOutputScheme);\r
+ ConfigData->EnableOnBspOnly = PcdGetBool (PcdCpuProcTraceBspOnly);\r
\r
return ConfigData;\r
}\r
MSR_IA32_RTIT_OUTPUT_BASE_REGISTER OutputBaseReg;\r
MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER OutputMaskPtrsReg;\r
RTIT_TOPA_TABLE_ENTRY *TopaEntryPtr;\r
+ BOOLEAN IsBsp;\r
\r
//\r
// The scope of the MSR_IA32_RTIT_* is core for below processor type, only program\r
return RETURN_SUCCESS;\r
}\r
\r
+ IsBsp = (CpuInfo->ProcessorInfo.StatusFlag & PROCESSOR_AS_BSP_BIT) ? TRUE : FALSE;\r
+\r
+ if (ProcTraceData->EnableOnBspOnly && !IsBsp) {\r
+ return RETURN_SUCCESS;\r
+ }\r
+\r
MemRegionBaseAddr = 0;\r
FirstIn = FALSE;\r
\r
// address base in MSR, IA32_RTIT_OUTPUT_BASE (560h) bits 47:12. Note that all regions must be\r
// aligned based on their size, not just 4K. Thus a 2M region must have bits 20:12 cleared.\r
//\r
- ThreadMemRegionTable = (UINTN *)AllocatePool (ProcTraceData->NumberOfProcessors * sizeof (UINTN *));\r
- if (ThreadMemRegionTable == NULL) {\r
- DEBUG ((DEBUG_ERROR, "Allocate ProcTrace ThreadMemRegionTable Failed\n"));\r
- return RETURN_OUT_OF_RESOURCES;\r
- }\r
\r
- ProcTraceData->ThreadMemRegionTable = ThreadMemRegionTable;\r
-\r
- for (Index = 0; Index < ProcTraceData->NumberOfProcessors; Index++, ProcTraceData->AllocatedThreads++) {\r
- Pages = EFI_SIZE_TO_PAGES (MemRegionSize);\r
- Alignment = MemRegionSize;\r
- AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
- if (AlignedAddress == 0) {\r
- DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated only for %d threads\n", ProcTraceData->AllocatedThreads));\r
- if (Index == 0) {\r
- //\r
- // Could not allocate for BSP even\r
- //\r
- FreePool ((VOID *)ThreadMemRegionTable);\r
- ThreadMemRegionTable = NULL;\r
- return RETURN_OUT_OF_RESOURCES;\r
+ Pages = EFI_SIZE_TO_PAGES (MemRegionSize);\r
+ Alignment = MemRegionSize;\r
+ if (ProcTraceData->EnableOnBspOnly) {\r
+ //\r
+ // When only enable ProcTrace on BSP, this is the first and only time ProcTraceInitialize() runs.\r
+ //\r
+ MemRegionBaseAddr = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
+ if (MemRegionBaseAddr == 0) {\r
+ //\r
+ // Could not allocate for BSP even\r
+ //\r
+ DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, failed to allocate buffer for BSP\n"));\r
+ return RETURN_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT MemRegionBaseAddr(aligned) for BSP only: 0x%llX.\n", (UINT64)MemRegionBaseAddr));\r
+ } else {\r
+ ThreadMemRegionTable = (UINTN *)AllocatePool (ProcTraceData->NumberOfProcessors * sizeof (UINTN *));\r
+ if (ThreadMemRegionTable == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "Allocate ProcTrace ThreadMemRegionTable Failed\n"));\r
+ return RETURN_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ProcTraceData->ThreadMemRegionTable = ThreadMemRegionTable;\r
+\r
+ for (Index = 0; Index < ProcTraceData->NumberOfProcessors; Index++, ProcTraceData->AllocatedThreads++) {\r
+ AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
+ if (AlignedAddress == 0) {\r
+ DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated only for %d threads\n", ProcTraceData->AllocatedThreads));\r
+ if (Index == 0) {\r
+ //\r
+ // Could not allocate for BSP even\r
+ //\r
+ FreePool ((VOID *)ThreadMemRegionTable);\r
+ ThreadMemRegionTable = NULL;\r
+ return RETURN_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ break;\r
}\r
\r
- break;\r
+ ThreadMemRegionTable[Index] = AlignedAddress;\r
+ DEBUG ((DEBUG_INFO, "ProcTrace: PT MemRegionBaseAddr(aligned) for thread %d: 0x%llX \n", Index, (UINT64)ThreadMemRegionTable[Index]));\r
}\r
\r
- ThreadMemRegionTable[Index] = AlignedAddress;\r
- DEBUG ((DEBUG_INFO, "ProcTrace: PT MemRegionBaseAddr(aligned) for thread %d: 0x%llX \n", Index, (UINT64)ThreadMemRegionTable[Index]));\r
+ DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT mem for %d thread \n", ProcTraceData->AllocatedThreads));\r
}\r
-\r
- DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT mem for %d thread \n", ProcTraceData->AllocatedThreads));\r
}\r
\r
- if (ProcessorNumber < ProcTraceData->AllocatedThreads) {\r
- MemRegionBaseAddr = ProcTraceData->ThreadMemRegionTable[ProcessorNumber];\r
- } else {\r
- return RETURN_SUCCESS;\r
+ if (!ProcTraceData->EnableOnBspOnly) {\r
+ if (ProcessorNumber < ProcTraceData->AllocatedThreads) {\r
+ MemRegionBaseAddr = ProcTraceData->ThreadMemRegionTable[ProcessorNumber];\r
+ } else {\r
+ return RETURN_SUCCESS;\r
+ }\r
}\r
\r
///\r
//\r
if (FirstIn) {\r
DEBUG ((DEBUG_INFO, "ProcTrace: Enabling ToPA scheme \n"));\r
- //\r
- // Let BSP allocate ToPA table mem for all threads\r
- //\r
- TopaMemArray = (UINTN *)AllocatePool (ProcTraceData->AllocatedThreads * sizeof (UINTN *));\r
- if (TopaMemArray == NULL) {\r
- DEBUG ((DEBUG_ERROR, "ProcTrace: Allocate mem for ToPA Failed\n"));\r
- return RETURN_OUT_OF_RESOURCES;\r
- }\r
\r
- ProcTraceData->TopaMemArray = TopaMemArray;\r
+ Pages = EFI_SIZE_TO_PAGES (sizeof (PROC_TRACE_TOPA_TABLE));\r
+ Alignment = 0x1000;\r
\r
- for (Index = 0; Index < ProcTraceData->AllocatedThreads; Index++) {\r
- Pages = EFI_SIZE_TO_PAGES (sizeof (PROC_TRACE_TOPA_TABLE));\r
- Alignment = 0x1000;\r
- AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
- if (AlignedAddress == 0) {\r
- if (Index < ProcTraceData->AllocatedThreads) {\r
- ProcTraceData->AllocatedThreads = Index;\r
- }\r
+ if (ProcTraceData->EnableOnBspOnly) {\r
+ //\r
+ // When only enable ProcTrace on BSP, this is the first and only time ProcTraceInitialize() runs.\r
+ //\r
+ TopaTableBaseAddr = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
+ if (TopaTableBaseAddr == 0) {\r
+ DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, failed to allocate ToPA mem for BSP"));\r
+ return RETURN_OUT_OF_RESOURCES;\r
+ }\r
\r
- DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated ToPA mem only for %d threads\n", ProcTraceData->AllocatedThreads));\r
- if (Index == 0) {\r
- //\r
- // Could not allocate for BSP even\r
- //\r
- FreePool ((VOID *)TopaMemArray);\r
- TopaMemArray = NULL;\r
- return RETURN_OUT_OF_RESOURCES;\r
+ DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for BSP only: 0x%llX \n", (UINT64)TopaTableBaseAddr));\r
+ } else {\r
+ //\r
+ // Let BSP allocate ToPA table mem for all threads\r
+ //\r
+ TopaMemArray = (UINTN *)AllocatePool (ProcTraceData->AllocatedThreads * sizeof (UINTN *));\r
+ if (TopaMemArray == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "ProcTrace: Allocate mem for ToPA Failed\n"));\r
+ return RETURN_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ProcTraceData->TopaMemArray = TopaMemArray;\r
+\r
+ for (Index = 0; Index < ProcTraceData->AllocatedThreads; Index++) {\r
+ AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
+ if (AlignedAddress == 0) {\r
+ if (Index < ProcTraceData->AllocatedThreads) {\r
+ ProcTraceData->AllocatedThreads = Index;\r
+ }\r
+\r
+ DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated ToPA mem only for %d threads\n", ProcTraceData->AllocatedThreads));\r
+ if (Index == 0) {\r
+ //\r
+ // Could not allocate for BSP even\r
+ //\r
+ FreePool ((VOID *)TopaMemArray);\r
+ TopaMemArray = NULL;\r
+ return RETURN_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ break;\r
}\r
\r
- break;\r
+ TopaMemArray[Index] = AlignedAddress;\r
+ DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for thread %d is 0x%llX \n", Index, (UINT64)TopaMemArray[Index]));\r
}\r
\r
- TopaMemArray[Index] = AlignedAddress;\r
- DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for thread %d is 0x%llX \n", Index, (UINT64)TopaMemArray[Index]));\r
+ DEBUG ((DEBUG_INFO, "ProcTrace: Allocated ToPA mem for %d thread \n", ProcTraceData->AllocatedThreads));\r
}\r
-\r
- DEBUG ((DEBUG_INFO, "ProcTrace: Allocated ToPA mem for %d thread \n", ProcTraceData->AllocatedThreads));\r
}\r
\r
- if (ProcessorNumber < ProcTraceData->AllocatedThreads) {\r
- TopaTableBaseAddr = ProcTraceData->TopaMemArray[ProcessorNumber];\r
- } else {\r
- return RETURN_SUCCESS;\r
+ if (!ProcTraceData->EnableOnBspOnly) {\r
+ if (ProcessorNumber < ProcTraceData->AllocatedThreads) {\r
+ TopaTableBaseAddr = ProcTraceData->TopaMemArray[ProcessorNumber];\r
+ } else {\r
+ return RETURN_SUCCESS;\r
+ }\r
}\r
\r
TopaTable = (PROC_TRACE_TOPA_TABLE *)TopaTableBaseAddr;\r