linux/arch/blackfin/mach-common/irqpanic.c
<<
>>
Prefs
   1/*
   2 * panic kernel with dump information
   3 *
   4 * Copyright 2005-2009 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/kernel_stat.h>
  11#include <linux/sched.h>
  12#include <asm/blackfin.h>
  13
  14#define L1_ICACHE_START 0xffa10000
  15#define L1_ICACHE_END   0xffa13fff
  16
  17/*
  18 * irq_panic - calls panic with string setup
  19 */
  20__attribute__ ((l1_text))
  21asmlinkage void irq_panic(int reason, struct pt_regs *regs)
  22{
  23        unsigned int cmd, tag, ca, cache_hi, cache_lo, *pa;
  24        unsigned short i, j, die;
  25        unsigned int bad[10][6];
  26
  27        /* check entire cache for coherency
  28         * Since printk is in cacheable memory,
  29         * don't call it until you have checked everything
  30        */
  31
  32        die = 0;
  33        i = 0;
  34
  35        /* check icache */
  36
  37        for (ca = L1_ICACHE_START; ca <= L1_ICACHE_END && i < 10; ca += 32) {
  38
  39                /* Grab various address bits for the itest_cmd fields                      */
  40                cmd = (((ca & 0x3000) << 4) |   /* ca[13:12] for SBNK[1:0]             */
  41                       ((ca & 0x0c00) << 16) |  /* ca[11:10] for WAYSEL[1:0]           */
  42                       ((ca & 0x3f8)) | /* ca[09:03] for SET[4:0] and DW[1:0]  */
  43                       0);      /* Access Tag, Read access             */
  44
  45                SSYNC();
  46                bfin_write_ITEST_COMMAND(cmd);
  47                SSYNC();
  48                tag = bfin_read_ITEST_DATA0();
  49                SSYNC();
  50
  51                /* if tag is marked as valid, check it */
  52                if (tag & 1) {
  53                        /* The icache is arranged in 4 groups of 64-bits */
  54                        for (j = 0; j < 32; j += 8) {
  55                                cmd = ((((ca + j) & 0x3000) << 4) |     /* ca[13:12] for SBNK[1:0]             */
  56                                       (((ca + j) & 0x0c00) << 16) |    /* ca[11:10] for WAYSEL[1:0]           */
  57                                       (((ca + j) & 0x3f8)) |   /* ca[09:03] for SET[4:0] and DW[1:0]  */
  58                                       4);      /* Access Data, Read access             */
  59
  60                                SSYNC();
  61                                bfin_write_ITEST_COMMAND(cmd);
  62                                SSYNC();
  63
  64                                cache_hi = bfin_read_ITEST_DATA1();
  65                                cache_lo = bfin_read_ITEST_DATA0();
  66
  67                                pa = ((unsigned int *)((tag & 0xffffcc00) |
  68                                                       ((ca + j) & ~(0xffffcc00))));
  69
  70                                /*
  71                                 * Debugging this, enable
  72                                 *
  73                                 * printk("addr: %08x %08x%08x | %08x%08x\n",
  74                                 *  ((unsigned int *)((tag & 0xffffcc00)  | ((ca+j) & ~(0xffffcc00)))),
  75                                 *   cache_hi, cache_lo, *(pa+1), *pa);
  76                                 */
  77
  78                                if (cache_hi != *(pa + 1) || cache_lo != *pa) {
  79                                        /* Since icache is not working, stay out of it, by not printing */
  80                                        die = 1;
  81                                        bad[i][0] = (ca + j);
  82                                        bad[i][1] = cache_hi;
  83                                        bad[i][2] = cache_lo;
  84                                        bad[i][3] = ((tag & 0xffffcc00) |
  85                                                ((ca + j) & ~(0xffffcc00)));
  86                                        bad[i][4] = *(pa + 1);
  87                                        bad[i][5] = *(pa);
  88                                        i++;
  89                                }
  90                        }
  91                }
  92        }
  93        if (die) {
  94                printk(KERN_EMERG "icache coherency error\n");
  95                for (j = 0; j <= i; j++) {
  96                        printk(KERN_EMERG
  97                            "cache address   : %08x  cache value : %08x%08x\n",
  98                             bad[j][0], bad[j][1], bad[j][2]);
  99                        printk(KERN_EMERG
 100                            "physical address: %08x  SDRAM value : %08x%08x\n",
 101                             bad[j][3], bad[j][4], bad[j][5]);
 102                }
 103                panic("icache coherency error");
 104        } else
 105                printk(KERN_EMERG "icache checked, and OK\n");
 106}
 107