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