758 lines
31 KiB
C
758 lines
31 KiB
C
/*********************************************************
|
|
* Copyright (C) 2014, 2019-2020 VMware, Inc. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation version 2 and no later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
*********************************************************/
|
|
|
|
/*
|
|
* perfctr_arch.h --
|
|
*
|
|
* Performance counters (x64 specific).
|
|
*/
|
|
|
|
#ifndef _PERFCTR_ARCH_H
|
|
#define _PERFCTR_ARCH_H
|
|
|
|
#ifndef _PERFCTR_H_
|
|
#error "This file can only be included by perfctr.h"
|
|
#endif
|
|
|
|
#define INCLUDE_ALLOW_USERLEVEL
|
|
|
|
#define INCLUDE_ALLOW_VMKERNEL
|
|
#define INCLUDE_ALLOW_MODULE
|
|
#define INCLUDE_ALLOW_VMCORE
|
|
#define INCLUDE_ALLOW_VMMON
|
|
#include "includeCheck.h"
|
|
|
|
#include "vm_asm.h"
|
|
#include "x86cpuid_asm.h"
|
|
|
|
#define PERFCTR_AMD_NUM_COUNTERS 4
|
|
#define PERFCTR_AMD_EXT_NUM_COUNTERS 6
|
|
#define PERFCTR_P6_NUM_COUNTERS 2
|
|
#define PERFCTR_NEHALEM_NUM_GEN_COUNTERS 4
|
|
#define PERFCTR_NEHALEM_NUM_FIXED_COUNTERS 3
|
|
#define PERFCTR_SANDYBRIDGE_NUM_GEN_COUNTERS 8 /* When HT is disabled */
|
|
#define PERFCTR_CORE_NUM_ARCH_EVENTS 8
|
|
#define PERFCTR_CORE_NUM_FIXED_COUNTERS 4
|
|
#define PERFCTR_AMD_VAL_MASK 0xffffffffffffLL
|
|
/*
|
|
* Even though the performance counters in P6 are 40 bits,
|
|
* we can only write to the lower 32 bits. Bit 31 is
|
|
* used to sign-extend the upper 8 bits.
|
|
*/
|
|
#define PERFCTR_P6_VAL_MASK 0xffffffffffLL
|
|
#define PERFCTR_P6_WRITE_MASK 0xffffffff
|
|
|
|
/*
|
|
* Performance counter width is determined at runtime in CORE.
|
|
* But the writables bits are fixed. we can only write to the
|
|
* lower 32 bits. Bit 31 is used to sign-extend the upper 8 bits.
|
|
*/
|
|
#define PERFCTR_CORE_WRITE_MASK 0xffffffff
|
|
|
|
/* Common Event Selection MSR bits. */
|
|
#define PERFCTR_CPU_EVENT_MASK 0x000000ff
|
|
#define PERFCTR_CPU_EVENT_SHIFT 0
|
|
#define PERFCTR_CPU_UNIT_MASK 0x0000ff00
|
|
#define PERFCTR_CPU_UNIT_SHIFT 8
|
|
#define PERFCTR_CPU_USER_MODE 0x00010000
|
|
#define PERFCTR_CPU_KERNEL_MODE 0x00020000
|
|
#define PERFCTR_CPU_EDGE_DETECT 0x00040000
|
|
#define PERFCTR_CPU_PIN_CONTROL 0x00080000
|
|
#define PERFCTR_CPU_APIC_INTR 0x00100000
|
|
#define PERFCTR_CPU_ENABLE 0x00400000
|
|
#define PERFCTR_CPU_INVERT_COUNTER_MASK 0x00800000
|
|
#define PERFCTR_CPU_COUNTER_MASK 0xff000000
|
|
#define PERFCTR_CPU_COUNTER_MASK_SHIFT 24
|
|
#define PERFCTR_CPU_EVENT_IN_USE 0x3C /* Unhalted Core cycles */
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* AMD K8
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* AMD Event Selection MSRs */
|
|
#define PERFCTR_AMD_EVENT_MASK PERFCTR_CPU_EVENT_MASK
|
|
#define PERFCTR_AMD_EXT_EVENT_MASK (0xfULL << 32)
|
|
#define PERFCTR_AMD_EVENT_SHIFT PERFCTR_CPU_EVENT_SHIFT
|
|
#define PERFCTR_AMD_UNIT_MASK PERFCTR_CPU_UNIT_MASK
|
|
#define PERFCTR_AMD_UNIT_SHIFT PERFCTR_CPU_UNIT_SHIFT
|
|
#define PERFCTR_AMD_USER_MODE PERFCTR_CPU_USER_MODE
|
|
#define PERFCTR_AMD_KERNEL_MODE PERFCTR_CPU_KERNEL_MODE
|
|
#define PERFCTR_AMD_EDGE_DETECT PERFCTR_CPU_EDGE_DETECT
|
|
#define PERFCTR_AMD_PIN_CONTROL PERFCTR_CPU_PIN_CONTROL
|
|
#define PERFCTR_AMD_APIC_INTR PERFCTR_CPU_APIC_INTR
|
|
#define PERFCTR_AMD_ENABLE PERFCTR_CPU_ENABLE
|
|
#define PERFCTR_AMD_INVERT_COUNTER_MASK PERFCTR_CPU_INVERT_COUNTER_MASK
|
|
#define PERFCTR_AMD_COUNTER_MASK PERFCTR_CPU_COUNTER_MASK
|
|
#define PERFCTR_AMD_COUNTER_MASK_SHIFT PERFCTR_CPU_COUNTER_MASK_SHIFT
|
|
#define PERFCTR_AMD_SHIFT_BY_UNITMASK(e) ((e) << 8 )
|
|
#define PERFCTR_AMD_EVTSEL_HOST (CONST64U(1) << 41)
|
|
#define PERFCTR_AMD_EVTSEL_GUEST (CONST64U(1) << 40)
|
|
|
|
/* AMD Performance Counter MSR Definitions */
|
|
#define PERFCTR_AMD_PERFEVTSEL0_ADDR 0xC0010000
|
|
#define PERFCTR_AMD_PERFCTR0_ADDR 0xC0010004
|
|
/* AMD with PerfCtrExtCore (PERFCORE) support MSR Definitions */
|
|
#define PERFCTR_AMD_EXT_BASE_ADDR 0xC0010200
|
|
#define PERFCTR_AMD_EXT_EVENTSEL 0
|
|
#define PERFCTR_AMD_EXT_CTR 1
|
|
#define PERFCTR_AMD_EXT_MSR_STRIDE 2
|
|
#define PERFCTR_AMD_AMD_EXT_CNTR_BASE_ADDR \
|
|
(PERFCTR_AMD_EXT_BASE_ADDR + PERFCTR_AMD_EXT_CTR)
|
|
#define PERFCTR_AMD_AMD_EXT_EVSL_BASE_ADDR \
|
|
(PERFCTR_AMD_EXT_BASE_ADDR + PERFCTR_AMD_EXT_EVENTSEL)
|
|
|
|
/* AMD Clocks */
|
|
#define PERFCTR_AMD_CPU_CLK_UNHALTED 0x76
|
|
|
|
/* AMD Load/Store unit events */
|
|
#define PERFCTR_AMD_SEGMENT_REGISTER_LOADS 0x20
|
|
#define PERFCTR_AMD_LS_BUFFER2_FULL 0x23
|
|
|
|
/*
|
|
* Event 0x2b counts SMIs on Opteron Rev.G (with upatch) and on
|
|
* GH >= Rev.B0 without patches. GH Rev.A has no such capability.
|
|
*/
|
|
#define PERFCTR_AMD_SMI_COUNT 0x2b
|
|
|
|
/*
|
|
* AMD Data Cache Events
|
|
* Family < 17H: 0x45 - Unified TLB hit
|
|
* 0x46 - Unified TLB miss
|
|
* Family >= 17H: 0x45 - L1 DTLB miss (L2 DTLB hit or miss)
|
|
* 0x46 - Tablewalker
|
|
*/
|
|
#define PERFCTR_AMD_DATA_CACHE_ACCESSES 0x40
|
|
#define PERFCTR_AMD_DATA_CACHE_MISSES 0x41
|
|
#define PERFCTR_AMD_DATA_CACHE_REFILLS_FROM_L2_OR_SYSTEM 0x42
|
|
#define PERFCTR_AMD_DATA_CACHE_REFILLS_FROM_SYSTEM 0x43
|
|
#define PERFCTR_AMD_DATA_CACHE_LINES_EVICTED 0x44
|
|
#define PERFCTR_AMD_L1_DTLB_MISS_AND_L2_DTLB_HIT_OR_MISS 0x45
|
|
#define PERFCTR_AMD_L1_DTLB_AND_L2_DTLB_MISS 0x46
|
|
#define PERFCTR_AMD_MISALIGNED_ACCESSES 0x47
|
|
#define PERFCTR_AMD_PREFETCH_INSTRS_DISPATCHED 0x4b
|
|
#define PERFCTR_AMD_DCACHE_MISSES_BY_LOCKED_INSTR 0x4c
|
|
|
|
/* AMD L2 Cache */
|
|
#define PERFCTR_AMD_REQUESTS_TO_L2 0x7d
|
|
#define PERFCTR_AMD_L2_MISS 0x7e
|
|
#define PERFCTR_AMD_L2_FILL_WRITEBACK 0x7f
|
|
|
|
/* AMD Instruction Cache Events */
|
|
|
|
#define PERFCTR_AMD_INSTR_FETCHES 0x80
|
|
#define PERFCTR_AMD_INSTR_MISSES 0x81
|
|
#define PERFCTR_AMD_INSTR_REFILLS_FROM_L2 0x82
|
|
#define PERFCTR_AMD_INSTR_REFILLS_FROM_SYSTEM 0x83
|
|
#define PERFCTR_AMD_L1_ITLB_MISS_L2_ITLB_HIT 0x84
|
|
#define PERFCTR_AMD_L1_ITLB_MISS_L2_ITLB_MISS 0x85
|
|
#define PERFCTR_AMD_INSTR_FETCH_STALL 0x87
|
|
|
|
/* AMD Execution Unit Events */
|
|
#define PERFCTR_AMD_RET_INSTR 0xc0
|
|
#define PERFCTR_AMD_RET_UOPS 0xc1
|
|
#define PERFCTR_AMD_RET_BRANCH_INSTR 0xc2
|
|
#define PERFCTR_AMD_RET_MISPRED_BRANCH_INSTR 0xc3
|
|
#define PERFCTR_AMD_RET_TAKEN_BRANCH_INSTR 0xc4
|
|
#define PERFCTR_AMD_RET_TAKEN_BRANCH_INSTR_MISPRED 0xc5
|
|
#define PERFCTR_AMD_RET_FAR_CONTROL_TRANSFERS 0xc6
|
|
#define PERFCTR_AMD_RET_BRANCH_RESYNCS 0xc7
|
|
#define PERFCTR_AMD_RET_NEAR_RETURNS 0xc8
|
|
#define PERFCTR_AMD_RET_NEAR_RETURNS_MISPRED 0xc9
|
|
#define PERFCTR_AMD_RET_INDIRECT_BRANCHES_MISPRED 0xca
|
|
#define PERFCTR_AMD_RET_MMX_FP_INSTR 0xcb
|
|
#define PERFCTR_AMD_INT_MASKED_CYCLES 0xcd
|
|
#define PERFCTR_AMD_INT_MASKED_CYCLES_WITH_INT_PEND 0xce
|
|
|
|
#define PERFCTR_AMD_INT_MASKED_COUNT \
|
|
((0xcd) | PERFCTR_AMD_EDGE_DETECT)
|
|
|
|
#define PERFCTR_AMD_INT_MASKED_COUNT_WITH_INT_PEND \
|
|
((0xce) | PERFCTR_AMD_EDGE_DETECT)
|
|
|
|
#define PERFCTR_AMD_INT_TAKEN 0xcf
|
|
#define PERFCTR_AMD_DECODER_EMPTY_CYCLES 0xd0
|
|
#define PERFCTR_AMD_DISPATCH_STALLS 0xd1
|
|
#define PERFCTR_AMD_DISPATCH_MISPRED_BRANCH_STALL_CYCLES 0xd2
|
|
#define PERFCTR_AMD_DISPATCH_SERIALIZATION_STALL_CYCLES 0xd3
|
|
#define PERFCTR_AMD_DISPATCH_SEGMENTLOAD_STALL_CYCLES 0xd4
|
|
#define PERFCTR_AMD_DISPATCH_REORDER_BUFFER_FULL_STALL_CYCLES 0xd5
|
|
#define PERFCTR_AMD_DISPATCH_RESERVATION_STATION_FULL_STALL_CYCLES 0xd6
|
|
#define PERFCTR_AMD_DISPATCH_LS_FULL_STALL_CYCLES 0xd8
|
|
#define PERFCTR_AMD_DISPATCH_WAIT_ALLQUIET_STALL_CYCLES 0xd9
|
|
#define PERFCTR_AMD_DISPATCH_FAR_XFER_OR_RESYNC_RETIRE_STALL_CYCLES 0xda
|
|
|
|
/* AMD Memory Controller Events */
|
|
|
|
#define PERFCTR_AMD_MEM_CTRL_PAGE_TABLE_OVERFLOWS 0xe1
|
|
#define PERFCTR_AMD_CPU_IO_REQUESTS_TO_MEMORY_IO 0xe9
|
|
#define PERFCTR_AMD_PROBE_RESPONSE_AND_UPSTREAM_REQ 0xec
|
|
|
|
/* AMD HyperTransport Interface Events */
|
|
|
|
#define PERFCTR_AMD_HT_L0_TX_BW 0xf6
|
|
#define PERFCTR_AMD_HT_L1_TX_BW 0xf7
|
|
#define PERFCTR_AMD_HT_L2_TX_BW 0xf8
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* Intel P6 family (excluding newer Core architecture)
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/*
|
|
* Event numbers for P6 Family Processors.
|
|
*/
|
|
|
|
/* P6 Data Cache Unit (DCU) */
|
|
#define PERFCTR_P6_DATA_MEM_REFS 0x00000043
|
|
#define PERFCTR_P6_DCU_LINES_IN 0x00000045
|
|
#define PERFCTR_P6_DCU_M_LINES_IN 0x00000046
|
|
#define PERFCTR_P6_DCU_MISS_OUTSTANDING 0x00000048
|
|
|
|
/* P6 Instruction Fetch Unit (IFU) */
|
|
#define PERFCTR_P6_IFU_IFETCH 0x00000080
|
|
#define PERFCTR_P6_IFU_IFETCH_MISS 0x00000081
|
|
#define PERFCTR_P6_ITLB_MISS 0x00000085
|
|
#define PERFCTR_P6_IFU_MEM_STALL 0x00000086
|
|
#define PERFCTR_P6_ILD_STALL 0x00000087
|
|
|
|
/* P6 L2 Cache */
|
|
#define PERFCTR_P6_L2_IFETCH 0x00000f28
|
|
#define PERFCTR_P6_L2_LD 0x00000f29
|
|
#define PERFCTR_P6_L2_ST 0x00000f2a
|
|
#define PERFCTR_P6_L2_LINES_IN 0x00000024
|
|
#define PERFCTR_P6_L2_LINES_OUT 0x00000026
|
|
#define PERFCTR_P6_L2_LINES_INM 0x00000025
|
|
#define PERFCTR_P6_L2_LINES_OUTM 0x00000027
|
|
#define PERFCTR_P6_L2_RQSTS 0x00000f2e
|
|
#define PERFCTR_P6_L2_ADS 0x00000021
|
|
#define PERFCTR_P6_L2_DBUS_BUSY_RD 0x00000023
|
|
|
|
/* P6 External Bus Logic */
|
|
#define PERFCTR_P6_BUSDRDY_CLOCKS_SELF 0x00000062
|
|
#define PERFCTR_P6_BUSDRDY_CLOCKS_ANY 0x00002062
|
|
#define PERFCTR_P6_BUS_LOCK_CLOCKS_SELF 0x00000063
|
|
#define PERFCTR_P6_BUS_LOCK_CLOCKS_ANY 0x00002063
|
|
#define PERFCTR_P6_BUS_REQ_OUTSTANDING 0x00000060
|
|
#define PERFCTR_P6_BUS_TRAN_BRD_SELF 0x00000065
|
|
#define PERFCTR_P6_BUS_TRAN_BRD_ANY 0x00002065
|
|
#define PERFCTR_P6_BUS_TRAN_RFO_SELF 0x00000066
|
|
#define PERFCTR_P6_BUS_TRAN_RFO_ANY 0x00002066
|
|
#define PERFCTR_P6_BUS_TRAN_WB_SELF 0x00000067
|
|
#define PERFCTR_P6_BUS_TRAN_WB_ANY 0x00002067
|
|
#define PERFCTR_P6_BUS_TRAN_IFETCH_SELF 0x00000068
|
|
#define PERFCTR_P6_BUS_TRAN_IFETCH_ANY 0x00002068
|
|
#define PERFCTR_P6_BUS_TRAN_INVAL_SELF 0x00000069
|
|
#define PERFCTR_P6_BUS_TRAN_INVAL_ANY 0x00002069
|
|
#define PERFCTR_P6_BUS_TRAN_PWR_SELF 0x0000006a
|
|
#define PERFCTR_P6_BUS_TRAN_PWR_ANY 0x0000206a
|
|
#define PERFCTR_P6_BUS_TRAN_P_SELF 0x0000006b
|
|
#define PERFCTR_P6_BUS_TRAN_P_ANY 0x0000206b
|
|
#define PERFCTR_P6_BUS_TRAN_IO_SELF 0x0000006c
|
|
#define PERFCTR_P6_BUS_TRAN_IO_ANY 0x0000206c
|
|
#define PERFCTR_P6_BUS_TRAN_DEF_SELF 0x0000006d
|
|
#define PERFCTR_P6_BUS_TRAN_DEF_ANY 0x0000206d
|
|
#define PERFCTR_P6_BUS_TRAN_DEF_SELF 0x0000006d
|
|
#define PERFCTR_P6_BUS_TRAN_DEF_ANY 0x0000206d
|
|
#define PERFCTR_P6_BUS_TRAN_BURST_SELF 0x0000006e
|
|
#define PERFCTR_P6_BUS_TRAN_BURST_ANY 0x0000206e
|
|
#define PERFCTR_P6_BUS_TRAN_ANY_SELF 0x00000070
|
|
#define PERFCTR_P6_BUS_TRAN_ANY_ANY 0x00002070
|
|
#define PERFCTR_P6_BUS_TRAN_MEM_SELF 0x0000006f
|
|
#define PERFCTR_P6_BUS_TRAN_MEM_ANY 0x0000206f
|
|
#define PERFCTR_P6_BUS_TRAN_RCV 0x00000064
|
|
#define PERFCTR_P6_BUS_BNR_DRV 0x00000061
|
|
#define PERFCTR_P6_BUS_HIT_DRV 0x0000007a
|
|
#define PERFCTR_P6_BUS_HITM_DRV 0x0000007b
|
|
#define PERFCTR_P6_BUS_SNOOP_STALL 0x0000007E
|
|
|
|
/* P6 Floating-Point Unit */
|
|
#define PERFCTR_P6_FLOPS 0x000000c1
|
|
#define PERFCTR_P6_FP_COMP_OPS_EXE 0x00000010
|
|
#define PERFCTR_P6_FP_ASSIST 0x00000011
|
|
#define PERFCTR_P6_MUL 0x00000012
|
|
#define PERFCTR_P6_DIV 0x00000013
|
|
#define PERFCTR_P6_CYCLES_DIV_BUSY 0x00000014
|
|
|
|
/* P6 Memory Ordering */
|
|
#define PERFCTR_P6_LD_BLOCKS 0x00000003
|
|
#define PERFCTR_P6_SB_DRAINS 0x00000004
|
|
#define PERFCTR_P6_MISALIGN_MEM_REF 0x00000005
|
|
#define PERFCTR_P6_EMON_KNI_PREF_DISPATCHED_NTA 0x00000007
|
|
#define PERFCTR_P6_EMON_KNI_PREF_DISPATCHED_T1 0x00000107
|
|
#define PERFCTR_P6_EMON_KNI_PREF_DISPATCHED_T2 0x00000207
|
|
#define PERFCTR_P6_EMON_KNI_PREF_DISPATCHED_WOS 0x00000307
|
|
#define PERFCTR_P6_EMON_KNI_PREF_MISS_NTA 0x0000004b
|
|
#define PERFCTR_P6_EMON_KNI_PREF_MISS_T1 0x0000014b
|
|
#define PERFCTR_P6_EMON_KNI_PREF_MISS_T2 0x0000024b
|
|
#define PERFCTR_P6_EMON_KNI_PREF_MISS_WOS 0x0000034b
|
|
|
|
/* P6 Instruction Decoding and Retirement */
|
|
#define PERFCTR_P6_INST_RETIRED 0x000000c0
|
|
#define PERFCTR_P6_UOPS_RETIRED 0x000000c2
|
|
#define PERFCTR_P6_INST_DECODED 0x000000d0
|
|
#define PERFCTR_P6_EMON_KNI_INST_RETIRED 0x000000d8
|
|
#define PERFCTR_P6_EMON_KNI_INST_RETIRED_SC 0x000001d8
|
|
#define PERFCTR_P6_EMON_KNI_COMP_INST_RETIRED 0x000000d9
|
|
#define PERFCTR_P6_EMON_KNI_COMP_INST_RETIRED_SC 0x000001d9
|
|
|
|
/* P6 Interrupts */
|
|
#define PERFCTR_P6_HW_INT_RX 0x000000c8
|
|
#define PERFCTR_P6_CYCLES_INT_MASKED 0x000000c6
|
|
#define PERFCTR_P6_CYCLES_INT_PENDING_AND_MASKED 0x000000c7
|
|
|
|
/* P6 Branches */
|
|
#define PERFCTR_P6_BR_INST_RETIRED 0x000000c4
|
|
#define PERFCTR_P6_BR_MISS_PRED_RETIRED 0x000000c5
|
|
#define PERFCTR_P6_BR_TAKEN_RETIRED 0x000000c9
|
|
#define PERFCTR_P6_BR_MISS_PRED_TAKEN_RET 0x000000ca
|
|
#define PERFCTR_P6_BR_INST_DECODED 0x000000e0
|
|
#define PERFCTR_P6_BTB_MISSES 0x000000e2
|
|
#define PERFCTR_P6_BR_BOGUS 0x000000e4
|
|
#define PERFCTR_P6_BACLEARS 0x000000e6
|
|
|
|
/* P6 Stalls */
|
|
#define PERFCTR_P6_RESOURCE_STALLS 0x000000a2
|
|
#define PERFCTR_P6_PARTIAL_RAT_CLEARS 0x000000d2
|
|
|
|
/* P6 Segment Register Loads */
|
|
#define PERFCTR_P6_SEGMENT_REG_LOADS 0x00000006
|
|
|
|
/* P6 Clocks */
|
|
#define PERFCTR_P6_CPU_CLK_UNHALTED 0x00000079
|
|
|
|
/* P6 MMX Unit */
|
|
#define PERFCTR_P6_MMX_INSTR_EXEC 0x000000b0
|
|
#define PERFCTR_P6_MMX_SAT_INSTR_EXEC 0x000000b1
|
|
#define PERFCTR_P6_MMX_UOPS_EXEC 0x000000b2
|
|
#define PERFCTR_P6_MMX_INSTR_TYPE_EXEC_PK_MUL 0x000001b3
|
|
#define PERFCTR_P6_MMX_INSTR_TYPE_EXEC_PK_SHIFT 0x000002b3
|
|
#define PERFCTR_P6_MMX_INSTR_TYPE_EXEC_PK_OP 0x000004b3
|
|
#define PERFCTR_P6_MMX_INSTR_TYPE_EXEC_UNPK_OP 0x000008b3
|
|
#define PERFCTR_P6_MMX_INSTR_TYPE_EXEC_PK_LOG 0x000010b3
|
|
#define PERFCTR_P6_MMX_INSTR_TYPE_EXEC_PK_ARITH 0x000020b3
|
|
#define PERFCTR_P6_FP_MMX_TRANS_TO 0x000000cc
|
|
#define PERFCTR_P6_FP_MMX_TRANS_FROM 0x000001cc
|
|
#define PERFCTR_P6_FP_MMX_ASSIST 0x000000cd
|
|
#define PERFCTR_P6_FP_MMX_INSTR_RET 0x000000ce
|
|
|
|
/* P6 Segment Register Renaming */
|
|
#define PERFCTR_P6_SEG_RENAME_STALLS_ES 0x000001d4
|
|
#define PERFCTR_P6_SEG_RENAME_STALLS_DS 0x000002d4
|
|
#define PERFCTR_P6_SEG_RENAME_STALLS_FS 0x000004d4
|
|
#define PERFCTR_P6_SEG_RENAME_STALLS_GS 0x000008d4
|
|
#define PERFCTR_P6_SEG_RENAME_STALLS_ANY 0x00000fd4
|
|
#define PERFCTR_P6_SEG_RENAMES_ES 0x000001d5
|
|
#define PERFCTR_P6_SEG_RENAMES_DS 0x000002d5
|
|
#define PERFCTR_P6_SEG_RENAMES_FS 0x000004d5
|
|
#define PERFCTR_P6_SEG_RENAMES_GS 0x000008d5
|
|
#define PERFCTR_P6_SEG_RENAMES_ANY 0x00000fd5
|
|
#define PERFCTR_P6_RET_SEG_RENAMES 0x000000d6
|
|
|
|
/*
|
|
* P6 Event Selection MSRs
|
|
*/
|
|
|
|
#define PERFCTR_P6_EVENT_MASK 0x000000ff
|
|
#define PERFCTR_P6_EVENT_SHIFT 0
|
|
#define PERFCTR_P6_UNIT_MASK 0x0000ff00
|
|
#define PERFCTR_P6_UNIT_SHIFT 8
|
|
#define PERFCTR_P6_USER_MODE 0x00010000
|
|
#define PERFCTR_P6_KERNEL_MODE 0x00020000
|
|
#define PERFCTR_P6_EDGE_DETECT 0x00040000
|
|
#define PERFCTR_P6_PIN_CONTROL 0x00080000
|
|
#define PERFCTR_P6_APIC_INTR 0x00100000
|
|
#define PERFCTR_P6_ENABLE 0x00400000
|
|
#define PERFCTR_P6_INVERT_COUNTER_MASK 0x00800000
|
|
#define PERFCTR_P6_COUNTER_MASK 0xff000000
|
|
#define PERFCTR_P6_COUNTER_MASK_SHIFT 24
|
|
#define PERFCTR_P6_SHIFT_BY_UNITMASK(e) (e << 8)
|
|
|
|
/*
|
|
* P6 Performance Counter MSR Addresses
|
|
*/
|
|
#define PERFCTR_P6_PERFEVTSEL0_ADDR 0x00000186
|
|
#define PERFCTR_P6_PERFCTR0_ADDR 0x000000c1
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* Intel Core architecture
|
|
*
|
|
* Use CPUID 0xa to get perf capabilities. Some (7) events are
|
|
* architectural; most are version-specific.
|
|
*
|
|
* V1: Yonah, V2: Merom, V2+: Penryn, V3: Nehalem, V4: Skylake
|
|
*
|
|
* V1 is similar to P6, with some additions:
|
|
* - Global control MSR
|
|
* V2 introduces:
|
|
* - 3 fixed counters
|
|
* - Ability to freeze a counter before PMI delivery.
|
|
* - Freeze during SMI (Penryn+ only)
|
|
* - VMCS global enable (Penryn+ only)
|
|
* V3 introduces:
|
|
* - (nothing we virtualize)
|
|
* V4 introduces:
|
|
* - Global unavailable (in-use) MSR
|
|
* - Freeze on PMI bit
|
|
* - ASCI bit
|
|
* - Global status set MSR
|
|
* - Global status reset MSR (previously called Ovf ctrl)
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
#define PERFCTR_CORE_PERFCTR0_ADDR 0x0c1
|
|
#define PERFCTR_CORE_PERFEVTSEL0_ADDR 0x186
|
|
#define PERFCTR_CORE_FIXED_CTR0_ADDR 0x309
|
|
#define PERFCTR_CORE_FIXED_CTR_CTRL_ADDR 0x38d
|
|
#define PERFCTR_CORE_FIXED_CTR_CTRL_PMI_MASK 0x888
|
|
#define PERFCTR_CORE_GLOBAL_STATUS_ADDR 0x38e
|
|
#define PERFCTR_CORE_GLOBAL_CTRL_ADDR 0x38f
|
|
#define PERFCTR_CORE_GLOBAL_OVF_CTRL_ADDR 0x390
|
|
#define PERFCTR_CORE_GLOBAL_STATUS_RESET_ADDR 0x390
|
|
#define PERFCTR_CORE_GLOBAL_STATUS_SET_ADDR 0x391
|
|
#define PERFCTR_CORE_GLOBAL_UNAVAILABLE_STATUS_ADDR 0x392
|
|
#define PERFCTR_CORE_PERFCTR0_FULL_WIDTH_ADDR 0x4c1
|
|
#define PERFCTR_CORE_GLOBAL_PMC0_ENABLE 0x1
|
|
#define PERFCTR_CORE_GLOBAL_PMC1_ENABLE 0x2
|
|
#define PERFCTR_CORE_GLOBAL_FIXED_ENABLE 0x700000000ULL
|
|
#define PERFCTR_CORE_USER_MODE PERFCTR_CPU_USER_MODE
|
|
#define PERFCTR_CORE_KERNEL_MODE PERFCTR_CPU_KERNEL_MODE
|
|
#define PERFCTR_CORE_APIC_INTR PERFCTR_CPU_APIC_INTR
|
|
#define PERFCTR_CORE_ENABLE PERFCTR_CPU_ENABLE
|
|
/* AnyThread Counting deprecated since PMU v5. */
|
|
#define PERFCTR_CORE_ANYTHREAD 0x00200000
|
|
#define PERFCTR_CORE_IN_TX (CONST64U(1) << 32)
|
|
#define PERFCTR_CORE_IN_TXCP (CONST64U(1) << 33)
|
|
#define PERFCTR_CORE_SHIFT_BY_UNITMASK(e) ((e) << 8)
|
|
#define PERFCTR_CORE_FIXED_CTR0_PMC 0x40000000
|
|
#define PERFCTR_CORE_FIXED_CTR1_PMC 0x40000001
|
|
#define PERFCTR_CORE_FIXED_PMI_MASKn(n) (CONST64U(0x8) << ((n) * 4))
|
|
#define PERFCTR_CORE_FIXED_ANY_MASKn(n) (CONST64U(0x4) << ((n) * 4))
|
|
#define PERFCTR_CORE_FIXED_KERNEL_MASKn(n) (CONST64U(0x1) << ((n) * 4))
|
|
#define PERFCTR_CORE_FIXED_USER_MASKn(n) (CONST64U(0x2) << ((n) * 4))
|
|
#define PERFCTR_CORE_FIXED_ENABLE_MASKn(n) (CONST64U(0x3) << ((n) * 4))
|
|
#define PERFCTR_CORE_FIXED_MASKn(n) (CONST64U(0xf) << ((n) * 4))
|
|
#define PERFCTR_CORE_FIXED_SHIFTBYn(n) ((n) * 4)
|
|
#define PERFCTR_CORE_FIXED_ANYTHREAD CONST64U(0x00000444)
|
|
#define PERFCTR_CORE_PMI_UNAVAILABLE_IN_USE (CONST64U(1) << 63)
|
|
// XXX serebrin/dhecht: 1-10-11: Make ANYTHREAD depend on number of fixed PMCs
|
|
|
|
#define PERFCTR_CORE_GLOBAL_STATUS_TOPA_PMI (1ULL << 55)
|
|
#define PERFCTR_CORE_GLOBAL_STATUS_CTR_FRZ (1ULL << 59)
|
|
#define PERFCTR_CORE_GLOBAL_STATUS_ASCI (1ULL << 60)
|
|
#define PERFCTR_CORE_GLOBAL_STATUS_OVFBUFFER (1ULL << 62)
|
|
|
|
/* Architectural event counters */
|
|
#define PERFCTR_CORE_UNHALTED_CORE_CYCLES 0x3c
|
|
#define PERFCTR_CORE_INST_RETIRED 0xc0
|
|
/* bus cycles */
|
|
#define PERFCTR_CORE_UNHALTED_REF_CYCLES (0x3c | (0x01 << 8))
|
|
#define PERFCTR_CORE_TOPDOWN_SLOTS (0xa4 | (0x01 << 8))
|
|
|
|
/*
|
|
* See Tables 30-2, 30-4 of the
|
|
* "Intel 64 and IA-32 Architecture's Software Developer Manual,
|
|
* Volume 3B, System Programming Guide, Part 2
|
|
*/
|
|
#define PERFCTR_CORE_LLC_REF (0x2e | (0x4f << 8))
|
|
#define PERFCTR_CORE_LLC_MISSES (0x2e | (0x41 << 8))
|
|
#define PERFCTR_CORE_LLC_MISSES_PREFETCH (0x2e | (0x71 << 8))
|
|
#define PERFCTR_CORE_LLC_MISSES_ALL (0x2e | (0xc1 << 8))
|
|
#define PERFCTR_CORE_LLC_MISSES_ALL_PREFETCH (0x2e | (0xf1 << 8))
|
|
#define PERFCTR_CORE_BRANCH_RETIRED 0xc4
|
|
#define PERFCTR_CORE_BRANCH_MISPRED_RETIRED 0xc5
|
|
|
|
/* Non-Architectural event counters in Intel Core and Core 2 */
|
|
#define PERFCTR_CORE_L2_LINES_IN 0x24
|
|
#define PERFCTR_CORE_L2_M_LINES_IN 0x25
|
|
#define PERFCTR_CORE_L2_LINES_OUT 0x26
|
|
#define PERFCTR_CORE_L2_M_LINES_OUT 0x27
|
|
#define PERFCTR_CORE_DATA_MEM_REF 0x43
|
|
#define PERFCTR_CORE_DATA_MEM_CACHE_REF 0x44
|
|
#define PERFCTR_CORE_DCACHE_REPL 0x45
|
|
#define PERFCTR_CORE_DCACHE_M_REPL 0x46
|
|
#define PERFCTR_CORE_DCACHE_M_EVICT 0x47
|
|
#define PERFCTR_CORE_DCACHE_PEND_MISS 0x48
|
|
#define PERFCTR_CORE_DTLB_MISS 0x49
|
|
#define PERFCTR_CORE_BUS_TRANS 0x70
|
|
#define PERFCTR_CORE_ICACHE_READS 0x80
|
|
#define PERFCTR_CORE_ICACHE_MISSES 0x81
|
|
#define PERFCTR_CORE_ITLB_MISSES 0x85
|
|
#define PERFCTR_CORE_UOPS_RETIRED 0xC2
|
|
#define PERFCTR_CORE_RESOURCE_STALLS 0xDC
|
|
#define PERFCTR_NEHALEM_OFFCORE_RESP0_EVENT (0xB7 | (0x01 << 8))
|
|
#define PERFCTR_NEHALEM_OFFCORE_RESP1_EVENT (0xBB | (0x01 << 8))
|
|
|
|
/* Intel TSX performance events introduced on Haswell */
|
|
#define PERFCTR_HASWELL_HLE_RETIRED_START (0xc8 | (0x01 << 8))
|
|
#define PERFCTR_HASWELL_HLE_RETIRED_COMMIT (0xc8 | (0x02 << 8))
|
|
#define PERFCTR_HASWELL_HLE_RETIRED_ABORT (0xc8 | (0x04 << 8))
|
|
#define PERFCTR_HASWELL_RTM_RETIRED_START (0xc9 | (0x01 << 8))
|
|
#define PERFCTR_HASWELL_RTM_RETIRED_COMMIT (0xc9 | (0x02 << 8))
|
|
#define PERFCTR_HASWELL_RTM_RETIRED_ABORT (0xc9 | (0x04 << 8))
|
|
|
|
/*
|
|
* Nehalem off-core response events. See Section 30.6.1.2 of the
|
|
* "Intel 64 and IA-32 Architecture's Software Developer Manual,
|
|
* Volume 3B, System Programming Guide, Part 2.
|
|
* One can specify
|
|
* (request from the core, response from the uncore) pairs.
|
|
*/
|
|
#define PERFCTR_NEHALEM_OFFCORE_RESP0_ADDR 0x1A6
|
|
// requests
|
|
#define PERFCTR_NEHALEM_OFFCORE_RQST_DMND_DATA_RD 0x1
|
|
#define PERFCTR_NEHALEM_OFFCORE_RQST_DMND_RFO 0x2
|
|
#define PERFCTR_NEHALEM_OFFCORE_RQST_DMND_IFETCH 0x4
|
|
#define PERFCTR_NEHALEM_OFFCORE_RQST_WB 0x8
|
|
#define PERFCTR_NEHALEM_OFFCORE_RQST_PF_DATA_RD 0x10
|
|
#define PERFCTR_NEHALEM_OFFCORE_RQST_PF_RFO 0x20
|
|
#define PERFCTR_NEHALEM_OFFCORE_RQST_PF_IFETCH 0x40
|
|
#define PERFCTR_NEHALEM_OFFCORE_RQST_OTHER 0x80
|
|
|
|
// responses
|
|
#define PERFCTR_NEHALEM_OFFCORE_RESP_UNCORE_HIT 0x100
|
|
#define PERFCTR_NEHALEM_OFFCORE_RESP_OTHER_CORE_HIT_SNP 0x200
|
|
#define PERFCTR_NEHALEM_OFFCORE_RESP_OTHER_CORE_HITM 0x400
|
|
#define PERFCTR_NEHALEM_OFFCORE_RESP_REMOTE_CACHE_FWD 0x1000
|
|
#define PERFCTR_NEHALEM_OFFCORE_RESP_REMOTE_DRAM 0x2000
|
|
#define PERFCTR_NEHALEM_OFFCORE_RESP_LOCAL_DRAM 0x4000
|
|
#define PERFCTR_NEHALEM_OFFCORE_RESP_NON_DRAM 0x8000
|
|
|
|
// Nehalem Uncore events.
|
|
|
|
/*
|
|
* Uncore event MSRs. See table B-5 "MSRs in processors based on the
|
|
* Intel micro-architecture (Nehalem), in "Intel 64 and IA-32 Architecture's
|
|
* Software Developer Manual, Volume 3B, System Programming Guide, Part 2".
|
|
* Though note that the addresses listed for PMCs and event select MSRs are
|
|
* incorrect (swapped) in the manual.
|
|
*/
|
|
#define PERFCTR_NEHALEM_UNCORE_GLOBALCTRL_ADDR 0x391
|
|
#define PERFCTR_NEHALEM_UNCORE_PERFEVTSEL0_ADDR 0x3c0
|
|
#define PERFCTR_NEHALEM_UNCORE_PERFCTR0_ADDR 0x3b0
|
|
|
|
/*
|
|
* The uncore event masks. See section 30.6.2 of the
|
|
* "Intel 64 and IA-32 Architecture's Software Developer Manual,
|
|
* Volume 3B, System Programming Guide, Part 2"
|
|
*/
|
|
|
|
// Enable the use of the programmable uncore counter "x".
|
|
#define PERFCTR_NEHALEM_UNCORE_ENABLE_CTR(x) (1 << (x))
|
|
#define PERFCTR_NEHALEM_UNCORE_EDGE_DETECT 0x40000
|
|
#define PERFCTR_NEHALEM_UNCORE_ENABLE 0x400000
|
|
#define PERFCTR_NEHALEM_UNCORE_L3_LINES_IN (0x0a | (0x0f << 8))
|
|
|
|
#define PERFCTR_CONFIG_ARCH_FIELDS \
|
|
uint32 addr; \
|
|
uint32 escrAddr; \
|
|
uint32 resetHi; \
|
|
Bool pebsEnabled; \
|
|
|
|
/*
|
|
* Program/reprogram event reg(s) associated w/perfctrs & start or stop perfctrs
|
|
*/
|
|
static INLINE void
|
|
PerfCtr_WriteEvtSel(uint32 addr, // IN: Event register to write
|
|
uint32 escrVal) // IN: event register value
|
|
{
|
|
X86MSR_SetMSR(addr, escrVal);
|
|
}
|
|
|
|
|
|
/*
|
|
* Set/reset performance counters to engender desired period before overflow
|
|
*/
|
|
static INLINE void
|
|
PerfCtr_WriteCounter(uint32 addr, // IN: counter to write
|
|
uint64 value) // IN: value to write
|
|
{
|
|
X86MSR_SetMSR(addr, value);
|
|
}
|
|
|
|
|
|
static INLINE uint64
|
|
PerfCtr_SelValidBits(Bool amd)
|
|
{
|
|
/*
|
|
* Intel enforces PIN_CONTROL as MBZ; AMD does not. Always mask on AMD
|
|
* to avoid toggling the physical pin.
|
|
*/
|
|
uint64 bits = PERFCTR_CPU_EVENT_MASK | PERFCTR_CPU_UNIT_MASK |
|
|
PERFCTR_CPU_USER_MODE | PERFCTR_CPU_KERNEL_MODE |
|
|
PERFCTR_CPU_EDGE_DETECT | PERFCTR_CPU_APIC_INTR |
|
|
PERFCTR_CPU_ENABLE | PERFCTR_CPU_INVERT_COUNTER_MASK |
|
|
PERFCTR_CPU_COUNTER_MASK;
|
|
if (amd) {
|
|
bits |= PERFCTR_AMD_EXT_EVENT_MASK | PERFCTR_AMD_EVTSEL_HOST |
|
|
PERFCTR_AMD_EVTSEL_GUEST;
|
|
} else {
|
|
bits |= PERFCTR_CORE_ANYTHREAD | PERFCTR_CORE_IN_TX |
|
|
PERFCTR_CORE_IN_TXCP;
|
|
}
|
|
return bits;
|
|
}
|
|
|
|
static INLINE uint64
|
|
PerfCtr_PgcValidBits(unsigned numGenCtrs, unsigned numFixCtrs)
|
|
{
|
|
return MASK64(numGenCtrs) | (MASK64(numFixCtrs) << 32);
|
|
}
|
|
|
|
static INLINE uint64
|
|
PerfCtr_FccValidBits(unsigned numFixCtrs)
|
|
{
|
|
return MASK64(numFixCtrs * 4);
|
|
}
|
|
|
|
static INLINE uint64
|
|
PerfCtr_PgcToOvfValidBits(uint64 pgcValBits)
|
|
{
|
|
return pgcValBits | MASKRANGE64(63, 61);
|
|
}
|
|
|
|
static INLINE uint64
|
|
PerfCtr_PgcToStsRstValidBits(uint64 pgcValBits)
|
|
{
|
|
return pgcValBits |
|
|
PERFCTR_CORE_GLOBAL_STATUS_TOPA_PMI |
|
|
MASKRANGE64(63, 58);
|
|
}
|
|
|
|
static INLINE uint64
|
|
PerfCtr_PgcToGssValidBits(uint64 pgcValBits)
|
|
{
|
|
return pgcValBits |
|
|
PERFCTR_CORE_GLOBAL_STATUS_TOPA_PMI |
|
|
MASKRANGE64(62, 58);
|
|
}
|
|
|
|
/*
|
|
*----------------------------------------------------------------------
|
|
*
|
|
* PerfCtr_HypervisorCPUIDSig --
|
|
*
|
|
* Get the hypervisor signature string from CPUID.
|
|
*
|
|
* Results:
|
|
* TRUE on success FALSE otherwise.
|
|
* Unqualified 16 byte nul-terminated hypervisor string which may contain
|
|
* garbage.
|
|
*
|
|
* Side effects:
|
|
* None
|
|
*
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
|
|
static INLINE Bool
|
|
PerfCtr_HypervisorCPUIDSig(CPUIDRegs *name)
|
|
{
|
|
CPUIDRegs regs;
|
|
|
|
__GET_CPUID(1, ®s);
|
|
if (!CPUID_ISSET(1, ECX, HYPERVISOR, regs.ecx)) {
|
|
return FALSE;
|
|
}
|
|
|
|
__GET_CPUID(0x40000000, name);
|
|
|
|
if (name->eax < 0x40000000) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
*----------------------------------------------------------------------
|
|
*
|
|
* PerfCtr_PEBSAvailable --
|
|
*
|
|
* Checks if this CPU is capable of PEBS.
|
|
*
|
|
* Results:
|
|
* TRUE if PEBS is supported, FALSE otherwise.
|
|
*
|
|
* Side effects:
|
|
* None
|
|
*
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
|
|
static INLINE Bool
|
|
PerfCtr_PEBSAvailable(void)
|
|
{
|
|
CPUIDRegs regs;
|
|
__GET_CPUID(0, ®s);
|
|
if (CPUID_IsVendorIntel(®s) &&
|
|
(X86MSR_GetMSR(MSR_MISC_ENABLE) &
|
|
(MSR_MISC_ENABLE_EMON_AVAILABLE | MSR_MISC_ENABLE_PEBS_UNAVAILABLE))
|
|
== MSR_MISC_ENABLE_EMON_AVAILABLE) {
|
|
CPUIDRegs hvendor;
|
|
|
|
/*
|
|
* Hyper-V doesn't support PEBS and may #GP if we try to write the
|
|
* PEBS enable MSR so always consider PEBS un-available on Hyper-V -
|
|
* PR 1039970.
|
|
*/
|
|
return !PerfCtr_HypervisorCPUIDSig(&hvendor) ||
|
|
!CPUID_IsRawVendor(&hvendor,
|
|
CPUID_HYPERV_HYPERVISOR_VENDOR_STRING);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
*----------------------------------------------------------------------
|
|
*
|
|
* PerfCtr_PTAvailable --
|
|
*
|
|
* Checks if this CPU is capable of PT(Intel processor trace).
|
|
*
|
|
* Results:
|
|
* TRUE if PT is supported, FALSE otherwise.
|
|
*
|
|
* Side effects:
|
|
* None
|
|
*
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
|
|
static INLINE Bool
|
|
PerfCtr_PTAvailable(void)
|
|
{
|
|
CPUIDRegs regs;
|
|
__GET_CPUID(0, ®s);
|
|
if (CPUID_IsVendorIntel(®s)) {
|
|
__GET_CPUID2(7, 0, ®s);
|
|
return (regs.ebx & CPUID_INTERNAL_MASK_PT) != 0;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#endif // _PERFCTR_ARCH_H
|