xref: /netbsd/sys/arch/vax/vax/ka750.c (revision bf9ec67e)
1 /*	$NetBSD: ka750.c,v 1.31 2000/06/04 18:02:35 ragge Exp $ */
2 /*
3  * Copyright (c) 1982, 1986, 1988 The Regents of the University of California.
4  * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)ka750.c	7.4 (Berkeley) 5/9/91
36  *	@(#)autoconf.c	7.20 (Berkeley) 5/9/91
37  */
38 
39 #include <sys/param.h>
40 #include <sys/device.h>
41 #include <sys/systm.h>
42 
43 #include <machine/bus.h>
44 #include <machine/ka750.h>
45 #include <machine/mtpr.h>
46 #include <machine/cpu.h>
47 #include <machine/clock.h>
48 #include <machine/sid.h>
49 
50 #include <vax/vax/gencons.h>
51 
52 #include "locators.h"
53 
54 void	ctuattach(void);
55 static	void ka750_clrf(void);
56 static	void ka750_conf(void);
57 static	void ka750_memerr(void);
58 static	int ka750_mchk(caddr_t);
59 
60 
61 struct	cpu_dep ka750_calls = {
62 	0,
63 	ka750_mchk,
64 	ka750_memerr,
65 	ka750_conf,
66 	generic_clkread,
67 	generic_clkwrite,
68 	1,	/* ~VUPS */
69 	4,	/* SCB pages */
70 	0,	/* halt call */
71 	0,	/* Reboot call */
72 	ka750_clrf,
73 };
74 
75 static	caddr_t mcraddr[4];	/* XXX */
76 
77 void
78 ka750_conf()
79 {
80 	printf("cpu0: KA750, hardware rev %d, ucode rev %d, ",
81 	    V750HARDW(vax_cpudata), V750UCODE(vax_cpudata));
82 	if (mfpr(PR_ACCS) & 255) {
83 		printf("FPA present, enabling.\n");
84 		mtpr(0x8000, PR_ACCS);
85 	} else
86 		printf("no FPA\n");
87 
88 	if (mfpr(PR_TODR) == 0) { /* Check for failing battery */
89 		mtpr(1, PR_TODR);
90 		printf("WARNING: TODR battery broken\n");
91 	}
92 
93 	/* Call ctuattach() here so it can setup its vectors. */
94 	ctuattach();
95 }
96 
97 static int ka750_memmatch(struct device  *, struct cfdata *, void *);
98 static void ka750_memenable(struct device *, struct device *, void *);
99 
100 struct	cfattach mem_cmi_ca = {
101 	sizeof(struct device), ka750_memmatch, ka750_memenable
102 };
103 
104 int
105 ka750_memmatch(struct device *parent, struct cfdata *cf, void *aux)
106 {
107 	struct	sbi_attach_args *sa = (struct sbi_attach_args *)aux;
108 
109 	if (cf->cf_loc[CMICF_TR] != sa->sa_nexnum &&
110 	    cf->cf_loc[CMICF_TR] > CMICF_TR_DEFAULT)
111 		return 0;
112 
113 	if (sa->sa_type != NEX_MEM16)
114 		return 0;
115 
116 	return 1;
117 }
118 
119 struct	mcr750 {
120 	int	mc_err;			/* error bits */
121 	int	mc_inh;			/* inhibit crd */
122 	int	mc_inf;			/* info bits */
123 };
124 
125 #define M750_ICRD	0x10000000	/* inhibit crd interrupts, in [1] */
126 #define M750_UNCORR	0xc0000000	/* uncorrectable error, in [0] */
127 #define M750_CORERR	0x20000000	/* correctable error, in [0] */
128 
129 #define M750_INH(mcr)	((mcr)->mc_inh = 0)
130 #define M750_ENA(mcr)	((mcr)->mc_err = (M750_UNCORR|M750_CORERR), \
131 			 (mcr)->mc_inh = M750_ICRD)
132 #define M750_ERR(mcr)	((mcr)->mc_err & (M750_UNCORR|M750_CORERR))
133 
134 #define M750_SYN(err)	((err) & 0x7f)
135 #define M750_ADDR(err)	(((err) >> 9) & 0x7fff)
136 
137 /* enable crd interrupts */
138 void
139 ka750_memenable(struct device *parent, struct device *self, void *aux)
140 {
141 	struct	sbi_attach_args *sa = (struct sbi_attach_args *)aux;
142 	struct mcr750 *mcr = (struct mcr750 *)sa->sa_ioh;
143 	int k, l, m, cardinfo;
144 
145 	mcraddr[self->dv_unit] = (caddr_t)sa->sa_ioh;
146 
147 	/* We will use this info for error reporting - later! */
148 	cardinfo = mcr->mc_inf;
149 	switch ((cardinfo >> 24) & 3) {
150 	case 0: printf(": L0011 ");
151 		break;
152 
153 	case 1: printf(": L0016 ");
154 		m = cardinfo & 0xaaaa;
155 		for (k = l = 0; k < 16; k++){
156 			if (m & 1)
157 				l++;
158 			m >>= 1;
159 		}
160 		printf("with %d M8750",l);
161 		break;
162 
163 	case 3: printf(": L0022 ");
164 		m = cardinfo & 0x5555;
165 		for (k = l = 0; k < 16; k++) {
166 			if (m & 1)
167 				l++;
168 			m>>=1;
169 		}
170 		printf("with %d M7199",l);
171 		m = cardinfo & 0xaaaa;
172 		if (m) {
173 			for (k = l = 0; k < 16; k++) {
174 				if (m & 1)
175 					l++;
176 				m >>= 1;
177 			}
178 			printf(" and %d M8750",l);
179 		}
180 		break;
181 	}
182 	printf("\n");
183 
184 
185 	M750_ENA((struct mcr750 *)mcraddr[0]);
186 }
187 
188 /* log crd errors */
189 void
190 ka750_memerr()
191 {
192 	register struct mcr750 *mcr = (struct mcr750 *)mcraddr[0];
193 	register int err;
194 
195 	if (M750_ERR(mcr)) {
196 		err = mcr->mc_err;	/* careful with i/o space refs */
197 		printf("mcr0: %s", err & M750_UNCORR ?
198 		    "hard error" : "soft ecc");
199 		printf(" addr %x syn %x\n", M750_ADDR(err), M750_SYN(err));
200 		M750_INH(mcr);
201 	}
202 }
203 
204 char *mc750[]={"0","1","2","3","4","5","6","7","8","9","10","11","12","13",
205 	"14","15"};
206 
207 struct mc750frame {
208 	int	mc5_bcnt;		/* byte count == 0x28 */
209 	int	mc5_summary;		/* summary parameter (as above) */
210 	int	mc5_va;			/* virtual address register */
211 	int	mc5_errpc;		/* error pc */
212 	int	mc5_mdr;
213 	int	mc5_svmode;		/* saved mode register */
214 	int	mc5_rdtimo;		/* read lock timeout */
215 	int	mc5_tbgpar;		/* tb group parity error register */
216 	int	mc5_cacherr;		/* cache error register */
217 	int	mc5_buserr;		/* bus error register */
218 	int	mc5_mcesr;		/* machine check status register */
219 	int	mc5_pc;			/* trapped pc */
220 	int	mc5_psl;		/* trapped psl */
221 };
222 
223 #define MC750_TBERR	2		/* type code of cp tbuf par */
224 #define MC750_TBPAR	4		/* tbuf par bit in mcesr */
225 
226 int
227 ka750_mchk(caddr_t cmcf)
228 {
229 	register struct mc750frame *mcf = (struct mc750frame *)cmcf;
230 	register int type = mcf->mc5_summary;
231 	int mcsr = mfpr(PR_MCSR);
232 
233 	printf("machine check %x: %s%s\n", type, mc750[type&0xf],
234 	    (type&0xf0) ? " abort" : " fault");
235 	printf(
236 "\tva %x errpc %x mdr %x smr %x rdtimo %x tbgpar %x cacherr %x\n",
237 	    mcf->mc5_va, mcf->mc5_errpc, mcf->mc5_mdr, mcf->mc5_svmode,
238 	    mcf->mc5_rdtimo, mcf->mc5_tbgpar, mcf->mc5_cacherr);
239 	printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n",
240 	    mcf->mc5_buserr, mcf->mc5_mcesr, mcf->mc5_pc, mcf->mc5_psl,
241 	    mcsr);
242 	mtpr(0, PR_TBIA);
243 	mtpr(0xf, PR_MCESR);
244 	if (type == MC750_TBERR && (mcf->mc5_mcesr&0xe) == MC750_TBPAR) {
245 		printf("tbuf par: flushing and returning\n");
246 		return (MCHK_RECOVERED);
247 	}
248 	return (MCHK_PANIC);
249 }
250 
251 void
252 ka750_clrf()
253 {
254 	int s = splhigh();
255 
256 #define WAIT	while ((mfpr(PR_TXCS) & GC_RDY) == 0) ;
257 
258 	WAIT;
259 
260 	mtpr(GC_CWFL|GC_CONS, PR_TXDB);
261 
262 	WAIT;
263 	mtpr(GC_CCFL|GC_CONS, PR_TXDB);
264 
265 	WAIT;
266 	splx(s);
267 }
268