1 /* 2 * Copyright (c) 1986, 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)ka860.c 7.4 (Berkeley) 12/16/90 8 */ 9 10 #if VAX8600 11 12 /* 13 * VAX 8600 specific routines. 14 */ 15 16 #include "sys/param.h" 17 18 #include "../include/cpu.h" 19 #include "../include/mtpr.h" 20 21 /* 22 * 8600 memory register (MERG) bit definitions 23 */ 24 #define M8600_ICRD 0x400 /* inhibit crd interrupts */ 25 #define M8600_TB_ERR 0xf00 /* translation buffer error mask */ 26 27 /* 28 * MDECC register 29 */ 30 #define M8600_ADDR_PE 0x080000 /* address parity error */ 31 #define M8600_DBL_ERR 0x100000 /* data double bit error */ 32 #define M8600_SNG_ERR 0x200000 /* data single bit error */ 33 #define M8600_BDT_ERR 0x400000 /* bad data error */ 34 35 /* 36 * ESPA register is used to address scratch pad registers in the Ebox. 37 * To access a register in the scratch pad, write the ESPA with the address 38 * and then read the ESPD register. 39 * 40 * NOTE: In assmebly code, the mfpr instruction that reads the ESPD 41 * register must immedately follow the mtpr instruction that setup 42 * the ESPA register -- per the VENUS processor register spec. 43 * 44 * The scratchpad registers that are supplied for a single bit ECC 45 * error are: 46 */ 47 #define SPAD_MSTAT1 0x25 /* scratch pad mstat1 register */ 48 #define SPAD_MSTAT2 0x26 /* scratch pad mstat2 register */ 49 #define SPAD_MDECC 0x27 /* scratch pad mdecc register */ 50 #define SPAD_MEAR 0x2a /* scratch pad mear register */ 51 52 #define M8600_MEMERR(mdecc) ((mdecc) & 0x780000) 53 #define M8600_HRDERR(mdecc) ((mdecc) & 0x580000) 54 #define M8600_SYN(mdecc) (((mdecc) >> 9) & 0x3f) 55 #define M8600_ADDR(mear) ((mear) & 0x3ffffffc) 56 #define M8600_ARRAY(mear) (((mear) >> 22) & 0x0f) 57 58 #define M8600_MDECC_BITS \ 59 "\20\27BAD_DT_ERR\26SNG_BIT_ERR\25DBL_BIT_ERR\24ADDR_PE" 60 61 #define M8600_MSTAT1_BITS "\20\30CPR_PE_A\27CPR_PE_B\26ABUS_DT_PE\ 62 \25ABUS_CTL_MSK_PE\24ABUS_ADR_PE\23ABUS_C/A_CYCLE\22ABUS_ADP_1\21ABUS_ADP_0\ 63 \20TB_MISS\17BLK_HIT\16C0_TAG_MISS\15CHE_MISS\14TB_VAL_ERR\13TB_PTE_B_PE\ 64 \12TB_PTE_A_PE\11TB_TAG_PE\10WR_DT_PE_B3\7WR_DT_PE_B2\6WR_DT_PE_B1\ 65 \5WR_DT_PE_B0\4CHE_RD_DT_PE\3CHE_SEL\2ANY_REFL\1CP_BW_CHE_DT_PE" 66 67 #define M8600_MSTAT2_BITS "\20\20CP_BYT_WR\17ABUS_BD_DT_CODE\10MULT_ERR\ 68 \7CHE_TAG_PE\6CHE_TAG_W_PE\5CHE_WRTN_BIT\4NXM\3CP-IO_BUF_ERR\2MBOX_LOCK" 69 70 /* enable CRD reports */ 71 ka860_memenable() 72 { 73 74 mtpr(MERG, mfpr(MERG) & ~M8600_ICRD); 75 } 76 77 /* log CRD errors */ 78 ka860_memerr() 79 { 80 register int reg11; /* known to be r11 below */ 81 int mdecc, mear, mstat1, mstat2, array; 82 83 /* 84 * Scratchpad registers in the Ebox must be read by 85 * storing their ID number in ESPA and then immediately 86 * reading ESPD's contents with no other intervening 87 * machine instructions! 88 * 89 * The asm's below have a number of constants which 90 * are defined correctly above and in mtpr.h. 91 */ 92 #ifdef lint 93 reg11 = 0; 94 #else 95 asm("mtpr $0x27,$0x4e; mfpr $0x4f,r11"); 96 #endif 97 mdecc = reg11; /* must acknowledge interrupt? */ 98 if (M8600_MEMERR(mdecc)) { 99 asm("mtpr $0x2a,$0x4e; mfpr $0x4f,r11"); 100 mear = reg11; 101 asm("mtpr $0x25,$0x4e; mfpr $0x4f,r11"); 102 mstat1 = reg11; 103 asm("mtpr $0x26,$0x4e; mfpr $0x4f,r11"); 104 mstat2 = reg11; 105 array = M8600_ARRAY(mear); 106 107 printf("mcr0: ecc error, addr %x (array %d) syn %x\n", 108 M8600_ADDR(mear), array, M8600_SYN(mdecc)); 109 printf("\tMSTAT1 = %b\n\tMSTAT2 = %b\n", 110 mstat1, M8600_MSTAT1_BITS, 111 mstat2, M8600_MSTAT2_BITS); 112 mtpr(EHSR, 0); 113 mtpr(MERG, mfpr(MERG) | M8600_ICRD); 114 } 115 } 116 117 #define NMC8600 7 118 char *mc8600[] = { 119 "unkn type", "fbox error", "ebox error", "ibox error", 120 "mbox error", "tbuf error", "mbox 1D error" 121 }; 122 /* codes for above */ 123 #define MC_FBOX 1 124 #define MC_EBOX 2 125 #define MC_IBOX 3 126 #define MC_MBOX 4 127 #define MC_TBUF 5 128 #define MC_MBOX1D 6 129 130 /* error bits */ 131 #define MBOX_FE 0x8000 /* Mbox fatal error */ 132 #define FBOX_SERV 0x10000000 /* Fbox service error */ 133 #define IBOX_ERR 0x2000 /* Ibox error */ 134 #define EBOX_ERR 0x1e00 /* Ebox error */ 135 #define MBOX_1D 0x81d0000 /* Mbox 1D error */ 136 #define EDP_PE 0x200 137 138 struct mc8600frame { 139 int mc86_bcnt; /* byte count == 0x58 */ 140 int mc86_ehmsts; 141 int mc86_evmqsav; 142 int mc86_ebcs; 143 int mc86_edpsr; 144 int mc86_cslint; 145 int mc86_ibesr; 146 int mc86_ebxwd1; 147 int mc86_ebxwd2; 148 int mc86_ivasav; 149 int mc86_vibasav; 150 int mc86_esasav; 151 int mc86_isasav; 152 int mc86_cpc; 153 int mc86_mstat1; 154 int mc86_mstat2; 155 int mc86_mdecc; 156 int mc86_merg; 157 int mc86_cshctl; 158 int mc86_mear; 159 int mc86_medr; 160 int mc86_accs; 161 int mc86_cses; 162 int mc86_pc; /* trapped pc */ 163 int mc86_psl; /* trapped psl */ 164 }; 165 166 /* machine check */ 167 ka860_mchk(cmcf) 168 caddr_t cmcf; 169 { 170 register struct mc8600frame *mcf = (struct mc8600frame *)cmcf; 171 register int type; 172 173 if (mcf->mc86_ebcs & MBOX_FE) 174 mcf->mc86_ehmsts |= MC_MBOX; 175 else if (mcf->mc86_ehmsts & FBOX_SERV) 176 mcf->mc86_ehmsts |= MC_FBOX; 177 else if (mcf->mc86_ebcs & EBOX_ERR) { 178 if (mcf->mc86_ebcs & EDP_PE) 179 mcf->mc86_ehmsts |= MC_MBOX; 180 else 181 mcf->mc86_ehmsts |= MC_EBOX; 182 } else if (mcf->mc86_ehmsts & IBOX_ERR) 183 mcf->mc86_ehmsts |= MC_IBOX; 184 else if (mcf->mc86_mstat1 & M8600_TB_ERR) 185 mcf->mc86_ehmsts |= MC_TBUF; 186 else if ((mcf->mc86_cslint & MBOX_1D) == MBOX_1D) 187 mcf->mc86_ehmsts |= MC_MBOX1D; 188 189 type = mcf->mc86_ehmsts & 0x7; 190 printf("machine check %x: %s\n", type, 191 type < NMC8600 ? mc8600[type] : "???"); 192 printf("\tehm.sts %x evmqsav %x ebcs %x edpsr %x cslint %x\n", 193 mcf->mc86_ehmsts, mcf->mc86_evmqsav, mcf->mc86_ebcs, 194 mcf->mc86_edpsr, mcf->mc86_cslint); 195 printf("\tibesr %x ebxwd %x %x ivasav %x vibasav %x\n", 196 mcf->mc86_ibesr, mcf->mc86_ebxwd1, mcf->mc86_ebxwd2, 197 mcf->mc86_ivasav, mcf->mc86_vibasav); 198 printf("\tesasav %x isasav %x cpc %x mstat %x %x mdecc %x\n", 199 mcf->mc86_esasav, mcf->mc86_isasav, mcf->mc86_cpc, 200 mcf->mc86_mstat1, mcf->mc86_mstat2, mcf->mc86_mdecc); 201 printf("\tmerg %x cshctl %x mear %x medr %x accs %x cses %x\n", 202 mcf->mc86_merg, mcf->mc86_cshctl, mcf->mc86_mear, 203 mcf->mc86_medr, mcf->mc86_accs, mcf->mc86_cses); 204 printf("\tpc %x psl %x\n", mcf->mc86_pc, mcf->mc86_psl); 205 mtpr(EHSR, 0); 206 return (MCHK_PANIC); 207 } 208 #endif 209