xref: /netbsd-src/sys/arch/vax/vax/ka670.c (revision ee918b29e1ca494b866845d941c9d30ab6dca848)
1 /*	$NetBSD: ka670.c,v 1.17 2017/05/22 16:46:15 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  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: ka670.c,v 1.17 2017/05/22 16:46:15 ragge Exp $");
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/cpu.h>
35 #include <sys/device.h>
36 #include <sys/kernel.h>
37 
38 #include <machine/sid.h>
39 #include <machine/nexus.h>
40 #include <machine/vsbus.h>
41 #include <machine/ka670.h>
42 #include <machine/clock.h>
43 
44 static void ka670_memerr(void);
45 static void ka670_conf(void);
46 static void ka670_attach_cpu(device_t);
47 static int ka670_mchk(void *);
48 static int ka670_cache_init(void);	/* "int mapen" as argument? */
49 
50 static const char * const ka670_devs[] = { "cpu", "sgec", "shac", "uba", NULL };
51 
52 const struct cpu_dep ka670_calls = {
53 	.cpu_mchk	= ka670_mchk,
54 	.cpu_memerr	= ka670_memerr,
55 	.cpu_conf	= ka670_conf,
56 	.cpu_gettime	= generic_gettime,
57 	.cpu_settime	= generic_settime,
58 	.cpu_vups	= 8,	/* 8 VUP */
59 	.cpu_scbsz	= 2,	/* SCB pages */
60 	.cpu_halt	= generic_halt,
61 	.cpu_reboot	= generic_reboot,
62 	.cpu_devs	= ka670_devs,
63 	.cpu_attach_cpu	= ka670_attach_cpu,
64 };
65 
66 #define KA670_MC_RESTART	0x00008000	/* Restart possible*/
67 #define KA670_PSL_FPDONE	0x00010000	/* First Part Done */
68 
69 struct ka670_mcframe {		/* Format of RigelMAX machine check frame: */
70 	int	mc670_bcnt;	/* byte count, always 24 (0x18) */
71 	int	mc670_code;	/* machine check type code and restart bit */
72 	int	mc670_addr;	/* most recent (faulting?) virtual address */
73 	int	mc670_viba;	/* contents of VIBA register */
74 	int	mc670_sisr;	/* ICCS bit 6 and SISR bits 15:0 */
75 	int	mc670_istate;	/* internal state */
76 	int	mc670_sc;	/* shift count register */
77 	int	mc670_pc;	/* trapped PC */
78 	int	mc670_psl;	/* trapped PSL */
79 };
80 
81 #if 0
82 
83 /*
84  * This is not the mchk types on KA670.
85  */
86 static const char * const ka670_mctype[] = {
87 	"no error (0)",			/* Code 0: No error */
88 	"FPA: protocol error",		/* Code 1-5: FPA errors */
89 	"FPA: illegal opcode",
90 	"FPA: operand parity error",
91 	"FPA: unknown status",
92 	"FPA: result parity error",
93 	"unused (6)",			/* Code 6-7: Unused */
94 	"unused (7)",
95 	"MMU error (TLB miss)",		/* Code 8-9: MMU errors */
96 	"MMU error (TLB hit)",
97 	"HW interrupt at unused IPL",	/* Code 10: Interrupt error */
98 	"MOVCx impossible state",	/* Code 11-13: Microcode errors */
99 	"undefined trap code (i-box)",
100 	"undefined control store address",
101 	"unused (14)",			/* Code 14-15: Unused */
102 	"unused (15)",
103 	"PC tag or data parity error",	/* Code 16: Cache error */
104 	"data bus parity error",	/* Code 17: Read error */
105 	"data bus error (NXM)",		/* Code 18: Write error */
106 	"undefined data bus state",	/* Code 19: Bus error */
107 };
108 #define MC670_MAX	19
109 #endif
110 
111 static int ka670_error_count = 0;
112 
113 int
ka670_mchk(void * addr)114 ka670_mchk(void *addr)
115 {
116 	struct ka670_mcframe * const mcf = addr;
117 
118 	mtpr(0x00, PR_MCESR);	/* Acknowledge the machine check */
119 	printf("machine check %d (0x%x)\n", mcf->mc670_code, mcf->mc670_code);
120 	printf("PC %x PSL %x\n", mcf->mc670_pc, mcf->mc670_psl);
121 	if (++ka670_error_count > 10) {
122 		printf("error_count exceeded: %d\n", ka670_error_count);
123 		return (-1);
124 	}
125 
126 	/*
127 	 * If either the Restart flag is set or the First-Part-Done flag
128 	 * is set, and the TRAP2 (double error) bit is not set, then the
129 	 * error is recoverable.
130 	 */
131 	if (mfpr(PR_PCSTS) & KA670_PCS_TRAP2) {
132 		printf("TRAP2 (double error) in ka670_mchk.\n");
133 		panic("unrecoverable state in ka670_mchk.");
134 		return (-1);
135 	}
136 	if ((mcf->mc670_code & KA670_MC_RESTART) ||
137 	    (mcf->mc670_psl & KA670_PSL_FPDONE)) {
138 		printf("ka670_mchk: recovering from machine-check.\n");
139 		ka670_cache_init();	/* reset caches */
140 		return (0);		/* go on; */
141 	}
142 
143 	/*
144 	 * Unknown error state, panic/halt the machine!
145 	 */
146 	printf("ka670_mchk: unknown error state!\n");
147 	return (-1);
148 }
149 
150 void
ka670_memerr(void)151 ka670_memerr(void)
152 {
153 	char sbuf[256];
154 
155 	/*
156 	 * Don\'t know what to do here. So just print some messages
157 	 * and try to go on...
158 	 */
159 
160 	printf("memory error!\n");
161 
162 	snprintb(sbuf, sizeof(sbuf), KA670_PCSTS_BITS, mfpr(PR_PCSTS));
163 	printf("primary cache status: %s\n", sbuf);
164 
165 	snprintb(sbuf, sizeof(sbuf), KA670_BCSTS_BITS, mfpr(PR_BCSTS));
166 	printf("secondary cache status: %s\n", sbuf);
167 }
168 
169 int
ka670_cache_init(void)170 ka670_cache_init(void)
171 {
172 	int val;
173 #ifdef DEBUG
174 	char sbuf[256];
175 #endif
176 
177 	mtpr(KA670_PCS_REFRESH, PR_PCSTS);	/* disable primary cache */
178 	val = mfpr(PR_PCSTS);
179 	mtpr(val, PR_PCSTS);			/* clear error flags */
180 	mtpr(8, PR_BCCTL);			/* disable backup cache */
181 	mtpr(0, PR_BCFBTS);	/* flush backup cache tag store */
182 	mtpr(0, PR_BCFPTS);	/* flush primary cache tag store */
183 	mtpr(0x0e, PR_BCCTL);	/* enable backup cache */
184 	mtpr(KA670_PCS_FLUSH | KA670_PCS_REFRESH, PR_PCSTS);	/* flush primary cache */
185 	mtpr(KA670_PCS_ENABLE | KA670_PCS_REFRESH, PR_PCSTS);	/* flush primary cache */
186 
187 #ifdef DEBUG
188 	snprintb(sbuf, sizeof(sbuf), KA670_PCSTS_BITS, mfpr(PR_PCSTS));
189 	printf("primary cache status: %s\n", sbuf);
190 
191 	snprintb(sbuf, sizeof(sbuf), KA670_BCSTS_BITS, mfpr(PR_BCSTS));
192 	printf("secondary cache status: %s\n", sbuf);
193 #endif
194 
195 	return (0);
196 }
197 
198 void
ka670_conf(void)199 ka670_conf(void)
200 {
201 
202 	/*
203 	 * ka670_conf() gets called with MMU enabled, now it's save to
204 	 * init/reset the caches.
205 	 */
206 	ka670_cache_init();
207 
208 	cpmbx = (struct cpmbx *)vax_map_physmem(0x20140400, 1);
209 }
210 
211 void
ka670_attach_cpu(device_t self)212 ka670_attach_cpu(device_t self)
213 {
214 	aprint_normal(
215 	    ": %s, Rigel (ucode rev %d), 2KB L1 cache, 128KB L2 cache\n",
216 	    "KA670",
217 	    vax_cpudata % 0377);
218 }
219