xref: /netbsd/sys/arch/vax/vax/ka750.c (revision c4a72b64)
1 /*	$NetBSD: ka750.c,v 1.34 2002/10/02 16:02:35 thorpej 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 CFATTACH_DECL(mem_cmi, sizeof(struct device),
101     ka750_memmatch, ka750_memenable, NULL, NULL);
102 
103 int
104 ka750_memmatch(struct device *parent, struct cfdata *cf, void *aux)
105 {
106 	struct	sbi_attach_args *sa = (struct sbi_attach_args *)aux;
107 
108 	if (cf->cf_loc[CMICF_TR] != sa->sa_nexnum &&
109 	    cf->cf_loc[CMICF_TR] > CMICF_TR_DEFAULT)
110 		return 0;
111 
112 	if (sa->sa_type != NEX_MEM16)
113 		return 0;
114 
115 	return 1;
116 }
117 
118 struct	mcr750 {
119 	int	mc_err;			/* error bits */
120 	int	mc_inh;			/* inhibit crd */
121 	int	mc_inf;			/* info bits */
122 };
123 
124 #define M750_ICRD	0x10000000	/* inhibit crd interrupts, in [1] */
125 #define M750_UNCORR	0xc0000000	/* uncorrectable error, in [0] */
126 #define M750_CORERR	0x20000000	/* correctable error, in [0] */
127 
128 #define M750_INH(mcr)	((mcr)->mc_inh = 0)
129 #define M750_ENA(mcr)	((mcr)->mc_err = (M750_UNCORR|M750_CORERR), \
130 			 (mcr)->mc_inh = M750_ICRD)
131 #define M750_ERR(mcr)	((mcr)->mc_err & (M750_UNCORR|M750_CORERR))
132 
133 #define M750_SYN(err)	((err) & 0x7f)
134 #define M750_ADDR(err)	(((err) >> 9) & 0x7fff)
135 
136 /* enable crd interrupts */
137 void
138 ka750_memenable(struct device *parent, struct device *self, void *aux)
139 {
140 	struct	sbi_attach_args *sa = (struct sbi_attach_args *)aux;
141 	struct mcr750 *mcr = (struct mcr750 *)sa->sa_ioh;
142 	int k, l, m, cardinfo;
143 
144 	mcraddr[self->dv_unit] = (caddr_t)sa->sa_ioh;
145 
146 	/* We will use this info for error reporting - later! */
147 	cardinfo = mcr->mc_inf;
148 	switch ((cardinfo >> 24) & 3) {
149 	case 0: printf(": L0011 ");
150 		break;
151 
152 	case 1: printf(": L0016 ");
153 		m = cardinfo & 0xaaaa;
154 		for (k = l = 0; k < 16; k++){
155 			if (m & 1)
156 				l++;
157 			m >>= 1;
158 		}
159 		printf("with %d M8750",l);
160 		break;
161 
162 	case 3: printf(": L0022 ");
163 		m = cardinfo & 0x5555;
164 		for (k = l = 0; k < 16; k++) {
165 			if (m & 1)
166 				l++;
167 			m>>=1;
168 		}
169 		printf("with %d M7199",l);
170 		m = cardinfo & 0xaaaa;
171 		if (m) {
172 			for (k = l = 0; k < 16; k++) {
173 				if (m & 1)
174 					l++;
175 				m >>= 1;
176 			}
177 			printf(" and %d M8750",l);
178 		}
179 		break;
180 	}
181 	printf("\n");
182 
183 
184 	M750_ENA((struct mcr750 *)mcraddr[0]);
185 }
186 
187 /* log crd errors */
188 void
189 ka750_memerr()
190 {
191 	register struct mcr750 *mcr = (struct mcr750 *)mcraddr[0];
192 	register int err;
193 
194 	if (M750_ERR(mcr)) {
195 		err = mcr->mc_err;	/* careful with i/o space refs */
196 		printf("mcr0: %s", err & M750_UNCORR ?
197 		    "hard error" : "soft ecc");
198 		printf(" addr %x syn %x\n", M750_ADDR(err), M750_SYN(err));
199 		M750_INH(mcr);
200 	}
201 }
202 
203 char *mc750[]={"0","1","2","3","4","5","6","7","8","9","10","11","12","13",
204 	"14","15"};
205 
206 struct mc750frame {
207 	int	mc5_bcnt;		/* byte count == 0x28 */
208 	int	mc5_summary;		/* summary parameter (as above) */
209 	int	mc5_va;			/* virtual address register */
210 	int	mc5_errpc;		/* error pc */
211 	int	mc5_mdr;
212 	int	mc5_svmode;		/* saved mode register */
213 	int	mc5_rdtimo;		/* read lock timeout */
214 	int	mc5_tbgpar;		/* tb group parity error register */
215 	int	mc5_cacherr;		/* cache error register */
216 	int	mc5_buserr;		/* bus error register */
217 	int	mc5_mcesr;		/* machine check status register */
218 	int	mc5_pc;			/* trapped pc */
219 	int	mc5_psl;		/* trapped psl */
220 };
221 
222 #define MC750_TBERR	2		/* type code of cp tbuf par */
223 #define MC750_TBPAR	4		/* tbuf par bit in mcesr */
224 
225 int
226 ka750_mchk(caddr_t cmcf)
227 {
228 	register struct mc750frame *mcf = (struct mc750frame *)cmcf;
229 	register int type = mcf->mc5_summary;
230 	int mcsr = mfpr(PR_MCSR);
231 
232 	printf("machine check %x: %s%s\n", type, mc750[type&0xf],
233 	    (type&0xf0) ? " abort" : " fault");
234 	printf(
235 "\tva %x errpc %x mdr %x smr %x rdtimo %x tbgpar %x cacherr %x\n",
236 	    mcf->mc5_va, mcf->mc5_errpc, mcf->mc5_mdr, mcf->mc5_svmode,
237 	    mcf->mc5_rdtimo, mcf->mc5_tbgpar, mcf->mc5_cacherr);
238 	printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n",
239 	    mcf->mc5_buserr, mcf->mc5_mcesr, mcf->mc5_pc, mcf->mc5_psl,
240 	    mcsr);
241 	mtpr(0, PR_TBIA);
242 	mtpr(0xf, PR_MCESR);
243 	if (type == MC750_TBERR && (mcf->mc5_mcesr&0xe) == MC750_TBPAR) {
244 		printf("tbuf par: flushing and returning\n");
245 		return (MCHK_RECOVERED);
246 	}
247 	return (MCHK_PANIC);
248 }
249 
250 void
251 ka750_clrf()
252 {
253 	int s = splhigh();
254 
255 #define WAIT	while ((mfpr(PR_TXCS) & GC_RDY) == 0) ;
256 
257 	WAIT;
258 
259 	mtpr(GC_CWFL|GC_CONS, PR_TXDB);
260 
261 	WAIT;
262 	mtpr(GC_CCFL|GC_CONS, PR_TXDB);
263 
264 	WAIT;
265 	splx(s);
266 }
267