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