diff options
Diffstat (limited to 'arch/powerpc/oprofile/op_model_power4.c')
-rw-r--r-- | arch/powerpc/oprofile/op_model_power4.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c index fe597a154d4f..a7c206b665af 100644 --- a/arch/powerpc/oprofile/op_model_power4.c +++ b/arch/powerpc/oprofile/op_model_power4.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM | 2 | * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM |
3 | * Added mmcra[slot] support: | ||
4 | * Copyright (C) 2006-2007 Will Schmidt <willschm@us.ibm.com>, IBM | ||
3 | * | 5 | * |
4 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
@@ -181,11 +183,17 @@ static void __attribute_used__ kernel_unknown_bucket(void) | |||
181 | * On GQ and newer the MMCRA stores the HV and PR bits at the time | 183 | * On GQ and newer the MMCRA stores the HV and PR bits at the time |
182 | * the SIAR was sampled. We use that to work out if the SIAR was sampled in | 184 | * the SIAR was sampled. We use that to work out if the SIAR was sampled in |
183 | * the hypervisor, our exception vectors or RTAS. | 185 | * the hypervisor, our exception vectors or RTAS. |
186 | * If the MMCRA_SAMPLE_ENABLE bit is set, we can use the MMCRA[slot] bits | ||
187 | * to more accurately identify the address of the sampled instruction. The | ||
188 | * mmcra[slot] bits represent the slot number of a sampled instruction | ||
189 | * within an instruction group. The slot will contain a value between 1 | ||
190 | * and 5 if MMCRA_SAMPLE_ENABLE is set, otherwise 0. | ||
184 | */ | 191 | */ |
185 | static unsigned long get_pc(struct pt_regs *regs) | 192 | static unsigned long get_pc(struct pt_regs *regs) |
186 | { | 193 | { |
187 | unsigned long pc = mfspr(SPRN_SIAR); | 194 | unsigned long pc = mfspr(SPRN_SIAR); |
188 | unsigned long mmcra; | 195 | unsigned long mmcra; |
196 | unsigned long slot; | ||
189 | 197 | ||
190 | /* Cant do much about it */ | 198 | /* Cant do much about it */ |
191 | if (!cur_cpu_spec->oprofile_mmcra_sihv) | 199 | if (!cur_cpu_spec->oprofile_mmcra_sihv) |
@@ -193,6 +201,12 @@ static unsigned long get_pc(struct pt_regs *regs) | |||
193 | 201 | ||
194 | mmcra = mfspr(SPRN_MMCRA); | 202 | mmcra = mfspr(SPRN_MMCRA); |
195 | 203 | ||
204 | if (mmcra & MMCRA_SAMPLE_ENABLE) { | ||
205 | slot = ((mmcra & MMCRA_SLOT) >> MMCRA_SLOT_SHIFT); | ||
206 | if (slot > 1) | ||
207 | pc += 4 * (slot - 1); | ||
208 | } | ||
209 | |||
196 | /* Were we in the hypervisor? */ | 210 | /* Were we in the hypervisor? */ |
197 | if (firmware_has_feature(FW_FEATURE_LPAR) && | 211 | if (firmware_has_feature(FW_FEATURE_LPAR) && |
198 | (mmcra & cur_cpu_spec->oprofile_mmcra_sihv)) | 212 | (mmcra & cur_cpu_spec->oprofile_mmcra_sihv)) |