xref: /original-bsd/sys/vax/vax/ka860.c (revision 7211505a)
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