linux/arch/alpha/kernel/core_lca.c
<<
>>
Prefs
   1/*
   2 *      linux/arch/alpha/kernel/core_lca.c
   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 * Code common to all LCA core logic chips.
   9 */
  10
  11#define __EXTERN_INLINE inline
  12#include <asm/io.h>
  13#include <asm/core_lca.h>
  14#undef __EXTERN_INLINE
  15
  16#include <linux/types.h>
  17#include <linux/pci.h>
  18#include <linux/init.h>
  19#include <linux/tty.h>
  20
  21#include <asm/ptrace.h>
  22#include <asm/smp.h>
  23
  24#include "proto.h"
  25#include "pci_impl.h"
  26
  27
  28/*
  29 * BIOS32-style PCI interface:
  30 */
  31
  32/*
  33 * Machine check reasons.  Defined according to PALcode sources
  34 * (osf.h and platform.h).
  35 */
  36#define MCHK_K_TPERR            0x0080
  37#define MCHK_K_TCPERR           0x0082
  38#define MCHK_K_HERR             0x0084
  39#define MCHK_K_ECC_C            0x0086
  40#define MCHK_K_ECC_NC           0x0088
  41#define MCHK_K_UNKNOWN          0x008A
  42#define MCHK_K_CACKSOFT         0x008C
  43#define MCHK_K_BUGCHECK         0x008E
  44#define MCHK_K_OS_BUGCHECK      0x0090
  45#define MCHK_K_DCPERR           0x0092
  46#define MCHK_K_ICPERR           0x0094
  47
  48
  49/*
  50 * Platform-specific machine-check reasons:
  51 */
  52#define MCHK_K_SIO_SERR         0x204   /* all platforms so far */
  53#define MCHK_K_SIO_IOCHK        0x206   /* all platforms so far */
  54#define MCHK_K_DCSR             0x208   /* all but Noname */
  55
  56
  57/*
  58 * Given a bus, device, and function number, compute resulting
  59 * configuration space address and setup the LCA_IOC_CONF register
  60 * accordingly.  It is therefore not safe to have concurrent
  61 * invocations to configuration space access routines, but there
  62 * really shouldn't be any need for this.
  63 *
  64 * Type 0:
  65 *
  66 *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
  67 *  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
  68 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  69 * | | | | | | | | | | | | | | | | | | | | | | | |F|F|F|R|R|R|R|R|R|0|0|
  70 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  71 *
  72 *      31:11   Device select bit.
  73 *      10:8    Function number
  74 *       7:2    Register number
  75 *
  76 * Type 1:
  77 *
  78 *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
  79 *  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
  80 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  81 * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
  82 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  83 *
  84 *      31:24   reserved
  85 *      23:16   bus number (8 bits = 128 possible buses)
  86 *      15:11   Device number (5 bits)
  87 *      10:8    function number
  88 *       7:2    register number
  89 *  
  90 * Notes:
  91 *      The function number selects which function of a multi-function device 
  92 *      (e.g., SCSI and Ethernet).
  93 * 
  94 *      The register selects a DWORD (32 bit) register offset.  Hence it
  95 *      doesn't get shifted by 2 bits as we want to "drop" the bottom two
  96 *      bits.
  97 */
  98
  99static int
 100mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
 101             unsigned long *pci_addr)
 102{
 103        unsigned long addr;
 104        u8 bus = pbus->number;
 105
 106        if (bus == 0) {
 107                int device = device_fn >> 3;
 108                int func = device_fn & 0x7;
 109
 110                /* Type 0 configuration cycle.  */
 111
 112                if (device > 12) {
 113                        return -1;
 114                }
 115
 116                *(vulp)LCA_IOC_CONF = 0;
 117                addr = (1 << (11 + device)) | (func << 8) | where;
 118        } else {
 119                /* Type 1 configuration cycle.  */
 120                *(vulp)LCA_IOC_CONF = 1;
 121                addr = (bus << 16) | (device_fn << 8) | where;
 122        }
 123        *pci_addr = addr;
 124        return 0;
 125}
 126
 127static unsigned int
 128conf_read(unsigned long addr)
 129{
 130        unsigned long flags, code, stat0;
 131        unsigned int value;
 132
 133        local_irq_save(flags);
 134
 135        /* Reset status register to avoid loosing errors.  */
 136        stat0 = *(vulp)LCA_IOC_STAT0;
 137        *(vulp)LCA_IOC_STAT0 = stat0;
 138        mb();
 139
 140        /* Access configuration space.  */
 141        value = *(vuip)addr;
 142        draina();
 143
 144        stat0 = *(vulp)LCA_IOC_STAT0;
 145        if (stat0 & LCA_IOC_STAT0_ERR) {
 146                code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
 147                        & LCA_IOC_STAT0_CODE_MASK);
 148                if (code != 1) {
 149                        printk("lca.c:conf_read: got stat0=%lx\n", stat0);
 150                }
 151
 152                /* Reset error status.  */
 153                *(vulp)LCA_IOC_STAT0 = stat0;
 154                mb();
 155
 156                /* Reset machine check.  */
 157                wrmces(0x7);
 158
 159                value = 0xffffffff;
 160        }
 161        local_irq_restore(flags);
 162        return value;
 163}
 164
 165static void
 166conf_write(unsigned long addr, unsigned int value)
 167{
 168        unsigned long flags, code, stat0;
 169
 170        local_irq_save(flags);  /* avoid getting hit by machine check */
 171
 172        /* Reset status register to avoid loosing errors.  */
 173        stat0 = *(vulp)LCA_IOC_STAT0;
 174        *(vulp)LCA_IOC_STAT0 = stat0;
 175        mb();
 176
 177        /* Access configuration space.  */
 178        *(vuip)addr = value;
 179        draina();
 180
 181        stat0 = *(vulp)LCA_IOC_STAT0;
 182        if (stat0 & LCA_IOC_STAT0_ERR) {
 183                code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
 184                        & LCA_IOC_STAT0_CODE_MASK);
 185                if (code != 1) {
 186                        printk("lca.c:conf_write: got stat0=%lx\n", stat0);
 187                }
 188
 189                /* Reset error status.  */
 190                *(vulp)LCA_IOC_STAT0 = stat0;
 191                mb();
 192
 193                /* Reset machine check. */
 194                wrmces(0x7);
 195        }
 196        local_irq_restore(flags);
 197}
 198
 199static int
 200lca_read_config(struct pci_bus *bus, unsigned int devfn, int where,
 201                int size, u32 *value)
 202{
 203        unsigned long addr, pci_addr;
 204        long mask;
 205        int shift;
 206
 207        if (mk_conf_addr(bus, devfn, where, &pci_addr))
 208                return PCIBIOS_DEVICE_NOT_FOUND;
 209
 210        shift = (where & 3) * 8;
 211        mask = (size - 1) * 8;
 212        addr = (pci_addr << 5) + mask + LCA_CONF;
 213        *value = conf_read(addr) >> (shift);
 214        return PCIBIOS_SUCCESSFUL;
 215}
 216
 217static int 
 218lca_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
 219                 u32 value)
 220{
 221        unsigned long addr, pci_addr;
 222        long mask;
 223
 224        if (mk_conf_addr(bus, devfn, where, &pci_addr))
 225                return PCIBIOS_DEVICE_NOT_FOUND;
 226
 227        mask = (size - 1) * 8;
 228        addr = (pci_addr << 5) + mask + LCA_CONF;
 229        conf_write(addr, value << ((where & 3) * 8));
 230        return PCIBIOS_SUCCESSFUL;
 231}
 232
 233struct pci_ops lca_pci_ops = 
 234{
 235        .read =         lca_read_config,
 236        .write =        lca_write_config,
 237};
 238
 239void
 240lca_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
 241{
 242        wmb();
 243        *(vulp)LCA_IOC_TBIA = 0;
 244        mb();
 245}
 246
 247void __init
 248lca_init_arch(void)
 249{
 250        struct pci_controller *hose;
 251
 252        /*
 253         * Create our single hose.
 254         */
 255
 256        pci_isa_hose = hose = alloc_pci_controller();
 257        hose->io_space = &ioport_resource;
 258        hose->mem_space = &iomem_resource;
 259        hose->index = 0;
 260
 261        hose->sparse_mem_base = LCA_SPARSE_MEM - IDENT_ADDR;
 262        hose->dense_mem_base = LCA_DENSE_MEM - IDENT_ADDR;
 263        hose->sparse_io_base = LCA_IO - IDENT_ADDR;
 264        hose->dense_io_base = 0;
 265
 266        /*
 267         * Set up the PCI to main memory translation windows.
 268         *
 269         * Mimic the SRM settings for the direct-map window.
 270         *   Window 0 is scatter-gather 8MB at 8MB (for isa).
 271         *   Window 1 is direct access 1GB at 1GB.
 272         *
 273         * Note that we do not try to save any of the DMA window CSRs
 274         * before setting them, since we cannot read those CSRs on LCA.
 275         */
 276        hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
 277        hose->sg_pci = NULL;
 278        __direct_map_base = 0x40000000;
 279        __direct_map_size = 0x40000000;
 280
 281        *(vulp)LCA_IOC_W_BASE0 = hose->sg_isa->dma_base | (3UL << 32);
 282        *(vulp)LCA_IOC_W_MASK0 = (hose->sg_isa->size - 1) & 0xfff00000;
 283        *(vulp)LCA_IOC_T_BASE0 = virt_to_phys(hose->sg_isa->ptes);
 284
 285        *(vulp)LCA_IOC_W_BASE1 = __direct_map_base | (2UL << 32);
 286        *(vulp)LCA_IOC_W_MASK1 = (__direct_map_size - 1) & 0xfff00000;
 287        *(vulp)LCA_IOC_T_BASE1 = 0;
 288
 289        *(vulp)LCA_IOC_TB_ENA = 0x80;
 290
 291        lca_pci_tbi(hose, 0, -1);
 292
 293        /*
 294         * Disable PCI parity for now.  The NCR53c810 chip has
 295         * troubles meeting the PCI spec which results in
 296         * data parity errors.
 297         */
 298        *(vulp)LCA_IOC_PAR_DIS = 1UL<<5;
 299
 300        /*
 301         * Finally, set up for restoring the correct HAE if using SRM.
 302         * Again, since we cannot read many of the CSRs on the LCA,
 303         * one of which happens to be the HAE, we save the value that
 304         * the SRM will expect...
 305         */
 306        if (alpha_using_srm)
 307                srm_hae = 0x80000000UL;
 308}
 309
 310/*
 311 * Constants used during machine-check handling.  I suppose these
 312 * could be moved into lca.h but I don't see much reason why anybody
 313 * else would want to use them.
 314 */
 315
 316#define ESR_EAV         (1UL<< 0)       /* error address valid */
 317#define ESR_CEE         (1UL<< 1)       /* correctable error */
 318#define ESR_UEE         (1UL<< 2)       /* uncorrectable error */
 319#define ESR_WRE         (1UL<< 3)       /* write-error */
 320#define ESR_SOR         (1UL<< 4)       /* error source */
 321#define ESR_CTE         (1UL<< 7)       /* cache-tag error */
 322#define ESR_MSE         (1UL<< 9)       /* multiple soft errors */
 323#define ESR_MHE         (1UL<<10)       /* multiple hard errors */
 324#define ESR_NXM         (1UL<<12)       /* non-existent memory */
 325
 326#define IOC_ERR         (  1<<4)        /* ioc logs an error */
 327#define IOC_CMD_SHIFT   0
 328#define IOC_CMD         (0xf<<IOC_CMD_SHIFT)
 329#define IOC_CODE_SHIFT  8
 330#define IOC_CODE        (0xf<<IOC_CODE_SHIFT)
 331#define IOC_LOST        (  1<<5)
 332#define IOC_P_NBR       ((__u32) ~((1<<13) - 1))
 333
 334static void
 335mem_error(unsigned long esr, unsigned long ear)
 336{
 337        printk("    %s %s error to %s occurred at address %x\n",
 338               ((esr & ESR_CEE) ? "Correctable" :
 339                (esr & ESR_UEE) ? "Uncorrectable" : "A"),
 340               (esr & ESR_WRE) ? "write" : "read",
 341               (esr & ESR_SOR) ? "memory" : "b-cache",
 342               (unsigned) (ear & 0x1ffffff8));
 343        if (esr & ESR_CTE) {
 344                printk("    A b-cache tag parity error was detected.\n");
 345        }
 346        if (esr & ESR_MSE) {
 347                printk("    Several other correctable errors occurred.\n");
 348        }
 349        if (esr & ESR_MHE) {
 350                printk("    Several other uncorrectable errors occurred.\n");
 351        }
 352        if (esr & ESR_NXM) {
 353                printk("    Attempted to access non-existent memory.\n");
 354        }
 355}
 356
 357static void
 358ioc_error(__u32 stat0, __u32 stat1)
 359{
 360        static const char * const pci_cmd[] = {
 361                "Interrupt Acknowledge", "Special", "I/O Read", "I/O Write",
 362                "Rsvd 1", "Rsvd 2", "Memory Read", "Memory Write", "Rsvd3",
 363                "Rsvd4", "Configuration Read", "Configuration Write",
 364                "Memory Read Multiple", "Dual Address", "Memory Read Line",
 365                "Memory Write and Invalidate"
 366        };
 367        static const char * const err_name[] = {
 368                "exceeded retry limit", "no device", "bad data parity",
 369                "target abort", "bad address parity", "page table read error",
 370                "invalid page", "data error"
 371        };
 372        unsigned code = (stat0 & IOC_CODE) >> IOC_CODE_SHIFT;
 373        unsigned cmd  = (stat0 & IOC_CMD)  >> IOC_CMD_SHIFT;
 374
 375        printk("    %s initiated PCI %s cycle to address %x"
 376               " failed due to %s.\n",
 377               code > 3 ? "PCI" : "CPU", pci_cmd[cmd], stat1, err_name[code]);
 378
 379        if (code == 5 || code == 6) {
 380                printk("    (Error occurred at PCI memory address %x.)\n",
 381                       (stat0 & ~IOC_P_NBR));
 382        }
 383        if (stat0 & IOC_LOST) {
 384                printk("    Other PCI errors occurred simultaneously.\n");
 385        }
 386}
 387
 388void
 389lca_machine_check(unsigned long vector, unsigned long la_ptr,
 390                  struct pt_regs *regs)
 391{
 392        const char * reason;
 393        union el_lca el;
 394
 395        el.c = (struct el_common *) la_ptr;
 396
 397        wrmces(rdmces());       /* reset machine check pending flag */
 398
 399        printk(KERN_CRIT "LCA machine check: vector=%#lx pc=%#lx code=%#x\n",
 400               vector, regs->pc, (unsigned int) el.c->code);
 401
 402        /*
 403         * The first quadword after the common header always seems to
 404         * be the machine check reason---don't know why this isn't
 405         * part of the common header instead.  In the case of a long
 406         * logout frame, the upper 32 bits is the machine check
 407         * revision level, which we ignore for now.
 408         */
 409        switch ((unsigned int) el.c->code) {
 410        case MCHK_K_TPERR:      reason = "tag parity error"; break;
 411        case MCHK_K_TCPERR:     reason = "tag control parity error"; break;
 412        case MCHK_K_HERR:       reason = "access to non-existent memory"; break;
 413        case MCHK_K_ECC_C:      reason = "correctable ECC error"; break;
 414        case MCHK_K_ECC_NC:     reason = "non-correctable ECC error"; break;
 415        case MCHK_K_CACKSOFT:   reason = "MCHK_K_CACKSOFT"; break;
 416        case MCHK_K_BUGCHECK:   reason = "illegal exception in PAL mode"; break;
 417        case MCHK_K_OS_BUGCHECK: reason = "callsys in kernel mode"; break;
 418        case MCHK_K_DCPERR:     reason = "d-cache parity error"; break;
 419        case MCHK_K_ICPERR:     reason = "i-cache parity error"; break;
 420        case MCHK_K_SIO_SERR:   reason = "SIO SERR occurred on PCI bus"; break;
 421        case MCHK_K_SIO_IOCHK:  reason = "SIO IOCHK occurred on ISA bus"; break;
 422        case MCHK_K_DCSR:       reason = "MCHK_K_DCSR"; break;
 423        case MCHK_K_UNKNOWN:
 424        default:                reason = "unknown"; break;
 425        }
 426
 427        switch (el.c->size) {
 428        case sizeof(struct el_lca_mcheck_short):
 429                printk(KERN_CRIT
 430                       "  Reason: %s (short frame%s, dc_stat=%#lx):\n",
 431                       reason, el.c->retry ? ", retryable" : "",
 432                       el.s->dc_stat);
 433                if (el.s->esr & ESR_EAV) {
 434                        mem_error(el.s->esr, el.s->ear);
 435                }
 436                if (el.s->ioc_stat0 & IOC_ERR) {
 437                        ioc_error(el.s->ioc_stat0, el.s->ioc_stat1);
 438                }
 439                break;
 440
 441        case sizeof(struct el_lca_mcheck_long):
 442                printk(KERN_CRIT "  Reason: %s (long frame%s):\n",
 443                       reason, el.c->retry ? ", retryable" : "");
 444                printk(KERN_CRIT
 445                       "    reason: %#lx  exc_addr: %#lx  dc_stat: %#lx\n", 
 446                       el.l->pt[0], el.l->exc_addr, el.l->dc_stat);
 447                printk(KERN_CRIT "    car: %#lx\n", el.l->car);
 448                if (el.l->esr & ESR_EAV) {
 449                        mem_error(el.l->esr, el.l->ear);
 450                }
 451                if (el.l->ioc_stat0 & IOC_ERR) {
 452                        ioc_error(el.l->ioc_stat0, el.l->ioc_stat1);
 453                }
 454                break;
 455
 456        default:
 457                printk(KERN_CRIT "  Unknown errorlog size %d\n", el.c->size);
 458        }
 459
 460        /* Dump the logout area to give all info.  */
 461#ifdef CONFIG_VERBOSE_MCHECK
 462        if (alpha_verbose_mcheck > 1) {
 463                unsigned long * ptr = (unsigned long *) la_ptr;
 464                long i;
 465                for (i = 0; i < el.c->size / sizeof(long); i += 2) {
 466                        printk(KERN_CRIT " +%8lx %016lx %016lx\n",
 467                               i*sizeof(long), ptr[i], ptr[i+1]);
 468                }
 469        }
 470#endif /* CONFIG_VERBOSE_MCHECK */
 471}
 472
 473/*
 474 * The following routines are needed to support the SPEED changing
 475 * necessary to successfully manage the thermal problem on the AlphaBook1.
 476 */
 477
 478void
 479lca_clock_print(void)
 480{
 481        long    pmr_reg;
 482
 483        pmr_reg = LCA_READ_PMR;
 484
 485        printk("Status of clock control:\n");
 486        printk("\tPrimary clock divisor\t0x%lx\n", LCA_GET_PRIMARY(pmr_reg));
 487        printk("\tOverride clock divisor\t0x%lx\n", LCA_GET_OVERRIDE(pmr_reg));
 488        printk("\tInterrupt override is %s\n",
 489               (pmr_reg & LCA_PMR_INTO) ? "on" : "off"); 
 490        printk("\tDMA override is %s\n",
 491               (pmr_reg & LCA_PMR_DMAO) ? "on" : "off"); 
 492
 493}
 494
 495int
 496lca_get_clock(void)
 497{
 498        long    pmr_reg;
 499
 500        pmr_reg = LCA_READ_PMR;
 501        return(LCA_GET_PRIMARY(pmr_reg));
 502
 503}
 504
 505void
 506lca_clock_fiddle(int divisor)
 507{
 508        long    pmr_reg;
 509
 510        pmr_reg = LCA_READ_PMR;
 511        LCA_SET_PRIMARY_CLOCK(pmr_reg, divisor);
 512        /* lca_norm_clock = divisor; */
 513        LCA_WRITE_PMR(pmr_reg);
 514        mb();
 515}
 516
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.