Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/include/util/perfmon.h need to be fixed.

0001 /*                    The Quest Operating System
0002  *  Copyright (C) 2005-2010  Richard West, Boston University
0003  *
0004  *  This program is free software: you can redistribute it and/or modify
0005  *  it under the terms of the GNU General Public License as published by
0006  *  the Free Software Foundation, either version 3 of the License, or
0007  *  (at your option) any later version.
0008  *
0009  *  This program is distributed in the hope that it will be useful,
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *  GNU General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU General Public License
0015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0016  */
0017 
0018 #ifndef _PERFMON_H_
0019 #define _PERFMON_H_
0020 
0021 #include "kernel.h"
0022 #include "sched/vcpu.h"
0023 
0024 /* Performance monitoring counter MSRs */
0025 #define IA32_PMC(x) (0xC1 + (x))
0026 /* Performance event select MSRs paired with PMCs */
0027 #define IA32_PERFEVTSEL(x) (0x186 + (x))
0028 /* Off-core Response MSR. 0 for Nehalem. 0 and 1 for Westmere. */
0029 #define MSR_OFFCORE_RSP(x) (0x1A6 + (x))
0030 #define OFFCORE_RSP0_EVT    0xB7
0031 #define OFFCORE_RSP1_EVT    0xBB /* Available in Westmere only */
0032 #define OFFCORE_RSP_MASK    0x01
0033 /* Uncore performance monitoring facility */
0034 #define MSR_UNCORE_PERF_GLOBAL_CTRL       0x391
0035 #define MSR_UNCORE_PERF_GLOBAL_STATUS     0x392
0036 #define MSR_UNCORE_PERF_GLOBAL_OVF_CTRL   0x393
0037 
0038 /* The addresses of these two clusters of MSRs are wrong in older version of intel manual */
0039 #define MSR_UNCORE_PERFEVTSEL(x)  (0x3C0 + (x))
0040 #define MSR_UNCORE_PMC(x)         (0x3B0 + (x))
0041 
0042 #define MSR_UNCORE_FIXED_CTR0        0x394
0043 #define MSR_UNCORE_FIXED_CTR_CTRL    0x395
0044 
0045 /* MSR_UNCORE_PERF_GLOBAL_CTRL bit fields to enable/disable
0046  * general-purpose and fixed-function counters in the uncore
0047  */
0048 #define UNCORE_EN_PC0       (0x1LL)
0049 #define UNCORE_EN_PC1       (0x1LL << 1)
0050 #define UNCORE_EN_PC2       (0x1LL << 2)
0051 #define UNCORE_EN_PC3       (0x1LL << 3)
0052 #define UNCORE_EN_PC4       (0x1LL << 4)
0053 #define UNCORE_EN_PC5       (0x1LL << 5)
0054 #define UNCORE_EN_PC6       (0x1LL << 6)
0055 #define UNCORE_EN_PC7       (0x1LL << 7)
0056 #define UNCORE_EN_FC0       (0x1LL << 32)
0057 #define UNCORE_PMI_CORE0    (0x1LL << 48)
0058 #define UNCORE_PMI_CORE1    (0x1LL << 49)
0059 #define UNCORE_PMI_CORE2    (0x1LL << 50)
0060 #define UNCORE_PMI_CORE3    (0x1LL << 51)
0061 #define UNCORE_PMI_FRZ      (0x1LL << 63)
0062 
0063 /* MSR_OFFCORE_RSP_Z Bit Field Definition */
0064 #define OFFCORE_DMND_DATA_RD            (0x1)
0065 #define OFFCORE_DMND_RFO                (0x1 << 1)
0066 #define OFFCORE_DMND_IFETCH             (0x1 << 2)
0067 #define OFFCORE_WB                      (0x1 << 3)
0068 #define OFFCORE_PF_DATA_RD              (0x1 << 4)
0069 #define OFFCORE_PF_RFO                  (0x1 << 5)
0070 #define OFFCORE_PF_IFETCH               (0x1 << 6)
0071 #define OFFCORE_OTHER                   (0x1 << 7)
0072 #define OFFCORE_UNCORE_HIT              (0x1 << 8)
0073 #define OFFCORE_OTHER_CORE_HIT_SNP      (0x1 << 9)
0074 #define OFFCORE_OTHER_CORE_HITM         (0x1 << 10)
0075 #define OFFCORE_REMOTE_CACHE_FWD        (0x1 << 12)
0076 #define OFFCORE_REMOTE_DRAM             (0x1 << 13)
0077 #define OFFCORE_LOCAL_DRAM              (0x1 << 14)
0078 #define OFFCORE_NON_DRAM                (0x1 << 15)
0079 
0080 typedef union {
0081   u32 raw;
0082   struct {
0083     u8 event_select;
0084     u8 unit_mask;
0085     u8 user:1;
0086     u8 os:1;
0087     u8 edge_detect:1;
0088     u8 pin_control:1;
0089     u8 int_enable:1;
0090     u8 _reserved0:1;
0091     u8 enable_counters:1;
0092     u8 invert_counter_mask:1;
0093     u8 counter_mask;
0094   } PACKED;
0095 } ia32_perfevtsel_t;
0096 
0097 typedef union {
0098   u32 raw;
0099   struct {
0100     u8 event_select;
0101     u8 unit_mask;
0102     u8 _reserved1:1;
0103     u8 reset_occ:1;
0104     u8 edge_detect:1;
0105     u8 _reserved2:1;
0106     u8 pmi_enable:1;
0107     u8 _reserved3:1;
0108     u8 enable_counters:1;
0109     u8 invert_counter_mask:1;
0110     u8 counter_mask;
0111   } PACKED;
0112 } unc_perfevtsel_t;
0113 
0114 static inline void
0115 perfmon_pmc_config (int x, u8 event_select, u8 unit_mask)
0116 {
0117   ia32_perfevtsel_t conf;
0118 
0119   conf.raw = 0;
0120   conf.event_select = event_select;
0121   conf.unit_mask = unit_mask;
0122   conf.enable_counters = 1;
0123   conf.user = conf.os = 1;
0124 
0125   wrmsr (IA32_PERFEVTSEL(x), conf.raw);
0126 }
0127 
0128 static inline void
0129 perfmon_uncore_pmc_config (int x, u8 event_select, u8 unit_mask)
0130 {
0131   unc_perfevtsel_t conf;
0132 
0133   conf.raw = 0;
0134   conf.event_select = event_select;
0135   conf.unit_mask = unit_mask;
0136   conf.enable_counters = 1;
0137 
0138   wrmsr (MSR_UNCORE_PERFEVTSEL(x), conf.raw);
0139 }
0140 
0141 static inline u64
0142 perfmon_pmc_read (int x)
0143 {
0144   return rdmsr (IA32_PMC(x));
0145 }
0146 
0147 static inline void
0148 perfmon_uncore_cntr_enable (uint64 counters)
0149 {
0150   wrmsr (MSR_UNCORE_PERF_GLOBAL_CTRL, counters);
0151 }
0152 
0153 /* Enable fixed counter. If pmi is true, enable pmi, otherwise pmi is disabled */
0154 static inline void
0155 perfmon_uncore_fixed_enable (bool pmi)
0156 {
0157   pmi ? wrmsr (MSR_UNCORE_FIXED_CTR_CTRL, 0x5LL) :
0158     wrmsr (MSR_UNCORE_FIXED_CTR_CTRL, 0x1LL);
0159 }
0160 
0161 static inline u64
0162 perfmon_uncore_pmc_read (int x)
0163 {
0164   return rdmsr (MSR_UNCORE_PMC(x));
0165 }
0166 
0167 extern bool perfmon_init (void);
0168 extern void offcore_perfmon_pmc_config (int, int, uint64);
0169 extern bool perfmon_enabled;
0170 extern bool nehalem_perfmon_enabled;
0171 extern bool westmere_perfmon_enabled;
0172 extern void perfmon_pervcpu_reset (vcpu*);
0173 extern void perfmon_vcpu_acnt_start (vcpu*);
0174 extern void perfmon_vcpu_acnt_end (vcpu*);
0175 
0176 #endif
0177 
0178 /*
0179  * Local Variables:
0180  * indent-tabs-mode: nil
0181  * mode: C
0182  * c-file-style: "gnu"
0183  * c-basic-offset: 2
0184  * End:
0185  */
0186 
0187 /* vi: set et sw=2 sts=2: */