xref: /original-bsd/sys/vax/vax/machdep.c (revision 6c57d260)
1 /*	machdep.c	4.37	81/05/12	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #ifdef BBNNET
6 #include "../bbnnet/net.h"
7 #include "../bbnnet/ucb.h"
8 #endif BBNNET
9 #include "../h/dir.h"
10 #include "../h/user.h"
11 #include "../h/map.h"
12 #include "../h/reg.h"
13 #include "../h/mtpr.h"
14 #include "../h/clock.h"
15 #include "../h/pte.h"
16 #include "../h/vm.h"
17 #include "../h/proc.h"
18 #include "../h/psl.h"
19 #include "../h/buf.h"
20 #include "../h/ubavar.h"
21 #include "../h/ubareg.h"
22 #include "../h/cons.h"
23 #include "../h/reboot.h"
24 #include "../h/conf.h"
25 #include "../h/mem.h"
26 #include "../h/cpu.h"
27 #include "../h/inode.h"
28 #include "../h/file.h"
29 #include "../h/text.h"
30 #include "../h/clist.h"
31 #include "../h/callout.h"
32 #include "../h/cmap.h"
33 #include <frame.h>
34 #include "../h/port.h"
35 #include "../h/rpb.h"
36 
37 int	icode[] =
38 {
39 	0x9f19af9f,	/* pushab [&"init",0]; pushab */
40 	0x02dd09af,	/* "/etc/init"; pushl $2 */
41 	0xbc5c5ed0,	/* movl sp,ap; chmk */
42 	0x2ffe110b,	/* $exec; brb .; "/ */
43 	0x2f637465,	/* etc/ */
44 	0x74696e69,	/* init" */
45 	0x00000000,	/* \0\0\0";  0 */
46 	0x00000014,	/* [&"init", */
47 	0x00000000,	/* 0] */
48 };
49 int	szicode = sizeof(icode);
50 
51 /*
52  * Declare these as initialized data so we can patch them.
53  */
54 int	nbuf = 0;
55 int	nswbuf = 0;
56 
57 /*
58  * Machine-dependent startup code
59  */
60 startup(firstaddr)
61 	int firstaddr;
62 {
63 	register int unixsize;
64 	register unsigned i;
65 	register struct pte *pte;
66 	register caddr_t v;
67 
68 	/*
69 	 * Initialize error message buffer (at end of core).
70 	 */
71 	maxmem -= CLSIZE;
72 	pte = msgbufmap;
73 	for (i = 0; i < CLSIZE; i++)
74 		*(int *)pte++ = PG_V | PG_KW | (maxmem + i);
75 	mtpr(TBIA, 1);
76 
77 	/*
78 	 * Good {morning,afternoon,evening,night}.
79 	 */
80 	printf(version);
81 	printf("real mem  = %d\n", ctob(maxmem));
82 
83 	/*
84 	 * First determine how many buffers are reasonable.
85 	 * Current alg is 32 per megabyte, with min of 32.
86 	 * We allocate 1/2 as many swap buffer headers as file i/o buffers.
87 	 */
88 	if (nbuf == 0) {
89 		nbuf = (32 * physmem) / btoc(1024*1024);
90 		if (nbuf < 32)
91 			nbuf = 32;
92 	}
93 	if (nswbuf == 0) {
94 		nswbuf = (nbuf / 2) &~ 1;	/* force even */
95 		if (nswbuf > 256)
96 			nswbuf = 256;		/* sanity */
97 	}
98 
99 	/*
100 	 * Allocate space for system data structures.
101 	 */
102 	v = (caddr_t)(0x80000000 | (firstaddr * NBPG));
103 #define	valloc(name, type, num) \
104 	    (name) = (type *)(v); (v) = (caddr_t)((name)+(num))
105 #define	valloclim(name, type, num, lim) \
106 	    (name) = (type *)(v); (v) = (caddr_t)((lim) = ((name)+(num)))
107 	valloc(buffers, char, BSIZE*nbuf);
108 	valloc(buf, struct buf, nbuf);
109 	valloc(swbuf, struct buf, nswbuf);
110 	valloc(swsize, short, nswbuf);	/* note: nswbuf is even */
111 	valloc(swpf, int, nswbuf);
112 	valloclim(inode, struct inode, ninode, inodeNINODE);
113 	valloclim(file, struct file, nfile, fileNFILE);
114 	valloclim(proc, struct proc, nproc, procNPROC);
115 	valloclim(text, struct text, ntext, textNTEXT);
116 	valloc(port, struct port, nport);
117 	valloc(cfree, struct cblock, nclist);
118 	valloc(callout, struct callout, ncallout);
119 	valloc(swapmap, struct map, nswapmap = nproc * 2);
120 	valloc(argmap, struct map, ARGMAPSIZE);
121 	valloc(kernelmap, struct map, nproc);
122 #ifdef BBNNET
123 	valloc(netmap, struct map, nnetpages/2);
124 	valloc(freetab, struct pfree, nnetpages);
125 	valloclim(workfree, struct work, nwork, workNWORK);
126 	valloclim(contab, struct ucb, nnetcon, conNCON);
127 	valloclim(host, struct host, nhost, hostNHOST);
128 #endif BBNNET
129 	/*
130 	 * Now allocate space for core map
131 	 */
132 	ncmap = (physmem*NBPG - ((int)v &~ 0x80000000)) /
133 		    (NBPG*CLSIZE + sizeof (struct cmap));
134 	valloclim(cmap, struct cmap, ncmap, ecmap);
135 	if ((((int)(ecmap+1))&~0x80000000) > SYSPTSIZE*NBPG)
136 		panic("sys pt too small");
137 
138 	/*
139 	 * Clear allocated space, and make r/w entries
140 	 * for the space in the kernel map.
141 	 */
142 	unixsize = btoc((int)(ecmap+1) &~ 0x80000000);
143 	if (unixsize >= physmem - 8*UPAGES)
144 		panic("no memory");
145 	pte = &Sysmap[firstaddr];
146 	for (i = firstaddr; i < unixsize; i++) {
147 		*(int *)(&Sysmap[i]) = PG_V | PG_KW | i;
148 		clearseg(i);
149 	}
150 	mtpr(TBIA, 1);
151 
152 	/*
153 	 * Initialize callouts
154 	 */
155 	callfree = callout;
156 	for (i = 1; i < ncallout; i++)
157 		callout[i-1].c_next = &callout[i];
158 
159 	/*
160 	 * Initialize memory allocator and swap
161 	 * and user page table maps.
162 	 *
163 	 * THE USER PAGE TABLE MAP IS CALLED ``kernelmap''
164 	 * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME.
165 	 */
166 	meminit(unixsize, maxmem);
167 	maxmem = freemem;
168 	printf("avail mem = %d\n", ctob(maxmem));
169 	rminit(kernelmap, USRPTSIZE, 1, "usrpt", nproc);
170 
171 #ifdef BBNNET
172 	/*
173 	 * Initialize network buffer management map.
174 	 */
175 	rminit(netmap, nnetpages-1, 1, "netpage", nnetpages/2);
176 #endif BBNNET
177 
178 	/*
179 	 * Configure the system.
180 	 */
181 	configure();
182 
183 	/*
184 	 * Clear restart inhibit flags.
185 	 */
186 	tocons(TXDB_CWSI);
187 	tocons(TXDB_CCSI);
188 }
189 
190 /*
191  * set up a physical address
192  * into users virtual address space.
193  */
194 sysphys()
195 {
196 
197 	if(!suser())
198 		return;
199 	u.u_error = EINVAL;
200 }
201 
202 /*
203  * Initialze the clock, based on the time base which is, e.g.
204  * from a filesystem.  Base provides the time to within six months,
205  * and the time of year clock provides the rest.
206  */
207 clkinit(base)
208 	time_t base;
209 {
210 	register unsigned todr = mfpr(TODR);
211 	long deltat;
212 	int year = YRREF;
213 
214 	if (base < 5*SECYR) {
215 		printf("WARNING: preposterous time in file system");
216 		time = 6*SECYR + 186*SECDAY + SECDAY/2;
217 		clkset();
218 		goto check;
219 	}
220 	/*
221 	 * Have been told that VMS keeps time internally with base TODRZERO.
222 	 * If this is correct, then this routine and VMS should maintain
223 	 * the same date, and switching shouldn't be painful.
224 	 * (Unfortunately, VMS keeps local time, so when you run UNIX
225 	 * and VMS, VMS runs on GMT...).
226 	 */
227 	if (todr < TODRZERO) {
228 		printf("WARNING: todr too small");
229 		time = base;
230 		/*
231 		 * Believe the time in the file system for lack of
232 		 * anything better, resetting the TODR.
233 		 */
234 		clkset();
235 		goto check;
236 	}
237 	/*
238 	 * Sneak to within 6 month of the time in the filesystem,
239 	 * by starting with the time of the year suggested by the TODR,
240 	 * and advancing through succesive years.  Adding the number of
241 	 * seconds in the current year takes us to the end of the current year
242 	 * and then around into the next year to the same position.
243 	 */
244 	for (time = (todr-TODRZERO)/100; time < base-SECYR/2; time += SECYR) {
245 		if (LEAPYEAR(year))
246 			time += SECDAY;
247 		year++;
248 	}
249 
250 	/*
251 	 * See if we gained/lost two or more days;
252 	 * if so, assume something is amiss.
253 	 */
254 	deltat = time - base;
255 	if (deltat < 0)
256 		deltat = -deltat;
257 	if (deltat < 2*SECDAY)
258 		return;
259 	printf("WARNING: clock %s %d days",
260 	    time < base ? "lost" : "gained", deltat / SECDAY);
261 check:
262 	printf(" -- CHECK AND RESET THE DATE!\n");
263 }
264 
265 /*
266  * Reset the TODR based on the time value; used when the TODR
267  * has a preposterous value and also when the time is reset
268  * by the stime system call.  Also called when the TODR goes past
269  * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight)
270  * to wrap the TODR around.
271  */
272 clkset()
273 {
274 	int year = YRREF;
275 	unsigned secyr;
276 	unsigned yrtime = time;
277 
278 	/*
279 	 * Whittle the time down to an offset in the current year,
280 	 * by subtracting off whole years as long as possible.
281 	 */
282 	for (;;) {
283 		secyr = SECYR;
284 		if (LEAPYEAR(year))
285 			secyr += SECDAY;
286 		if (yrtime < secyr)
287 			break;
288 		yrtime -= secyr;
289 		year++;
290 	}
291 	mtpr(TODR, TODRZERO + yrtime*100);
292 }
293 
294 #ifdef PGINPROF
295 /*
296  * Return the difference (in microseconds)
297  * between the  current time and a previous
298  * time as represented  by the arguments.
299  * If there is a pending clock interrupt
300  * which has not been serviced due to high
301  * ipl, return error code.
302  */
303 vmtime(otime, olbolt, oicr)
304 	register int otime, olbolt, oicr;
305 {
306 
307 	if (mfpr(ICCS)&ICCS_INT)
308 		return(-1);
309 	else
310 		return(((time-otime)*60 + lbolt-olbolt)*16667 + mfpr(ICR)-oicr);
311 }
312 #endif
313 
314 /*
315  * Send an interrupt to process
316  *
317  * SHOULD CHANGE THIS TO PASS ONE MORE WORK SO THAT ALL INFORMATION
318  * PROVIDED BY HARDWARE IS AVAILABLE TO THE USER PROCESS.
319  */
320 sendsig(p, n)
321 	int (*p)();
322 {
323 	register int *usp, *regs;
324 
325 	regs = u.u_ar0;
326 	usp = (int *)regs[SP];
327 	usp -= 5;
328 	if ((int)usp <= USRSTACK - ctob(u.u_ssize))
329 		(void) grow((unsigned)usp);
330 	;			/* Avoid asm() label botch */
331 #ifndef lint
332 	asm("probew $3,$20,(r11)");
333 	asm("beql bad");
334 #else
335 	if (useracc((caddr_t)usp, 0x20, 1))
336 		goto bad;
337 #endif
338 	*usp++ = n;
339 	if (n == SIGILL || n == SIGFPE) {
340 		*usp++ = u.u_code;
341 		u.u_code = 0;
342 	} else
343 		*usp++ = 0;
344 	*usp++ = (int)p;
345 	*usp++ = regs[PC];
346 	*usp++ = regs[PS];
347 	regs[SP] = (int)(usp - 5);
348 	regs[PS] &= ~(PSL_CM|PSL_FPD);
349 	regs[PC] = (int)u.u_pcb.pcb_sigc;
350 	return;
351 
352 asm("bad:");
353 bad:
354 	/*
355 	 * Process has trashed its stack; give it an illegal
356 	 * instruction to halt it in its tracks.
357 	 */
358 	u.u_signal[SIGILL] = SIG_DFL;
359 	u.u_procp->p_siga0 &= ~(1<<(SIGILL-1));
360 	u.u_procp->p_siga1 &= ~(1<<(SIGILL-1));
361 	psignal(u.u_procp, SIGILL);
362 }
363 
364 dorti()
365 {
366 	struct frame frame;
367 	register int sp;
368 	register int reg, mask;
369 	extern int ipcreg[];
370 
371 	(void) copyin((caddr_t)u.u_ar0[FP], (caddr_t)&frame, sizeof (frame));
372 	sp = u.u_ar0[FP] + sizeof (frame);
373 	u.u_ar0[PC] = frame.fr_savpc;
374 	u.u_ar0[FP] = frame.fr_savfp;
375 	u.u_ar0[AP] = frame.fr_savap;
376 	mask = frame.fr_mask;
377 	for (reg = 0; reg <= 11; reg++) {
378 		if (mask&1) {
379 			u.u_ar0[ipcreg[reg]] = fuword((caddr_t)sp);
380 			sp += 4;
381 		}
382 		mask >>= 1;
383 	}
384 	sp += frame.fr_spa;
385 	u.u_ar0[PS] = (u.u_ar0[PS] & 0xffff0000) | frame.fr_psw;
386 	if (frame.fr_s)
387 		sp += 4 + 4 * (fuword((caddr_t)sp) & 0xff);
388 	/* phew, now the rei */
389 	u.u_ar0[PC] = fuword((caddr_t)sp);
390 	sp += 4;
391 	u.u_ar0[PS] = fuword((caddr_t)sp);
392 	sp += 4;
393 	u.u_ar0[PS] |= PSL_USERSET;
394 	u.u_ar0[PS] &= ~PSL_USERCLR;
395 	u.u_ar0[SP] = (int)sp;
396 }
397 
398 /*
399  * Memenable enables the memory controlle corrected data reporting.
400  * This runs at regular intervals, turning on the interrupt.
401  * The interrupt is turned off, per memory controller, when error
402  * reporting occurs.  Thus we report at most once per memintvl.
403  */
404 int	memintvl = MEMINTVL;
405 
406 memenable()
407 {
408 	register struct mcr *mcr;
409 	register int m;
410 
411 	for (m = 0; m < nmcr; m++) {
412 		mcr = mcraddr[m];
413 		switch (cpu) {
414 #if VAX780
415 		case VAX_780:
416 			M780_ENA(mcr);
417 			break;
418 #endif
419 #if VAX750
420 		case VAX_750:
421 			M750_ENA(mcr);
422 			break;
423 #endif
424 #if VAX7ZZ
425 		case VAX_7ZZ:
426 			M7ZZ_ENA(mcr);
427 			break;
428 #endif
429 		}
430 	}
431 	if (memintvl > 0)
432 		timeout(memenable, (caddr_t)0, memintvl);
433 }
434 
435 /*
436  * Memerr is the interrupt routine for corrected read data
437  * interrupts.  It looks to see which memory controllers have
438  * unreported errors, reports them, and disables further
439  * reporting for a time on those controller.
440  */
441 memerr()
442 {
443 	register struct mcr *mcr;
444 	register int m;
445 
446 	for (m = 0; m < nmcr; m++) {
447 		mcr = mcraddr[m];
448 		switch (cpu) {
449 #if VAX780
450 		case VAX_780:
451 			if (M780_ERR(mcr)) {
452 				printf("mcr%d: soft ecc addr %x syn %x\n",
453 				    m, M780_ADDR(mcr), M780_SYN(mcr));
454 				M780_INH(mcr);
455 			}
456 			break;
457 #endif
458 #if VAX750
459 		case VAX_750:
460 			if (M750_ERR(mcr)) {
461 				printf("mcr%d: soft ecc addr %x syn %x\n",
462 				    m, M750_ADDR(mcr), M750_SYN(mcr));
463 				M750_INH(mcr);
464 			}
465 			break;
466 #endif
467 #if VAX7ZZ
468 		case VAX_7ZZ:
469 			if (M7ZZ_ERR(mcr)) {
470 				struct mcr amcr;
471 				amcr.mc_reg[0] = mcr->mc_reg[0];
472 				printf("mcr%d: soft ecc addr %x syn %x\n",
473 				    m, M7ZZ_ADDR(&amcr), M7ZZ_SYN(&amcr));
474 				M7ZZ_INH(mcr);
475 			}
476 			break;
477 #endif
478 		}
479 	}
480 }
481 
482 /*
483  * Invalidate single all pte's in a cluster
484  */
485 tbiscl(v)
486 	unsigned v;
487 {
488 	register caddr_t addr;		/* must be first reg var */
489 	register int i;
490 
491 	asm(".set TBIS,58");
492 	addr = ptob(v);
493 	for (i = 0; i < CLSIZE; i++) {
494 #ifdef lint
495 		mtpr(TBIS, addr);
496 #else
497 		asm("mtpr r11,$TBIS");
498 #endif
499 		addr += NBPG;
500 	}
501 }
502 
503 int	waittime = -1;
504 
505 boot(paniced, arghowto)
506 	int paniced, arghowto;
507 {
508 	register int howto;		/* r11 == how to boot */
509 	register int devtype;		/* r10 == major of root dev */
510 
511 	howto = arghowto;
512 	if ((howto&RB_NOSYNC)==0 && waittime < 0 && bfreelist[0].b_forw) {
513 		waittime = 0;
514 		update();
515 		printf("syncing disks... ");
516 		while (++waittime <= 5)
517 			sleep((caddr_t)&lbolt, PZERO);
518 		printf("done\n");
519 	}
520 	splx(0x1f);			/* extreme priority */
521 	devtype = major(rootdev);
522 	if (howto&RB_HALT) {
523 		printf("halting (in tight loop); hit\n\t^P\n\tHALT\n\n");
524 		mtpr(IPL, 0x1f);
525 		for (;;)
526 			;
527 	} else {
528 		if (paniced == RB_PANIC)
529 			doadump();
530 		tocons(TXDB_BOOT);
531 	}
532 #if defined(VAX750) || defined(VAX7ZZ)
533 	if (cpu != VAX_780)
534 		{ asm("movl r11,r5"); }		/* boot flags go in r5 */
535 #endif
536 	for (;;)
537 		asm("halt");
538 #ifdef lint
539 	printf("howto %d, devtype %d\n", howto, devtype);
540 #endif
541 	/*NOTREACHED*/
542 }
543 
544 tocons(c)
545 {
546 
547 	while ((mfpr(TXCS)&TXCS_RDY) == 0)
548 		continue;
549 	mtpr(TXDB, c);
550 }
551 
552 /*
553  * Doadump comes here after turning off memory management and
554  * getting on the dump stack, either when called above, or by
555  * the auto-restart code.
556  */
557 dumpsys()
558 {
559 
560 	rpb.rp_flag = 1;
561 	if ((minor(dumpdev)&07) != 1)
562 		return;
563 	printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
564 	printf("dump ");
565 	switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
566 
567 	case ENXIO:
568 		printf("device bad\n");
569 		break;
570 
571 	case EFAULT:
572 		printf("device not ready\n");
573 		break;
574 
575 	case EINVAL:
576 		printf("area improper\n");
577 		break;
578 
579 	case EIO:
580 		printf("i/o error");
581 		break;
582 
583 	default:
584 		printf("succeeded");
585 		break;
586 	}
587 }
588 
589 /*
590  * Machine check error recovery code.
591  * Print out the machine check frame and then give up.
592  */
593 #if defined(VAX780) || defined(VAX750)
594 char *mc780[] = {
595 	"cp read",	"ctrl str par",	"cp tbuf par",	"cp cache par",
596 	"cp rdtimo", 	"cp rds",	"ucode lost",	0,
597 	0,		0,		"ib tbuf par",	0,
598 	"ib rds",	"ib rd timo",	0,		"ib cache par"
599 };
600 #endif
601 #if VAX7ZZ
602 #define	NMC7ZZ	12
603 char *mc7ZZ[] = {
604 	"tb par",	"bad retry",	"bad intr id",	"cant write ptem",
605 	"unkn mcr err",	"iib rd err",	"nxm ref",	"cp rds",
606 	"unalgn ioref",	"nonlw ioref",	"bad ioaddr",	"unalgn ubaddr",
607 };
608 #endif
609 
610 /*
611  * Frame for each cpu
612  */
613 struct mc780frame {
614 	int	mc8_bcnt;		/* byte count == 0x28 */
615 	int	mc8_summary;		/* summary parameter (as above) */
616 	int	mc8_cpues;		/* cpu error status */
617 	int	mc8_upc;		/* micro pc */
618 	int	mc8_vaviba;		/* va/viba register */
619 	int	mc8_dreg;		/* d register */
620 	int	mc8_tber0;		/* tbuf error reg 0 */
621 	int	mc8_tber1;		/* tbuf error reg 1 */
622 	int	mc8_timo;		/* timeout address divided by 4 */
623 	int	mc8_parity;		/* parity */
624 	int	mc8_sbier;		/* sbi error register */
625 	int	mc8_pc;			/* trapped pc */
626 	int	mc8_psl;		/* trapped psl */
627 };
628 struct mc750frame {
629 	int	mc5_bcnt;		/* byte count == 0x28 */
630 	int	mc5_summary;		/* summary parameter (as above) */
631 	int	mc5_va;			/* virtual address register */
632 	int	mc5_errpc;		/* error pc */
633 	int	mc5_mdr;
634 	int	mc5_svmode;		/* saved mode register */
635 	int	mc5_rdtimo;		/* read lock timeout */
636 	int	mc5_tbgpar;		/* tb group parity error register */
637 	int	mc5_cacherr;		/* cache error register */
638 	int	mc5_buserr;		/* bus error register */
639 	int	mc5_mcesr;		/* machine check status register */
640 	int	mc5_pc;			/* trapped pc */
641 	int	mc5_psl;		/* trapped psl */
642 };
643 struct mc7ZZframe {
644 	int	mc3_bcnt;		/* byte count == 0xc */
645 	int	mc3_summary;		/* summary parameter */
646 	int	mc3_parm[2];		/* parameter 1 and 2 */
647 	int	mc3_pc;			/* trapped pc */
648 	int	mc3_psl;		/* trapped psl */
649 };
650 
651 machinecheck(cmcf)
652 	caddr_t cmcf;
653 {
654 	register u_int type = ((struct mc780frame *)cmcf)->mc8_summary;
655 
656 	printf("machine check %x: ", type);
657 	switch (cpu) {
658 #if VAX780
659 	case VAX_780:
660 #endif
661 #if VAX750
662 	case VAX_750:
663 #endif
664 #if defined(VAX780) || defined(VAX750)
665 		printf("%s%s\n", mc780[type&0xf],
666 		    (type&0xf0) ? " abort" : " fault");
667 		break;
668 #endif
669 #if VAX7ZZ
670 	case VAX_7ZZ:
671 		if (type < NMC7ZZ)
672 			printf("%s", mc7ZZ[type]);
673 		printf("\n");
674 		break;
675 #endif
676 	}
677 	switch (cpu) {
678 #if VAX780
679 	case VAX_780: {
680 		register struct mc780frame *mcf = (struct mc780frame *)cmcf;
681 		register int sbifs;
682 		printf("\tcpues %x upc %x va/viba %x dreg %x tber %x %x\n",
683 		   mcf->mc8_cpues, mcf->mc8_upc, mcf->mc8_vaviba,
684 		   mcf->mc8_dreg, mcf->mc8_tber0, mcf->mc8_tber1);
685 		sbifs = mfpr(SBIFS);
686 		printf("\ttimo %x parity %x sbier %x pc %x psl %x sbifs %x\n",
687 		   mcf->mc8_timo*4, mcf->mc8_parity, mcf->mc8_sbier,
688 		   mcf->mc8_pc, mcf->mc8_psl, sbifs);
689 		/* THE FUNNY BITS IN THE FOLLOWING ARE FROM THE ``BLACK */
690 		/* BOOK AND SHOULD BE PUT IN AN ``sbi.h'' */
691 		mtpr(SBIFS, sbifs &~ 0x2000000);
692 		mtpr(SBIER, mfpr(SBIER) | 0x70c0);
693 		break;
694 	}
695 #endif
696 #if VAX750
697 	case VAX_750: {
698 		register struct mc750frame *mcf = (struct mc750frame *)cmcf;
699 		printf("\tva %x errpc %x mdr %x smr %x tbgpar %x cacherr %x\n",
700 		    mcf->mc5_va, mcf->mc5_errpc, mcf->mc5_mdr, mcf->mc5_svmode,
701 		    mcf->mc5_rdtimo, mcf->mc5_tbgpar, mcf->mc5_cacherr);
702 		printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n",
703 		    mcf->mc5_buserr, mcf->mc5_mcesr, mcf->mc5_pc, mcf->mc5_psl,
704 		    mfpr(MCSR));
705 		mtpr(MCESR, 0xf);
706 		break;
707 		}
708 #endif
709 #if VAX7ZZ
710 	case VAX_7ZZ: {
711 		register struct mc7ZZframe *mcf = (struct mc7ZZframe *)cmcf;
712 		printf("params %x,%x pc %x psl %x mcesr %x\n",
713 		    mcf->mc3_parm[0], mcf->mc3_parm[1],
714 		    mcf->mc3_pc, mcf->mc3_psl, mfpr(MCESR));
715 		mtpr(MCESR, 0xf);
716 		break;
717 		}
718 #endif
719 	}
720 	panic("mchk");
721 }
722