root/arch/alpha/kernel/lca.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mk_conf_addr
  2. conf_read
  3. conf_write
  4. pcibios_read_config_byte
  5. pcibios_read_config_word
  6. pcibios_read_config_dword
  7. pcibios_write_config_byte
  8. pcibios_write_config_word
  9. pcibios_write_config_dword
  10. lca_init
  11. mem_error
  12. ioc_error
  13. lca_machine_check

   1 /*
   2  * Code common to all LCA chips.
   3  *
   4  * Written by David Mosberger (davidm@cs.arizona.edu) with some code
   5  * taken from Dave Rusling's (david.rusling@reo.mts.dec.com) 32-bit
   6  * bios code.
   7  */
   8 #include <linux/kernel.h>
   9 #include <linux/config.h>
  10 #include <linux/types.h>
  11 #include <linux/bios32.h>
  12 #include <linux/pci.h>
  13 
  14 #include <asm/ptrace.h>
  15 #include <asm/system.h>
  16 #include <asm/io.h>
  17 
  18 /*
  19  * BIOS32-style PCI interface:
  20  */
  21 
  22 #ifdef CONFIG_ALPHA_LCA
  23 
  24 #define vulp    volatile unsigned long *
  25 
  26 /*
  27  * Machine check reasons.  Defined according to PALcode sources
  28  * (osf.h and platform.h).
  29  */
  30 #define MCHK_K_TPERR            0x0080
  31 #define MCHK_K_TCPERR           0x0082
  32 #define MCHK_K_HERR             0x0084
  33 #define MCHK_K_ECC_C            0x0086
  34 #define MCHK_K_ECC_NC           0x0088
  35 #define MCHK_K_UNKNOWN          0x008A
  36 #define MCHK_K_CACKSOFT         0x008C
  37 #define MCHK_K_BUGCHECK         0x008E
  38 #define MCHK_K_OS_BUGCHECK      0x0090
  39 #define MCHK_K_DCPERR           0x0092
  40 #define MCHK_K_ICPERR           0x0094
  41 
  42 /*
  43  * Platform-specific machine-check reasons:
  44  */
  45 #define MCHK_K_SIO_SERR         0x204   /* all platforms so far */
  46 #define MCHK_K_SIO_IOCHK        0x206   /* all platforms so far */
  47 #define MCHK_K_DCSR             0x208   /* all but Noname */
  48 
  49 /*
  50  * Given a bus, device, and function number, compute resulting
  51  * configuration space address and setup the LCA_IOC_CONF register
  52  * accordingly.  It is therefore not safe to have concurrent
  53  * invocations to configuration space access routines, but there
  54  * really shouldn't be any need for this.
  55  *
  56  * Type 0:
  57  *
  58  *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
  59  *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
  60  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  61  * | | | | | | | | | | | | | | | | | | | | | | | |F|F|F|R|R|R|R|R|R|0|0|
  62  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  63  *
  64  *      31:11   Device select bit.
  65  *      10:8    Function number
  66  *       7:2    Register number
  67  *
  68  * Type 1:
  69  *
  70  *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
  71  *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
  72  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  73  * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
  74  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  75  *
  76  *      31:24   reserved
  77  *      23:16   bus number (8 bits = 128 possible buses)
  78  *      15:11   Device number (5 bits)
  79  *      10:8    function number
  80  *       7:2    register number
  81  *  
  82  * Notes:
  83  *      The function number selects which function of a multi-function device 
  84  *      (e.g., scsi and ethernet).
  85  * 
  86  *      The register selects a DWORD (32 bit) register offset.  Hence it
  87  *      doesn't get shifted by 2 bits as we want to "drop" the bottom two
  88  *      bits.
  89  */
  90 static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
     /* [previous][next][first][last][top][bottom][index][help] */
  91                         unsigned char where, unsigned long *pci_addr)
  92 {
  93         unsigned long addr;
  94 
  95         if (bus == 0) {
  96                 int device = device_fn >> 3;
  97                 int func = device_fn & 0x7;
  98 
  99                 /* type 0 configuration cycle: */
 100 
 101                 if (device > 12) {
 102                         return -1;
 103                 }
 104 
 105                 *((volatile unsigned long*) LCA_IOC_CONF) = 0;
 106                 addr = (1 << (11 + device)) | (func << 8) | where;
 107         } else {
 108                 /* type 1 configuration cycle: */
 109                 *((volatile unsigned long*) LCA_IOC_CONF) = 1;
 110                 addr = (bus << 16) | (device_fn << 8) | where;
 111         }
 112         *pci_addr = addr;
 113         return 0;
 114 }
 115 
 116 
 117 static unsigned int conf_read(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 118 {
 119         unsigned long flags, code, stat0;
 120         unsigned int value;
 121 
 122         save_flags(flags);
 123         cli();
 124 
 125         /* reset status register to avoid loosing errors: */
 126         stat0 = *((volatile unsigned long*)LCA_IOC_STAT0);
 127         *((volatile unsigned long*)LCA_IOC_STAT0) = stat0;
 128         mb();
 129 
 130         /* access configuration space: */
 131 
 132         value = *((volatile unsigned int*)addr);
 133         draina();
 134 
 135         stat0 = *((unsigned long*)LCA_IOC_STAT0);
 136         if (stat0 & LCA_IOC_STAT0_ERR) {
 137                 code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
 138                         & LCA_IOC_STAT0_CODE_MASK);
 139                 if (code != 1) {
 140                         printk("lca.c:conf_read: got stat0=%lx\n", stat0);
 141                 }
 142 
 143                 /* reset error status: */
 144                 *((volatile unsigned long*)LCA_IOC_STAT0) = stat0;
 145                 mb();
 146                 wrmces(0x7);                    /* reset machine check */
 147 
 148                 value = 0xffffffff;
 149         }
 150         restore_flags(flags);
 151         return value;
 152 }
 153 
 154 
 155 static void conf_write(unsigned long addr, unsigned int value)
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157         unsigned long flags, code, stat0;
 158 
 159         save_flags(flags);      /* avoid getting hit by machine check */
 160         cli();
 161 
 162         /* reset status register to avoid loosing errors: */
 163         stat0 = *((volatile unsigned long*)LCA_IOC_STAT0);
 164         *((volatile unsigned long*)LCA_IOC_STAT0) = stat0;
 165         mb();
 166 
 167         /* access configuration space: */
 168 
 169         *((volatile unsigned int*)addr) = value;
 170         draina();
 171 
 172         stat0 = *((unsigned long*)LCA_IOC_STAT0);
 173         if (stat0 & LCA_IOC_STAT0_ERR) {
 174                 code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
 175                         & LCA_IOC_STAT0_CODE_MASK);
 176                 if (code != 1) {
 177                         printk("lca.c:conf_write: got stat0=%lx\n", stat0);
 178                 }
 179 
 180                 /* reset error status: */
 181                 *((volatile unsigned long*)LCA_IOC_STAT0) = stat0;
 182                 mb();
 183                 wrmces(0x7);                    /* reset machine check */
 184         }
 185         restore_flags(flags);
 186 }
 187 
 188 
 189 int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
     /* [previous][next][first][last][top][bottom][index][help] */
 190                               unsigned char where, unsigned char *value)
 191 {
 192         unsigned long addr = LCA_CONF;
 193         unsigned long pci_addr;
 194 
 195         *value = 0xff;
 196 
 197         if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
 198                 return PCIBIOS_SUCCESSFUL;
 199         }
 200         addr |= (pci_addr << 5) + 0x00;
 201         *value = conf_read(addr) >> ((where & 3) * 8);
 202         return PCIBIOS_SUCCESSFUL;
 203 }
 204 
 205 
 206 int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
     /* [previous][next][first][last][top][bottom][index][help] */
 207                               unsigned char where, unsigned short *value)
 208 {
 209         unsigned long addr = LCA_CONF;
 210         unsigned long pci_addr;
 211 
 212         *value = 0xffff;
 213 
 214         if (where & 0x1) {
 215                 return PCIBIOS_BAD_REGISTER_NUMBER;
 216         }
 217         if (mk_conf_addr(bus, device_fn, where, &pci_addr)) {
 218                 return PCIBIOS_SUCCESSFUL;
 219         }
 220         addr |= (pci_addr << 5) + 0x08;
 221         *value = conf_read(addr) >> ((where & 3) * 8);
 222         return PCIBIOS_SUCCESSFUL;
 223 }
 224 
 225 
 226 int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
     /* [previous][next][first][last][top][bottom][index][help] */
 227                                unsigned char where, unsigned int *value)
 228 {
 229         unsigned long addr = LCA_CONF;
 230         unsigned long pci_addr;
 231 
 232         *value = 0xffffffff;
 233         if (where & 0x3) {
 234                 return PCIBIOS_BAD_REGISTER_NUMBER;
 235         }
 236         if (mk_conf_addr(bus, device_fn, where, &pci_addr)) {
 237                 return PCIBIOS_SUCCESSFUL;
 238         }
 239         addr |= (pci_addr << 5) + 0x18;
 240         *value = conf_read(addr);
 241         return PCIBIOS_SUCCESSFUL;
 242 }
 243 
 244 
 245 int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
     /* [previous][next][first][last][top][bottom][index][help] */
 246                                unsigned char where, unsigned char value)
 247 {
 248         unsigned long addr = LCA_CONF;
 249         unsigned long pci_addr;
 250 
 251         if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
 252                 return PCIBIOS_SUCCESSFUL;
 253         }
 254         addr |= (pci_addr << 5) + 0x00;
 255         conf_write(addr, value << ((where & 3) * 8));
 256         return PCIBIOS_SUCCESSFUL;
 257 }
 258 
 259 
 260 int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
     /* [previous][next][first][last][top][bottom][index][help] */
 261                                unsigned char where, unsigned short value)
 262 {
 263         unsigned long addr = LCA_CONF;
 264         unsigned long pci_addr;
 265 
 266         if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
 267                 return PCIBIOS_SUCCESSFUL;
 268         }
 269         addr |= (pci_addr << 5) + 0x08;
 270         conf_write(addr, value << ((where & 3) * 8));
 271         return PCIBIOS_SUCCESSFUL;
 272 }
 273 
 274 
 275 int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
     /* [previous][next][first][last][top][bottom][index][help] */
 276                                 unsigned char where, unsigned int value)
 277 {
 278         unsigned long addr = LCA_CONF;
 279         unsigned long pci_addr;
 280 
 281         if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
 282                 return PCIBIOS_SUCCESSFUL;
 283         }
 284         addr |= (pci_addr << 5) + 0x18;
 285         conf_write(addr, value << ((where & 3) * 8));
 286         return PCIBIOS_SUCCESSFUL;
 287 }
 288 
 289 
 290 unsigned long lca_init(unsigned long mem_start, unsigned long mem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
 291 {
 292         /*
 293          * Set up the PCI->physical memory translation windows.
 294          * For now, window 1 is disabled.  In the future, we may
 295          * want to use it to do scatter/gather DMA.  Window 0
 296          * goes at 1 GB and is 1 GB large.
 297          */
 298         *(vulp)LCA_IOC_W_BASE1 = 0UL<<33;
 299         *(vulp)LCA_IOC_W_BASE0 = 1UL<<33 | LCA_DMA_WIN_BASE;
 300         *(vulp)LCA_IOC_W_MASK0 = LCA_DMA_WIN_SIZE - 1;
 301         *(vulp)LCA_IOC_T_BASE0 = 0;
 302 
 303         /*
 304          * Disable PCI parity for now.  The NCR53c810 chip has
 305          * troubles meeting the PCI spec which results in
 306          * data parity errors.
 307          */
 308         *(vulp)LCA_IOC_PAR_DIS = 1UL<<5;
 309         return mem_start;
 310 }
 311 
 312 
 313 
 314 
 315 /*
 316  * Constants used during machine-check handling.  I suppose these
 317  * could be moved into lca.h but I don't see much reason why anybody
 318  * else would want to use them.
 319  */
 320 #define ESR_EAV         (1UL<< 0)       /* error address valid */
 321 #define ESR_CEE         (1UL<< 1)       /* correctable error */
 322 #define ESR_UEE         (1UL<< 2)       /* uncorrectable error */
 323 #define ESR_WRE         (1UL<< 3)       /* write-error */
 324 #define ESR_SOR         (1UL<< 4)       /* error source */
 325 #define ESR_CTE         (1UL<< 7)       /* cache-tag error */
 326 #define ESR_MSE         (1UL<< 9)       /* multiple soft errors */
 327 #define ESR_MHE         (1UL<<10)       /* multiple hard errors */
 328 #define ESR_NXM         (1UL<<12)       /* non-existent memory */
 329 
 330 #define IOC_ERR         (  1<<4)        /* ioc logs an error */
 331 #define IOC_CMD_SHIFT   0
 332 #define IOC_CMD         (0xf<<IOC_CMD_SHIFT)
 333 #define IOC_CODE_SHIFT  8
 334 #define IOC_CODE        (0xf<<IOC_CODE_SHIFT)
 335 #define IOC_LOST        (  1<<5)
 336 #define IOC_P_NBR       ((__u32) ~((1<<13) - 1))
 337 
 338 
 339 void mem_error (unsigned long esr, unsigned long ear)
     /* [previous][next][first][last][top][bottom][index][help] */
 340 {
 341     printk("    %s %s error to %s occurred at address %x\n",
 342            (esr & ESR_CEE) ? "Correctable" : ((esr & ESR_UEE) ? "Uncorrectable" : "A"),
 343            (esr & ESR_WRE) ? "write" : "read",
 344            (esr & ESR_SOR) ? "b-cache" : "memory",
 345            (unsigned) (ear & 0x1ffffff8));
 346     if (esr & ESR_CTE) {
 347         printk("    A b-cache tag parity error was detected.\n");
 348     }
 349     if (esr & ESR_MSE) {
 350         printk("    Several other correctable errors occurred.\n");
 351     }
 352     if (esr & ESR_MHE) {
 353         printk("    Several other uncorrectable errors occurred.\n");
 354     }
 355     if (esr & ESR_NXM) {
 356         printk("    Attempted to access non-existent memory.\n");
 357     }
 358 }
 359 
 360 
 361 void ioc_error (__u32 stat0, __u32 stat1)
     /* [previous][next][first][last][top][bottom][index][help] */
 362 {
 363     const char *pci_cmd[] = {
 364         "Interrupt Acknowledge", "Special", "I/O Read", "I/O Write",
 365         "Rsvd 1", "Rsvd 2", "Memory Read", "Memory Write", "Rsvd3", "Rsvd4",
 366         "Configuration Read", "Configuration Write", "Memory Read Multiple",
 367         "Dual Address", "Memory Read Line", "Memory Write and Invalidate"
 368     };
 369     const char *err_name[] = {
 370         "exceeded retry limit", "no device", "bad data parity", "target abort",
 371         "bad address parity", "page table read error", "invalid page", "data error"
 372     };
 373     unsigned code = (stat0 & IOC_CODE) >> IOC_CODE_SHIFT;
 374     unsigned cmd  = (stat0 & IOC_CMD)  >> IOC_CMD_SHIFT;
 375 
 376     printk("    %s initiated PCI %s cycle to address %x failed due to %s.\n",
 377            code > 3 ? "PCI" : "CPU", pci_cmd[cmd], stat1, err_name[code]);
 378     if (code == 5 || code == 6) {
 379         printk("    (Error occurred at PCI memory address %x.)\n", (stat0 & ~IOC_P_NBR));
 380     }
 381     if (stat0 & IOC_LOST) {
 382         printk("    Other PCI errors occurred simultaneously.\n");
 383     }
 384 }
 385 
 386 
 387 void lca_machine_check (unsigned long vector, unsigned long la, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 388 {
 389         const char * reason;
 390         union el_lca el;
 391         char buf[128];
 392 
 393         printk("lca: machine check (la=0x%lx,pc=0x%lx)\n", la, regs->pc);
 394         el.c = (struct el_common *) la;
 395         /*
 396          * The first quadword after the common header always seems to
 397          * be the machine check reason---don't know why this isn't
 398          * part of the common header instead.  In the case of a long
 399          * logout frame, the upper 32 bits is the machine check
 400          * revision level, which we ignore for now.
 401          */
 402         switch (el.s->reason & 0xffffffff) {
 403               case MCHK_K_TPERR:        reason = "tag parity error"; break;
 404               case MCHK_K_TCPERR:       reason = "tag something parity error"; break;
 405               case MCHK_K_HERR:         reason = "access to non-existent memory"; break;
 406               case MCHK_K_ECC_C:        reason = "correctable ECC error"; break;
 407               case MCHK_K_ECC_NC:       reason = "non-correctable ECC error"; break;
 408               case MCHK_K_CACKSOFT:     reason = "MCHK_K_CACKSOFT"; break; /* what's this? */
 409               case MCHK_K_BUGCHECK:     reason = "illegal exception in PAL mode"; break;
 410               case MCHK_K_OS_BUGCHECK:  reason = "callsys in kernel mode"; break;
 411               case MCHK_K_DCPERR:       reason = "d-cache parity error"; break;
 412               case MCHK_K_ICPERR:       reason = "i-cache parity error"; break;
 413               case MCHK_K_SIO_SERR:     reason = "SIO SERR occurred on on PCI bus"; break;
 414               case MCHK_K_SIO_IOCHK:    reason = "SIO IOCHK occurred on ISA bus"; break;
 415               case MCHK_K_DCSR:         reason = "MCHK_K_DCSR"; break;
 416               case MCHK_K_UNKNOWN:
 417               default:
 418                 sprintf(buf, "reason for machine-check unknown (0x%lx)",
 419                         el.s->reason & 0xffffffff);
 420                 reason = buf;
 421                 break;
 422         }
 423 
 424         wrmces(rdmces());       /* reset machine check pending flag */
 425 
 426         switch (el.c->size) {
 427               case sizeof(struct el_lca_mcheck_short):
 428                 printk("  Reason: %s (short frame%s, dc_stat=%lx):\n",
 429                        reason, el.c->retry ? ", retryable" : "", el.s->dc_stat);
 430                 if (el.s->esr & ESR_EAV) {
 431                     mem_error(el.s->esr, el.s->ear);
 432                 }
 433                 if (el.s->ioc_stat0 & IOC_ERR) {
 434                     ioc_error(el.s->ioc_stat0, el.s->ioc_stat1);
 435                 }
 436                 break;
 437 
 438               case sizeof(struct el_lca_mcheck_long):
 439                 printk("  Reason: %s (long frame%s):\n",
 440                        reason, el.c->retry ? ", retryable" : "");
 441                 printk("    reason: %lx  exc_addr: %lx  dc_stat: %lx\n", 
 442                        el.l->pt[0], el.l->exc_addr, el.l->dc_stat);
 443                 printk("    car: %lx\n", el.l->car);
 444                 if (el.l->esr & ESR_EAV) {
 445                     mem_error(el.l->esr, el.l->ear);
 446                 }
 447                 if (el.l->ioc_stat0 & IOC_ERR) {
 448                     ioc_error(el.l->ioc_stat0, el.l->ioc_stat1);
 449                 }
 450                 break;
 451 
 452               default:
 453                 printk("  Unknown errorlog size %d\n", el.c->size);
 454         }
 455 }
 456 
 457 #endif /* CONFIG_ALPHA_LCA */

/* [previous][next][first][last][top][bottom][index][help] */