Page MenuHomeFreeBSD

D5644.diff
No OneTemporary

D5644.diff

Index: sys/dev/hwpmc/hwpmc_mips.c
===================================================================
--- sys/dev/hwpmc/hwpmc_mips.c
+++ sys/dev/hwpmc/hwpmc_mips.c
@@ -51,6 +51,8 @@
static struct mips_cpu **mips_pcpu;
+#define PMC_MIPS_NCNTRS_MAX 4
+
#if defined(__mips_n64)
# define MIPS_IS_VALID_KERNELADDR(reg) ((((reg) & 3) == 0) && \
((vm_offset_t)(reg) >= MIPS_XKPHYS_START))
@@ -178,6 +180,47 @@
return 0;
}
+static void
+pmc_mips_wr_perfctl(int ri, uint32_t x)
+{
+
+ switch (ri) {
+ case 0:
+ mips_wr_perfctl0(x);
+ break;
+ case 1:
+ mips_wr_perfctl1(x);
+ break;
+ case 2:
+ mips_wr_perfctl2(x);
+ break;
+ case 3:
+ mips_wr_perfctl3(x);
+ break;
+ default:
+ panic("pmc_mips_wr_perfctl() invalid ri argument: %d\n", ri);
+ }
+}
+
+static uint32_t
+pmc_mips_rd_perfctl(int ri)
+{
+
+ switch (ri) {
+ case 0:
+ return (mips_rd_perfctl0());
+ case 1:
+ return (mips_rd_perfctl1());
+ case 2:
+ return (mips_rd_perfctl2());
+ case 3:
+ return (mips_rd_perfctl3());
+ default:
+ break;
+ }
+ panic("pmc_mips_rd_perfctl() invalid ri argument: %d\n", ri);
+}
+
static int
mips_start_pmc(int cpu, int ri)
{
@@ -190,17 +233,7 @@
config = pm->pm_md.pm_mips_evsel;
/* Enable the PMC. */
- switch (ri) {
- case 0:
- mips_wr_perfcnt0(config);
- break;
- case 1:
- mips_wr_perfcnt2(config);
- break;
- default:
- break;
- }
-
+ pmc_mips_wr_perfctl(ri, config);
return 0;
}
@@ -219,16 +252,7 @@
* Clearing the entire register turns the counter off as well
* as removes the previously sampled event.
*/
- switch (ri) {
- case 0:
- mips_wr_perfcnt0(0);
- break;
- case 1:
- mips_wr_perfcnt2(0);
- break;
- default:
- break;
- }
+ pmc_mips_wr_perfctl(ri, 0);
return 0;
}
@@ -256,7 +280,7 @@
int retval, ri;
struct pmc *pm;
struct mips_cpu *pc;
- uint32_t r0, r2;
+ uint32_t sr[PMC_MIPS_NCNTRS_MAX];
pmc_value_t r;
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
@@ -266,10 +290,9 @@
pc = mips_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 < mips_npmcs; ri++) {
+ sr[ri] = pmc_mips_rd_perfctl(ri);
+ }
for (ri = 0; ri < mips_npmcs; ri++) {
pm = mips_pcpu[cpu]->pc_mipspmcs[ri].phw_pmc;
@@ -291,10 +314,7 @@
TRAPF_USERMODE(tf));
if (error) {
/* Clear/disable the relevant counter */
- if (ri == 0)
- r0 = 0;
- else if (ri == 1)
- r2 = 0;
+ sr[ri] = 0;
mips_stop_pmc(cpu, ri);
}
@@ -308,8 +328,9 @@
* Any counter which overflowed will have its sample count
* reloaded in the loop above.
*/
- mips_wr_perfcnt0(r0);
- mips_wr_perfcnt2(r2);
+ for (ri = 0; ri < mips_npmcs; ri++) {
+ pmc_mips_wr_perfctl(ri, sr[ri]);
+ }
return retval;
}
@@ -414,12 +435,24 @@
{
struct pmc_mdep *pmc_mdep;
struct pmc_classdep *pcd;
+ int ri;
/*
- * TODO: Use More bit of PerfCntlX register to detect actual
+ * Use More bit of PerfCtlX register to detect actual
* number of counters
*/
- mips_npmcs = 2;
+ for (ri = 0; ri < PMC_MIPS_NCNTRS_MAX; ri++) {
+ if ((pmc_mips_rd_perfctl(ri) & MIPS_PERFCTL_M) == 0) {
+ break;
+ }
+ }
+ if (ri == PMC_MIPS_NCNTRS_MAX) {
+ printf("pmc_mips_initialize: your CPU appears support more " \
+ "than %d hardware perfcounters, consider increasing " \
+ "PMC_MIPS_NCNTRS_MAX\n", PMC_MIPS_NCNTRS_MAX);
+ ri -= 1;
+ }
+ mips_npmcs = ri + 1;
PMCDBG1(MDP,INI,1,"mips-init npmcs=%d", mips_npmcs);
Index: sys/dev/hwpmc/hwpmc_mips24k.c
===================================================================
--- sys/dev/hwpmc/hwpmc_mips24k.c
+++ sys/dev/hwpmc/hwpmc_mips24k.c
@@ -193,9 +193,15 @@
switch (pmc) {
case 0:
- mips_wr_perfcnt1(reg);
+ mips_wr_perfcnt0(reg);
break;
case 1:
+ mips_wr_perfcnt1(reg);
+ break;
+ case 2:
+ mips_wr_perfcnt2(reg);
+ break;
+ case 3:
mips_wr_perfcnt3(reg);
break;
default:
Index: sys/dev/hwpmc/hwpmc_mips74k.c
===================================================================
--- sys/dev/hwpmc/hwpmc_mips74k.c
+++ sys/dev/hwpmc/hwpmc_mips74k.c
@@ -225,9 +225,15 @@
switch (pmc) {
case 0:
- mips_wr_perfcnt1(reg);
+ mips_wr_perfcnt0(reg);
break;
case 1:
+ mips_wr_perfcnt1(reg);
+ break;
+ case 2:
+ mips_wr_perfcnt2(reg);
+ break;
+ case 3:
mips_wr_perfcnt3(reg);
break;
default:
Index: sys/mips/include/cpufunc.h
===================================================================
--- sys/mips/include/cpufunc.h
+++ sys/mips/include/cpufunc.h
@@ -285,10 +285,17 @@
MIPS_RW32_COP0_SEL(watchhi2, MIPS_COP_0_WATCH_HI, 2);
MIPS_RW32_COP0_SEL(watchhi3, MIPS_COP_0_WATCH_HI, 3);
-MIPS_RW32_COP0_SEL(perfcnt0, MIPS_COP_0_PERFCNT, 0);
-MIPS_RW32_COP0_SEL(perfcnt1, MIPS_COP_0_PERFCNT, 1);
-MIPS_RW32_COP0_SEL(perfcnt2, MIPS_COP_0_PERFCNT, 2);
-MIPS_RW32_COP0_SEL(perfcnt3, MIPS_COP_0_PERFCNT, 3);
+/* Performance Counter Control registers */
+MIPS_RW32_COP0_SEL(perfctl0, MIPS_COP_0_PERFCNT, 0);
+MIPS_RW32_COP0_SEL(perfctl1, MIPS_COP_0_PERFCNT, 2);
+MIPS_RW32_COP0_SEL(perfctl2, MIPS_COP_0_PERFCNT, 4);
+MIPS_RW32_COP0_SEL(perfctl3, MIPS_COP_0_PERFCNT, 6);
+
+/* Performance Counter Count registers */
+MIPS_RW32_COP0_SEL(perfcnt0, MIPS_COP_0_PERFCNT, 1);
+MIPS_RW32_COP0_SEL(perfcnt1, MIPS_COP_0_PERFCNT, 3);
+MIPS_RW32_COP0_SEL(perfcnt2, MIPS_COP_0_PERFCNT, 5);
+MIPS_RW32_COP0_SEL(perfcnt3, MIPS_COP_0_PERFCNT, 7);
#undef MIPS_RW32_COP0
#undef MIPS_RW32_COP0_SEL
Index: sys/mips/include/cpuregs.h
===================================================================
--- sys/mips/include/cpuregs.h
+++ sys/mips/include/cpuregs.h
@@ -420,6 +420,15 @@
/* Master-Checker Mode - 1: enabled */
#define MIPS_CONFIG_CM 0x80000000
+/* Performance Counter Control register(s) bits */
+#define MIPS_PERFCTL_EXL (1 << 0)
+#define MIPS_PERFCTL_K (1 << 1)
+#define MIPS_PERFCTL_S (1 << 2)
+#define MIPS_PERFCTL_U (1 << 3)
+#define MIPS_PERFCTL_IE (1 << 4)
+#define MIPS_PERFCTL_PCTD (1 << 15)
+#define MIPS_PERFCTL_M (1 << 31)
+
/*
* The bits in the MIPS4 config register.
*/

File Metadata

Mime Type
text/plain
Expires
Sat, Jun 27, 1:21 AM (3 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34377238
Default Alt Text
D5644.diff (5 KB)

Event Timeline