linux/arch/sparc/kernel/psycho_common.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* psycho_common.c: Code common to PSYCHO and derivative PCI controllers.
   3 *
   4 * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
   5 */
   6#include <linux/kernel.h>
   7#include <linux/interrupt.h>
   8#include <linux/numa.h>
   9
  10#include <asm/upa.h>
  11
  12#include "pci_impl.h"
  13#include "iommu_common.h"
  14#include "psycho_common.h"
  15
  16#define  PSYCHO_STRBUF_CTRL_DENAB       0x0000000000000002ULL
  17#define  PSYCHO_STCERR_WRITE            0x0000000000000002ULL
  18#define  PSYCHO_STCERR_READ             0x0000000000000001ULL
  19#define  PSYCHO_STCTAG_PPN              0x0fffffff00000000ULL
  20#define  PSYCHO_STCTAG_VPN              0x00000000ffffe000ULL
  21#define  PSYCHO_STCTAG_VALID            0x0000000000000002ULL
  22#define  PSYCHO_STCTAG_WRITE            0x0000000000000001ULL
  23#define  PSYCHO_STCLINE_LINDX           0x0000000001e00000ULL
  24#define  PSYCHO_STCLINE_SPTR            0x00000000001f8000ULL
  25#define  PSYCHO_STCLINE_LADDR           0x0000000000007f00ULL
  26#define  PSYCHO_STCLINE_EPTR            0x00000000000000fcULL
  27#define  PSYCHO_STCLINE_VALID           0x0000000000000002ULL
  28#define  PSYCHO_STCLINE_FOFN            0x0000000000000001ULL
  29
  30static DEFINE_SPINLOCK(stc_buf_lock);
  31static unsigned long stc_error_buf[128];
  32static unsigned long stc_tag_buf[16];
  33static unsigned long stc_line_buf[16];
  34
  35static void psycho_check_stc_error(struct pci_pbm_info *pbm)
  36{
  37        unsigned long err_base, tag_base, line_base;
  38        struct strbuf *strbuf = &pbm->stc;
  39        u64 control;
  40        int i;
  41
  42        if (!strbuf->strbuf_control)
  43                return;
  44
  45        err_base = strbuf->strbuf_err_stat;
  46        tag_base = strbuf->strbuf_tag_diag;
  47        line_base = strbuf->strbuf_line_diag;
  48
  49        spin_lock(&stc_buf_lock);
  50
  51        /* This is __REALLY__ dangerous.  When we put the streaming
  52         * buffer into diagnostic mode to probe it's tags and error
  53         * status, we _must_ clear all of the line tag valid bits
  54         * before re-enabling the streaming buffer.  If any dirty data
  55         * lives in the STC when we do this, we will end up
  56         * invalidating it before it has a chance to reach main
  57         * memory.
  58         */
  59        control = upa_readq(strbuf->strbuf_control);
  60        upa_writeq(control | PSYCHO_STRBUF_CTRL_DENAB, strbuf->strbuf_control);
  61        for (i = 0; i < 128; i++) {
  62                u64 val;
  63
  64                val = upa_readq(err_base + (i * 8UL));
  65                upa_writeq(0UL, err_base + (i * 8UL));
  66                stc_error_buf[i] = val;
  67        }
  68        for (i = 0; i < 16; i++) {
  69                stc_tag_buf[i] = upa_readq(tag_base + (i * 8UL));
  70                stc_line_buf[i] = upa_readq(line_base + (i * 8UL));
  71                upa_writeq(0UL, tag_base + (i * 8UL));
  72                upa_writeq(0UL, line_base + (i * 8UL));
  73        }
  74
  75        /* OK, state is logged, exit diagnostic mode. */
  76        upa_writeq(control, strbuf->strbuf_control);
  77
  78        for (i = 0; i < 16; i++) {
  79                int j, saw_error, first, last;
  80
  81                saw_error = 0;
  82                first = i * 8;
  83                last = first + 8;
  84                for (j = first; j < last; j++) {
  85                        u64 errval = stc_error_buf[j];
  86                        if (errval != 0) {
  87                                saw_error++;
  88                                printk(KERN_ERR "%s: STC_ERR(%d)[wr(%d)"
  89                                       "rd(%d)]\n",
  90                                       pbm->name,
  91                                       j,
  92                                       (errval & PSYCHO_STCERR_WRITE) ? 1 : 0,
  93                                       (errval & PSYCHO_STCERR_READ) ? 1 : 0);
  94                        }
  95                }
  96                if (saw_error != 0) {
  97                        u64 tagval = stc_tag_buf[i];
  98                        u64 lineval = stc_line_buf[i];
  99                        printk(KERN_ERR "%s: STC_TAG(%d)[PA(%016llx)VA(%08llx)"
 100                               "V(%d)W(%d)]\n",
 101                               pbm->name,
 102                               i,
 103                               ((tagval & PSYCHO_STCTAG_PPN) >> 19UL),
 104                               (tagval & PSYCHO_STCTAG_VPN),
 105                               ((tagval & PSYCHO_STCTAG_VALID) ? 1 : 0),
 106                               ((tagval & PSYCHO_STCTAG_WRITE) ? 1 : 0));
 107                        printk(KERN_ERR "%s: STC_LINE(%d)[LIDX(%llx)SP(%llx)"
 108                               "LADDR(%llx)EP(%llx)V(%d)FOFN(%d)]\n",
 109                               pbm->name,
 110                               i,
 111                               ((lineval & PSYCHO_STCLINE_LINDX) >> 21UL),
 112                               ((lineval & PSYCHO_STCLINE_SPTR) >> 15UL),
 113                               ((lineval & PSYCHO_STCLINE_LADDR) >> 8UL),
 114                               ((lineval & PSYCHO_STCLINE_EPTR) >> 2UL),
 115                               ((lineval & PSYCHO_STCLINE_VALID) ? 1 : 0),
 116                               ((lineval & PSYCHO_STCLINE_FOFN) ? 1 : 0));
 117                }
 118        }
 119
 120        spin_unlock(&stc_buf_lock);
 121}
 122
 123#define PSYCHO_IOMMU_TAG                0xa580UL
 124#define PSYCHO_IOMMU_DATA               0xa600UL
 125
 126static void psycho_record_iommu_tags_and_data(struct pci_pbm_info *pbm,
 127                                              u64 *tag, u64 *data)
 128{
 129        int i;
 130
 131        for (i = 0; i < 16; i++) {
 132                unsigned long base = pbm->controller_regs;
 133                unsigned long off = i * 8UL;
 134
 135                tag[i] = upa_readq(base + PSYCHO_IOMMU_TAG+off);
 136                data[i] = upa_readq(base + PSYCHO_IOMMU_DATA+off);
 137
 138                /* Now clear out the entry. */
 139                upa_writeq(0, base + PSYCHO_IOMMU_TAG + off);
 140                upa_writeq(0, base + PSYCHO_IOMMU_DATA + off);
 141        }
 142}
 143
 144#define  PSYCHO_IOMMU_TAG_ERRSTS (0x3UL << 23UL)
 145#define  PSYCHO_IOMMU_TAG_ERR    (0x1UL << 22UL)
 146#define  PSYCHO_IOMMU_TAG_WRITE  (0x1UL << 21UL)
 147#define  PSYCHO_IOMMU_TAG_STREAM (0x1UL << 20UL)
 148#define  PSYCHO_IOMMU_TAG_SIZE   (0x1UL << 19UL)
 149#define  PSYCHO_IOMMU_TAG_VPAGE  0x7ffffULL
 150#define  PSYCHO_IOMMU_DATA_VALID (1UL << 30UL)
 151#define  PSYCHO_IOMMU_DATA_CACHE (1UL << 28UL)
 152#define  PSYCHO_IOMMU_DATA_PPAGE 0xfffffffULL
 153
 154static void psycho_dump_iommu_tags_and_data(struct pci_pbm_info *pbm,
 155                                            u64 *tag, u64 *data)
 156{
 157        int i;
 158
 159        for (i = 0; i < 16; i++) {
 160                u64 tag_val, data_val;
 161                const char *type_str;
 162                tag_val = tag[i];
 163                if (!(tag_val & PSYCHO_IOMMU_TAG_ERR))
 164                        continue;
 165
 166                data_val = data[i];
 167                switch((tag_val & PSYCHO_IOMMU_TAG_ERRSTS) >> 23UL) {
 168                case 0:
 169                        type_str = "Protection Error";
 170                        break;
 171                case 1:
 172                        type_str = "Invalid Error";
 173                        break;
 174                case 2:
 175                        type_str = "TimeOut Error";
 176                        break;
 177                case 3:
 178                default:
 179                        type_str = "ECC Error";
 180                        break;
 181                }
 182
 183                printk(KERN_ERR "%s: IOMMU TAG(%d)[error(%s) wr(%d) "
 184                       "str(%d) sz(%dK) vpg(%08llx)]\n",
 185                       pbm->name, i, type_str,
 186                       ((tag_val & PSYCHO_IOMMU_TAG_WRITE) ? 1 : 0),
 187                       ((tag_val & PSYCHO_IOMMU_TAG_STREAM) ? 1 : 0),
 188                       ((tag_val & PSYCHO_IOMMU_TAG_SIZE) ? 64 : 8),
 189                       (tag_val & PSYCHO_IOMMU_TAG_VPAGE) << IOMMU_PAGE_SHIFT);
 190                printk(KERN_ERR "%s: IOMMU DATA(%d)[valid(%d) cache(%d) "
 191                       "ppg(%016llx)]\n",
 192                       pbm->name, i,
 193                       ((data_val & PSYCHO_IOMMU_DATA_VALID) ? 1 : 0),
 194                       ((data_val & PSYCHO_IOMMU_DATA_CACHE) ? 1 : 0),
 195                       (data_val & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT);
 196        }
 197}
 198
 199#define  PSYCHO_IOMMU_CTRL_XLTESTAT     0x0000000006000000UL
 200#define  PSYCHO_IOMMU_CTRL_XLTEERR      0x0000000001000000UL
 201
 202void psycho_check_iommu_error(struct pci_pbm_info *pbm,
 203                              unsigned long afsr,
 204                              unsigned long afar,
 205                              enum psycho_error_type type)
 206{
 207        u64 control, iommu_tag[16], iommu_data[16];
 208        struct iommu *iommu = pbm->iommu;
 209        unsigned long flags;
 210
 211        spin_lock_irqsave(&iommu->lock, flags);
 212        control = upa_readq(iommu->iommu_control);
 213        if (control & PSYCHO_IOMMU_CTRL_XLTEERR) {
 214                const char *type_str;
 215
 216                control &= ~PSYCHO_IOMMU_CTRL_XLTEERR;
 217                upa_writeq(control, iommu->iommu_control);
 218
 219                switch ((control & PSYCHO_IOMMU_CTRL_XLTESTAT) >> 25UL) {
 220                case 0:
 221                        type_str = "Protection Error";
 222                        break;
 223                case 1:
 224                        type_str = "Invalid Error";
 225                        break;
 226                case 2:
 227                        type_str = "TimeOut Error";
 228                        break;
 229                case 3:
 230                default:
 231                        type_str = "ECC Error";
 232                        break;
 233                }
 234                printk(KERN_ERR "%s: IOMMU Error, type[%s]\n",
 235                       pbm->name, type_str);
 236
 237                /* It is very possible for another DVMA to occur while
 238                 * we do this probe, and corrupt the system further.
 239                 * But we are so screwed at this point that we are
 240                 * likely to crash hard anyways, so get as much
 241                 * diagnostic information to the console as we can.
 242                 */
 243                psycho_record_iommu_tags_and_data(pbm, iommu_tag, iommu_data);
 244                psycho_dump_iommu_tags_and_data(pbm, iommu_tag, iommu_data);
 245        }
 246        psycho_check_stc_error(pbm);
 247        spin_unlock_irqrestore(&iommu->lock, flags);
 248}
 249
 250#define  PSYCHO_PCICTRL_SBH_ERR  0x0000000800000000UL
 251#define  PSYCHO_PCICTRL_SERR     0x0000000400000000UL
 252
 253static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm)
 254{
 255        irqreturn_t ret = IRQ_NONE;
 256        u64 csr, csr_error_bits;
 257        u16 stat, *addr;
 258
 259        csr = upa_readq(pbm->pci_csr);
 260        csr_error_bits = csr & (PSYCHO_PCICTRL_SBH_ERR | PSYCHO_PCICTRL_SERR);
 261        if (csr_error_bits) {
 262                /* Clear the errors.  */
 263                upa_writeq(csr, pbm->pci_csr);
 264
 265                /* Log 'em.  */
 266                if (csr_error_bits & PSYCHO_PCICTRL_SBH_ERR)
 267                        printk(KERN_ERR "%s: PCI streaming byte hole "
 268                               "error asserted.\n", pbm->name);
 269                if (csr_error_bits & PSYCHO_PCICTRL_SERR)
 270                        printk(KERN_ERR "%s: PCI SERR signal asserted.\n",
 271                               pbm->name);
 272                ret = IRQ_HANDLED;
 273        }
 274        addr = psycho_pci_config_mkaddr(pbm, pbm->pci_first_busno,
 275                                        0, PCI_STATUS);
 276        pci_config_read16(addr, &stat);
 277        if (stat & (PCI_STATUS_PARITY |
 278                    PCI_STATUS_SIG_TARGET_ABORT |
 279                    PCI_STATUS_REC_TARGET_ABORT |
 280                    PCI_STATUS_REC_MASTER_ABORT |
 281                    PCI_STATUS_SIG_SYSTEM_ERROR)) {
 282                printk(KERN_ERR "%s: PCI bus error, PCI_STATUS[%04x]\n",
 283                       pbm->name, stat);
 284                pci_config_write16(addr, 0xffff);
 285                ret = IRQ_HANDLED;
 286        }
 287        return ret;
 288}
 289
 290#define  PSYCHO_PCIAFSR_PMA     0x8000000000000000ULL
 291#define  PSYCHO_PCIAFSR_PTA     0x4000000000000000ULL
 292#define  PSYCHO_PCIAFSR_PRTRY   0x2000000000000000ULL
 293#define  PSYCHO_PCIAFSR_PPERR   0x1000000000000000ULL
 294#define  PSYCHO_PCIAFSR_SMA     0x0800000000000000ULL
 295#define  PSYCHO_PCIAFSR_STA     0x0400000000000000ULL
 296#define  PSYCHO_PCIAFSR_SRTRY   0x0200000000000000ULL
 297#define  PSYCHO_PCIAFSR_SPERR   0x0100000000000000ULL
 298#define  PSYCHO_PCIAFSR_RESV1   0x00ff000000000000ULL
 299#define  PSYCHO_PCIAFSR_BMSK    0x0000ffff00000000ULL
 300#define  PSYCHO_PCIAFSR_BLK     0x0000000080000000ULL
 301#define  PSYCHO_PCIAFSR_RESV2   0x0000000040000000ULL
 302#define  PSYCHO_PCIAFSR_MID     0x000000003e000000ULL
 303#define  PSYCHO_PCIAFSR_RESV3   0x0000000001ffffffULL
 304
 305irqreturn_t psycho_pcierr_intr(int irq, void *dev_id)
 306{
 307        struct pci_pbm_info *pbm = dev_id;
 308        u64 afsr, afar, error_bits;
 309        int reported;
 310
 311        afsr = upa_readq(pbm->pci_afsr);
 312        afar = upa_readq(pbm->pci_afar);
 313        error_bits = afsr &
 314                (PSYCHO_PCIAFSR_PMA | PSYCHO_PCIAFSR_PTA |
 315                 PSYCHO_PCIAFSR_PRTRY | PSYCHO_PCIAFSR_PPERR |
 316                 PSYCHO_PCIAFSR_SMA | PSYCHO_PCIAFSR_STA |
 317                 PSYCHO_PCIAFSR_SRTRY | PSYCHO_PCIAFSR_SPERR);
 318        if (!error_bits)
 319                return psycho_pcierr_intr_other(pbm);
 320        upa_writeq(error_bits, pbm->pci_afsr);
 321        printk(KERN_ERR "%s: PCI Error, primary error type[%s]\n",
 322               pbm->name,
 323               (((error_bits & PSYCHO_PCIAFSR_PMA) ?
 324                 "Master Abort" :
 325                 ((error_bits & PSYCHO_PCIAFSR_PTA) ?
 326                  "Target Abort" :
 327                  ((error_bits & PSYCHO_PCIAFSR_PRTRY) ?
 328                   "Excessive Retries" :
 329                   ((error_bits & PSYCHO_PCIAFSR_PPERR) ?
 330                    "Parity Error" : "???"))))));
 331        printk(KERN_ERR "%s: bytemask[%04llx] UPA_MID[%02llx] was_block(%d)\n",
 332               pbm->name,
 333               (afsr & PSYCHO_PCIAFSR_BMSK) >> 32UL,
 334               (afsr & PSYCHO_PCIAFSR_MID) >> 25UL,
 335               (afsr & PSYCHO_PCIAFSR_BLK) ? 1 : 0);
 336        printk(KERN_ERR "%s: PCI AFAR [%016llx]\n", pbm->name, afar);
 337        printk(KERN_ERR "%s: PCI Secondary errors [", pbm->name);
 338        reported = 0;
 339        if (afsr & PSYCHO_PCIAFSR_SMA) {
 340                reported++;
 341                printk("(Master Abort)");
 342        }
 343        if (afsr & PSYCHO_PCIAFSR_STA) {
 344                reported++;
 345                printk("(Target Abort)");
 346        }
 347        if (afsr & PSYCHO_PCIAFSR_SRTRY) {
 348                reported++;
 349                printk("(Excessive Retries)");
 350        }
 351        if (afsr & PSYCHO_PCIAFSR_SPERR) {
 352                reported++;
 353                printk("(Parity Error)");
 354        }
 355        if (!reported)
 356                printk("(none)");
 357        printk("]\n");
 358
 359        if (error_bits & (PSYCHO_PCIAFSR_PTA | PSYCHO_PCIAFSR_STA)) {
 360                psycho_check_iommu_error(pbm, afsr, afar, PCI_ERR);
 361                pci_scan_for_target_abort(pbm, pbm->pci_bus);
 362        }
 363        if (error_bits & (PSYCHO_PCIAFSR_PMA | PSYCHO_PCIAFSR_SMA))
 364                pci_scan_for_master_abort(pbm, pbm->pci_bus);
 365
 366        if (error_bits & (PSYCHO_PCIAFSR_PPERR | PSYCHO_PCIAFSR_SPERR))
 367                pci_scan_for_parity_error(pbm, pbm->pci_bus);
 368
 369        return IRQ_HANDLED;
 370}
 371
 372static void psycho_iommu_flush(struct pci_pbm_info *pbm)
 373{
 374        int i;
 375
 376        for (i = 0; i < 16; i++) {
 377                unsigned long off = i * 8;
 378
 379                upa_writeq(0, pbm->controller_regs + PSYCHO_IOMMU_TAG + off);
 380                upa_writeq(0, pbm->controller_regs + PSYCHO_IOMMU_DATA + off);
 381        }
 382}
 383
 384#define PSYCHO_IOMMU_CONTROL            0x0200UL
 385#define  PSYCHO_IOMMU_CTRL_TSBSZ        0x0000000000070000UL
 386#define  PSYCHO_IOMMU_TSBSZ_1K          0x0000000000000000UL
 387#define  PSYCHO_IOMMU_TSBSZ_2K          0x0000000000010000UL
 388#define  PSYCHO_IOMMU_TSBSZ_4K          0x0000000000020000UL
 389#define  PSYCHO_IOMMU_TSBSZ_8K          0x0000000000030000UL
 390#define  PSYCHO_IOMMU_TSBSZ_16K         0x0000000000040000UL
 391#define  PSYCHO_IOMMU_TSBSZ_32K         0x0000000000050000UL
 392#define  PSYCHO_IOMMU_TSBSZ_64K         0x0000000000060000UL
 393#define  PSYCHO_IOMMU_TSBSZ_128K        0x0000000000070000UL
 394#define  PSYCHO_IOMMU_CTRL_TBWSZ        0x0000000000000004UL
 395#define  PSYCHO_IOMMU_CTRL_DENAB        0x0000000000000002UL
 396#define  PSYCHO_IOMMU_CTRL_ENAB         0x0000000000000001UL
 397#define PSYCHO_IOMMU_FLUSH              0x0210UL
 398#define PSYCHO_IOMMU_TSBBASE            0x0208UL
 399
 400int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize,
 401                      u32 dvma_offset, u32 dma_mask,
 402                      unsigned long write_complete_offset)
 403{
 404        struct iommu *iommu = pbm->iommu;
 405        u64 control;
 406        int err;
 407
 408        iommu->iommu_control  = pbm->controller_regs + PSYCHO_IOMMU_CONTROL;
 409        iommu->iommu_tsbbase  = pbm->controller_regs + PSYCHO_IOMMU_TSBBASE;
 410        iommu->iommu_flush    = pbm->controller_regs + PSYCHO_IOMMU_FLUSH;
 411        iommu->iommu_tags     = pbm->controller_regs + PSYCHO_IOMMU_TAG;
 412        iommu->write_complete_reg = (pbm->controller_regs +
 413                                     write_complete_offset);
 414
 415        iommu->iommu_ctxflush = 0;
 416
 417        control = upa_readq(iommu->iommu_control);
 418        control |= PSYCHO_IOMMU_CTRL_DENAB;
 419        upa_writeq(control, iommu->iommu_control);
 420
 421        psycho_iommu_flush(pbm);
 422
 423        /* Leave diag mode enabled for full-flushing done in pci_iommu.c */
 424        err = iommu_table_init(iommu, tsbsize * 1024 * 8,
 425                               dvma_offset, dma_mask, pbm->numa_node);
 426        if (err)
 427                return err;
 428
 429        upa_writeq(__pa(iommu->page_table), iommu->iommu_tsbbase);
 430
 431        control = upa_readq(iommu->iommu_control);
 432        control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
 433        control |= PSYCHO_IOMMU_CTRL_ENAB;
 434
 435        switch (tsbsize) {
 436        case 64:
 437                control |= PSYCHO_IOMMU_TSBSZ_64K;
 438                break;
 439        case 128:
 440                control |= PSYCHO_IOMMU_TSBSZ_128K;
 441                break;
 442        default:
 443                return -EINVAL;
 444        }
 445
 446        upa_writeq(control, iommu->iommu_control);
 447
 448        return 0;
 449
 450}
 451
 452void psycho_pbm_init_common(struct pci_pbm_info *pbm, struct platform_device *op,
 453                            const char *chip_name, int chip_type)
 454{
 455        struct device_node *dp = op->dev.of_node;
 456
 457        pbm->name = dp->full_name;
 458        pbm->numa_node = NUMA_NO_NODE;
 459        pbm->chip_type = chip_type;
 460        pbm->chip_version = of_getintprop_default(dp, "version#", 0);
 461        pbm->chip_revision = of_getintprop_default(dp, "module-revision#", 0);
 462        pbm->op = op;
 463        pbm->pci_ops = &sun4u_pci_ops;
 464        pbm->config_space_reg_bits = 8;
 465        pbm->index = pci_num_pbms++;
 466        pci_get_pbm_props(pbm);
 467        pci_determine_mem_io_space(pbm);
 468
 469        printk(KERN_INFO "%s: %s PCI Bus Module ver[%x:%x]\n",
 470               pbm->name, chip_name,
 471               pbm->chip_version, pbm->chip_revision);
 472}
 473
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.