irqreturn_t c0_compare_interrupt(int irq, void *dev_id) { const int r2 = cpu_has_mips_r2; struct clock_event_device *cd; int cpu = smp_processor_id(); /* */ if (handle_perf_irq(r2)) goto out; /* */ if (!r2 || (read_c0_cause() & (1 << 30))) { /* */ write_c0_compare(read_c0_compare()); cd = &per_cpu(mips_clockevent_device, cpu); cd->event_handler(cd); } out: return IRQ_HANDLED; }
irqreturn_t c0_compare_interrupt(int irq, void *dev_id) { const int r2 = cpu_has_mips_r2; struct clock_event_device *cd; int cpu = smp_processor_id(); /* * Suckage alert: * Before R2 of the architecture there was no way to see if a * performance counter interrupt was pending, so we have to run * the performance counter interrupt handler anyway. */ if (handle_perf_irq(r2)) goto out; /* * The same applies to performance counter interrupts. But with the * above we now know that the reason we got here must be a timer * interrupt. Being the paranoiacs we are we check anyway. */ if (!r2 || (read_c0_cause() & (1 << 30))) { /* Clear Count/Compare Interrupt */ write_c0_compare(read_c0_compare()); cd = &per_cpu(mips_clockevent_device, cpu); cd->event_handler(cd); } out: return IRQ_HANDLED; }
static int tx4939_proc_show_cp0(char *sysbuf, char **start, off_t off, int count, int *eof, void *data) { int len = 0; len += sprintf(sysbuf + len, "INDEX :0x%08x\n", read_c0_index()); len += sprintf(sysbuf + len, "ENTRYLO0:0x%08lx\n", read_c0_entrylo0()); len += sprintf(sysbuf + len, "ENTRYLO1:0x%08lx\n", read_c0_entrylo1()); len += sprintf(sysbuf + len, "CONTEXT :0x%08lx\n", read_c0_context()); len += sprintf(sysbuf + len, "PAGEMASK:0x%08x\n", read_c0_pagemask()); len += sprintf(sysbuf + len, "WIRED :0x%08x\n", read_c0_wired()); len += sprintf(sysbuf + len, "COUNT :0x%08x\n", read_c0_count()); len += sprintf(sysbuf + len, "ENTRYHI :0x%08lx\n", read_c0_entryhi()); len += sprintf(sysbuf + len, "COMPARE :0x%08x\n", read_c0_compare()); len += sprintf(sysbuf + len, "STATUS :0x%08x\n", read_c0_status()); len += sprintf(sysbuf + len, "CAUSE :0x%08x\n", read_c0_cause()); len += sprintf(sysbuf + len, "PRId :0x%08x\n", read_c0_prid()); len += sprintf(sysbuf + len, "CONFIG :0x%08x\n", read_c0_config()); len += sprintf(sysbuf + len, "XCONTEXT:0x%08lx\n", read_c0_xcontext()); len += sprintf(sysbuf + len, "TagLo :0x%08x\n", read_c0_taglo()); len += sprintf(sysbuf + len, "TagHi :0x%08x\n", read_c0_taghi()); len += sprintf(sysbuf + len, "ErrorEPC:0x%08lx\n", read_c0_errorepc()); *eof = 1; return len; }
/** * This is the timer interrupt service routine. */ void rt_hw_timer_handler() { unsigned int count; count = read_c0_compare(); write_c0_compare(count); write_c0_count(0); /* increase a OS tick */ rt_tick_increase(); }
ulong get_timer(ulong base) { unsigned int count; unsigned int expirelo = read_c0_compare(); /* Check to see if we have missed any timestamps. */ count = read_c0_count(); while ((count - expirelo) < 0x7fffffff) { expirelo += CYCLES_PER_JIFFY; timestamp++; } write_c0_compare(expirelo); return timestamp - base; }
void __init plat_timer_setup(struct irqaction *irq) { /* Connect the timer interrupt */ irq->dev_id = (void *) irq; setup_irq(BCM_LINUX_SYSTIMER_IRQ, irq); #ifdef CONFIG_MIPS_MT_SMTC irq->handler = smtc_timer_interrupt; irq_desc[BCM_LINUX_SYSTIMER_IRQ].status &= ~IRQ_DISABLED; irq_desc[BCM_LINUX_SYSTIMER_IRQ].status |= IRQ_PER_CPU; #endif /* reset COMPARE for first timer interrupt if it is missed */ if(read_c0_count() > read_c0_compare()) write_c0_compare(read_c0_count() + (mips_hpt_frequency/HZ)); }
static int pnx8550_timers_read (char* page, char** start, off_t offset, int count, int* eof, void* data) { int len = 0; int configPR = read_c0_config7(); if (offset==0) { len += sprintf(&page[len],"Timer: count, compare, tc, status\n"); len += sprintf(&page[len]," 1: %11i, %8i, %1i, %s\n", read_c0_count(), read_c0_compare(), (configPR>>6)&0x1, ((configPR>>3)&0x1)? "off":"on"); len += sprintf(&page[len]," 2: %11i, %8i, %1i, %s\n", read_c0_count2(), read_c0_compare2(), (configPR>>7)&0x1, ((configPR>>4)&0x1)? "off":"on"); len += sprintf(&page[len]," 3: %11i, %8i, %1i, %s\n", read_c0_count3(), read_c0_compare3(), (configPR>>8)&0x1, ((configPR>>5)&0x1)? "off":"on"); }
ulong get_timer(ulong base) { return (read_c0_count()/(CONFIG_SYS_MIPS_TIMER_FREQ/CONFIG_SYS_HZ)) - base; #ifndef CONFIG_MIPS_CPU_PR4450 unsigned int count; unsigned int expirelo = read_c0_compare(); /* Check to see if we have missed any timestamps. */ count = read_c0_count(); while ((count - expirelo) < 0x7fffffff) { expirelo += CYCLES_PER_JIFFY; timestamp++; } write_c0_compare(expirelo); return (timestamp - base); #endif }
void dump_cp0(char *key) { if (key == NULL) key = ""; print_cp0(key, 0, "INDEX ", read_c0_index()); print_cp0(key, 2, "ENTRYLO1", read_c0_entrylo0()); print_cp0(key, 3, "ENTRYLO2", read_c0_entrylo1()); print_cp0(key, 4, "CONTEXT ", read_c0_context()); print_cp0(key, 5, "PAGEMASK", read_c0_pagemask()); print_cp0(key, 6, "WIRED ", read_c0_wired()); //print_cp0(key, 8, "BADVADDR", read_c0_badvaddr()); print_cp0(key, 9, "COUNT ", read_c0_count()); print_cp0(key, 10, "ENTRYHI ", read_c0_entryhi()); print_cp0(key, 11, "COMPARE ", read_c0_compare()); print_cp0(key, 12, "STATUS ", read_c0_status()); print_cp0(key, 13, "CAUSE ", read_c0_cause() & 0xffff87ff); print_cp0(key, 16, "CONFIG ", read_c0_config()); return; }
irqreturn_t c0_compare_interrupt(int irq, void *dev_id) { const int r2 = cpu_has_mips_r2; struct clock_event_device *cd; int cpu = smp_processor_id(); /* * Suckage alert: * Before R2 of the architecture there was no way to see if a * performance counter interrupt was pending, so we have to run * the performance counter interrupt handler anyway. */ if (handle_perf_irq(r2)) goto out; /* * The same applies to performance counter interrupts. But with the * above we now know that the reason we got here must be a timer * interrupt. Being the paranoiacs we are we check anyway. */ if (!r2 || (read_c0_cause() & (1 << 30))) { /* Clear Count/Compare Interrupt */ write_c0_compare(read_c0_compare()); cd = &per_cpu(mips_clockevent_device, cpu); cd->event_handler(cd); } #ifdef CONFIG_OPROFILE_WASP //pkamath: oprofile-0.9.2 does not support interrupt based profiling. //Therefore we will check for a profiling event every timer interrupt. // Note that this may impact accuracy of the profile if (!r2 || (read_c0_cause() & (1 << 26))) perf_irq(); //End of code changes #endif out: return IRQ_HANDLED; }
/* * Timer ack for an R4k-compatible timer of a known frequency. */ static void c0_timer_ack(void) { write_c0_compare(read_c0_compare()); }