Path: blob/master/arch/powerpc/oprofile/op_model_power4.c
10818 views
/*1* Copyright (C) 2004 Anton Blanchard <[email protected]>, IBM2* Added mmcra[slot] support:3* Copyright (C) 2006-2007 Will Schmidt <[email protected]>, IBM4*5* This program is free software; you can redistribute it and/or6* modify it under the terms of the GNU General Public License7* as published by the Free Software Foundation; either version8* 2 of the License, or (at your option) any later version.9*/1011#include <linux/oprofile.h>12#include <linux/init.h>13#include <linux/smp.h>14#include <asm/firmware.h>15#include <asm/ptrace.h>16#include <asm/system.h>17#include <asm/processor.h>18#include <asm/cputable.h>19#include <asm/rtas.h>20#include <asm/oprofile_impl.h>21#include <asm/reg.h>2223#define dbg(args...)2425static unsigned long reset_value[OP_MAX_COUNTER];2627static int oprofile_running;28static int use_slot_nums;2930/* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */31static u32 mmcr0_val;32static u64 mmcr1_val;33static u64 mmcra_val;3435static int power4_reg_setup(struct op_counter_config *ctr,36struct op_system_config *sys,37int num_ctrs)38{39int i;4041/*42* The performance counter event settings are given in the mmcr0,43* mmcr1 and mmcra values passed from the user in the44* op_system_config structure (sys variable).45*/46mmcr0_val = sys->mmcr0;47mmcr1_val = sys->mmcr1;48mmcra_val = sys->mmcra;4950for (i = 0; i < cur_cpu_spec->num_pmcs; ++i)51reset_value[i] = 0x80000000UL - ctr[i].count;5253/* setup user and kernel profiling */54if (sys->enable_kernel)55mmcr0_val &= ~MMCR0_KERNEL_DISABLE;56else57mmcr0_val |= MMCR0_KERNEL_DISABLE;5859if (sys->enable_user)60mmcr0_val &= ~MMCR0_PROBLEM_DISABLE;61else62mmcr0_val |= MMCR0_PROBLEM_DISABLE;6364if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) ||65__is_processor(PV_970) || __is_processor(PV_970FX) ||66__is_processor(PV_970MP) || __is_processor(PV_970GX) ||67__is_processor(PV_POWER5) || __is_processor(PV_POWER5p))68use_slot_nums = 1;6970return 0;71}7273extern void ppc_enable_pmcs(void);7475/*76* Older CPUs require the MMCRA sample bit to be always set, but newer77* CPUs only want it set for some groups. Eventually we will remove all78* knowledge of this bit in the kernel, oprofile userspace should be79* setting it when required.80*81* In order to keep current installations working we force the bit for82* those older CPUs. Once everyone has updated their oprofile userspace we83* can remove this hack.84*/85static inline int mmcra_must_set_sample(void)86{87if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) ||88__is_processor(PV_970) || __is_processor(PV_970FX) ||89__is_processor(PV_970MP) || __is_processor(PV_970GX))90return 1;9192return 0;93}9495static int power4_cpu_setup(struct op_counter_config *ctr)96{97unsigned int mmcr0 = mmcr0_val;98unsigned long mmcra = mmcra_val;99100ppc_enable_pmcs();101102/* set the freeze bit */103mmcr0 |= MMCR0_FC;104mtspr(SPRN_MMCR0, mmcr0);105106mmcr0 |= MMCR0_FCM1|MMCR0_PMXE|MMCR0_FCECE;107mmcr0 |= MMCR0_PMC1CE|MMCR0_PMCjCE;108mtspr(SPRN_MMCR0, mmcr0);109110mtspr(SPRN_MMCR1, mmcr1_val);111112if (mmcra_must_set_sample())113mmcra |= MMCRA_SAMPLE_ENABLE;114mtspr(SPRN_MMCRA, mmcra);115116dbg("setup on cpu %d, mmcr0 %lx\n", smp_processor_id(),117mfspr(SPRN_MMCR0));118dbg("setup on cpu %d, mmcr1 %lx\n", smp_processor_id(),119mfspr(SPRN_MMCR1));120dbg("setup on cpu %d, mmcra %lx\n", smp_processor_id(),121mfspr(SPRN_MMCRA));122123return 0;124}125126static int power4_start(struct op_counter_config *ctr)127{128int i;129unsigned int mmcr0;130131/* set the PMM bit (see comment below) */132mtmsrd(mfmsr() | MSR_PMM);133134for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {135if (ctr[i].enabled) {136classic_ctr_write(i, reset_value[i]);137} else {138classic_ctr_write(i, 0);139}140}141142mmcr0 = mfspr(SPRN_MMCR0);143144/*145* We must clear the PMAO bit on some (GQ) chips. Just do it146* all the time147*/148mmcr0 &= ~MMCR0_PMAO;149150/*151* now clear the freeze bit, counting will not start until we152* rfid from this excetion, because only at that point will153* the PMM bit be cleared154*/155mmcr0 &= ~MMCR0_FC;156mtspr(SPRN_MMCR0, mmcr0);157158oprofile_running = 1;159160dbg("start on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);161return 0;162}163164static void power4_stop(void)165{166unsigned int mmcr0;167168/* freeze counters */169mmcr0 = mfspr(SPRN_MMCR0);170mmcr0 |= MMCR0_FC;171mtspr(SPRN_MMCR0, mmcr0);172173oprofile_running = 0;174175dbg("stop on cpu %d, mmcr0 %x\n", smp_processor_id(), mmcr0);176177mb();178}179180/* Fake functions used by canonicalize_pc */181static void __used hypervisor_bucket(void)182{183}184185static void __used rtas_bucket(void)186{187}188189static void __used kernel_unknown_bucket(void)190{191}192193/*194* On GQ and newer the MMCRA stores the HV and PR bits at the time195* the SIAR was sampled. We use that to work out if the SIAR was sampled in196* the hypervisor, our exception vectors or RTAS.197* If the MMCRA_SAMPLE_ENABLE bit is set, we can use the MMCRA[slot] bits198* to more accurately identify the address of the sampled instruction. The199* mmcra[slot] bits represent the slot number of a sampled instruction200* within an instruction group. The slot will contain a value between 1201* and 5 if MMCRA_SAMPLE_ENABLE is set, otherwise 0.202*/203static unsigned long get_pc(struct pt_regs *regs)204{205unsigned long pc = mfspr(SPRN_SIAR);206unsigned long mmcra;207unsigned long slot;208209/* Can't do much about it */210if (!cur_cpu_spec->oprofile_mmcra_sihv)211return pc;212213mmcra = mfspr(SPRN_MMCRA);214215if (use_slot_nums && (mmcra & MMCRA_SAMPLE_ENABLE)) {216slot = ((mmcra & MMCRA_SLOT) >> MMCRA_SLOT_SHIFT);217if (slot > 1)218pc += 4 * (slot - 1);219}220221/* Were we in the hypervisor? */222if (firmware_has_feature(FW_FEATURE_LPAR) &&223(mmcra & cur_cpu_spec->oprofile_mmcra_sihv))224/* function descriptor madness */225return *((unsigned long *)hypervisor_bucket);226227/* We were in userspace, nothing to do */228if (mmcra & cur_cpu_spec->oprofile_mmcra_sipr)229return pc;230231#ifdef CONFIG_PPC_RTAS232/* Were we in RTAS? */233if (pc >= rtas.base && pc < (rtas.base + rtas.size))234/* function descriptor madness */235return *((unsigned long *)rtas_bucket);236#endif237238/* Were we in our exception vectors or SLB real mode miss handler? */239if (pc < 0x1000000UL)240return (unsigned long)__va(pc);241242/* Not sure where we were */243if (!is_kernel_addr(pc))244/* function descriptor madness */245return *((unsigned long *)kernel_unknown_bucket);246247return pc;248}249250static int get_kernel(unsigned long pc, unsigned long mmcra)251{252int is_kernel;253254if (!cur_cpu_spec->oprofile_mmcra_sihv) {255is_kernel = is_kernel_addr(pc);256} else {257is_kernel = ((mmcra & cur_cpu_spec->oprofile_mmcra_sipr) == 0);258}259260return is_kernel;261}262263static bool pmc_overflow(unsigned long val)264{265if ((int)val < 0)266return true;267268/*269* Events on POWER7 can roll back if a speculative event doesn't270* eventually complete. Unfortunately in some rare cases they will271* raise a performance monitor exception. We need to catch this to272* ensure we reset the PMC. In all cases the PMC will be 256 or less273* cycles from overflow.274*275* We only do this if the first pass fails to find any overflowing276* PMCs because a user might set a period of less than 256 and we277* don't want to mistakenly reset them.278*/279if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256))280return true;281282return false;283}284285static void power4_handle_interrupt(struct pt_regs *regs,286struct op_counter_config *ctr)287{288unsigned long pc;289int is_kernel;290int val;291int i;292unsigned int mmcr0;293unsigned long mmcra;294295mmcra = mfspr(SPRN_MMCRA);296297pc = get_pc(regs);298is_kernel = get_kernel(pc, mmcra);299300/* set the PMM bit (see comment below) */301mtmsrd(mfmsr() | MSR_PMM);302303for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {304val = classic_ctr_read(i);305if (pmc_overflow(val)) {306if (oprofile_running && ctr[i].enabled) {307oprofile_add_ext_sample(pc, regs, i, is_kernel);308classic_ctr_write(i, reset_value[i]);309} else {310classic_ctr_write(i, 0);311}312}313}314315mmcr0 = mfspr(SPRN_MMCR0);316317/* reset the perfmon trigger */318mmcr0 |= MMCR0_PMXE;319320/*321* We must clear the PMAO bit on some (GQ) chips. Just do it322* all the time323*/324mmcr0 &= ~MMCR0_PMAO;325326/* Clear the appropriate bits in the MMCRA */327mmcra &= ~cur_cpu_spec->oprofile_mmcra_clear;328mtspr(SPRN_MMCRA, mmcra);329330/*331* now clear the freeze bit, counting will not start until we332* rfid from this exception, because only at that point will333* the PMM bit be cleared334*/335mmcr0 &= ~MMCR0_FC;336mtspr(SPRN_MMCR0, mmcr0);337}338339struct op_powerpc_model op_model_power4 = {340.reg_setup = power4_reg_setup,341.cpu_setup = power4_cpu_setup,342.start = power4_start,343.stop = power4_stop,344.handle_interrupt = power4_handle_interrupt,345};346347348