]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiCpuPkg / Library / CpuCommonFeaturesLib / ProcTrace.c
CommitLineData
bc230057
ED
1/** @file\r
2 Intel Processor Trace feature.\r
3\r
7367cc6c 4 Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>\r
0acd8697 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
bc230057
ED
6\r
7**/\r
8\r
9#include "CpuCommonFeatures.h"\r
10\r
bc230057 11///\r
b2b0ffc9 12/// This macro define the max entries in the Topa table.\r
7367cc6c
LG
13/// Each entry in the table contains some attribute bits, a pointer to an output region, and the size of the region.\r
14/// The last entry in the table may hold a pointer to the next table. This pointer can either point to the top of the\r
15/// current table (for circular array) or to the base of another table.\r
16/// At least 2 entries are needed because the list of entries must\r
17/// be terminated by an entry with the END bit set to 1, so 2\r
b2b0ffc9 18/// entries are required to use a single valid entry.\r
bc230057 19///\r
053e878b 20#define MAX_TOPA_ENTRY_COUNT 2\r
bc230057
ED
21\r
22///\r
23/// Processor trace output scheme selection.\r
24///\r
25typedef enum {\r
330021fa
ED
26 RtitOutputSchemeSingleRange = 0,\r
27 RtitOutputSchemeToPA\r
28} RTIT_OUTPUT_SCHEME;\r
bc230057
ED
29\r
30typedef struct {\r
053e878b
MK
31 BOOLEAN TopaSupported;\r
32 BOOLEAN SingleRangeSupported;\r
33 MSR_IA32_RTIT_CTL_REGISTER RtitCtrl;\r
34 MSR_IA32_RTIT_OUTPUT_BASE_REGISTER RtitOutputBase;\r
35 MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER RtitOutputMaskPtrs;\r
bc230057
ED
36} PROC_TRACE_PROCESSOR_DATA;\r
37\r
38typedef struct {\r
053e878b 39 UINT32 NumberOfProcessors;\r
bc230057 40\r
053e878b
MK
41 UINT8 ProcTraceOutputScheme;\r
42 UINT32 ProcTraceMemSize;\r
bc230057 43\r
053e878b
MK
44 UINTN *ThreadMemRegionTable;\r
45 UINTN AllocatedThreads;\r
bc230057 46\r
053e878b 47 UINTN *TopaMemArray;\r
bc230057 48\r
053e878b 49 PROC_TRACE_PROCESSOR_DATA *ProcessorData;\r
bc230057
ED
50} PROC_TRACE_DATA;\r
51\r
52typedef struct {\r
b2b0ffc9 53 RTIT_TOPA_TABLE_ENTRY TopaEntry[MAX_TOPA_ENTRY_COUNT];\r
bc230057
ED
54} PROC_TRACE_TOPA_TABLE;\r
55\r
56/**\r
57 Prepares for the data used by CPU feature detection and initialization.\r
58\r
59 @param[in] NumberOfProcessors The number of CPUs in the platform.\r
60\r
61 @return Pointer to a buffer of CPU related configuration data.\r
62\r
63 @note This service could be called by BSP only.\r
64**/\r
65VOID *\r
66EFIAPI\r
67ProcTraceGetConfigData (\r
68 IN UINTN NumberOfProcessors\r
69 )\r
70{\r
71 PROC_TRACE_DATA *ConfigData;\r
72\r
73 ConfigData = AllocateZeroPool (sizeof (PROC_TRACE_DATA) + sizeof (PROC_TRACE_PROCESSOR_DATA) * NumberOfProcessors);\r
74 ASSERT (ConfigData != NULL);\r
053e878b 75 ConfigData->ProcessorData = (PROC_TRACE_PROCESSOR_DATA *)((UINT8 *)ConfigData + sizeof (PROC_TRACE_DATA));\r
bc230057 76\r
053e878b
MK
77 ConfigData->NumberOfProcessors = (UINT32)NumberOfProcessors;\r
78 ConfigData->ProcTraceMemSize = PcdGet32 (PcdCpuProcTraceMemSize);\r
bc230057
ED
79 ConfigData->ProcTraceOutputScheme = PcdGet8 (PcdCpuProcTraceOutputScheme);\r
80\r
81 return ConfigData;\r
82}\r
83\r
84/**\r
7367cc6c 85 Detects if Intel Processor Trace feature supported on current\r
bc230057
ED
86 processor.\r
87\r
88 @param[in] ProcessorNumber The index of the CPU executing this function.\r
89 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
90 structure for the CPU executing this function.\r
91 @param[in] ConfigData A pointer to the configuration buffer returned\r
92 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
93 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
94 RegisterCpuFeature().\r
95\r
96 @retval TRUE Processor Trace feature is supported.\r
97 @retval FALSE Processor Trace feature is not supported.\r
98\r
99 @note This service could be called by BSP/APs.\r
100**/\r
101BOOLEAN\r
102EFIAPI\r
103ProcTraceSupport (\r
104 IN UINTN ProcessorNumber,\r
105 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
106 IN VOID *ConfigData OPTIONAL\r
107 )\r
108{\r
053e878b
MK
109 PROC_TRACE_DATA *ProcTraceData;\r
110 CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx;\r
111 CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX Ecx;\r
bc230057
ED
112\r
113 //\r
114 // Check if ProcTraceMemorySize option is enabled (0xFF means disable by user)\r
115 //\r
053e878b 116 ProcTraceData = (PROC_TRACE_DATA *)ConfigData;\r
3dcb5325 117 ASSERT (ProcTraceData != NULL);\r
b2b0ffc9 118 if ((ProcTraceData->ProcTraceMemSize > RtitTopaMemorySize128M) ||\r
053e878b
MK
119 (ProcTraceData->ProcTraceOutputScheme > RtitOutputSchemeToPA))\r
120 {\r
bc230057
ED
121 return FALSE;\r
122 }\r
123\r
124 //\r
125 // Check if Processor Trace is supported\r
126 //\r
127 AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0, NULL, &Ebx.Uint32, NULL, NULL);\r
49fb6057 128 if (Ebx.Bits.IntelProcessorTrace == 0) {\r
bc230057
ED
129 return FALSE;\r
130 }\r
131\r
132 AsmCpuidEx (CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF, NULL, NULL, &Ecx.Uint32, NULL);\r
053e878b
MK
133 ProcTraceData->ProcessorData[ProcessorNumber].TopaSupported = (BOOLEAN)(Ecx.Bits.RTIT == 1);\r
134 ProcTraceData->ProcessorData[ProcessorNumber].SingleRangeSupported = (BOOLEAN)(Ecx.Bits.SingleRangeOutput == 1);\r
330021fa 135 if ((ProcTraceData->ProcessorData[ProcessorNumber].TopaSupported && (ProcTraceData->ProcTraceOutputScheme == RtitOutputSchemeToPA)) ||\r
053e878b
MK
136 (ProcTraceData->ProcessorData[ProcessorNumber].SingleRangeSupported && (ProcTraceData->ProcTraceOutputScheme == RtitOutputSchemeSingleRange)))\r
137 {\r
138 ProcTraceData->ProcessorData[ProcessorNumber].RtitCtrl.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_CTL);\r
139 ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputBase.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_OUTPUT_BASE);\r
49fb6057 140 ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputMaskPtrs.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_OUTPUT_MASK_PTRS);\r
bc230057
ED
141 return TRUE;\r
142 }\r
143\r
144 return FALSE;\r
145}\r
146\r
147/**\r
148 Initializes Intel Processor Trace feature to specific state.\r
149\r
150 @param[in] ProcessorNumber The index of the CPU executing this function.\r
151 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
152 structure for the CPU executing this function.\r
153 @param[in] ConfigData A pointer to the configuration buffer returned\r
154 by CPU_FEATURE_GET_CONFIG_DATA. NULL if\r
155 CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
156 RegisterCpuFeature().\r
157 @param[in] State If TRUE, then the Processor Trace feature must be\r
158 enabled.\r
159 If FALSE, then the Processor Trace feature must be\r
160 disabled.\r
161\r
162 @retval RETURN_SUCCESS Intel Processor Trace feature is initialized.\r
163\r
164**/\r
165RETURN_STATUS\r
166EFIAPI\r
167ProcTraceInitialize (\r
168 IN UINTN ProcessorNumber,\r
169 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,\r
4ec586b9 170 IN VOID *ConfigData OPTIONAL,\r
bc230057
ED
171 IN BOOLEAN State\r
172 )\r
173{\r
053e878b
MK
174 UINT32 MemRegionSize;\r
175 UINTN Pages;\r
176 UINTN Alignment;\r
177 UINTN MemRegionBaseAddr;\r
178 UINTN *ThreadMemRegionTable;\r
179 UINTN Index;\r
180 UINTN TopaTableBaseAddr;\r
181 UINTN AlignedAddress;\r
182 UINTN *TopaMemArray;\r
183 PROC_TRACE_TOPA_TABLE *TopaTable;\r
184 PROC_TRACE_DATA *ProcTraceData;\r
185 BOOLEAN FirstIn;\r
186 MSR_IA32_RTIT_CTL_REGISTER CtrlReg;\r
187 MSR_IA32_RTIT_STATUS_REGISTER StatusReg;\r
188 MSR_IA32_RTIT_OUTPUT_BASE_REGISTER OutputBaseReg;\r
b2b0ffc9 189 MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER OutputMaskPtrsReg;\r
053e878b 190 RTIT_TOPA_TABLE_ENTRY *TopaEntryPtr;\r
bc230057 191\r
d28daadd
ED
192 //\r
193 // The scope of the MSR_IA32_RTIT_* is core for below processor type, only program\r
194 // MSR_IA32_RTIT_* for thread 0 in each core.\r
195 //\r
196 if (IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||\r
053e878b
MK
197 IS_GOLDMONT_PLUS_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel))\r
198 {\r
d28daadd
ED
199 if (CpuInfo->ProcessorInfo.Location.Thread != 0) {\r
200 return RETURN_SUCCESS;\r
201 }\r
202 }\r
203\r
053e878b 204 ProcTraceData = (PROC_TRACE_DATA *)ConfigData;\r
3dcb5325 205 ASSERT (ProcTraceData != NULL);\r
bc230057 206\r
bc230057
ED
207 //\r
208 // Clear MSR_IA32_RTIT_CTL[0] and IA32_RTIT_STS only if MSR_IA32_RTIT_CTL[0]==1b\r
209 //\r
49fb6057 210 CtrlReg.Uint64 = ProcTraceData->ProcessorData[ProcessorNumber].RtitCtrl.Uint64;\r
b2b0ffc9 211 if (CtrlReg.Bits.TraceEn != 0) {\r
bc230057
ED
212 ///\r
213 /// Clear bit 0 in MSR IA32_RTIT_CTL (570)\r
214 ///\r
b2b0ffc9 215 CtrlReg.Bits.TraceEn = 0;\r
bc230057
ED
216 CPU_REGISTER_TABLE_WRITE64 (\r
217 ProcessorNumber,\r
218 Msr,\r
219 MSR_IA32_RTIT_CTL,\r
b2b0ffc9 220 CtrlReg.Uint64\r
bc230057
ED
221 );\r
222\r
223 ///\r
224 /// Clear MSR IA32_RTIT_STS (571h) to all zeros\r
225 ///\r
b2b0ffc9 226 StatusReg.Uint64 = 0x0;\r
bc230057
ED
227 CPU_REGISTER_TABLE_WRITE64 (\r
228 ProcessorNumber,\r
229 Msr,\r
230 MSR_IA32_RTIT_STATUS,\r
b2b0ffc9 231 StatusReg.Uint64\r
bc230057
ED
232 );\r
233 }\r
234\r
484dc050
SZ
235 if (!State) {\r
236 return RETURN_SUCCESS;\r
237 }\r
238\r
239 MemRegionBaseAddr = 0;\r
053e878b 240 FirstIn = FALSE;\r
484dc050
SZ
241\r
242 if (ProcTraceData->ThreadMemRegionTable == NULL) {\r
243 FirstIn = TRUE;\r
244 DEBUG ((DEBUG_INFO, "Initialize Processor Trace\n"));\r
245 }\r
246\r
247 ///\r
248 /// Refer to PROC_TRACE_MEM_SIZE Table for Size Encoding\r
249 ///\r
053e878b 250 MemRegionSize = (UINT32)(1 << (ProcTraceData->ProcTraceMemSize + 12));\r
484dc050
SZ
251 if (FirstIn) {\r
252 DEBUG ((DEBUG_INFO, "ProcTrace: MemSize requested: 0x%X \n", MemRegionSize));\r
253 }\r
254\r
bc230057
ED
255 if (FirstIn) {\r
256 //\r
257 // Let BSP allocate and create the necessary memory region (Aligned to the size of\r
258 // the memory region from setup option(ProcTraceMemSize) which is an integral multiple of 4kB)\r
49fb6057 259 // for all the enabled threads to store Processor Trace debug data. Then Configure the trace\r
bc230057 260 // address base in MSR, IA32_RTIT_OUTPUT_BASE (560h) bits 47:12. Note that all regions must be\r
49fb6057 261 // aligned based on their size, not just 4K. Thus a 2M region must have bits 20:12 cleared.\r
bc230057 262 //\r
053e878b 263 ThreadMemRegionTable = (UINTN *)AllocatePool (ProcTraceData->NumberOfProcessors * sizeof (UINTN *));\r
bc230057
ED
264 if (ThreadMemRegionTable == NULL) {\r
265 DEBUG ((DEBUG_ERROR, "Allocate ProcTrace ThreadMemRegionTable Failed\n"));\r
266 return RETURN_OUT_OF_RESOURCES;\r
267 }\r
053e878b 268\r
bc230057
ED
269 ProcTraceData->ThreadMemRegionTable = ThreadMemRegionTable;\r
270\r
271 for (Index = 0; Index < ProcTraceData->NumberOfProcessors; Index++, ProcTraceData->AllocatedThreads++) {\r
053e878b
MK
272 Pages = EFI_SIZE_TO_PAGES (MemRegionSize);\r
273 Alignment = MemRegionSize;\r
274 AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
bc230057
ED
275 if (AlignedAddress == 0) {\r
276 DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated only for %d threads\n", ProcTraceData->AllocatedThreads));\r
277 if (Index == 0) {\r
278 //\r
279 // Could not allocate for BSP even\r
280 //\r
053e878b 281 FreePool ((VOID *)ThreadMemRegionTable);\r
bc230057
ED
282 ThreadMemRegionTable = NULL;\r
283 return RETURN_OUT_OF_RESOURCES;\r
284 }\r
053e878b 285\r
bc230057
ED
286 break;\r
287 }\r
288\r
289 ThreadMemRegionTable[Index] = AlignedAddress;\r
053e878b 290 DEBUG ((DEBUG_INFO, "ProcTrace: PT MemRegionBaseAddr(aligned) for thread %d: 0x%llX \n", Index, (UINT64)ThreadMemRegionTable[Index]));\r
bc230057
ED
291 }\r
292\r
293 DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT mem for %d thread \n", ProcTraceData->AllocatedThreads));\r
49fb6057
SZ
294 }\r
295\r
296 if (ProcessorNumber < ProcTraceData->AllocatedThreads) {\r
297 MemRegionBaseAddr = ProcTraceData->ThreadMemRegionTable[ProcessorNumber];\r
bc230057 298 } else {\r
49fb6057 299 return RETURN_SUCCESS;\r
bc230057
ED
300 }\r
301\r
302 ///\r
303 /// Check Processor Trace output scheme: Single Range output or ToPA table\r
304 ///\r
305\r
306 //\r
307 // Single Range output scheme\r
308 //\r
7367cc6c 309 if (ProcTraceData->ProcessorData[ProcessorNumber].SingleRangeSupported &&\r
053e878b
MK
310 (ProcTraceData->ProcTraceOutputScheme == RtitOutputSchemeSingleRange))\r
311 {\r
bc230057
ED
312 if (FirstIn) {\r
313 DEBUG ((DEBUG_INFO, "ProcTrace: Enabling Single Range Output scheme \n"));\r
314 }\r
315\r
316 //\r
317 // Clear MSR IA32_RTIT_CTL (0x570) ToPA (Bit 8)\r
318 //\r
b2b0ffc9 319 CtrlReg.Bits.ToPA = 0;\r
bc230057
ED
320 CPU_REGISTER_TABLE_WRITE64 (\r
321 ProcessorNumber,\r
322 Msr,\r
323 MSR_IA32_RTIT_CTL,\r
b2b0ffc9 324 CtrlReg.Uint64\r
bc230057
ED
325 );\r
326\r
327 //\r
b2b0ffc9 328 // Program MSR IA32_RTIT_OUTPUT_BASE (0x560) bits[63:7] with the allocated Memory Region\r
bc230057 329 //\r
053e878b
MK
330 OutputBaseReg.Uint64 = ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputBase.Uint64;\r
331 OutputBaseReg.Bits.Base = (MemRegionBaseAddr >> 7) & 0x01FFFFFF;\r
332 OutputBaseReg.Bits.BaseHi = RShiftU64 ((UINT64)MemRegionBaseAddr, 32) & 0xFFFFFFFF;\r
bc230057
ED
333 CPU_REGISTER_TABLE_WRITE64 (\r
334 ProcessorNumber,\r
335 Msr,\r
336 MSR_IA32_RTIT_OUTPUT_BASE,\r
b2b0ffc9 337 OutputBaseReg.Uint64\r
bc230057
ED
338 );\r
339\r
340 //\r
341 // Program the Mask bits for the Memory Region to MSR IA32_RTIT_OUTPUT_MASK_PTRS (561h)\r
342 //\r
053e878b 343 OutputMaskPtrsReg.Uint64 = ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputMaskPtrs.Uint64;\r
b2b0ffc9 344 OutputMaskPtrsReg.Bits.MaskOrTableOffset = ((MemRegionSize - 1) >> 7) & 0x01FFFFFF;\r
053e878b 345 OutputMaskPtrsReg.Bits.OutputOffset = RShiftU64 (MemRegionSize - 1, 32) & 0xFFFFFFFF;\r
bc230057
ED
346 CPU_REGISTER_TABLE_WRITE64 (\r
347 ProcessorNumber,\r
348 Msr,\r
349 MSR_IA32_RTIT_OUTPUT_MASK_PTRS,\r
b2b0ffc9 350 OutputMaskPtrsReg.Uint64\r
bc230057 351 );\r
bc230057
ED
352 }\r
353\r
354 //\r
355 // ToPA(Table of physical address) scheme\r
356 //\r
7367cc6c 357 if (ProcTraceData->ProcessorData[ProcessorNumber].TopaSupported &&\r
053e878b
MK
358 (ProcTraceData->ProcTraceOutputScheme == RtitOutputSchemeToPA))\r
359 {\r
bc230057
ED
360 //\r
361 // Create ToPA structure aligned at 4KB for each logical thread\r
362 // with at least 2 entries by 8 bytes size each. The first entry\r
363 // should have the trace output base address in bits 47:12, 6:9\r
364 // for Size, bits 4,2 and 0 must be cleared. The second entry\r
365 // should have the base address of the table location in bits\r
366 // 47:12, bits 4 and 2 must be cleared and bit 0 must be set.\r
367 //\r
368 if (FirstIn) {\r
369 DEBUG ((DEBUG_INFO, "ProcTrace: Enabling ToPA scheme \n"));\r
370 //\r
371 // Let BSP allocate ToPA table mem for all threads\r
372 //\r
053e878b 373 TopaMemArray = (UINTN *)AllocatePool (ProcTraceData->AllocatedThreads * sizeof (UINTN *));\r
bc230057
ED
374 if (TopaMemArray == NULL) {\r
375 DEBUG ((DEBUG_ERROR, "ProcTrace: Allocate mem for ToPA Failed\n"));\r
376 return RETURN_OUT_OF_RESOURCES;\r
377 }\r
053e878b 378\r
bc230057
ED
379 ProcTraceData->TopaMemArray = TopaMemArray;\r
380\r
381 for (Index = 0; Index < ProcTraceData->AllocatedThreads; Index++) {\r
053e878b
MK
382 Pages = EFI_SIZE_TO_PAGES (sizeof (PROC_TRACE_TOPA_TABLE));\r
383 Alignment = 0x1000;\r
384 AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
bc230057
ED
385 if (AlignedAddress == 0) {\r
386 if (Index < ProcTraceData->AllocatedThreads) {\r
387 ProcTraceData->AllocatedThreads = Index;\r
388 }\r
053e878b 389\r
49fb6057 390 DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated ToPA mem only for %d threads\n", ProcTraceData->AllocatedThreads));\r
bc230057
ED
391 if (Index == 0) {\r
392 //\r
49fb6057 393 // Could not allocate for BSP even\r
bc230057 394 //\r
053e878b 395 FreePool ((VOID *)TopaMemArray);\r
bc230057
ED
396 TopaMemArray = NULL;\r
397 return RETURN_OUT_OF_RESOURCES;\r
398 }\r
053e878b 399\r
bc230057
ED
400 break;\r
401 }\r
402\r
403 TopaMemArray[Index] = AlignedAddress;\r
053e878b 404 DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for thread %d is 0x%llX \n", Index, (UINT64)TopaMemArray[Index]));\r
bc230057
ED
405 }\r
406\r
407 DEBUG ((DEBUG_INFO, "ProcTrace: Allocated ToPA mem for %d thread \n", ProcTraceData->AllocatedThreads));\r
49fb6057
SZ
408 }\r
409\r
410 if (ProcessorNumber < ProcTraceData->AllocatedThreads) {\r
411 TopaTableBaseAddr = ProcTraceData->TopaMemArray[ProcessorNumber];\r
bc230057 412 } else {\r
49fb6057 413 return RETURN_SUCCESS;\r
bc230057
ED
414 }\r
415\r
053e878b
MK
416 TopaTable = (PROC_TRACE_TOPA_TABLE *)TopaTableBaseAddr;\r
417 TopaEntryPtr = &TopaTable->TopaEntry[0];\r
418 TopaEntryPtr->Uint64 = 0;\r
419 TopaEntryPtr->Bits.Base = (MemRegionBaseAddr >> 12) & 0x000FFFFF;\r
420 TopaEntryPtr->Bits.BaseHi = RShiftU64 ((UINT64)MemRegionBaseAddr, 32) & 0xFFFFFFFF;\r
421 TopaEntryPtr->Bits.Size = ProcTraceData->ProcTraceMemSize;\r
422 TopaEntryPtr->Bits.END = 0;\r
b2b0ffc9 423\r
053e878b
MK
424 TopaEntryPtr = &TopaTable->TopaEntry[1];\r
425 TopaEntryPtr->Uint64 = 0;\r
426 TopaEntryPtr->Bits.Base = (TopaTableBaseAddr >> 12) & 0x000FFFFF;\r
427 TopaEntryPtr->Bits.BaseHi = RShiftU64 ((UINT64)TopaTableBaseAddr, 32) & 0xFFFFFFFF;\r
428 TopaEntryPtr->Bits.END = 1;\r
bc230057
ED
429\r
430 //\r
b2b0ffc9 431 // Program the MSR IA32_RTIT_OUTPUT_BASE (0x560) bits[63:7] with ToPA base\r
bc230057 432 //\r
053e878b
MK
433 OutputBaseReg.Uint64 = ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputBase.Uint64;\r
434 OutputBaseReg.Bits.Base = (TopaTableBaseAddr >> 7) & 0x01FFFFFF;\r
435 OutputBaseReg.Bits.BaseHi = RShiftU64 ((UINT64)TopaTableBaseAddr, 32) & 0xFFFFFFFF;\r
bc230057
ED
436 CPU_REGISTER_TABLE_WRITE64 (\r
437 ProcessorNumber,\r
438 Msr,\r
439 MSR_IA32_RTIT_OUTPUT_BASE,\r
b2b0ffc9 440 OutputBaseReg.Uint64\r
bc230057
ED
441 );\r
442\r
443 //\r
444 // Set the MSR IA32_RTIT_OUTPUT_MASK (0x561) bits[63:7] to 0\r
445 //\r
053e878b 446 OutputMaskPtrsReg.Uint64 = ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputMaskPtrs.Uint64;\r
b2b0ffc9 447 OutputMaskPtrsReg.Bits.MaskOrTableOffset = 0;\r
053e878b 448 OutputMaskPtrsReg.Bits.OutputOffset = 0;\r
bc230057
ED
449 CPU_REGISTER_TABLE_WRITE64 (\r
450 ProcessorNumber,\r
451 Msr,\r
452 MSR_IA32_RTIT_OUTPUT_MASK_PTRS,\r
b2b0ffc9 453 OutputMaskPtrsReg.Uint64\r
bc230057
ED
454 );\r
455 //\r
456 // Enable ToPA output scheme by enabling MSR IA32_RTIT_CTL (0x570) ToPA (Bit 8)\r
457 //\r
b2b0ffc9 458 CtrlReg.Bits.ToPA = 1;\r
bc230057
ED
459 CPU_REGISTER_TABLE_WRITE64 (\r
460 ProcessorNumber,\r
461 Msr,\r
462 MSR_IA32_RTIT_CTL,\r
b2b0ffc9 463 CtrlReg.Uint64\r
bc230057
ED
464 );\r
465 }\r
466\r
467 ///\r
468 /// Enable the Processor Trace feature from MSR IA32_RTIT_CTL (570h)\r
469 ///\r
053e878b
MK
470 CtrlReg.Bits.OS = 1;\r
471 CtrlReg.Bits.User = 1;\r
b2b0ffc9 472 CtrlReg.Bits.BranchEn = 1;\r
053e878b 473 CtrlReg.Bits.TraceEn = 1;\r
bc230057
ED
474 CPU_REGISTER_TABLE_WRITE64 (\r
475 ProcessorNumber,\r
476 Msr,\r
477 MSR_IA32_RTIT_CTL,\r
b2b0ffc9 478 CtrlReg.Uint64\r
bc230057
ED
479 );\r
480\r
481 return RETURN_SUCCESS;\r
482}\r