xref: /netbsd/sys/arch/vax/vax/ka670.c (revision c4a72b64)
1 /*	$NetBSD: ka670.c,v 1.9 2002/09/28 09:53:08 ragge 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 
60 struct	cpu_dep ka670_calls = {
61 	0,
62 	ka670_mchk,
63 	ka670_memerr,
64 	ka670_conf,
65 	generic_clkread,
66 	generic_clkwrite,
67 	8,	/* 8 VUP */
68 	2,	/* SCB pages */
69 	generic_halt,
70 	generic_reboot,
71 	0,
72 };
73 
74 #define KA670_MC_RESTART	0x00008000	/* Restart possible*/
75 #define KA670_PSL_FPDONE	0x00010000	/* First Part Done */
76 
77 struct ka670_mcframe {		/* Format of RigelMAX machine check frame: */
78 	int	mc670_bcnt;	/* byte count, always 24 (0x18) */
79 	int	mc670_code;	/* machine check type code and restart bit */
80 	int	mc670_addr;	/* most recent (faulting?) virtual address */
81 	int	mc670_viba;	/* contents of VIBA register */
82 	int	mc670_sisr;	/* ICCS bit 6 and SISR bits 15:0 */
83 	int	mc670_istate;	/* internal state */
84 	int	mc670_sc;	/* shift count register */
85 	int	mc670_pc;	/* trapped PC */
86 	int	mc670_psl;	/* trapped PSL */
87 };
88 
89 #if 0
90 
91 /*
92  * This is not the mchk types on KA670.
93  */
94 static char *ka670_mctype[] = {
95 	"no error (0)",			/* Code 0: No error */
96 	"FPA: protocol error",		/* Code 1-5: FPA errors */
97 	"FPA: illegal opcode",
98 	"FPA: operand parity error",
99 	"FPA: unknown status",
100 	"FPA: result parity error",
101 	"unused (6)",			/* Code 6-7: Unused */
102 	"unused (7)",
103 	"MMU error (TLB miss)",		/* Code 8-9: MMU errors */
104 	"MMU error (TLB hit)",
105 	"HW interrupt at unused IPL",	/* Code 10: Interrupt error */
106 	"MOVCx impossible state",	/* Code 11-13: Microcode errors */
107 	"undefined trap code (i-box)",
108 	"undefined control store address",
109 	"unused (14)",			/* Code 14-15: Unused */
110 	"unused (15)",
111 	"PC tag or data parity error",	/* Code 16: Cache error */
112 	"data bus parity error",	/* Code 17: Read error */
113 	"data bus error (NXM)",		/* Code 18: Write error */
114 	"undefined data bus state",	/* Code 19: Bus error */
115 };
116 #define MC670_MAX	19
117 #endif
118 
119 static int ka670_error_count = 0;
120 
121 int
122 ka670_mchk(addr)
123 	caddr_t addr;
124 {
125 	register struct ka670_mcframe *mcf = (void*)addr;
126 
127 	mtpr(0x00, PR_MCESR);	/* Acknowledge the machine check */
128 	printf("machine check %d (0x%x)\n", mcf->mc670_code, mcf->mc670_code);
129 	printf("PC %x PSL %x\n", mcf->mc670_pc, mcf->mc670_psl);
130 	if (++ka670_error_count > 10) {
131 		printf("error_count exceeded: %d\n", ka670_error_count);
132 		return (-1);
133 	}
134 
135 	/*
136 	 * If either the Restart flag is set or the First-Part-Done flag
137 	 * is set, and the TRAP2 (double error) bit is not set, then the
138 	 * error is recoverable.
139 	 */
140 	if (mfpr(PR_PCSTS) & KA670_PCS_TRAP2) {
141 		printf("TRAP2 (double error) in ka670_mchk.\n");
142 		panic("unrecoverable state in ka670_mchk.");
143 		return (-1);
144 	}
145 	if ((mcf->mc670_code & KA670_MC_RESTART) ||
146 	    (mcf->mc670_psl & KA670_PSL_FPDONE)) {
147 		printf("ka670_mchk: recovering from machine-check.\n");
148 		ka670_cache_init();	/* reset caches */
149 		return (0);		/* go on; */
150 	}
151 
152 	/*
153 	 * Unknown error state, panic/halt the machine!
154 	 */
155 	printf("ka670_mchk: unknown error state!\n");
156 	return (-1);
157 }
158 
159 void
160 ka670_memerr()
161 {
162 	char sbuf[256];
163 
164 	/*
165 	 * Don\'t know what to do here. So just print some messages
166 	 * and try to go on...
167 	 */
168 
169 	printf("memory error!\n");
170 
171 	bitmask_snprintf(mfpr(PR_PCSTS), KA670_PCSTS_BITS, sbuf, sizeof(sbuf));
172 	printf("primary cache status: %s\n", sbuf);
173 
174 	bitmask_snprintf(mfpr(PR_BCSTS), KA670_BCSTS_BITS, sbuf, sizeof(sbuf));
175 	printf("secondary cache status: %s\n", sbuf);
176 }
177 
178 int
179 ka670_cache_init()
180 {
181 	int val;
182 #ifdef DEBUG
183 	char sbuf[256];
184 #endif
185 
186 	mtpr(KA670_PCS_REFRESH, PR_PCSTS);	/* disable primary cache */
187 	val = mfpr(PR_PCSTS);
188 	mtpr(val, PR_PCSTS);			/* clear error flags */
189 	mtpr(8, PR_BCCTL);			/* disable backup cache */
190 	mtpr(0, PR_BCFBTS);	/* flush backup cache tag store */
191 	mtpr(0, PR_BCFPTS);	/* flush primary cache tag store */
192 	mtpr(0x0e, PR_BCCTL);	/* enable backup cache */
193 	mtpr(KA670_PCS_FLUSH | KA670_PCS_REFRESH, PR_PCSTS);	/* flush primary cache */
194 	mtpr(KA670_PCS_ENABLE | KA670_PCS_REFRESH, PR_PCSTS);	/* flush primary cache */
195 
196 #ifdef DEBUG
197 	bitmask_snprintf(mfpr(PR_PCSTS), KA670_PCSTS_BITS, sbuf, sizeof(sbuf));
198 	printf("primary cache status: %s\n", sbuf);
199 
200 	bitmask_snprintf(mfpr(PR_BCSTS), KA670_BCSTS_BITS, sbuf, sizeof(sbuf));
201 	printf("secondary cache status: %s\n", sbuf);
202 #endif
203 
204 	return (0);
205 }
206 void
207 ka670_conf()
208 {
209 	printf("cpu0: KA670, ucode rev %d\n", vax_cpudata % 0377);
210 
211 	/*
212 	 * ka670_conf() gets called with MMU enabled, now it's save to
213 	 * init/reset the caches.
214 	 */
215 	ka670_cache_init();
216 
217 	cpmbx = (struct cpmbx *)vax_map_physmem(0x20140400, 1);
218 }
219