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