static void fsl_emb_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) { unsigned long pc; int is_kernel; int val; int i; /* set the PMM bit (see comment below) */ mtmsr(mfmsr() | MSR_PMM); pc = regs->nip; is_kernel = is_kernel_addr(pc); for (i = 0; i < num_counters; ++i) { val = ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { oprofile_add_ext_sample(pc, regs, i, is_kernel); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); } } } /* The freeze bit was set by the interrupt. */ /* Clear the freeze bit, and reenable the interrupt. * The counters won't actually start until the rfi clears * the PMM bit */ pmc_start_ctrs(1); }
/* handle the perfmon overflow vector */ static void pa6t_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) { unsigned long pc = mfspr(SPRN_PA6T_SIAR); int is_kernel = is_kernel_addr(pc); u64 val; int i; u64 mmcr0; /* disable perfmon counting until rfid */ mmcr0 = mfspr(SPRN_PA6T_MMCR0); mtspr(SPRN_PA6T_MMCR0, mmcr0 | PA6T_MMCR0_HANDDIS); /* Record samples. We've got one global bit for whether a sample * was taken, so add it for any counter that triggered overflow. */ for (i = 0; i < cur_cpu_spec->num_pmcs; i++) { val = ctr_read(i); if (val & (0x1UL << 39)) { /* Overflow bit set */ if (oprofile_running && ctr[i].enabled) { if (mmcr0 & PA6T_MMCR0_SIARLOG) oprofile_add_ext_sample(pc, regs, i, is_kernel); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0UL); } } } /* Restore mmcr0 to a good known value since the PMI changes it */ mmcr0 = mmcr0_val | PA6T_MMCR0_HANDDIS; mtspr(SPRN_PA6T_MMCR0, mmcr0); }
void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) { int is_kernel = !user_mode(regs); unsigned long pc = profile_pc(regs); oprofile_add_ext_sample(pc, regs, event, is_kernel); }
static void fsl7450_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) { unsigned long pc; int is_kernel; int val; int i; /* */ mtmsr(mfmsr() | MSR_PMM); pc = mfspr(SPRN_SIAR); is_kernel = is_kernel_addr(pc); for (i = 0; i < num_pmcs; ++i) { val = classic_ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { oprofile_add_ext_sample(pc, regs, i, is_kernel); classic_ctr_write(i, reset_value[i]); } else { classic_ctr_write(i, 0); } } } /* */ /* */ pmc_start_ctrs(); }
static void fsl_emb_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) { unsigned long pc; int is_kernel; int val; int i; pc = regs->nip; is_kernel = is_kernel_addr(pc); for (i = 0; i < num_counters; ++i) { val = ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { oprofile_add_ext_sample(pc, regs, i, is_kernel); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); } } } /* The freeze bit was set by the interrupt. */ /* Clear the freeze bit, and reenable the interrupt. The * counters won't actually start until the rfi clears the PMM * bit. The PMM bit should not be set until after the interrupt * is cleared to avoid it getting lost in some hypervisor * environments. */ mtmsr(mfmsr() | MSR_PMM); pmc_start_ctrs(1); }
static void pa6t_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) { unsigned long pc = mfspr(SPRN_PA6T_SIAR); int is_kernel = is_kernel_addr(pc); u64 val; int i; u64 mmcr0; mmcr0 = mfspr(SPRN_PA6T_MMCR0); mtspr(SPRN_PA6T_MMCR0, mmcr0 | PA6T_MMCR0_HANDDIS); for (i = 0; i < cur_cpu_spec->num_pmcs; i++) { val = ctr_read(i); if (val & (0x1UL << 39)) { if (oprofile_running && ctr[i].enabled) { if (mmcr0 & PA6T_MMCR0_SIARLOG) oprofile_add_ext_sample(pc, regs, i, is_kernel); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0UL); } } } mmcr0 = mmcr0_val | PA6T_MMCR0_HANDDIS; mtspr(SPRN_PA6T_MMCR0, mmcr0); }
void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) { int is_kernel = !user_mode(regs); unsigned long pc = profile_pc(regs); #ifdef CONFIG_CA_CSS ca_css_add_ext_sample(pc, regs, event, is_kernel); #else oprofile_add_ext_sample(pc, regs, event, is_kernel); #endif }
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; unsigned long mmcra; mmcra = mfspr(SPRN_MMCRA); pc = get_pc(regs); is_kernel = get_kernel(pc, mmcra); /* set the PMM bit (see comment below) */ mtmsrd(mfmsr() | MSR_PMM); for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) { val = ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { oprofile_add_ext_sample(pc, regs, i, is_kernel); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); } } } 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; /* Clear the appropriate bits in the MMCRA */ mmcra &= ~cur_cpu_spec->oprofile_mmcra_clear; mtspr(SPRN_MMCRA, mmcra); /* * 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); }
static void rs64_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) { unsigned int mmcr0; int is_kernel; int val; int i; unsigned long pc = mfspr(SPRN_SIAR); is_kernel = is_kernel_addr(pc); /* set the PMM bit (see comment below) */ mtmsrd(mfmsr() | MSR_PMM); for (i = 0; i < num_counters; ++i) { val = classic_ctr_read(i); if (val < 0) { if (ctr[i].enabled) { oprofile_add_ext_sample(pc, regs, i, is_kernel); classic_ctr_write(i, reset_value[i]); } else { classic_ctr_write(i, 0); } } } mmcr0 = mfspr(SPRN_MMCR0); /* reset the perfmon trigger */ mmcr0 |= MMCR0_PMXE; /* * 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); }