/* * The Bus Watcher monitors internal bus transactions and maintains * counts of transactions with error status, logging details and * causing one of several interrupts. This driver provides a handler * for those interrupts which aggregates the counts (to avoid * saturating the 8-bit counters) and provides a presence in * /proc/bus_watcher if PROC_FS is on.
*/
staticvoid print_summary(uint32_t status, uint32_t l2_err,
uint32_t memio_err)
{
printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
printk("\nLast recorded signature:\n");
printk("Request %02x from %d, answered by %d with Dcode %d\n",
(unsignedint)(G_SCD_BERR_TID(status) & 0x3f),
(int)(G_SCD_BERR_TID(status) >> 6),
(int)G_SCD_BERR_RID(status),
(int)G_SCD_BERR_DCODE(status));
}
/* * check_bus_watcher is exported for use in situations where we want * to see the most recent status of the bus watcher, which might have * already been destructively read out of the registers. * * notes: this is currently used by the cache error handler * should provide locking against the interrupt handler
*/ void check_bus_watcher(void)
{
u32 status, l2_err, memio_err;
#ifdefined(CONFIG_SIBYTE_BCM112X) || defined(CONFIG_SIBYTE_SB1250) /* Use non-destructive register */
status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS_DEBUG)); #elifdefined(CONFIG_SIBYTE_BCM1x80) /* Use non-destructive register */ /* Same as 1250 except BUS_ERR_STATUS_DEBUG is in a different place. */
status = csr_in32(IOADDR(A_BCM1480_BUS_ERR_STATUS_DEBUG)); #else #error bus watcher being built for unknown Sibyte SOC! #endif if (!(status & 0x7fffffff)) {
printk("Using last values reaped by bus watcher driver\n");
status = bw_stats.status;
l2_err = bw_stats.l2_err;
memio_err = bw_stats.memio_err;
} else {
l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
} if (status & ~(1UL << 31))
print_summary(status, l2_err, memio_err); else
printk("Bus watcher indicates no error\n");
}
#ifdef CONFIG_PROC_FS
/* For simplicity, I want to assume a single read is required each
time */ staticint bw_proc_show(struct seq_file *m, void *v)
{ struct bw_stats_struct *stats = m->private;
seq_puts(m, "SiByte Bus Watcher statistics\n");
seq_puts(m, "-----------------------------\n");
seq_printf(m, "L2-d-cor %8ld\nL2-d-bad %8ld\n",
stats->l2_cor_d, stats->l2_bad_d);
seq_printf(m, "L2-t-cor %8ld\nL2-t-bad %8ld\n",
stats->l2_cor_t, stats->l2_bad_t);
seq_printf(m, "MC-d-cor %8ld\nMC-d-bad %8ld\n",
stats->mem_cor_d, stats->mem_bad_d);
seq_printf(m, "IO-err %8ld\n", stats->bus_error);
seq_puts(m, "\nLast recorded signature:\n");
seq_printf(m, "Request %02x from %d, answered by %d with Dcode %d\n",
(unsignedint)(G_SCD_BERR_TID(stats->status) & 0x3f),
(int)(G_SCD_BERR_TID(stats->status) >> 6),
(int)G_SCD_BERR_RID(stats->status),
(int)G_SCD_BERR_DCODE(stats->status)); /* XXXKW indicate multiple errors between printings, or stats
collection (or both)? */ if (stats->status & M_SCD_BERR_MULTERRS)
seq_puts(m, "Multiple errors observed since last check.\n"); if (stats->status_printed) {
seq_puts(m, "(no change since last printing)\n");
} else {
stats->status_printed = 1;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.