xref: /netbsd/sys/arch/vax/vax/ka670.c (revision bf9ec67e)
1 /*	$NetBSD: ka670.c,v 1.7 2000/08/09 03:02:54 tv Exp $	*/
2 /*
3  * Copyright (c) 1999 Ludd, University of Lule}, Sweden.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Ludd by Bertram Barth.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed at Ludd, University of
19  *	Lule}, Sweden and its contributors.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <sys/param.h>
36 #include <sys/types.h>
37 #include <sys/device.h>
38 #include <sys/kernel.h>
39 #include <sys/systm.h>
40 
41 #include <uvm/uvm_extern.h>
42 
43 #include <machine/pte.h>
44 #include <machine/cpu.h>
45 #include <machine/mtpr.h>
46 #include <machine/sid.h>
47 #include <machine/pmap.h>
48 #include <machine/nexus.h>
49 #include <machine/uvax.h>
50 #include <machine/vsbus.h>
51 #include <machine/ka670.h>
52 #include <machine/clock.h>
53 
54 static	void ka670_conf __P((void));
55 
56 static	int ka670_mchk __P((caddr_t));
57 static	void ka670_memerr __P((void));
58 static	int ka670_cache_init __P((void));	/* "int mapen" as argument? */
59 static	void ka670_halt __P((void));
60 static	void ka670_reboot __P((int));
61 
62 struct	cpu_dep ka670_calls = {
63 	0,
64 	ka670_mchk,
65 	ka670_memerr,
66 	ka670_conf,
67 	generic_clkread,
68 	generic_clkwrite,
69 	8,	/* 8 VUP */
70 	2,	/* SCB pages */
71 	ka670_halt,
72 	ka670_reboot,
73 	0,
74 };
75 
76 #define KA670_MC_RESTART	0x00008000	/* Restart possible*/
77 #define KA670_PSL_FPDONE	0x00010000	/* First Part Done */
78 
79 struct ka670_mcframe {		/* Format of RigelMAX machine check frame: */
80 	int	mc670_bcnt;	/* byte count, always 24 (0x18) */
81 	int	mc670_code;	/* machine check type code and restart bit */
82 	int	mc670_addr;	/* most recent (faulting?) virtual address */
83 	int	mc670_viba;	/* contents of VIBA register */
84 	int	mc670_sisr;	/* ICCS bit 6 and SISR bits 15:0 */
85 	int	mc670_istate;	/* internal state */
86 	int	mc670_sc;	/* shift count register */
87 	int	mc670_pc;	/* trapped PC */
88 	int	mc670_psl;	/* trapped PSL */
89 };
90 
91 #if 0
92 
93 /*
94  * This is not the mchk types on KA670.
95  */
96 static char *ka670_mctype[] = {
97 	"no error (0)",			/* Code 0: No error */
98 	"FPA: protocol error",		/* Code 1-5: FPA errors */
99 	"FPA: illegal opcode",
100 	"FPA: operand parity error",
101 	"FPA: unknown status",
102 	"FPA: result parity error",
103 	"unused (6)",			/* Code 6-7: Unused */
104 	"unused (7)",
105 	"MMU error (TLB miss)",		/* Code 8-9: MMU errors */
106 	"MMU error (TLB hit)",
107 	"HW interrupt at unused IPL",	/* Code 10: Interrupt error */
108 	"MOVCx impossible state",	/* Code 11-13: Microcode errors */
109 	"undefined trap code (i-box)",
110 	"undefined control store address",
111 	"unused (14)",			/* Code 14-15: Unused */
112 	"unused (15)",
113 	"PC tag or data parity error",	/* Code 16: Cache error */
114 	"data bus parity error",	/* Code 17: Read error */
115 	"data bus error (NXM)",		/* Code 18: Write error */
116 	"undefined data bus state",	/* Code 19: Bus error */
117 };
118 #define MC670_MAX	19
119 #endif
120 
121 static int ka670_error_count = 0;
122 
123 int
124 ka670_mchk(addr)
125 	caddr_t addr;
126 {
127 	register struct ka670_mcframe *mcf = (void*)addr;
128 
129 	mtpr(0x00, PR_MCESR);	/* Acknowledge the machine check */
130 	printf("machine check %d (0x%x)\n", mcf->mc670_code, mcf->mc670_code);
131 	printf("PC %x PSL %x\n", mcf->mc670_pc, mcf->mc670_psl);
132 	if (++ka670_error_count > 10) {
133 		printf("error_count exceeded: %d\n", ka670_error_count);
134 		return (-1);
135 	}
136 
137 	/*
138 	 * If either the Restart flag is set or the First-Part-Done flag
139 	 * is set, and the TRAP2 (double error) bit is not set, then the
140 	 * error is recoverable.
141 	 */
142 	if (mfpr(PR_PCSTS) & KA670_PCS_TRAP2) {
143 		printf("TRAP2 (double error) in ka670_mchk.\n");
144 		panic("unrecoverable state in ka670_mchk.\n");
145 		return (-1);
146 	}
147 	if ((mcf->mc670_code & KA670_MC_RESTART) ||
148 	    (mcf->mc670_psl & KA670_PSL_FPDONE)) {
149 		printf("ka670_mchk: recovering from machine-check.\n");
150 		ka670_cache_init();	/* reset caches */
151 		return (0);		/* go on; */
152 	}
153 
154 	/*
155 	 * Unknown error state, panic/halt the machine!
156 	 */
157 	printf("ka670_mchk: unknown error state!\n");
158 	return (-1);
159 }
160 
161 void
162 ka670_memerr()
163 {
164 	char sbuf[256];
165 
166 	/*
167 	 * Don\'t know what to do here. So just print some messages
168 	 * and try to go on...
169 	 */
170 
171 	printf("memory error!\n");
172 
173 	bitmask_snprintf(mfpr(PR_PCSTS), KA670_PCSTS_BITS, sbuf, sizeof(sbuf));
174 	printf("primary cache status: %s\n", sbuf);
175 
176 	bitmask_snprintf(mfpr(PR_BCSTS), KA670_BCSTS_BITS, sbuf, sizeof(sbuf));
177 	printf("secondary cache status: %s\n", sbuf);
178 }
179 
180 int
181 ka670_cache_init()
182 {
183 	int val;
184 #ifdef DEBUG
185 	char sbuf[256];
186 #endif
187 
188 	mtpr(KA670_PCS_REFRESH, PR_PCSTS);	/* disable primary cache */
189 	val = mfpr(PR_PCSTS);
190 	mtpr(val, PR_PCSTS);			/* clear error flags */
191 	mtpr(8, PR_BCCTL);			/* disable backup cache */
192 	mtpr(0, PR_BCFBTS);	/* flush backup cache tag store */
193 	mtpr(0, PR_BCFPTS);	/* flush primary cache tag store */
194 	mtpr(0x0e, PR_BCCTL);	/* enable backup cache */
195 	mtpr(KA670_PCS_FLUSH | KA670_PCS_REFRESH, PR_PCSTS);	/* flush primary cache */
196 	mtpr(KA670_PCS_ENABLE | KA670_PCS_REFRESH, PR_PCSTS);	/* flush primary cache */
197 
198 #ifdef DEBUG
199 	bitmask_snprintf(mfpr(PR_PCSTS), KA670_PCSTS_BITS, sbuf, sizeof(sbuf));
200 	printf("primary cache status: %s\n", sbuf);
201 
202 	bitmask_snprintf(mfpr(PR_BCSTS), KA670_BCSTS_BITS, sbuf, sizeof(sbuf));
203 	printf("secondary cache status: %s\n", sbuf);
204 #endif
205 
206 	return (0);
207 }
208 void
209 ka670_conf()
210 {
211 	printf("cpu0: KA670, ucode rev %d\n", vax_cpudata % 0377);
212 
213 	/*
214 	 * ka670_conf() gets called with MMU enabled, now it's save to
215 	 * init/reset the caches.
216 	 */
217 	ka670_cache_init();
218 }
219 
220 static void
221 ka670_halt()
222 {
223 	asm("halt");
224 }
225 
226 static void
227 ka670_reboot(arg)
228 	int arg;
229 {
230 	asm("halt");
231 }
232 
233