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