Blame view
arch/powerpc/oprofile/op_model_power4.c
8.48 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 |
/* * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM |
078f19404 [POWERPC] Oprofil... |
3 4 |
* Added mmcra[slot] support: * Copyright (C) 2006-2007 Will Schmidt <willschm@us.ibm.com>, IBM |
1da177e4c Linux-2.6.12-rc2 |
5 6 7 8 9 10 11 12 13 14 |
* * 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; either version * 2 of the License, or (at your option) any later version. */ #include <linux/oprofile.h> #include <linux/init.h> #include <linux/smp.h> |
57cfb814f [PATCH] powerpc: ... |
15 |
#include <asm/firmware.h> |
1da177e4c Linux-2.6.12-rc2 |
16 17 18 19 |
#include <asm/ptrace.h> #include <asm/system.h> #include <asm/processor.h> #include <asm/cputable.h> |
1da177e4c Linux-2.6.12-rc2 |
20 |
#include <asm/rtas.h> |
dca859329 [PATCH] ppc64: Mo... |
21 |
#include <asm/oprofile_impl.h> |
cb09cff30 [PATCH] ppc64: fi... |
22 |
#include <asm/reg.h> |
1da177e4c Linux-2.6.12-rc2 |
23 24 |
#define dbg(args...) |
1da177e4c Linux-2.6.12-rc2 |
25 |
static unsigned long reset_value[OP_MAX_COUNTER]; |
1da177e4c Linux-2.6.12-rc2 |
26 |
static int oprofile_running; |
e5fc948b1 powerpc: Fix opro... |
27 |
static int use_slot_nums; |
1da177e4c Linux-2.6.12-rc2 |
28 29 30 31 |
/* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */ static u32 mmcr0_val; static u64 mmcr1_val; |
15e812ad8 [PATCH] powerpc: ... |
32 |
static u64 mmcra_val; |
1da177e4c Linux-2.6.12-rc2 |
33 |
|
1474855d0 [CELL] oprofile: ... |
34 |
static int power4_reg_setup(struct op_counter_config *ctr, |
1da177e4c Linux-2.6.12-rc2 |
35 36 37 38 |
struct op_system_config *sys, int num_ctrs) { int i; |
1da177e4c Linux-2.6.12-rc2 |
39 |
/* |
1da177e4c Linux-2.6.12-rc2 |
40 41 42 43 44 45 46 |
* The performance counter event settings are given in the mmcr0, * mmcr1 and mmcra values passed from the user in the * op_system_config structure (sys variable). */ mmcr0_val = sys->mmcr0; mmcr1_val = sys->mmcr1; mmcra_val = sys->mmcra; |
a6908cd00 [PATCH] ppc64: Us... |
47 |
for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) |
1da177e4c Linux-2.6.12-rc2 |
48 49 50 51 52 53 54 55 56 57 58 59 |
reset_value[i] = 0x80000000UL - ctr[i].count; /* setup user and kernel profiling */ if (sys->enable_kernel) mmcr0_val &= ~MMCR0_KERNEL_DISABLE; else mmcr0_val |= MMCR0_KERNEL_DISABLE; if (sys->enable_user) mmcr0_val &= ~MMCR0_PROBLEM_DISABLE; else mmcr0_val |= MMCR0_PROBLEM_DISABLE; |
1474855d0 [CELL] oprofile: ... |
60 |
|
e5fc948b1 powerpc: Fix opro... |
61 62 63 64 65 |
if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) || __is_processor(PV_970) || __is_processor(PV_970FX) || __is_processor(PV_970MP) || __is_processor(PV_970GX) || __is_processor(PV_POWER5) || __is_processor(PV_POWER5p)) use_slot_nums = 1; |
1474855d0 [CELL] oprofile: ... |
66 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
67 |
} |
b950bdd0f powerpc: Expose P... |
68 |
extern void ppc_enable_pmcs(void); |
1da177e4c Linux-2.6.12-rc2 |
69 |
|
cb09cff30 [PATCH] ppc64: fi... |
70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
/* * Older CPUs require the MMCRA sample bit to be always set, but newer * CPUs only want it set for some groups. Eventually we will remove all * knowledge of this bit in the kernel, oprofile userspace should be * setting it when required. * * In order to keep current installations working we force the bit for * those older CPUs. Once everyone has updated their oprofile userspace we * can remove this hack. */ static inline int mmcra_must_set_sample(void) { if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) || __is_processor(PV_970) || __is_processor(PV_970FX) || |
362ff7b2a [POWERPC] Add 970... |
84 |
__is_processor(PV_970MP) || __is_processor(PV_970GX)) |
cb09cff30 [PATCH] ppc64: fi... |
85 86 87 88 |
return 1; return 0; } |
1474855d0 [CELL] oprofile: ... |
89 |
static int power4_cpu_setup(struct op_counter_config *ctr) |
1da177e4c Linux-2.6.12-rc2 |
90 91 92 |
{ unsigned int mmcr0 = mmcr0_val; unsigned long mmcra = mmcra_val; |
b950bdd0f powerpc: Expose P... |
93 |
ppc_enable_pmcs(); |
1da177e4c Linux-2.6.12-rc2 |
94 95 96 97 98 99 100 101 102 103 |
/* set the freeze bit */ mmcr0 |= MMCR0_FC; mtspr(SPRN_MMCR0, mmcr0); mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE; mmcr0 |= MMCR0_PMC1CE|MMCR0_PMCjCE; mtspr(SPRN_MMCR0, mmcr0); mtspr(SPRN_MMCR1, mmcr1_val); |
cb09cff30 [PATCH] ppc64: fi... |
104 105 |
if (mmcra_must_set_sample()) mmcra |= MMCRA_SAMPLE_ENABLE; |
1da177e4c Linux-2.6.12-rc2 |
106 107 108 109 110 111 112 113 114 115 116 |
mtspr(SPRN_MMCRA, mmcra); dbg("setup on cpu %d, mmcr0 %lx ", smp_processor_id(), mfspr(SPRN_MMCR0)); dbg("setup on cpu %d, mmcr1 %lx ", smp_processor_id(), mfspr(SPRN_MMCR1)); dbg("setup on cpu %d, mmcra %lx ", smp_processor_id(), mfspr(SPRN_MMCRA)); |
1474855d0 [CELL] oprofile: ... |
117 118 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
119 |
} |
1474855d0 [CELL] oprofile: ... |
120 |
static int power4_start(struct op_counter_config *ctr) |
1da177e4c Linux-2.6.12-rc2 |
121 122 123 124 125 126 |
{ int i; unsigned int mmcr0; /* set the PMM bit (see comment below) */ mtmsrd(mfmsr() | MSR_PMM); |
a6908cd00 [PATCH] ppc64: Us... |
127 |
for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) { |
1da177e4c Linux-2.6.12-rc2 |
128 |
if (ctr[i].enabled) { |
c69b767a2 [POWERPC] Oprofil... |
129 |
classic_ctr_write(i, reset_value[i]); |
1da177e4c Linux-2.6.12-rc2 |
130 |
} else { |
c69b767a2 [POWERPC] Oprofil... |
131 |
classic_ctr_write(i, 0); |
1da177e4c Linux-2.6.12-rc2 |
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
} } mmcr0 = mfspr(SPRN_MMCR0); /* * We must clear the PMAO bit on some (GQ) chips. Just do it * all the time */ mmcr0 &= ~MMCR0_PMAO; /* * now clear the freeze bit, counting will not start until we * rfid from this excetion, because only at that point will * the PMM bit be cleared */ mmcr0 &= ~MMCR0_FC; mtspr(SPRN_MMCR0, mmcr0); oprofile_running = 1; dbg("start on cpu %d, mmcr0 %x ", smp_processor_id(), mmcr0); |
1474855d0 [CELL] oprofile: ... |
155 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
} static void power4_stop(void) { unsigned int mmcr0; /* freeze counters */ mmcr0 = mfspr(SPRN_MMCR0); mmcr0 |= MMCR0_FC; mtspr(SPRN_MMCR0, mmcr0); oprofile_running = 0; dbg("stop on cpu %d, mmcr0 %x ", smp_processor_id(), mmcr0); mb(); } /* Fake functions used by canonicalize_pc */ |
3ff6eecca remove __attribut... |
176 |
static void __used hypervisor_bucket(void) |
1da177e4c Linux-2.6.12-rc2 |
177 178 |
{ } |
3ff6eecca remove __attribut... |
179 |
static void __used rtas_bucket(void) |
1da177e4c Linux-2.6.12-rc2 |
180 181 |
{ } |
3ff6eecca remove __attribut... |
182 |
static void __used kernel_unknown_bucket(void) |
1da177e4c Linux-2.6.12-rc2 |
183 184 |
{ } |
1da177e4c Linux-2.6.12-rc2 |
185 186 187 188 |
/* * On GQ and newer the MMCRA stores the HV and PR bits at the time * the SIAR was sampled. We use that to work out if the SIAR was sampled in * the hypervisor, our exception vectors or RTAS. |
078f19404 [POWERPC] Oprofil... |
189 190 191 192 193 |
* If the MMCRA_SAMPLE_ENABLE bit is set, we can use the MMCRA[slot] bits * to more accurately identify the address of the sampled instruction. The * mmcra[slot] bits represent the slot number of a sampled instruction * within an instruction group. The slot will contain a value between 1 * and 5 if MMCRA_SAMPLE_ENABLE is set, otherwise 0. |
1da177e4c Linux-2.6.12-rc2 |
194 195 196 197 198 |
*/ static unsigned long get_pc(struct pt_regs *regs) { unsigned long pc = mfspr(SPRN_SIAR); unsigned long mmcra; |
078f19404 [POWERPC] Oprofil... |
199 |
unsigned long slot; |
1da177e4c Linux-2.6.12-rc2 |
200 |
|
25985edce Fix common misspe... |
201 |
/* Can't do much about it */ |
e78dbc800 [PATCH] powerpc: ... |
202 |
if (!cur_cpu_spec->oprofile_mmcra_sihv) |
15e812ad8 [PATCH] powerpc: ... |
203 |
return pc; |
1da177e4c Linux-2.6.12-rc2 |
204 205 |
mmcra = mfspr(SPRN_MMCRA); |
e5fc948b1 powerpc: Fix opro... |
206 |
if (use_slot_nums && (mmcra & MMCRA_SAMPLE_ENABLE)) { |
078f19404 [POWERPC] Oprofil... |
207 208 209 210 |
slot = ((mmcra & MMCRA_SLOT) >> MMCRA_SLOT_SHIFT); if (slot > 1) pc += 4 * (slot - 1); } |
1da177e4c Linux-2.6.12-rc2 |
211 |
/* Were we in the hypervisor? */ |
e78dbc800 [PATCH] powerpc: ... |
212 213 |
if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & cur_cpu_spec->oprofile_mmcra_sihv)) |
1da177e4c Linux-2.6.12-rc2 |
214 215 216 217 |
/* function descriptor madness */ return *((unsigned long *)hypervisor_bucket); /* We were in userspace, nothing to do */ |
e78dbc800 [PATCH] powerpc: ... |
218 |
if (mmcra & cur_cpu_spec->oprofile_mmcra_sipr) |
1da177e4c Linux-2.6.12-rc2 |
219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
return pc; #ifdef CONFIG_PPC_RTAS /* Were we in RTAS? */ if (pc >= rtas.base && pc < (rtas.base + rtas.size)) /* function descriptor madness */ return *((unsigned long *)rtas_bucket); #endif /* Were we in our exception vectors or SLB real mode miss handler? */ if (pc < 0x1000000UL) return (unsigned long)__va(pc); /* Not sure where we were */ |
51fae6de2 [PATCH] powerpc: ... |
233 |
if (!is_kernel_addr(pc)) |
1da177e4c Linux-2.6.12-rc2 |
234 235 |
/* function descriptor madness */ return *((unsigned long *)kernel_unknown_bucket); |
15e812ad8 [PATCH] powerpc: ... |
236 |
return pc; |
1da177e4c Linux-2.6.12-rc2 |
237 |
} |
e78dbc800 [PATCH] powerpc: ... |
238 |
static int get_kernel(unsigned long pc, unsigned long mmcra) |
1da177e4c Linux-2.6.12-rc2 |
239 240 |
{ int is_kernel; |
e78dbc800 [PATCH] powerpc: ... |
241 |
if (!cur_cpu_spec->oprofile_mmcra_sihv) { |
51fae6de2 [PATCH] powerpc: ... |
242 |
is_kernel = is_kernel_addr(pc); |
1da177e4c Linux-2.6.12-rc2 |
243 |
} else { |
e78dbc800 [PATCH] powerpc: ... |
244 |
is_kernel = ((mmcra & cur_cpu_spec->oprofile_mmcra_sipr) == 0); |
1da177e4c Linux-2.6.12-rc2 |
245 246 247 248 |
} return is_kernel; } |
ad5d5292f powerpc/oprofile:... |
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
static bool pmc_overflow(unsigned long val) { if ((int)val < 0) return true; /* * Events on POWER7 can roll back if a speculative event doesn't * eventually complete. Unfortunately in some rare cases they will * raise a performance monitor exception. We need to catch this to * ensure we reset the PMC. In all cases the PMC will be 256 or less * cycles from overflow. * * We only do this if the first pass fails to find any overflowing * PMCs because a user might set a period of less than 256 and we * don't want to mistakenly reset them. */ if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256)) return true; return false; } |
1da177e4c Linux-2.6.12-rc2 |
270 271 272 273 274 275 276 277 |
static void power4_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) { unsigned long pc; int is_kernel; int val; int i; unsigned int mmcr0; |
e78dbc800 [PATCH] powerpc: ... |
278 279 280 |
unsigned long mmcra; mmcra = mfspr(SPRN_MMCRA); |
1da177e4c Linux-2.6.12-rc2 |
281 282 |
pc = get_pc(regs); |
e78dbc800 [PATCH] powerpc: ... |
283 |
is_kernel = get_kernel(pc, mmcra); |
1da177e4c Linux-2.6.12-rc2 |
284 285 286 |
/* set the PMM bit (see comment below) */ mtmsrd(mfmsr() | MSR_PMM); |
a6908cd00 [PATCH] ppc64: Us... |
287 |
for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) { |
c69b767a2 [POWERPC] Oprofil... |
288 |
val = classic_ctr_read(i); |
ad5d5292f powerpc/oprofile:... |
289 |
if (pmc_overflow(val)) { |
1da177e4c Linux-2.6.12-rc2 |
290 |
if (oprofile_running && ctr[i].enabled) { |
6c6bd754b [PATCH] powerpc: ... |
291 |
oprofile_add_ext_sample(pc, regs, i, is_kernel); |
c69b767a2 [POWERPC] Oprofil... |
292 |
classic_ctr_write(i, reset_value[i]); |
1da177e4c Linux-2.6.12-rc2 |
293 |
} else { |
c69b767a2 [POWERPC] Oprofil... |
294 |
classic_ctr_write(i, 0); |
1da177e4c Linux-2.6.12-rc2 |
295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
} } } mmcr0 = mfspr(SPRN_MMCR0); /* reset the perfmon trigger */ mmcr0 |= MMCR0_PMXE; /* * We must clear the PMAO bit on some (GQ) chips. Just do it * all the time */ mmcr0 &= ~MMCR0_PMAO; |
e78dbc800 [PATCH] powerpc: ... |
309 310 311 |
/* Clear the appropriate bits in the MMCRA */ mmcra &= ~cur_cpu_spec->oprofile_mmcra_clear; mtspr(SPRN_MMCRA, mmcra); |
1da177e4c Linux-2.6.12-rc2 |
312 313 314 315 316 317 318 319 |
/* * now clear the freeze bit, counting will not start until we * rfid from this exception, because only at that point will * the PMM bit be cleared */ mmcr0 &= ~MMCR0_FC; mtspr(SPRN_MMCR0, mmcr0); } |
a3e48c10c [PATCH] powerpc: ... |
320 |
struct op_powerpc_model op_model_power4 = { |
1da177e4c Linux-2.6.12-rc2 |
321 322 323 324 325 326 |
.reg_setup = power4_reg_setup, .cpu_setup = power4_cpu_setup, .start = power4_start, .stop = power4_stop, .handle_interrupt = power4_handle_interrupt, }; |