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