static int perf_proc_irq(void) { unsigned long snapshot; /* * It would be nice to do this as a loop, but we don't have * indirect access to CP0 registers. */ snapshot = read_c0_perfcntr0(); if ((long)snapshot < 0) { extencount[0] += (unsigned long long)((unsigned)read_c0_perfcntr0()); write_c0_perfcntr0(0); } snapshot = read_c0_perfcntr1(); if ((long)snapshot < 0) { extencount[1] += (unsigned long long)((unsigned)read_c0_perfcntr1()); write_c0_perfcntr1(0); } snapshot = read_c0_perfcntr2(); if ((long)snapshot < 0) { extencount[2] += (unsigned long long)((unsigned)read_c0_perfcntr2()); write_c0_perfcntr2(0); } snapshot = read_c0_perfcntr3(); if ((long)snapshot < 0) { extencount[3] += (unsigned long long)((unsigned)read_c0_perfcntr3()); write_c0_perfcntr3(0); } return 0; }
static int proc_write_perf(struct file *file, const char *buffer, unsigned long count, void *data) { int len; int nparsed; int index; char mybuf[TXTBUFSZ]; int which[4]; unsigned long control[4]; long long ctrdata[4]; if(count >= TXTBUFSZ) len = TXTBUFSZ-1; else len = count; memset(mybuf,0,TXTBUFSZ); if(copy_from_user(mybuf, buffer, len)) return -EFAULT; nparsed = sscanf(mybuf, "%d %lx %Ld %d %lx %Ld %d %lx %Ld %d %lx %Ld", &which[0], &control[0], &ctrdata[0], &which[1], &control[1], &ctrdata[1], &which[2], &control[2], &ctrdata[2], &which[3], &control[3], &ctrdata[3]); for(index = 0; nparsed >= 3; index++) { switch (which[index]) { case 0: write_c0_perfctrl0(control[index]); if(ctrdata[index] != -1) { extencount[0] = (unsigned long long)ctrdata[index]; write_c0_perfcntr0((unsigned long)0); } break; case 1: write_c0_perfctrl1(control[index]); if(ctrdata[index] != -1) { extencount[1] = (unsigned long long)ctrdata[index]; write_c0_perfcntr1((unsigned long)0); } break; case 2: write_c0_perfctrl2(control[index]); if(ctrdata[index] != -1) { extencount[2] = (unsigned long long)ctrdata[index]; write_c0_perfcntr2((unsigned long)0); } break; case 3: write_c0_perfctrl3(control[index]); if(ctrdata[index] != -1) { extencount[3] = (unsigned long long)ctrdata[index]; write_c0_perfcntr3((unsigned long)0); } break; } nparsed -= 3; } return (len); }
void start_cntrs(unsigned int event0, unsigned int event1) { write_c0_perfcntr0(0x00000000); write_c0_perfcntr1(0x00000000); /* * go... */ write_c0_perfctrl0(0x80000000 | M_PERFCTL_EVENT(event0) | 0xf); write_c0_perfctrl1(0x00000000 | M_PERFCTL_EVENT(event1) | 0xf); }
static int __init init_perf_proc(void) { extern struct proc_dir_entry *get_mips_proc_dir(void); struct proc_dir_entry *mips_proc_dir = get_mips_proc_dir(); write_c0_perfcntr0(0); write_c0_perfcntr1(0); write_c0_perfcntr2(0); write_c0_perfcntr3(0); perf_proc = create_proc_entry("perf", 0644, mips_proc_dir); perf_proc->read_proc = proc_read_perf; perf_proc->write_proc = proc_write_perf; perf_irq = perf_proc_irq; return 0; }
//#ifdef Z_DEBUG //static void ls232_cpu_setup (void) //#else static void ls232_cpu_setup (void *args) //#endif { //uint64_t perfcount; uint32_t perfcount0; uint32_t perfcount1; PERF_DEBUG_Z #if 1 //perfcount = (reg.reset_counter2 << 32) |reg.reset_counter1; perfcount0 = reg.reset_counter1; perfcount1 = reg.reset_counter2; #ifdef LS232_PERFCONTER write_c0_perfcntr0(perfcount0); write_c0_perfcntr1(perfcount1); #else write_c0_perflo(reg.control); write_c0_perfhi(perfcount); #endif #endif }