From owner-svn-src-all@FreeBSD.ORG Wed Nov 9 17:38:27 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8B05E106564A; Wed, 9 Nov 2011 17:38:27 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 61CD08FC12; Wed, 9 Nov 2011 17:38:27 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pA9HcRg6092641; Wed, 9 Nov 2011 17:38:27 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pA9HcRIe092639; Wed, 9 Nov 2011 17:38:27 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201111091738.pA9HcRIe092639@svn.freebsd.org> From: Adrian Chadd Date: Wed, 9 Nov 2011 17:38:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r227395 - head/sys/dev/hwpmc X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Nov 2011 17:38:27 -0000 Author: adrian Date: Wed Nov 9 17:38:27 2011 New Revision: 227395 URL: http://svn.freebsd.org/changeset/base/227395 Log: Flip on processing interrupt profile events for mips24k. This is a bit hackish and should be made more generic (ie, support more than two hard-coded performance counter+config register pairs) so it can be used for mips74k and other chips. All this does is process the initial interrupt event. It doesn't (yet) handle callgraph events, so even if you route the exception/interrupt to this routine and flip the bit on, it will hang and crash pmc unless you disable callgraph support when you enable a sample based PMC. Modified: head/sys/dev/hwpmc/hwpmc_mips24k.c Modified: head/sys/dev/hwpmc/hwpmc_mips24k.c ============================================================================== --- head/sys/dev/hwpmc/hwpmc_mips24k.c Wed Nov 9 17:25:43 2011 (r227394) +++ head/sys/dev/hwpmc/hwpmc_mips24k.c Wed Nov 9 17:38:27 2011 (r227395) @@ -254,6 +254,8 @@ mips24k_allocate_pmc(int cpu, int ri, st config |= MIPS24K_PMC_USER_ENABLE; if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0) config |= MIPS24K_PMC_ENABLE; + if (caps & PMC_CAP_INTERRUPT) + config |= MIPS24K_PMC_INTERRUPT_ENABLE; pm->pm_md.pm_mips24k.pm_mips24k_evsel = config; @@ -404,7 +406,65 @@ mips24k_release_pmc(int cpu, int ri, str static int mips24k_intr(int cpu, struct trapframe *tf) { - return 0; + int error; + int retval, ri; + struct pmc *pm; + struct mips24k_cpu *pc; + uint32_t r, r0, r2; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[mips24k,%d] CPU %d out of range", __LINE__, cpu)); + + retval = 0; + pc = mips24k_pcpu[cpu]; + + /* Stop PMCs without clearing the counter */ + r0 = mips_rd_perfcnt0(); + mips_wr_perfcnt0(r0 & ~(0x1f)); + r2 = mips_rd_perfcnt2(); + mips_wr_perfcnt2(r2 & ~(0x1f)); + + for (ri = 0; ri < mips24k_npmcs; ri++) { + pm = mips24k_pcpu[cpu]->pc_mipspmcs[ri].phw_pmc; + if (pm == NULL) + continue; + if (! PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) + continue; + + r = mips24k_pmcn_read(ri); + + /* If bit 31 is set, the counter has overflowed */ + if ((r & 0x80000000) == 0) + continue; + + retval = 1; + if (pm->pm_state != PMC_STATE_RUNNING) + continue; + error = pmc_process_interrupt(cpu, pm, tf, + TRAPF_USERMODE(tf)); + if (error) { + /* Clear/disable the relevant counter */ + if (ri == 0) + r0 = 0; + else if (ri == 1) + r2 = 0; + mips24k_stop_pmc(cpu, ri); + } + + /* Reload sampling count */ + mips24k_write_pmc(cpu, ri, pm->pm_sc.pm_reloadcount); + } + + /* + * Re-enable the PMC counters where they left off. + * + * Any counter which overflowed will have its sample count + * reloaded in the loop above. + */ + mips_wr_perfcnt0(r0); + mips_wr_perfcnt2(r2); + + return retval; } static int