mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg: Update code to support enable ProcTrace only on BSP
Update code to support enable ProcTrace only on BSP. Add a new dynamic PCD to indicate if enable ProcTrace only on BSP. In ProcTrace.c code, if this new PCD is true, only allocate buffer and set CtrlReg.Bits.TraceEn to 1 for BSP. Bugzila: https://bugzilla.tianocore.org/show_bug.cgi?id=4423 Signed-off-by: Dun Tan <dun.tan@intel.com> Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Xiao X Chen <xiao.x.chen@intel.com>
This commit is contained in:
parent
5a349b96b1
commit
61e2c83424
|
@ -4,7 +4,7 @@
|
||||||
# This library registers CPU features defined in Intel(R) 64 and IA-32
|
# This library registers CPU features defined in Intel(R) 64 and IA-32
|
||||||
# Architectures Software Developer's Manual.
|
# Architectures Software Developer's Manual.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2017 - 2023, Intel Corporation. All rights reserved.<BR>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
|
@ -62,3 +62,4 @@
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset ## SOMETIMES_CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset ## SOMETIMES_CONSUMES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceOutputScheme ## SOMETIMES_CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceOutputScheme ## SOMETIMES_CONSUMES
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceMemSize ## SOMETIMES_CONSUMES
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceMemSize ## SOMETIMES_CONSUMES
|
||||||
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceBspOnly ## SOMETIMES_CONSUMES
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Intel Processor Trace feature.
|
Intel Processor Trace feature.
|
||||||
|
|
||||||
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2017 - 2023, Intel Corporation. All rights reserved.<BR>
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
@ -46,6 +46,8 @@ typedef struct {
|
||||||
|
|
||||||
UINTN *TopaMemArray;
|
UINTN *TopaMemArray;
|
||||||
|
|
||||||
|
BOOLEAN EnableOnBspOnly;
|
||||||
|
|
||||||
PROC_TRACE_PROCESSOR_DATA *ProcessorData;
|
PROC_TRACE_PROCESSOR_DATA *ProcessorData;
|
||||||
} PROC_TRACE_DATA;
|
} PROC_TRACE_DATA;
|
||||||
|
|
||||||
|
@ -77,6 +79,7 @@ ProcTraceGetConfigData (
|
||||||
ConfigData->NumberOfProcessors = (UINT32)NumberOfProcessors;
|
ConfigData->NumberOfProcessors = (UINT32)NumberOfProcessors;
|
||||||
ConfigData->ProcTraceMemSize = PcdGet32 (PcdCpuProcTraceMemSize);
|
ConfigData->ProcTraceMemSize = PcdGet32 (PcdCpuProcTraceMemSize);
|
||||||
ConfigData->ProcTraceOutputScheme = PcdGet8 (PcdCpuProcTraceOutputScheme);
|
ConfigData->ProcTraceOutputScheme = PcdGet8 (PcdCpuProcTraceOutputScheme);
|
||||||
|
ConfigData->EnableOnBspOnly = PcdGetBool (PcdCpuProcTraceBspOnly);
|
||||||
|
|
||||||
return ConfigData;
|
return ConfigData;
|
||||||
}
|
}
|
||||||
|
@ -188,6 +191,7 @@ ProcTraceInitialize (
|
||||||
MSR_IA32_RTIT_OUTPUT_BASE_REGISTER OutputBaseReg;
|
MSR_IA32_RTIT_OUTPUT_BASE_REGISTER OutputBaseReg;
|
||||||
MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER OutputMaskPtrsReg;
|
MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER OutputMaskPtrsReg;
|
||||||
RTIT_TOPA_TABLE_ENTRY *TopaEntryPtr;
|
RTIT_TOPA_TABLE_ENTRY *TopaEntryPtr;
|
||||||
|
BOOLEAN IsBsp;
|
||||||
|
|
||||||
//
|
//
|
||||||
// The scope of the MSR_IA32_RTIT_* is core for below processor type, only program
|
// The scope of the MSR_IA32_RTIT_* is core for below processor type, only program
|
||||||
|
@ -236,6 +240,12 @@ ProcTraceInitialize (
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IsBsp = (CpuInfo->ProcessorInfo.StatusFlag & PROCESSOR_AS_BSP_BIT) ? TRUE : FALSE;
|
||||||
|
|
||||||
|
if (ProcTraceData->EnableOnBspOnly && !IsBsp) {
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
MemRegionBaseAddr = 0;
|
MemRegionBaseAddr = 0;
|
||||||
FirstIn = FALSE;
|
FirstIn = FALSE;
|
||||||
|
|
||||||
|
@ -260,43 +270,62 @@ ProcTraceInitialize (
|
||||||
// address base in MSR, IA32_RTIT_OUTPUT_BASE (560h) bits 47:12. Note that all regions must be
|
// address base in MSR, IA32_RTIT_OUTPUT_BASE (560h) bits 47:12. Note that all regions must be
|
||||||
// aligned based on their size, not just 4K. Thus a 2M region must have bits 20:12 cleared.
|
// aligned based on their size, not just 4K. Thus a 2M region must have bits 20:12 cleared.
|
||||||
//
|
//
|
||||||
ThreadMemRegionTable = (UINTN *)AllocatePool (ProcTraceData->NumberOfProcessors * sizeof (UINTN *));
|
|
||||||
if (ThreadMemRegionTable == NULL) {
|
|
||||||
DEBUG ((DEBUG_ERROR, "Allocate ProcTrace ThreadMemRegionTable Failed\n"));
|
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcTraceData->ThreadMemRegionTable = ThreadMemRegionTable;
|
Pages = EFI_SIZE_TO_PAGES (MemRegionSize);
|
||||||
|
Alignment = MemRegionSize;
|
||||||
for (Index = 0; Index < ProcTraceData->NumberOfProcessors; Index++, ProcTraceData->AllocatedThreads++) {
|
if (ProcTraceData->EnableOnBspOnly) {
|
||||||
Pages = EFI_SIZE_TO_PAGES (MemRegionSize);
|
//
|
||||||
Alignment = MemRegionSize;
|
// When only enable ProcTrace on BSP, this is the first and only time ProcTraceInitialize() runs.
|
||||||
AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
|
//
|
||||||
if (AlignedAddress == 0) {
|
MemRegionBaseAddr = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
|
||||||
DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated only for %d threads\n", ProcTraceData->AllocatedThreads));
|
if (MemRegionBaseAddr == 0) {
|
||||||
if (Index == 0) {
|
//
|
||||||
//
|
// Could not allocate for BSP even
|
||||||
// Could not allocate for BSP even
|
//
|
||||||
//
|
DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, failed to allocate buffer for BSP\n"));
|
||||||
FreePool ((VOID *)ThreadMemRegionTable);
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
ThreadMemRegionTable = NULL;
|
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadMemRegionTable[Index] = AlignedAddress;
|
DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT MemRegionBaseAddr(aligned) for BSP only: 0x%llX.\n", (UINT64)MemRegionBaseAddr));
|
||||||
DEBUG ((DEBUG_INFO, "ProcTrace: PT MemRegionBaseAddr(aligned) for thread %d: 0x%llX \n", Index, (UINT64)ThreadMemRegionTable[Index]));
|
} else {
|
||||||
}
|
ThreadMemRegionTable = (UINTN *)AllocatePool (ProcTraceData->NumberOfProcessors * sizeof (UINTN *));
|
||||||
|
if (ThreadMemRegionTable == NULL) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "Allocate ProcTrace ThreadMemRegionTable Failed\n"));
|
||||||
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT mem for %d thread \n", ProcTraceData->AllocatedThreads));
|
ProcTraceData->ThreadMemRegionTable = ThreadMemRegionTable;
|
||||||
|
|
||||||
|
for (Index = 0; Index < ProcTraceData->NumberOfProcessors; Index++, ProcTraceData->AllocatedThreads++) {
|
||||||
|
AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
|
||||||
|
if (AlignedAddress == 0) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated only for %d threads\n", ProcTraceData->AllocatedThreads));
|
||||||
|
if (Index == 0) {
|
||||||
|
//
|
||||||
|
// Could not allocate for BSP even
|
||||||
|
//
|
||||||
|
FreePool ((VOID *)ThreadMemRegionTable);
|
||||||
|
ThreadMemRegionTable = NULL;
|
||||||
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadMemRegionTable[Index] = AlignedAddress;
|
||||||
|
DEBUG ((DEBUG_INFO, "ProcTrace: PT MemRegionBaseAddr(aligned) for thread %d: 0x%llX \n", Index, (UINT64)ThreadMemRegionTable[Index]));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT mem for %d thread \n", ProcTraceData->AllocatedThreads));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ProcessorNumber < ProcTraceData->AllocatedThreads) {
|
if (!ProcTraceData->EnableOnBspOnly) {
|
||||||
MemRegionBaseAddr = ProcTraceData->ThreadMemRegionTable[ProcessorNumber];
|
if (ProcessorNumber < ProcTraceData->AllocatedThreads) {
|
||||||
} else {
|
MemRegionBaseAddr = ProcTraceData->ThreadMemRegionTable[ProcessorNumber];
|
||||||
return RETURN_SUCCESS;
|
} else {
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -367,50 +396,67 @@ ProcTraceInitialize (
|
||||||
//
|
//
|
||||||
if (FirstIn) {
|
if (FirstIn) {
|
||||||
DEBUG ((DEBUG_INFO, "ProcTrace: Enabling ToPA scheme \n"));
|
DEBUG ((DEBUG_INFO, "ProcTrace: Enabling ToPA scheme \n"));
|
||||||
//
|
|
||||||
// Let BSP allocate ToPA table mem for all threads
|
|
||||||
//
|
|
||||||
TopaMemArray = (UINTN *)AllocatePool (ProcTraceData->AllocatedThreads * sizeof (UINTN *));
|
|
||||||
if (TopaMemArray == NULL) {
|
|
||||||
DEBUG ((DEBUG_ERROR, "ProcTrace: Allocate mem for ToPA Failed\n"));
|
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcTraceData->TopaMemArray = TopaMemArray;
|
Pages = EFI_SIZE_TO_PAGES (sizeof (PROC_TRACE_TOPA_TABLE));
|
||||||
|
Alignment = 0x1000;
|
||||||
|
|
||||||
for (Index = 0; Index < ProcTraceData->AllocatedThreads; Index++) {
|
if (ProcTraceData->EnableOnBspOnly) {
|
||||||
Pages = EFI_SIZE_TO_PAGES (sizeof (PROC_TRACE_TOPA_TABLE));
|
//
|
||||||
Alignment = 0x1000;
|
// When only enable ProcTrace on BSP, this is the first and only time ProcTraceInitialize() runs.
|
||||||
AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
|
//
|
||||||
if (AlignedAddress == 0) {
|
TopaTableBaseAddr = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
|
||||||
if (Index < ProcTraceData->AllocatedThreads) {
|
if (TopaTableBaseAddr == 0) {
|
||||||
ProcTraceData->AllocatedThreads = Index;
|
DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, failed to allocate ToPA mem for BSP"));
|
||||||
}
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
|
|
||||||
DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated ToPA mem only for %d threads\n", ProcTraceData->AllocatedThreads));
|
|
||||||
if (Index == 0) {
|
|
||||||
//
|
|
||||||
// Could not allocate for BSP even
|
|
||||||
//
|
|
||||||
FreePool ((VOID *)TopaMemArray);
|
|
||||||
TopaMemArray = NULL;
|
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TopaMemArray[Index] = AlignedAddress;
|
DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for BSP only: 0x%llX \n", (UINT64)TopaTableBaseAddr));
|
||||||
DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for thread %d is 0x%llX \n", Index, (UINT64)TopaMemArray[Index]));
|
} else {
|
||||||
}
|
//
|
||||||
|
// Let BSP allocate ToPA table mem for all threads
|
||||||
|
//
|
||||||
|
TopaMemArray = (UINTN *)AllocatePool (ProcTraceData->AllocatedThreads * sizeof (UINTN *));
|
||||||
|
if (TopaMemArray == NULL) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "ProcTrace: Allocate mem for ToPA Failed\n"));
|
||||||
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO, "ProcTrace: Allocated ToPA mem for %d thread \n", ProcTraceData->AllocatedThreads));
|
ProcTraceData->TopaMemArray = TopaMemArray;
|
||||||
|
|
||||||
|
for (Index = 0; Index < ProcTraceData->AllocatedThreads; Index++) {
|
||||||
|
AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
|
||||||
|
if (AlignedAddress == 0) {
|
||||||
|
if (Index < ProcTraceData->AllocatedThreads) {
|
||||||
|
ProcTraceData->AllocatedThreads = Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated ToPA mem only for %d threads\n", ProcTraceData->AllocatedThreads));
|
||||||
|
if (Index == 0) {
|
||||||
|
//
|
||||||
|
// Could not allocate for BSP even
|
||||||
|
//
|
||||||
|
FreePool ((VOID *)TopaMemArray);
|
||||||
|
TopaMemArray = NULL;
|
||||||
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
TopaMemArray[Index] = AlignedAddress;
|
||||||
|
DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for thread %d is 0x%llX \n", Index, (UINT64)TopaMemArray[Index]));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_INFO, "ProcTrace: Allocated ToPA mem for %d thread \n", ProcTraceData->AllocatedThreads));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ProcessorNumber < ProcTraceData->AllocatedThreads) {
|
if (!ProcTraceData->EnableOnBspOnly) {
|
||||||
TopaTableBaseAddr = ProcTraceData->TopaMemArray[ProcessorNumber];
|
if (ProcessorNumber < ProcTraceData->AllocatedThreads) {
|
||||||
} else {
|
TopaTableBaseAddr = ProcTraceData->TopaMemArray[ProcessorNumber];
|
||||||
return RETURN_SUCCESS;
|
} else {
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TopaTable = (PROC_TRACE_TOPA_TABLE *)TopaTableBaseAddr;
|
TopaTable = (PROC_TRACE_TOPA_TABLE *)TopaTableBaseAddr;
|
||||||
|
|
|
@ -338,6 +338,13 @@
|
||||||
# @Prompt Current boot is a power-on reset.
|
# @Prompt Current boot is a power-on reset.
|
||||||
gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset|FALSE|BOOLEAN|0x0000001B
|
gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset|FALSE|BOOLEAN|0x0000001B
|
||||||
|
|
||||||
|
## This PCD indicates whether CPU processor trace is enabled on BSP only when CPU processor trace is enabled.<BR><BR>
|
||||||
|
# This PCD is ignored if CPU processor trace is disabled.<BR><BR>
|
||||||
|
# TRUE - CPU processor trace is enabled on BSP only.<BR>
|
||||||
|
# FASLE - CPU processor trace is enabled on all CPU.<BR>
|
||||||
|
# @Prompt Enable CPU processor trace only on BSP.
|
||||||
|
gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceBspOnly|FALSE|BOOLEAN|0x60000019
|
||||||
|
|
||||||
[PcdsFixedAtBuild.X64, PcdsPatchableInModule.X64, PcdsDynamic.X64, PcdsDynamicEx.X64]
|
[PcdsFixedAtBuild.X64, PcdsPatchableInModule.X64, PcdsDynamic.X64, PcdsDynamicEx.X64]
|
||||||
## Indicate access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock.
|
## Indicate access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock.
|
||||||
# MMIO access is always allowed regardless of the value of this PCD.
|
# MMIO access is always allowed regardless of the value of this PCD.
|
||||||
|
|
Loading…
Reference in New Issue