xref: /netbsd/sys/arch/pmax/pmax/dec_3max.c (revision bf9ec67e)
1 /* $NetBSD: dec_3max.c,v 1.37 2001/09/18 16:24:16 tsutsui Exp $ */
2 
3 /*
4  * Copyright (c) 1998 Jonathan Stone.  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. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *	This product includes software developed by Jonathan Stone for
17  *      the NetBSD Project.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1988 University of Utah.
35  * Copyright (c) 1992, 1993
36  *	The Regents of the University of California.  All rights reserved.
37  *
38  * This code is derived from software contributed to Berkeley by
39  * the Systems Programming Group of the University of Utah Computer
40  * Science Department, The Mach Operating System project at
41  * Carnegie-Mellon University and Ralph Campbell.
42  *
43  * Redistribution and use in source and binary forms, with or without
44  * modification, are permitted provided that the following conditions
45  * are met:
46  * 1. Redistributions of source code must retain the above copyright
47  *    notice, this list of conditions and the following disclaimer.
48  * 2. Redistributions in binary form must reproduce the above copyright
49  *    notice, this list of conditions and the following disclaimer in the
50  *    documentation and/or other materials provided with the distribution.
51  * 3. All advertising materials mentioning features or use of this software
52  *    must display the following acknowledgement:
53  *	This product includes software developed by the University of
54  *	California, Berkeley and its contributors.
55  * 4. Neither the name of the University nor the names of its contributors
56  *    may be used to endorse or promote products derived from this software
57  *    without specific prior written permission.
58  *
59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69  * SUCH DAMAGE.
70  *
71  *	@(#)machdep.c	8.3 (Berkeley) 1/12/94
72  */
73 
74 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
75 
76 __KERNEL_RCSID(0, "$NetBSD: dec_3max.c,v 1.37 2001/09/18 16:24:16 tsutsui Exp $");
77 
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/device.h>
81 
82 #include <machine/cpu.h>
83 #include <machine/intr.h>
84 #include <machine/locore.h>
85 #include <machine/sysconf.h>
86 
87 #include <mips/mips/mips_mcclock.h>	/* mcclock CPUspeed estimation */
88 
89 #include <pmax/pmax/machdep.h>
90 #include <pmax/pmax/kn02.h>
91 #include <pmax/pmax/memc.h>
92 #include <pmax/dev/dcvar.h>
93 
94 #include "rasterconsole.h"
95 
96 void		dec_3max_init __P((void));		/* XXX */
97 static void	dec_3max_bus_reset __P((void));
98 
99 static void	dec_3max_cons_init __P((void));
100 static void	dec_3max_errintr __P((void));
101 static void	dec_3max_intr __P((unsigned, unsigned, unsigned, unsigned));
102 static void	dec_3max_intr_establish __P((struct device *, void *,
103 		    int, int (*)(void *), void *));
104 
105 
106 #define	kn02_wbflush()	mips1_wbflush()	/* XXX to be corrected XXX */
107 
108 void
109 dec_3max_init()
110 {
111 	u_int32_t csr;
112 
113 	platform.iobus = "tcbus";
114 	platform.bus_reset = dec_3max_bus_reset;
115 	platform.cons_init = dec_3max_cons_init;
116 	platform.iointr = dec_3max_intr;
117 	platform.intr_establish = dec_3max_intr_establish;
118 	platform.memsize = memsize_bitmap;
119 	/* no high resolution timer available */
120 
121 	/* clear any memory errors */
122 	*(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0;
123 	kn02_wbflush();
124 
125 	splvec.splbio = MIPS_SPL0;
126 	splvec.splnet = MIPS_SPL0;
127 	splvec.spltty = MIPS_SPL0;
128 	splvec.splvm = MIPS_SPL0;
129 	splvec.splclock = MIPS_SPL_0_1;
130 	splvec.splstatclock = MIPS_SPL_0_1;
131 
132 	/* calibrate cpu_mhz value */
133 	mc_cpuspeed(MIPS_PHYS_TO_KSEG1(KN02_SYS_CLOCK), MIPS_INT_MASK_1);
134 
135 	/*
136 	 * Enable ECC memory correction, turn off LEDs, and
137 	 * disable all TURBOchannel interrupts.
138 	 */
139 	csr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
140 	csr &= ~(KN02_CSR_WRESERVED|KN02_CSR_IOINTEN|KN02_CSR_CORRECT|0xff);
141 	*(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR) = csr;
142 	kn02_wbflush();
143 
144 	strcpy(cpu_model, "DECstation 5000/200 (3MAX)");
145 }
146 
147 /*
148  * Initialize the memory system and I/O buses.
149  */
150 static void
151 dec_3max_bus_reset()
152 {
153 	/*
154 	 * Reset interrupts, clear any errors from newconf probes
155 	 */
156 
157 	*(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0;
158 	kn02_wbflush();
159 
160 	*(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN) = 0;
161 	kn02_wbflush();
162 }
163 
164 static void
165 dec_3max_cons_init()
166 {
167 	int kbd, crt, screen;
168 	extern int tcfb_cnattach __P((int));		/* XXX */
169 
170 	kbd = crt = screen = 0;
171 	prom_findcons(&kbd, &crt, &screen);
172 
173 	if (screen > 0) {
174 #if NRASTERCONSOLE > 0
175 		if (kbd == 7 && tcfb_cnattach(crt) > 0) {
176 			dckbd_cnattach(KN02_SYS_DZ);
177 			return;
178 		}
179 #else
180 		printf("No framebuffer device configured for slot %d: ", crt);
181 		printf("using serial console\n");
182 #endif
183 	}
184 	/*
185 	 * Delay to allow PROM putchars to complete.
186 	 * FIFO depth * character time,
187 	 * character time = (1000000 / (defaultrate / 10))
188 	 */
189 	DELAY(160000000 / 9600);	/* XXX */
190 
191 	dc_cnattach(KN02_SYS_DZ, kbd);
192 }
193 
194 static const struct {
195 	int cookie;
196 	int intrbit;
197 } kn02intrs[] = {
198 	{ SYS_DEV_OPT0,	 KN02_IP_SLOT0 },
199 	{ SYS_DEV_OPT1,	 KN02_IP_SLOT1 },
200 	{ SYS_DEV_OPT2,	 KN02_IP_SLOT2 },
201 	{ SYS_DEV_SCSI,	 KN02_IP_SCSI },
202 	{ SYS_DEV_LANCE, KN02_IP_LANCE },
203 	{ SYS_DEV_SCC0,	 KN02_IP_DZ },
204 };
205 
206 static void
207 dec_3max_intr_establish(dev, cookie, level, handler, arg)
208 	struct device *dev;
209 	void *cookie;
210 	int level;
211 	int (*handler) __P((void *));
212 	void *arg;
213 {
214 	int i;
215 	u_int32_t csr;
216 
217 	for (i = 0; i < sizeof(kn02intrs)/sizeof(kn02intrs[0]); i++) {
218 		if (kn02intrs[i].cookie == (int)cookie)
219 			goto found;
220 	}
221 	panic("intr_establish: invalid cookie %d", (int)cookie);
222 
223 found:
224 	intrtab[(int)cookie].ih_func = handler;
225 	intrtab[(int)cookie].ih_arg = arg;
226 
227 	csr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR) & 0x00ffff00;
228 	csr |= (kn02intrs[i].intrbit << 16);
229 	*(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR) = csr;
230 	kn02_wbflush();
231 }
232 
233 
234 #define CALLINTR(vvv)						\
235 	do {							\
236 		intrcnt[vvv] += 1;				\
237 		(*intrtab[vvv].ih_func)(intrtab[vvv].ih_arg);	\
238 	} while (0)
239 
240 static void
241 dec_3max_intr(status, cause, pc, ipending)
242 	unsigned status;
243 	unsigned cause;
244 	unsigned pc;
245 	unsigned ipending;
246 {
247 	static int warned = 0;
248 	u_int32_t csr;
249 
250 	/* handle clock interrupts ASAP */
251 	if (ipending & MIPS_INT_MASK_1) {
252 		struct clockframe cf;
253 
254 		csr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
255 		if ((csr & KN02_CSR_PSWARN) && !warned) {
256 			warned = 1;
257 			printf("WARNING: power supply is overheating!\n");
258 		} else if (warned && !(csr & KN02_CSR_PSWARN)) {
259 			warned = 0;
260 			printf("WARNING: power supply is OK again\n");
261 		}
262 
263 		__asm __volatile("lbu $0,48(%0)" ::
264 			"r"(MIPS_PHYS_TO_KSEG1(KN02_SYS_CLOCK)));
265 		cf.pc = pc;
266 		cf.sr = status;
267 		hardclock(&cf);
268 		pmax_clock_evcnt.ev_count++;
269 
270 		/* keep clock interrupts enabled when we return */
271 		cause &= ~MIPS_INT_MASK_1;
272 	}
273 
274 	/* If clock interrupts were enabled, re-enable them ASAP. */
275 	_splset(MIPS_SR_INT_IE | (status & MIPS_INT_MASK_1));
276 
277 	if (ipending & MIPS_INT_MASK_0) {
278 		csr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
279 		csr &= (csr >> KN02_CSR_IOINTEN_SHIFT);
280 		if (csr & (KN02_IP_DZ | KN02_IP_LANCE | KN02_IP_SCSI)) {
281 			if (csr & KN02_IP_DZ)
282 				CALLINTR(SYS_DEV_SCC0);
283 			if (csr & KN02_IP_LANCE)
284 				CALLINTR(SYS_DEV_LANCE);
285 			if (csr & KN02_IP_SCSI)
286 				CALLINTR(SYS_DEV_SCSI);
287 		}
288 		if (csr & (KN02_IP_SLOT2 | KN02_IP_SLOT1 | KN02_IP_SLOT0)) {
289 			if (csr & KN02_IP_SLOT2)
290 				CALLINTR(SYS_DEV_OPT2);
291 			if (csr & KN02_IP_SLOT1)
292 				CALLINTR(SYS_DEV_OPT1);
293 			if (csr & KN02_IP_SLOT0)
294 				CALLINTR(SYS_DEV_OPT0);
295 		}
296 	}
297 	if (ipending & MIPS_INT_MASK_3) {
298 		dec_3max_errintr();
299 		pmax_memerr_evcnt.ev_count++;
300 	}
301 
302 	_splset(MIPS_SR_INT_IE | (status & ~cause & MIPS_HARD_INT_MASK));
303 }
304 
305 
306 /*
307  * Handle Memory error.   3max, 3maxplus has ECC.
308  * Correct single-bit error, panic on double-bit error.
309  * XXX on double-error on clean user page, mark bad and reload frame?
310  */
311 static void
312 dec_3max_errintr()
313 {
314 	u_int32_t erradr, errsyn, csr;
315 
316 	/* Fetch error address, ECC chk/syn bits, clear interrupt */
317 	erradr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR);
318 	errsyn = MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN);
319 	*(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0;
320 	kn02_wbflush();
321 	csr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
322 
323 	/* Send to kn02/kn03 memory subsystem handler */
324 	dec_mtasic_err(erradr, errsyn, csr & KN02_CSR_BNK32M);
325 }
326