diff options
Diffstat (limited to 'arch/powerpc/oprofile/op_model_7450.c')
| -rw-r--r-- | arch/powerpc/oprofile/op_model_7450.c | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c index 32abfdbb0eb..d29b6e4e5e7 100644 --- a/arch/powerpc/oprofile/op_model_7450.c +++ b/arch/powerpc/oprofile/op_model_7450.c @@ -1,5 +1,5 @@ /* - * oprofile/op_model_7450.c + * arch/powerpc/oprofile/op_model_7450.c * * Freescale 745x/744x oprofile support, based on fsl_booke support * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM @@ -16,10 +16,8 @@ */ #include <linux/oprofile.h> -#include <linux/init.h> #include <linux/smp.h> #include <asm/ptrace.h> -#include <asm/system.h> #include <asm/processor.h> #include <asm/cputable.h> #include <asm/page.h> @@ -29,7 +27,7 @@ static unsigned long reset_value[OP_MAX_COUNTER]; static int oprofile_running; -static u32 mmcr0_val, mmcr1_val, mmcr2_val; +static u32 mmcr0_val, mmcr1_val, mmcr2_val, num_pmcs; #define MMCR0_PMC1_SHIFT 6 #define MMCR0_PMC2_SHIFT 0 @@ -81,31 +79,33 @@ static void pmc_stop_ctrs(void) /* Configures the counters on this CPU based on the global * settings */ -static void fsl7450_cpu_setup(void *unused) +static int fsl7450_cpu_setup(struct op_counter_config *ctr) { /* freeze all counters */ pmc_stop_ctrs(); mtspr(SPRN_MMCR0, mmcr0_val); mtspr(SPRN_MMCR1, mmcr1_val); - mtspr(SPRN_MMCR2, mmcr2_val); -} + if (num_pmcs > 4) + mtspr(SPRN_MMCR2, mmcr2_val); -#define NUM_CTRS 6 + return 0; +} /* Configures the global settings for the countes on all CPUs. */ -static void fsl7450_reg_setup(struct op_counter_config *ctr, +static int fsl7450_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, int num_ctrs) { int i; + num_pmcs = num_ctrs; /* Our counters count up, and "count" refers to * how much before the next interrupt, and we interrupt * on overflow. So we calculate the starting value * which will give us "count" until overflow. * Then we set the events on the enabled counters */ - for (i = 0; i < NUM_CTRS; ++i) + for (i = 0; i < num_ctrs; ++i) reset_value[i] = 0x80000000UL - ctr[i].count; /* Set events for Counters 1 & 2 */ @@ -121,25 +121,28 @@ static void fsl7450_reg_setup(struct op_counter_config *ctr, /* Set events for Counters 3-6 */ mmcr1_val = mmcr1_event3(ctr[2].event) - | mmcr1_event4(ctr[3].event) - | mmcr1_event5(ctr[4].event) - | mmcr1_event6(ctr[5].event); + | mmcr1_event4(ctr[3].event); + if (num_ctrs > 4) + mmcr1_val |= mmcr1_event5(ctr[4].event) + | mmcr1_event6(ctr[5].event); mmcr2_val = 0; + + return 0; } /* Sets the counters on this CPU to the chosen values, and starts them */ -static void fsl7450_start(struct op_counter_config *ctr) +static int fsl7450_start(struct op_counter_config *ctr) { int i; mtmsr(mfmsr() | MSR_PMM); - for (i = 0; i < NUM_CTRS; ++i) { + for (i = 0; i < num_pmcs; ++i) { if (ctr[i].enabled) - ctr_write(i, reset_value[i]); + classic_ctr_write(i, reset_value[i]); else - ctr_write(i, 0); + classic_ctr_write(i, 0); } /* Clear the freeze bit, and enable the interrupt. @@ -148,6 +151,8 @@ static void fsl7450_start(struct op_counter_config *ctr) pmc_start_ctrs(); oprofile_running = 1; + + return 0; } /* Stop the counters on this CPU */ @@ -176,16 +181,16 @@ static void fsl7450_handle_interrupt(struct pt_regs *regs, mtmsr(mfmsr() | MSR_PMM); pc = mfspr(SPRN_SIAR); - is_kernel = (pc >= KERNELBASE); + is_kernel = is_kernel_addr(pc); - for (i = 0; i < NUM_CTRS; ++i) { - val = ctr_read(i); + for (i = 0; i < num_pmcs; ++i) { + val = classic_ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { - oprofile_add_pc(pc, is_kernel, i); - ctr_write(i, reset_value[i]); + oprofile_add_ext_sample(pc, regs, i, is_kernel); + classic_ctr_write(i, reset_value[i]); } else { - ctr_write(i, 0); + classic_ctr_write(i, 0); } } } @@ -193,7 +198,7 @@ static void fsl7450_handle_interrupt(struct pt_regs *regs, /* 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 PM/M bit */ pmc_start_ctrs(); } |
