root/arch/x86/oprofile/op_model_p4.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. setup_num_counters
  2. addr_increment
  3. get_stagger
  4. p4_shutdown
  5. p4_fill_in_addresses
  6. pmc_setup_one_p4_counter
  7. p4_setup_ctrs
  8. p4_check_ctrs
  9. p4_start
  10. p4_stop

   1 /**
   2  * @file op_model_p4.c
   3  * P4 model-specific MSR operations
   4  *
   5  * @remark Copyright 2002 OProfile authors
   6  * @remark Read the file COPYING
   7  *
   8  * @author Graydon Hoare
   9  */
  10 
  11 #include <linux/oprofile.h>
  12 #include <linux/smp.h>
  13 #include <linux/ptrace.h>
  14 #include <asm/nmi.h>
  15 #include <asm/msr.h>
  16 #include <asm/fixmap.h>
  17 #include <asm/apic.h>
  18 
  19 
  20 #include "op_x86_model.h"
  21 #include "op_counter.h"
  22 
  23 #define NUM_EVENTS 39
  24 
  25 #define NUM_COUNTERS_NON_HT 8
  26 #define NUM_ESCRS_NON_HT 45
  27 #define NUM_CCCRS_NON_HT 18
  28 #define NUM_CONTROLS_NON_HT (NUM_ESCRS_NON_HT + NUM_CCCRS_NON_HT)
  29 
  30 #define NUM_COUNTERS_HT2 4
  31 #define NUM_ESCRS_HT2 23
  32 #define NUM_CCCRS_HT2 9
  33 #define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2)
  34 
  35 #define OP_CTR_OVERFLOW                 (1ULL<<31)
  36 
  37 static unsigned int num_counters = NUM_COUNTERS_NON_HT;
  38 static unsigned int num_controls = NUM_CONTROLS_NON_HT;
  39 
  40 /* this has to be checked dynamically since the
  41    hyper-threadedness of a chip is discovered at
  42    kernel boot-time. */
  43 static inline void setup_num_counters(void)
  44 {
  45 #ifdef CONFIG_SMP
  46         if (smp_num_siblings == 2) {
  47                 num_counters = NUM_COUNTERS_HT2;
  48                 num_controls = NUM_CONTROLS_HT2;
  49         }
  50 #endif
  51 }
  52 
  53 static inline int addr_increment(void)
  54 {
  55 #ifdef CONFIG_SMP
  56         return smp_num_siblings == 2 ? 2 : 1;
  57 #else
  58         return 1;
  59 #endif
  60 }
  61 
  62 
  63 /* tables to simulate simplified hardware view of p4 registers */
  64 struct p4_counter_binding {
  65         int virt_counter;
  66         int counter_address;
  67         int cccr_address;
  68 };
  69 
  70 struct p4_event_binding {
  71         int escr_select;  /* value to put in CCCR */
  72         int event_select; /* value to put in ESCR */
  73         struct {
  74                 int virt_counter; /* for this counter... */
  75                 int escr_address; /* use this ESCR       */
  76         } bindings[2];
  77 };
  78 
  79 /* nb: these CTR_* defines are a duplicate of defines in
  80    event/i386.p4*events. */
  81 
  82 
  83 #define CTR_BPU_0      (1 << 0)
  84 #define CTR_MS_0       (1 << 1)
  85 #define CTR_FLAME_0    (1 << 2)
  86 #define CTR_IQ_4       (1 << 3)
  87 #define CTR_BPU_2      (1 << 4)
  88 #define CTR_MS_2       (1 << 5)
  89 #define CTR_FLAME_2    (1 << 6)
  90 #define CTR_IQ_5       (1 << 7)
  91 
  92 static struct p4_counter_binding p4_counters[NUM_COUNTERS_NON_HT] = {
  93         { CTR_BPU_0,   MSR_P4_BPU_PERFCTR0,   MSR_P4_BPU_CCCR0 },
  94         { CTR_MS_0,    MSR_P4_MS_PERFCTR0,    MSR_P4_MS_CCCR0 },
  95         { CTR_FLAME_0, MSR_P4_FLAME_PERFCTR0, MSR_P4_FLAME_CCCR0 },
  96         { CTR_IQ_4,    MSR_P4_IQ_PERFCTR4,    MSR_P4_IQ_CCCR4 },
  97         { CTR_BPU_2,   MSR_P4_BPU_PERFCTR2,   MSR_P4_BPU_CCCR2 },
  98         { CTR_MS_2,    MSR_P4_MS_PERFCTR2,    MSR_P4_MS_CCCR2 },
  99         { CTR_FLAME_2, MSR_P4_FLAME_PERFCTR2, MSR_P4_FLAME_CCCR2 },
 100         { CTR_IQ_5,    MSR_P4_IQ_PERFCTR5,    MSR_P4_IQ_CCCR5 }
 101 };
 102 
 103 #define NUM_UNUSED_CCCRS (NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT)
 104 
 105 /* p4 event codes in libop/op_event.h are indices into this table. */
 106 
 107 static struct p4_event_binding p4_events[NUM_EVENTS] = {
 108 
 109         { /* BRANCH_RETIRED */
 110                 0x05, 0x06,
 111                 { {CTR_IQ_4, MSR_P4_CRU_ESCR2},
 112                   {CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 113         },
 114 
 115         { /* MISPRED_BRANCH_RETIRED */
 116                 0x04, 0x03,
 117                 { { CTR_IQ_4, MSR_P4_CRU_ESCR0},
 118                   { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
 119         },
 120 
 121         { /* TC_DELIVER_MODE */
 122                 0x01, 0x01,
 123                 { { CTR_MS_0, MSR_P4_TC_ESCR0},
 124                   { CTR_MS_2, MSR_P4_TC_ESCR1} }
 125         },
 126 
 127         { /* BPU_FETCH_REQUEST */
 128                 0x00, 0x03,
 129                 { { CTR_BPU_0, MSR_P4_BPU_ESCR0},
 130                   { CTR_BPU_2, MSR_P4_BPU_ESCR1} }
 131         },
 132 
 133         { /* ITLB_REFERENCE */
 134                 0x03, 0x18,
 135                 { { CTR_BPU_0, MSR_P4_ITLB_ESCR0},
 136                   { CTR_BPU_2, MSR_P4_ITLB_ESCR1} }
 137         },
 138 
 139         { /* MEMORY_CANCEL */
 140                 0x05, 0x02,
 141                 { { CTR_FLAME_0, MSR_P4_DAC_ESCR0},
 142                   { CTR_FLAME_2, MSR_P4_DAC_ESCR1} }
 143         },
 144 
 145         { /* MEMORY_COMPLETE */
 146                 0x02, 0x08,
 147                 { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0},
 148                   { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} }
 149         },
 150 
 151         { /* LOAD_PORT_REPLAY */
 152                 0x02, 0x04,
 153                 { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0},
 154                   { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} }
 155         },
 156 
 157         { /* STORE_PORT_REPLAY */
 158                 0x02, 0x05,
 159                 { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0},
 160                   { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} }
 161         },
 162 
 163         { /* MOB_LOAD_REPLAY */
 164                 0x02, 0x03,
 165                 { { CTR_BPU_0, MSR_P4_MOB_ESCR0},
 166                   { CTR_BPU_2, MSR_P4_MOB_ESCR1} }
 167         },
 168 
 169         { /* PAGE_WALK_TYPE */
 170                 0x04, 0x01,
 171                 { { CTR_BPU_0, MSR_P4_PMH_ESCR0},
 172                   { CTR_BPU_2, MSR_P4_PMH_ESCR1} }
 173         },
 174 
 175         { /* BSQ_CACHE_REFERENCE */
 176                 0x07, 0x0c,
 177                 { { CTR_BPU_0, MSR_P4_BSU_ESCR0},
 178                   { CTR_BPU_2, MSR_P4_BSU_ESCR1} }
 179         },
 180 
 181         { /* IOQ_ALLOCATION */
 182                 0x06, 0x03,
 183                 { { CTR_BPU_0, MSR_P4_FSB_ESCR0},
 184                   { 0, 0 } }
 185         },
 186 
 187         { /* IOQ_ACTIVE_ENTRIES */
 188                 0x06, 0x1a,
 189                 { { CTR_BPU_2, MSR_P4_FSB_ESCR1},
 190                   { 0, 0 } }
 191         },
 192 
 193         { /* FSB_DATA_ACTIVITY */
 194                 0x06, 0x17,
 195                 { { CTR_BPU_0, MSR_P4_FSB_ESCR0},
 196                   { CTR_BPU_2, MSR_P4_FSB_ESCR1} }
 197         },
 198 
 199         { /* BSQ_ALLOCATION */
 200                 0x07, 0x05,
 201                 { { CTR_BPU_0, MSR_P4_BSU_ESCR0},
 202                   { 0, 0 } }
 203         },
 204 
 205         { /* BSQ_ACTIVE_ENTRIES */
 206                 0x07, 0x06,
 207                 { { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */},
 208                   { 0, 0 } }
 209         },
 210 
 211         { /* X87_ASSIST */
 212                 0x05, 0x03,
 213                 { { CTR_IQ_4, MSR_P4_CRU_ESCR2},
 214                   { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 215         },
 216 
 217         { /* SSE_INPUT_ASSIST */
 218                 0x01, 0x34,
 219                 { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 220                   { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 221         },
 222 
 223         { /* PACKED_SP_UOP */
 224                 0x01, 0x08,
 225                 { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 226                   { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 227         },
 228 
 229         { /* PACKED_DP_UOP */
 230                 0x01, 0x0c,
 231                 { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 232                   { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 233         },
 234 
 235         { /* SCALAR_SP_UOP */
 236                 0x01, 0x0a,
 237                 { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 238                   { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 239         },
 240 
 241         { /* SCALAR_DP_UOP */
 242                 0x01, 0x0e,
 243                 { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 244                   { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 245         },
 246 
 247         { /* 64BIT_MMX_UOP */
 248                 0x01, 0x02,
 249                 { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 250                   { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 251         },
 252 
 253         { /* 128BIT_MMX_UOP */
 254                 0x01, 0x1a,
 255                 { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 256                   { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 257         },
 258 
 259         { /* X87_FP_UOP */
 260                 0x01, 0x04,
 261                 { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 262                   { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 263         },
 264 
 265         { /* X87_SIMD_MOVES_UOP */
 266                 0x01, 0x2e,
 267                 { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
 268                   { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
 269         },
 270 
 271         { /* MACHINE_CLEAR */
 272                 0x05, 0x02,
 273                 { { CTR_IQ_4, MSR_P4_CRU_ESCR2},
 274                   { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 275         },
 276 
 277         { /* GLOBAL_POWER_EVENTS */
 278                 0x06, 0x13 /* older manual says 0x05, newer 0x13 */,
 279                 { { CTR_BPU_0, MSR_P4_FSB_ESCR0},
 280                   { CTR_BPU_2, MSR_P4_FSB_ESCR1} }
 281         },
 282 
 283         { /* TC_MS_XFER */
 284                 0x00, 0x05,
 285                 { { CTR_MS_0, MSR_P4_MS_ESCR0},
 286                   { CTR_MS_2, MSR_P4_MS_ESCR1} }
 287         },
 288 
 289         { /* UOP_QUEUE_WRITES */
 290                 0x00, 0x09,
 291                 { { CTR_MS_0, MSR_P4_MS_ESCR0},
 292                   { CTR_MS_2, MSR_P4_MS_ESCR1} }
 293         },
 294 
 295         { /* FRONT_END_EVENT */
 296                 0x05, 0x08,
 297                 { { CTR_IQ_4, MSR_P4_CRU_ESCR2},
 298                   { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 299         },
 300 
 301         { /* EXECUTION_EVENT */
 302                 0x05, 0x0c,
 303                 { { CTR_IQ_4, MSR_P4_CRU_ESCR2},
 304                   { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 305         },
 306 
 307         { /* REPLAY_EVENT */
 308                 0x05, 0x09,
 309                 { { CTR_IQ_4, MSR_P4_CRU_ESCR2},
 310                   { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
 311         },
 312 
 313         { /* INSTR_RETIRED */
 314                 0x04, 0x02,
 315                 { { CTR_IQ_4, MSR_P4_CRU_ESCR0},
 316                   { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
 317         },
 318 
 319         { /* UOPS_RETIRED */
 320                 0x04, 0x01,
 321                 { { CTR_IQ_4, MSR_P4_CRU_ESCR0},
 322                   { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
 323         },
 324 
 325         { /* UOP_TYPE */
 326                 0x02, 0x02,
 327                 { { CTR_IQ_4, MSR_P4_RAT_ESCR0},
 328                   { CTR_IQ_5, MSR_P4_RAT_ESCR1} }
 329         },
 330 
 331         { /* RETIRED_MISPRED_BRANCH_TYPE */
 332                 0x02, 0x05,
 333                 { { CTR_MS_0, MSR_P4_TBPU_ESCR0},
 334                   { CTR_MS_2, MSR_P4_TBPU_ESCR1} }
 335         },
 336 
 337         { /* RETIRED_BRANCH_TYPE */
 338                 0x02, 0x04,
 339                 { { CTR_MS_0, MSR_P4_TBPU_ESCR0},
 340                   { CTR_MS_2, MSR_P4_TBPU_ESCR1} }
 341         }
 342 };
 343 
 344 
 345 #define MISC_PMC_ENABLED_P(x) ((x) & 1 << 7)
 346 
 347 #define ESCR_RESERVED_BITS 0x80000003
 348 #define ESCR_CLEAR(escr) ((escr) &= ESCR_RESERVED_BITS)
 349 #define ESCR_SET_USR_0(escr, usr) ((escr) |= (((usr) & 1) << 2))
 350 #define ESCR_SET_OS_0(escr, os) ((escr) |= (((os) & 1) << 3))
 351 #define ESCR_SET_USR_1(escr, usr) ((escr) |= (((usr) & 1)))
 352 #define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1))
 353 #define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25))
 354 #define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9))
 355 
 356 #define CCCR_RESERVED_BITS 0x38030FFF
 357 #define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS)
 358 #define CCCR_SET_REQUIRED_BITS(cccr) ((cccr) |= 0x00030000)
 359 #define CCCR_SET_ESCR_SELECT(cccr, sel) ((cccr) |= (((sel) & 0x07) << 13))
 360 #define CCCR_SET_PMI_OVF_0(cccr) ((cccr) |= (1<<26))
 361 #define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27))
 362 #define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12))
 363 #define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12))
 364 #define CCCR_OVF_P(cccr) ((cccr) & (1U<<31))
 365 #define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31)))
 366 
 367 
 368 /* this assigns a "stagger" to the current CPU, which is used throughout
 369    the code in this module as an extra array offset, to select the "even"
 370    or "odd" part of all the divided resources. */
 371 static unsigned int get_stagger(void)
 372 {
 373 #ifdef CONFIG_SMP
 374         int cpu = smp_processor_id();
 375         return cpu != cpumask_first(this_cpu_cpumask_var_ptr(cpu_sibling_map));
 376 #endif
 377         return 0;
 378 }
 379 
 380 
 381 /* finally, mediate access to a real hardware counter
 382    by passing a "virtual" counter numer to this macro,
 383    along with your stagger setting. */
 384 #define VIRT_CTR(stagger, i) ((i) + ((num_counters) * (stagger)))
 385 
 386 static unsigned long reset_value[NUM_COUNTERS_NON_HT];
 387 
 388 static void p4_shutdown(struct op_msrs const * const msrs)
 389 {
 390         int i;
 391 
 392         for (i = 0; i < num_counters; ++i) {
 393                 if (msrs->counters[i].addr)
 394                         release_perfctr_nmi(msrs->counters[i].addr);
 395         }
 396         /*
 397          * some of the control registers are specially reserved in
 398          * conjunction with the counter registers (hence the starting offset).
 399          * This saves a few bits.
 400          */
 401         for (i = num_counters; i < num_controls; ++i) {
 402                 if (msrs->controls[i].addr)
 403                         release_evntsel_nmi(msrs->controls[i].addr);
 404         }
 405 }
 406 
 407 static int p4_fill_in_addresses(struct op_msrs * const msrs)
 408 {
 409         unsigned int i;
 410         unsigned int addr, cccraddr, stag;
 411 
 412         setup_num_counters();
 413         stag = get_stagger();
 414 
 415         /* the counter & cccr registers we pay attention to */
 416         for (i = 0; i < num_counters; ++i) {
 417                 addr = p4_counters[VIRT_CTR(stag, i)].counter_address;
 418                 cccraddr = p4_counters[VIRT_CTR(stag, i)].cccr_address;
 419                 if (reserve_perfctr_nmi(addr)) {
 420                         msrs->counters[i].addr = addr;
 421                         msrs->controls[i].addr = cccraddr;
 422                 }
 423         }
 424 
 425         /* 43 ESCR registers in three or four discontiguous group */
 426         for (addr = MSR_P4_BSU_ESCR0 + stag;
 427              addr < MSR_P4_IQ_ESCR0; ++i, addr += addr_increment()) {
 428                 if (reserve_evntsel_nmi(addr))
 429                         msrs->controls[i].addr = addr;
 430         }
 431 
 432         /* no IQ_ESCR0/1 on some models, we save a seconde time BSU_ESCR0/1
 433          * to avoid special case in nmi_{save|restore}_registers() */
 434         if (boot_cpu_data.x86_model >= 0x3) {
 435                 for (addr = MSR_P4_BSU_ESCR0 + stag;
 436                      addr <= MSR_P4_BSU_ESCR1; ++i, addr += addr_increment()) {
 437                         if (reserve_evntsel_nmi(addr))
 438                                 msrs->controls[i].addr = addr;
 439                 }
 440         } else {
 441                 for (addr = MSR_P4_IQ_ESCR0 + stag;
 442                      addr <= MSR_P4_IQ_ESCR1; ++i, addr += addr_increment()) {
 443                         if (reserve_evntsel_nmi(addr))
 444                                 msrs->controls[i].addr = addr;
 445                 }
 446         }
 447 
 448         for (addr = MSR_P4_RAT_ESCR0 + stag;
 449              addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) {
 450                 if (reserve_evntsel_nmi(addr))
 451                         msrs->controls[i].addr = addr;
 452         }
 453 
 454         for (addr = MSR_P4_MS_ESCR0 + stag;
 455              addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) {
 456                 if (reserve_evntsel_nmi(addr))
 457                         msrs->controls[i].addr = addr;
 458         }
 459 
 460         for (addr = MSR_P4_IX_ESCR0 + stag;
 461              addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) {
 462                 if (reserve_evntsel_nmi(addr))
 463                         msrs->controls[i].addr = addr;
 464         }
 465 
 466         /* there are 2 remaining non-contiguously located ESCRs */
 467 
 468         if (num_counters == NUM_COUNTERS_NON_HT) {
 469                 /* standard non-HT CPUs handle both remaining ESCRs*/
 470                 if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5))
 471                         msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
 472                 if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR4))
 473                         msrs->controls[i++].addr = MSR_P4_CRU_ESCR4;
 474 
 475         } else if (stag == 0) {
 476                 /* HT CPUs give the first remainder to the even thread, as
 477                    the 32nd control register */
 478                 if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR4))
 479                         msrs->controls[i++].addr = MSR_P4_CRU_ESCR4;
 480 
 481         } else {
 482                 /* and two copies of the second to the odd thread,
 483                    for the 22st and 23nd control registers */
 484                 if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5)) {
 485                         msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
 486                         msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
 487                 }
 488         }
 489 
 490         for (i = 0; i < num_counters; ++i) {
 491                 if (!counter_config[i].enabled)
 492                         continue;
 493                 if (msrs->controls[i].addr)
 494                         continue;
 495                 op_x86_warn_reserved(i);
 496                 p4_shutdown(msrs);
 497                 return -EBUSY;
 498         }
 499 
 500         return 0;
 501 }
 502 
 503 
 504 static void pmc_setup_one_p4_counter(unsigned int ctr)
 505 {
 506         int i;
 507         int const maxbind = 2;
 508         unsigned int cccr = 0;
 509         unsigned int escr = 0;
 510         unsigned int high = 0;
 511         unsigned int counter_bit;
 512         struct p4_event_binding *ev = NULL;
 513         unsigned int stag;
 514 
 515         stag = get_stagger();
 516 
 517         /* convert from counter *number* to counter *bit* */
 518         counter_bit = 1 << VIRT_CTR(stag, ctr);
 519 
 520         /* find our event binding structure. */
 521         if (counter_config[ctr].event <= 0 || counter_config[ctr].event > NUM_EVENTS) {
 522                 printk(KERN_ERR
 523                        "oprofile: P4 event code 0x%lx out of range\n",
 524                        counter_config[ctr].event);
 525                 return;
 526         }
 527 
 528         ev = &(p4_events[counter_config[ctr].event - 1]);
 529 
 530         for (i = 0; i < maxbind; i++) {
 531                 if (ev->bindings[i].virt_counter & counter_bit) {
 532 
 533                         /* modify ESCR */
 534                         rdmsr(ev->bindings[i].escr_address, escr, high);
 535                         ESCR_CLEAR(escr);
 536                         if (stag == 0) {
 537                                 ESCR_SET_USR_0(escr, counter_config[ctr].user);
 538                                 ESCR_SET_OS_0(escr, counter_config[ctr].kernel);
 539                         } else {
 540                                 ESCR_SET_USR_1(escr, counter_config[ctr].user);
 541                                 ESCR_SET_OS_1(escr, counter_config[ctr].kernel);
 542                         }
 543                         ESCR_SET_EVENT_SELECT(escr, ev->event_select);
 544                         ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask);
 545                         wrmsr(ev->bindings[i].escr_address, escr, high);
 546 
 547                         /* modify CCCR */
 548                         rdmsr(p4_counters[VIRT_CTR(stag, ctr)].cccr_address,
 549                               cccr, high);
 550                         CCCR_CLEAR(cccr);
 551                         CCCR_SET_REQUIRED_BITS(cccr);
 552                         CCCR_SET_ESCR_SELECT(cccr, ev->escr_select);
 553                         if (stag == 0)
 554                                 CCCR_SET_PMI_OVF_0(cccr);
 555                         else
 556                                 CCCR_SET_PMI_OVF_1(cccr);
 557                         wrmsr(p4_counters[VIRT_CTR(stag, ctr)].cccr_address,
 558                               cccr, high);
 559                         return;
 560                 }
 561         }
 562 
 563         printk(KERN_ERR
 564                "oprofile: P4 event code 0x%lx no binding, stag %d ctr %d\n",
 565                counter_config[ctr].event, stag, ctr);
 566 }
 567 
 568 
 569 static void p4_setup_ctrs(struct op_x86_model_spec const *model,
 570                           struct op_msrs const * const msrs)
 571 {
 572         unsigned int i;
 573         unsigned int low, high;
 574         unsigned int stag;
 575 
 576         stag = get_stagger();
 577 
 578         rdmsr(MSR_IA32_MISC_ENABLE, low, high);
 579         if (!MISC_PMC_ENABLED_P(low)) {
 580                 printk(KERN_ERR "oprofile: P4 PMC not available\n");
 581                 return;
 582         }
 583 
 584         /* clear the cccrs we will use */
 585         for (i = 0; i < num_counters; i++) {
 586                 if (unlikely(!msrs->controls[i].addr))
 587                         continue;
 588                 rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
 589                 CCCR_CLEAR(low);
 590                 CCCR_SET_REQUIRED_BITS(low);
 591                 wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
 592         }
 593 
 594         /* clear all escrs (including those outside our concern) */
 595         for (i = num_counters; i < num_controls; i++) {
 596                 if (unlikely(!msrs->controls[i].addr))
 597                         continue;
 598                 wrmsr(msrs->controls[i].addr, 0, 0);
 599         }
 600 
 601         /* setup all counters */
 602         for (i = 0; i < num_counters; ++i) {
 603                 if (counter_config[i].enabled && msrs->controls[i].addr) {
 604                         reset_value[i] = counter_config[i].count;
 605                         pmc_setup_one_p4_counter(i);
 606                         wrmsrl(p4_counters[VIRT_CTR(stag, i)].counter_address,
 607                                -(u64)counter_config[i].count);
 608                 } else {
 609                         reset_value[i] = 0;
 610                 }
 611         }
 612 }
 613 
 614 
 615 static int p4_check_ctrs(struct pt_regs * const regs,
 616                          struct op_msrs const * const msrs)
 617 {
 618         unsigned long ctr, low, high, stag, real;
 619         int i;
 620 
 621         stag = get_stagger();
 622 
 623         for (i = 0; i < num_counters; ++i) {
 624 
 625                 if (!reset_value[i])
 626                         continue;
 627 
 628                 /*
 629                  * there is some eccentricity in the hardware which
 630                  * requires that we perform 2 extra corrections:
 631                  *
 632                  * - check both the CCCR:OVF flag for overflow and the
 633                  *   counter high bit for un-flagged overflows.
 634                  *
 635                  * - write the counter back twice to ensure it gets
 636                  *   updated properly.
 637                  *
 638                  * the former seems to be related to extra NMIs happening
 639                  * during the current NMI; the latter is reported as errata
 640                  * N15 in intel doc 249199-029, pentium 4 specification
 641                  * update, though their suggested work-around does not
 642                  * appear to solve the problem.
 643                  */
 644 
 645                 real = VIRT_CTR(stag, i);
 646 
 647                 rdmsr(p4_counters[real].cccr_address, low, high);
 648                 rdmsr(p4_counters[real].counter_address, ctr, high);
 649                 if (CCCR_OVF_P(low) || !(ctr & OP_CTR_OVERFLOW)) {
 650                         oprofile_add_sample(regs, i);
 651                         wrmsrl(p4_counters[real].counter_address,
 652                                -(u64)reset_value[i]);
 653                         CCCR_CLEAR_OVF(low);
 654                         wrmsr(p4_counters[real].cccr_address, low, high);
 655                         wrmsrl(p4_counters[real].counter_address,
 656                                -(u64)reset_value[i]);
 657                 }
 658         }
 659 
 660         /* P4 quirk: you have to re-unmask the apic vector */
 661         apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
 662 
 663         /* See op_model_ppro.c */
 664         return 1;
 665 }
 666 
 667 
 668 static void p4_start(struct op_msrs const * const msrs)
 669 {
 670         unsigned int low, high, stag;
 671         int i;
 672 
 673         stag = get_stagger();
 674 
 675         for (i = 0; i < num_counters; ++i) {
 676                 if (!reset_value[i])
 677                         continue;
 678                 rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
 679                 CCCR_SET_ENABLE(low);
 680                 wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
 681         }
 682 }
 683 
 684 
 685 static void p4_stop(struct op_msrs const * const msrs)
 686 {
 687         unsigned int low, high, stag;
 688         int i;
 689 
 690         stag = get_stagger();
 691 
 692         for (i = 0; i < num_counters; ++i) {
 693                 if (!reset_value[i])
 694                         continue;
 695                 rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
 696                 CCCR_SET_DISABLE(low);
 697                 wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
 698         }
 699 }
 700 
 701 #ifdef CONFIG_SMP
 702 struct op_x86_model_spec op_p4_ht2_spec = {
 703         .num_counters           = NUM_COUNTERS_HT2,
 704         .num_controls           = NUM_CONTROLS_HT2,
 705         .fill_in_addresses      = &p4_fill_in_addresses,
 706         .setup_ctrs             = &p4_setup_ctrs,
 707         .check_ctrs             = &p4_check_ctrs,
 708         .start                  = &p4_start,
 709         .stop                   = &p4_stop,
 710         .shutdown               = &p4_shutdown
 711 };
 712 #endif
 713 
 714 struct op_x86_model_spec op_p4_spec = {
 715         .num_counters           = NUM_COUNTERS_NON_HT,
 716         .num_controls           = NUM_CONTROLS_NON_HT,
 717         .fill_in_addresses      = &p4_fill_in_addresses,
 718         .setup_ctrs             = &p4_setup_ctrs,
 719         .check_ctrs             = &p4_check_ctrs,
 720         .start                  = &p4_start,
 721         .stop                   = &p4_stop,
 722         .shutdown               = &p4_shutdown
 723 };

/* [<][>][^][v][top][bottom][index][help] */