ka43.c revision 1.9 1 /* $NetBSD: ka43.c,v 1.9 1998/06/20 18:46:19 ragge Exp $ */
2 /*
3 * Copyright (c) 1996 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 <vm/vm.h>
42 #include <vm/vm_kern.h>
43
44 #include <machine/pte.h>
45 #include <machine/cpu.h>
46 #include <machine/mtpr.h>
47 #include <machine/sid.h>
48 #include <machine/pmap.h>
49 #include <machine/nexus.h>
50 #include <machine/uvax.h>
51 #include <machine/vsbus.h>
52 #include <machine/ka43.h>
53 #include <machine/clock.h>
54
55 #include "smg.h"
56
57 void ka43_conf __P((struct device*, struct device*, void*));
58 void ka43_steal_pages __P((void));
59
60 int ka43_mchk __P((caddr_t));
61 void ka43_memerr __P((void));
62
63 void ka43_clear_errors __P((void));
64
65 int ka43_cache_init __P((void)); /* "int mapen" as argument? */
66 int ka43_cache_reset __P((void));
67 int ka43_cache_enable __P((void));
68 int ka43_cache_disable __P((void));
69 int ka43_cache_invalidate __P((void));
70
71 struct cpu_dep ka43_calls = {
72 ka43_steal_pages,
73 no_nicr_clock,
74 ka43_mchk,
75 ka43_memerr,
76 ka43_conf,
77 chip_clkread,
78 chip_clkwrite,
79 7, /* 7.6 VUP */
80 };
81
82 /*
83 * ka43_steal_pages() is called with MMU disabled, after that call MMU gets
84 * enabled. Thus we initialize these four pointers with physical addresses,
85 * but before leving ka43_steal_pages() we reset them to virtual addresses.
86 */
87 struct ka43_cpu *ka43_cpu = (void*)KA43_CPU_BASE;
88
89 u_int *ka43_creg = (void*)KA43_CH2_CREG;
90 u_int *ka43_ctag = (void*)KA43_CT2_BASE;
91
92 #define KA43_MC_RESTART 0x00008000 /* Restart possible*/
93 #define KA43_PSL_FPDONE 0x00010000 /* First Part Done */
94
95 struct ka43_mcframe { /* Format of RigelMAX machine check frame: */
96 int mc43_bcnt; /* byte count, always 24 (0x18) */
97 int mc43_code; /* machine check type code and restart bit */
98 int mc43_addr; /* most recent (faulting?) virtual address */
99 int mc43_viba; /* contents of VIBA register */
100 int mc43_sisr; /* ICCS bit 6 and SISR bits 15:0 */
101 int mc43_istate; /* internal state */
102 int mc43_sc; /* shift count register */
103 int mc43_pc; /* trapped PC */
104 int mc43_psl; /* trapped PSL */
105 };
106
107 static char *ka43_mctype[] = {
108 "no error (0)", /* Code 0: No error */
109 "FPA: protocol error", /* Code 1-5: FPA errors */
110 "FPA: illegal opcode",
111 "FPA: operand parity error",
112 "FPA: unknown status",
113 "FPA: result parity error",
114 "unused (6)", /* Code 6-7: Unused */
115 "unused (7)",
116 "MMU error (TLB miss)", /* Code 8-9: MMU errors */
117 "MMU error (TLB hit)",
118 "HW interrupt at unused IPL", /* Code 10: Interrupt error */
119 "MOVCx impossible state", /* Code 11-13: Microcode errors */
120 "undefined trap code (i-box)",
121 "undefined control store address",
122 "unused (14)", /* Code 14-15: Unused */
123 "unused (15)",
124 "PC tag or data parity error", /* Code 16: Cache error */
125 "data bus parity error", /* Code 17: Read error */
126 "data bus error (NXM)", /* Code 18: Write error */
127 "undefined data bus state", /* Code 19: Bus error */
128 };
129 #define MC43_MAX 19
130
131 static int ka43_error_count = 0;
132
133 int
134 ka43_mchk(addr)
135 caddr_t addr;
136 {
137 register struct ka43_mcframe *mcf = (void*)addr;
138
139 mtpr(0x00, PR_MCESR); /* Acknowledge the machine check */
140 printf("machine check %d (0x%x)\n", mcf->mc43_code, mcf->mc43_code);
141 printf("reason: %s\n", ka43_mctype[mcf->mc43_code & 0xff]);
142 if (++ka43_error_count > 10) {
143 printf("error_count exceeded: %d\n", ka43_error_count);
144 return (-1);
145 }
146
147 /*
148 * If either the Restart flag is set or the First-Part-Done flag
149 * is set, and the TRAP2 (double error) bit is not set, the the
150 * error is recoverable.
151 */
152 if (mfpr(PR_PCSTS) & KA43_PCS_TRAP2) {
153 printf("TRAP2 (double error) in ka43_mchk.\n");
154 panic("unrecoverable state in ka43_mchk.\n");
155 return (-1);
156 }
157 if ((mcf->mc43_code & KA43_MC_RESTART) ||
158 (mcf->mc43_psl & KA43_PSL_FPDONE)) {
159 printf("ka43_mchk: recovering from machine-check.\n");
160 ka43_cache_reset(); /* reset caches */
161 return (0); /* go on; */
162 }
163
164 /*
165 * Unknown error state, panic/halt the machine!
166 */
167 printf("ka43_mchk: unknown error state!\n");
168 return (-1);
169 }
170
171 void
172 ka43_memerr()
173 {
174 /*
175 * Don\'t know what to do here. So just print some messages
176 * and try to go on...
177 */
178 printf("memory error!\n");
179 printf("primary cache status: %b\n", mfpr(PR_PCSTS), KA43_PCSTS_BITS);
180 printf("secondary cache status: %b\n", *ka43_creg, KA43_SESR_BITS);
181 }
182
183 int
184 ka43_cache_init()
185 {
186 return (ka43_cache_reset());
187 }
188
189 void
190 ka43_clear_errors()
191 {
192 int val = *ka43_creg;
193 val |= KA43_SESR_SERR | KA43_SESR_LERR | KA43_SESR_CERR;
194 *ka43_creg = val;
195 }
196
197 int
198 ka43_cache_reset()
199 {
200 /*
201 * resetting primary and secondary caches is done in three steps:
202 * 1. disable both caches
203 * 2. manually clear secondary cache
204 * 3. enable both caches
205 */
206 ka43_cache_disable();
207 ka43_cache_invalidate();
208 ka43_cache_enable();
209
210 printf("primary cache status: %b\n", mfpr(PR_PCSTS), KA43_PCSTS_BITS);
211 printf("secondary cache status: %b\n", *ka43_creg, KA43_SESR_BITS);
212
213 return (0);
214 }
215
216 int
217 ka43_cache_disable()
218 {
219 int val;
220
221 /*
222 * first disable primary cache and clear error flags
223 */
224 mtpr(KA43_PCS_REFRESH, PR_PCSTS); /* disable primary cache */
225 val = mfpr(PR_PCSTS);
226 mtpr(val, PR_PCSTS); /* clear error flags */
227
228 /*
229 * now disable secondary cache and clear error flags
230 */
231 val = *ka43_creg & ~KA43_SESR_CENB; /* BICL !!! */
232 *ka43_creg = val; /* disable secondary cache */
233 val = KA43_SESR_SERR | KA43_SESR_LERR | KA43_SESR_CERR;
234 *ka43_creg = val; /* clear error flags */
235
236 return (0);
237 }
238
239 int
240 ka43_cache_invalidate()
241 {
242 int i, val;
243
244 val = KA43_PCTAG_PARITY; /* clear valid flag, set parity bit */
245 for (i = 0; i < 256; i++) { /* 256 Quadword entries */
246 mtpr(i*8, PR_PCIDX); /* write index of tag */
247 mtpr(val, PR_PCTAG); /* write value into tag */
248 }
249 val = KA43_PCS_FLUSH | KA43_PCS_REFRESH;
250 mtpr(val, PR_PCSTS); /* flush primary cache */
251
252 /*
253 * Rigel\'s secondary cache doesn\'t implement a valid-flag.
254 * Thus we initialize all entries with out-of-range/dummy
255 * addresses which will never be referenced (ie. never hit).
256 * After enabling cache we also access 128K of memory starting
257 * at 0x00 so that secondary cache will be filled with these
258 * valid addresses...
259 */
260 val = 0xff;
261 /* if (memory > 28 MB) val = 0x55; */
262 for (i = 0; i < KA43_CT2_SIZE; i+= 4) { /* Quadword entries ?? */
263 ka43_ctag[i/4] = val; /* reset upper and lower */
264 }
265
266 return (0);
267 }
268
269
270 int
271 ka43_cache_enable()
272 {
273 volatile char *membase = (void*)0x80000000; /* physical 0x00 */
274 int i, val;
275
276 val = KA43_PCS_FLUSH | KA43_PCS_REFRESH;
277 mtpr(val, PR_PCSTS); /* flush primary cache */
278
279 /*
280 * now we enable secondary cache and access first 128K of memory
281 * so that secondary cache gets really initialized and holds
282 * valid addresses/data...
283 */
284 *ka43_creg = KA43_SESR_CENB; /* enable secondary cache */
285 for (i=0; i<128*1024; i++) {
286 val += membase[i]; /* some dummy operation... */
287 }
288
289 val = KA43_PCS_ENABLE | KA43_PCS_REFRESH;
290 mtpr(val, PR_PCSTS); /* enable primary cache */
291
292 return (0);
293 }
294
295 void
296 ka43_conf(parent, self, aux)
297 struct device *parent, *self;
298 void *aux;
299 {
300
301 printf(": KA43\n");
302 /*
303 * ka43_conf() gets called with MMU enabled, now it's save to
304 * init/reset the caches.
305 */
306 ka43_cache_init();
307 }
308
309
310 /*
311 * The interface for communication with the LANCE ethernet controller
312 * is setup in the xxx_steal_pages() routine. We decrease highest
313 * available address by 64K and use this area as communication buffer.
314 */
315
316 void
317 ka43_steal_pages()
318 {
319 extern vm_offset_t avail_start, virtual_avail;
320 extern short *clk_page;
321 extern int clk_adrshift, clk_tweak;
322 int junk, val;
323
324 /*
325 * SCB is already copied/initialized at addr avail_start
326 * by pmap_bootstrap(), but it's not yet mapped. Thus we use
327 * the MAPPHYS() macro to reserve these two pages and to
328 * perform the mapping. The mapped address is assigned to junk.
329 */
330 MAPPHYS(junk, 2, VM_PROT_READ|VM_PROT_WRITE);
331
332 clk_adrshift = 1; /* Addressed at long's... */
333 clk_tweak = 2; /* ...and shift two */
334 MAPVIRT(clk_page, 2);
335 pmap_map((vm_offset_t)clk_page, (vm_offset_t)KA43_WAT_BASE,
336 (vm_offset_t)KA43_WAT_BASE + NBPG, VM_PROT_READ|VM_PROT_WRITE);
337
338 /* LANCE CSR */
339 MAPVIRT(lance_csr, 1);
340 pmap_map((vm_offset_t)lance_csr, (vm_offset_t)NI_BASE,
341 (vm_offset_t)NI_BASE + NBPG, VM_PROT_READ|VM_PROT_WRITE);
342
343 MAPVIRT(vs_cpu, 1);
344 pmap_map((vm_offset_t)vs_cpu, (vm_offset_t)VS_REGS,
345 (vm_offset_t)VS_REGS + NBPG, VM_PROT_READ|VM_PROT_WRITE);
346
347 MAPVIRT(dz_regs, 2);
348 pmap_map((vm_offset_t)dz_regs, (vm_offset_t)DZ_CSR,
349 (vm_offset_t)DZ_CSR + NBPG, VM_PROT_READ|VM_PROT_WRITE);
350
351 MAPVIRT(lance_addr, 1);
352 pmap_map((vm_offset_t)lance_addr, (vm_offset_t)NI_ADDR,
353 (vm_offset_t)NI_ADDR + NBPG, VM_PROT_READ|VM_PROT_WRITE);
354
355 /* 2nd level CCR */
356 MAPVIRT(ka43_creg, 1);
357 pmap_map((vm_offset_t)ka43_creg, (vm_offset_t)KA43_CH2_CREG,
358 (vm_offset_t)KA43_CH2_CREG + NBPG, VM_PROT_READ|VM_PROT_WRITE);
359
360 /* 2nd level CTA */
361 MAPVIRT(ka43_ctag, KA43_CT2_SIZE/NBPG);
362 pmap_map((vm_offset_t)ka43_ctag, (vm_offset_t)KA43_CT2_BASE,
363 (vm_offset_t)KA43_CT2_BASE + KA43_CT2_SIZE,
364 VM_PROT_READ|VM_PROT_WRITE);
365
366 /*
367 * Oh holy shit! It took me over one year(!) to find out that
368 * the 3100/76 has to use diag-mem instead of physical memory
369 * for communication with LANCE (using phys-mem results in
370 * parity errors and mchk exceptions with code 17 (0x11)).
371 *
372 * Many thanks to Matt Thomas, without his help it could have
373 * been some more years... ;-)
374 */
375 #define LEMEM (((int)le_iomem & ~KERNBASE)|KA43_DIAGMEM)
376 MAPPHYS(le_iomem, (NI_IOSIZE/NBPG), VM_PROT_READ|VM_PROT_WRITE);
377 pmap_map((vm_offset_t)le_iomem, LEMEM, LEMEM + NI_IOSIZE,
378 VM_PROT_READ|VM_PROT_WRITE);
379
380 #if NSMG > 0
381 if ((vax_confdata & 0x80) == 0) {
382 MAPVIRT(sm_addr, (SMSIZE / NBPG));
383 pmap_map((vm_offset_t)sm_addr, (vm_offset_t)SMADDR,
384 (vm_offset_t)SMADDR + SMSIZE, VM_PROT_READ|VM_PROT_WRITE);
385 ((struct vs_cpu *)VS_REGS)->vc_vdcorg = 0;
386 }
387 #endif
388
389 /*
390 * if LANCE\'s io-buffer is above 16 MB, then the appropriate flag
391 * in the parity control register has to be set (it works as an
392 * additional address bit). In any case, don\'t enable CPEN and
393 * DPEN in the PARCTL register, somewhow they are internally managed
394 * by the RIGEL chip itself!?!
395 */
396 val = ka43_cpu->parctl & 0x03; /* read the old value */
397 if (((int)le_iomem & ~KERNBASE) > 0xffffff)
398 val |= KA43_PCTL_DMA;
399 ka43_cpu->parctl = val; /* and write new value */
400
401 /*
402 * Clear restart and boot in progress flags in the CPMBX.
403 */
404 ((struct ka43_clock *)KA43_WAT_BASE)->cpmbx =
405 ((struct ka43_clock *)KA43_WAT_BASE)->cpmbx & 0xF0;
406
407 #if 0
408 /*
409 * Clear all error flags, not really neccessary here, this will
410 * be done by ka43_cache_init() anyway...
411 */
412 ka43_clear_errors();
413 #endif
414
415 /*
416 * MM is not yet enabled, thus we still used the physical addresses,
417 * but before leaving this routine, we need to reset them to virtual.
418 */
419 ka43_cpu = (void *)vs_cpu;
420 }
421