xref: /original-bsd/sys/vax/vax/machdep.c (revision f0fd5f8a)
1 /*	machdep.c	4.72	82/12/17	*/
2 
3 #include "../machine/reg.h"
4 #include "../machine/pte.h"
5 #include "../machine/psl.h"
6 
7 #include "../h/param.h"
8 #include "../h/systm.h"
9 #include "../h/dir.h"
10 #include "../h/user.h"
11 #include "../h/kernel.h"
12 #include "../h/map.h"
13 #include "../h/vm.h"
14 #include "../h/proc.h"
15 #include "../h/buf.h"
16 #include "../h/reboot.h"
17 #include "../h/conf.h"
18 #include "../h/inode.h"
19 #include "../h/file.h"
20 #include "../h/text.h"
21 #include "../h/clist.h"
22 #include "../h/callout.h"
23 #include "../h/cmap.h"
24 #include <frame.h>
25 #include "../h/mbuf.h"
26 #include "../h/msgbuf.h"
27 #include "../h/quota.h"
28 
29 #include "../vax/cons.h"
30 #include "../vax/cpu.h"
31 #include "../vax/mem.h"
32 #include "../vax/mtpr.h"
33 #include "../vax/rpb.h"
34 #include "../vaxuba/ubavar.h"
35 #include "../vaxuba/ubareg.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 #ifdef MUSH
52 int	mcode[] =
53 {
54 	0x9f19af9f,	/* pushab [&"mush",0]; pushab */
55 	0x02dd09af,	/* "/etc/mush"; pushl $2 */
56 	0xbc5c5ed0,	/* movl sp,ap; chmk */
57 	0x2f01bc0b,	/* $exec; chmk $exit; "/ */
58 	0x2f637465,	/* etc/ */
59 	0x6873756d,	/* mush" */
60 	0x00000000,	/* \0\0\0";  0 */
61 	0x00000014,	/* [&"mush", */
62 	0x00000000,	/* 0] */
63 };
64 int	szmcode = sizeof(mcode);
65 #endif
66 
67 /*
68  * Declare these as initialized data so we can patch them.
69  */
70 int	nbuf = 0;
71 int	nswbuf = 0;
72 
73 /*
74  * Machine-dependent startup code
75  */
76 startup(firstaddr)
77 	int firstaddr;
78 {
79 	register int unixsize;
80 	register unsigned i;
81 	register struct pte *pte;
82 	int mapaddr, j;
83 	register caddr_t v;
84 
85 	/*
86 	 * Initialize error message buffer (at end of core).
87 	 */
88 	maxmem -= btoc(sizeof (struct msgbuf));
89 	pte = msgbufmap;
90 	for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
91 		*(int *)pte++ = PG_V | PG_KW | (maxmem + i);
92 	mtpr(TBIA, 1);
93 
94 	/*
95 	 * Good {morning,afternoon,evening,night}.
96 	 */
97 	printf(version);
98 	printf("real mem  = %d\n", ctob(maxmem));
99 
100 	/*
101 	 * Determine how many buffers to allocate.
102 	 * Use 10% of memory, with min of 16.
103 	 * We allocate 1/2 as many swap buffer headers as file i/o buffers.
104 	 */
105 	if (nbuf == 0) {
106 		nbuf = ((physmem * NBPG) / 10) / (2 * CLBYTES);
107 		if (nbuf < 16)
108 			nbuf = 16;
109 	}
110 	if (nswbuf == 0) {
111 		nswbuf = (nbuf / 2) &~ 1;	/* force even */
112 		if (nswbuf > 256)
113 			nswbuf = 256;		/* sanity */
114 	}
115 
116 	/*
117 	 * Allocate space for system data structures.
118 	 * The first available real memory address is in "firstaddr".
119 	 * As pages of memory are allocated, "firstaddr" is incremented.
120 	 * The first available kernel virtual address is in "v".
121 	 * As pages of kernel virtual memory are allocated, "v" is incremented.
122 	 * An index into the kernel page table corresponding to the
123 	 * virtual memory address maintained in "v" is kept in "mapaddr".
124 	 */
125 	mapaddr = firstaddr;
126 	v = (caddr_t)(0x80000000 | (firstaddr * NBPG));
127 #define	valloc(name, type, num) \
128 	    (name) = (type *)(v); (v) = (caddr_t)((name)+(num))
129 #define	valloclim(name, type, num, lim) \
130 	    (name) = (type *)(v); (v) = (caddr_t)((lim) = ((name)+(num)))
131 	valloc(buffers, char, MAXBSIZE * nbuf);
132 	for (i = 0; i < nbuf; i++) {
133 		for (j = 0; j < 2 * CLSIZE; j++) {
134 			*(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr;
135 			clearseg((unsigned)firstaddr);
136 			firstaddr++;
137 		}
138 		mapaddr += MAXBSIZE / NBPG;
139 	}
140 	valloc(buf, struct buf, nbuf);
141 	valloc(swbuf, struct buf, nswbuf);
142 	valloc(swsize, short, nswbuf);	/* note: nswbuf is even */
143 	valloc(swpf, int, nswbuf);
144 	valloclim(inode, struct inode, ninode, inodeNINODE);
145 	valloclim(file, struct file, nfile, fileNFILE);
146 	valloclim(proc, struct proc, nproc, procNPROC);
147 	valloclim(text, struct text, ntext, textNTEXT);
148 	valloc(cfree, struct cblock, nclist);
149 	valloc(callout, struct callout, ncallout);
150 	valloc(swapmap, struct map, nswapmap = nproc * 2);
151 	valloc(argmap, struct map, ARGMAPSIZE);
152 	valloc(kernelmap, struct map, nproc);
153 	valloc(mbmap, struct map, nmbclusters/4);
154 #ifdef QUOTA
155 	valloclim(quota, struct quota, nquota, quotaNQUOTA);
156 	valloclim(dquot, struct dquot, ndquot, dquotNDQUOT);
157 #endif
158 	/*
159 	 * Now allocate space for core map
160 	 * Allow space for all of phsical memory minus the amount
161 	 * dedicated to the system. The amount of physical memory
162 	 * dedicated to the system is the total virtual memory of
163 	 * the system minus the space in the buffers which is not
164 	 * allocated real memory.
165 	 */
166 	ncmap = (physmem*NBPG - ((int)v &~ 0x80000000) +
167 		(nbuf * (MAXBSIZE - 2 * CLBYTES))) /
168 		    (NBPG*CLSIZE + sizeof (struct cmap));
169 	valloclim(cmap, struct cmap, ncmap, ecmap);
170 	if ((((int)(ecmap+1))&~0x80000000) > SYSPTSIZE*NBPG)
171 		panic("sys pt too small");
172 
173 	/*
174 	 * Clear allocated space, and make r/w entries
175 	 * for the space in the kernel map.
176 	 */
177 	unixsize = btoc((int)(ecmap+1) &~ 0x80000000);
178 	for (i = mapaddr; i < unixsize; i++) {
179 		*(int *)(&Sysmap[i]) = PG_V | PG_KW | firstaddr;
180 		clearseg((unsigned)firstaddr);
181 		firstaddr++;
182 	}
183 	if (firstaddr >= physmem - 8*UPAGES)
184 		panic("no memory");
185 	mtpr(TBIA, 1);
186 
187 	/*
188 	 * Initialize callouts
189 	 */
190 	callfree = callout;
191 	for (i = 1; i < ncallout; i++)
192 		callout[i-1].c_next = &callout[i];
193 
194 	/*
195 	 * Initialize memory allocator and swap
196 	 * and user page table maps.
197 	 *
198 	 * THE USER PAGE TABLE MAP IS CALLED ``kernelmap''
199 	 * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME.
200 	 */
201 	meminit(firstaddr, maxmem);
202 	maxmem = freemem;
203 	printf("avail mem = %d\n", ctob(maxmem));
204 	rminit(kernelmap, (long)USRPTSIZE, (long)1,
205 	    "usrpt", nproc);
206 	rminit(mbmap, (long)((nmbclusters - 1) * CLSIZE), (long)CLSIZE,
207 	    "mbclusters", nmbclusters/4);
208 
209 	/*
210 	 * Configure the system.
211 	 */
212 	configure();
213 
214 	/*
215 	 * Clear restart inhibit flags.
216 	 */
217 	tocons(TXDB_CWSI);
218 	tocons(TXDB_CCSI);
219 }
220 
221 #ifdef PGINPROF
222 /*
223  * Return the difference (in microseconds)
224  * between the  current time and a previous
225  * time as represented  by the arguments.
226  * If there is a pending clock interrupt
227  * which has not been serviced due to high
228  * ipl, return error code.
229  */
230 vmtime(otime, olbolt, oicr)
231 	register int otime, olbolt, oicr;
232 {
233 
234 	if (mfpr(ICCS)&ICCS_INT)
235 		return(-1);
236 	else
237 		return(((time.tv_sec-otime)*60 + lbolt-olbolt)*16667 + mfpr(ICR)-oicr);
238 }
239 #endif
240 
241 /*
242  * Send an interrupt to process
243  *
244  * SHOULD CHANGE THIS TO PASS ONE MORE WORD SO THAT ALL INFORMATION
245  * PROVIDED BY HARDWARE IS AVAILABLE TO THE USER PROCESS.
246  */
247 sendsig(p, n)
248 	int (*p)();
249 {
250 	register int *usp, *regs;
251 
252 	regs = u.u_ar0;
253 	usp = (int *)regs[SP];
254 	usp -= 5;
255 	if ((int)usp <= USRSTACK - ctob(u.u_ssize))
256 		(void) grow((unsigned)usp);
257 	;			/* Avoid asm() label botch */
258 #ifndef lint
259 	asm("probew $3,$20,(r11)");
260 	asm("beql bad");
261 #else
262 	if (useracc((caddr_t)usp, 0x20, 1))
263 		goto bad;
264 #endif
265 	*usp++ = n;
266 	if (n == SIGILL || n == SIGFPE) {
267 		*usp++ = u.u_code;
268 		u.u_code = 0;
269 	} else
270 		*usp++ = 0;
271 	*usp++ = (int)p;
272 	*usp++ = regs[PC];
273 	*usp++ = regs[PS];
274 	regs[SP] = (int)(usp - 5);
275 	regs[PS] &= ~(PSL_CM|PSL_FPD);
276 	regs[PC] = (int)u.u_pcb.pcb_sigc;
277 	return;
278 
279 asm("bad:");
280 bad:
281 	/*
282 	 * Process has trashed its stack; give it an illegal
283 	 * instruction to halt it in its tracks.
284 	 */
285 	u.u_signal[SIGILL] = SIG_DFL;
286 	u.u_procp->p_siga0 &= ~(1<<(SIGILL-1));
287 	u.u_procp->p_siga1 &= ~(1<<(SIGILL-1));
288 	psignal(u.u_procp, SIGILL);
289 }
290 
291 dorti()
292 {
293 	struct frame frame;
294 	register int sp;
295 	register int reg, mask;
296 	extern int ipcreg[];
297 
298 	(void) copyin((caddr_t)u.u_ar0[FP], (caddr_t)&frame, sizeof (frame));
299 	sp = u.u_ar0[FP] + sizeof (frame);
300 	u.u_ar0[PC] = frame.fr_savpc;
301 	u.u_ar0[FP] = frame.fr_savfp;
302 	u.u_ar0[AP] = frame.fr_savap;
303 	mask = frame.fr_mask;
304 	for (reg = 0; reg <= 11; reg++) {
305 		if (mask&1) {
306 			u.u_ar0[ipcreg[reg]] = fuword((caddr_t)sp);
307 			sp += 4;
308 		}
309 		mask >>= 1;
310 	}
311 	sp += frame.fr_spa;
312 	u.u_ar0[PS] = (u.u_ar0[PS] & 0xffff0000) | frame.fr_psw;
313 	if (frame.fr_s)
314 		sp += 4 + 4 * (fuword((caddr_t)sp) & 0xff);
315 	/* phew, now the rei */
316 	u.u_ar0[PC] = fuword((caddr_t)sp);
317 	sp += 4;
318 	u.u_ar0[PS] = fuword((caddr_t)sp);
319 	sp += 4;
320 	u.u_ar0[PS] |= PSL_USERSET;
321 	u.u_ar0[PS] &= ~PSL_USERCLR;
322 	u.u_ar0[SP] = (int)sp;
323 }
324 
325 /*
326  * Memenable enables the memory controlle corrected data reporting.
327  * This runs at regular intervals, turning on the interrupt.
328  * The interrupt is turned off, per memory controller, when error
329  * reporting occurs.  Thus we report at most once per memintvl.
330  */
331 int	memintvl = MEMINTVL;
332 
333 memenable()
334 {
335 	register struct mcr *mcr;
336 	register int m;
337 
338 	for (m = 0; m < nmcr; m++) {
339 		mcr = mcraddr[m];
340 		switch (cpu) {
341 #if VAX780
342 		case VAX_780:
343 			M780_ENA(mcr);
344 			break;
345 #endif
346 #if VAX750
347 		case VAX_750:
348 			M750_ENA(mcr);
349 			break;
350 #endif
351 #if VAX730
352 		case VAX_730:
353 			M730_ENA(mcr);
354 			break;
355 #endif
356 		}
357 	}
358 	if (memintvl > 0)
359 		timeout(memenable, (caddr_t)0, memintvl);
360 }
361 
362 /*
363  * Memerr is the interrupt routine for corrected read data
364  * interrupts.  It looks to see which memory controllers have
365  * unreported errors, reports them, and disables further
366  * reporting for a time on those controller.
367  */
368 memerr()
369 {
370 	register struct mcr *mcr;
371 	register int m;
372 
373 	for (m = 0; m < nmcr; m++) {
374 		mcr = mcraddr[m];
375 		switch (cpu) {
376 #if VAX780
377 		case VAX_780:
378 			if (M780_ERR(mcr)) {
379 				printf("mcr%d: soft ecc addr %x syn %x\n",
380 				    m, M780_ADDR(mcr), M780_SYN(mcr));
381 #ifdef TRENDATA
382 				memlog(m, mcr);
383 #endif
384 				M780_INH(mcr);
385 			}
386 			break;
387 #endif
388 #if VAX750
389 		case VAX_750:
390 			if (M750_ERR(mcr)) {
391 				printf("mcr%d: soft ecc addr %x syn %x\n",
392 				    m, M750_ADDR(mcr), M750_SYN(mcr));
393 				M750_INH(mcr);
394 			}
395 			break;
396 #endif
397 #if VAX730
398 		case VAX_730:
399 			if (M730_ERR(mcr)) {
400 				struct mcr amcr;
401 				amcr.mc_reg[0] = mcr->mc_reg[0];
402 				printf("mcr%d: soft ecc addr %x syn %x\n",
403 				    m, M730_ADDR(&amcr), M730_SYN(&amcr));
404 				M730_INH(mcr);
405 			}
406 			break;
407 #endif
408 		}
409 	}
410 }
411 
412 #ifdef TRENDATA
413 /*
414  * Figure out what chip to replace on Trendata boards.
415  * Assumes all your memory is Trendata or the non-Trendata
416  * memory never fails..
417  */
418 struct {
419 	u_char	m_syndrome;
420 	char	m_chip[4];
421 } memlogtab[] = {
422 	0x01,	"C00",	0x02,	"C01",	0x04,	"C02",	0x08,	"C03",
423 	0x10,	"C04",	0x19,	"L01",	0x1A,	"L02",	0x1C,	"L04",
424 	0x1F,	"L07",	0x20,	"C05",	0x38,	"L00",	0x3B,	"L03",
425 	0x3D,	"L05",	0x3E,	"L06",	0x40,	"C06",	0x49,	"L09",
426 	0x4A,	"L10",	0x4c,	"L12",	0x4F,	"L15",	0x51,	"L17",
427 	0x52,	"L18",	0x54,	"L20",	0x57,	"L23",	0x58,	"L24",
428 	0x5B,	"L27",	0x5D,	"L29",	0x5E,	"L30",	0x68,	"L08",
429 	0x6B,	"L11",	0x6D,	"L13",	0x6E,	"L14",	0x70,	"L16",
430 	0x73,	"L19",	0x75,	"L21",	0x76,	"L22",	0x79,	"L25",
431 	0x7A,	"L26",	0x7C,	"L28",	0x7F,	"L31",	0x80,	"C07",
432 	0x89,	"U01",	0x8A,	"U02",	0x8C,	"U04",	0x8F,	"U07",
433 	0x91,	"U09",	0x92,	"U10",	0x94,	"U12",	0x97, 	"U15",
434 	0x98,	"U16",	0x9B,	"U19",	0x9D,	"U21",	0x9E, 	"U22",
435 	0xA8,	"U00",	0xAB,	"U03",	0xAD,	"U05",	0xAE,	"U06",
436 	0xB0,	"U08",	0xB3,	"U11",	0xB5,	"U13",	0xB6,	"U14",
437 	0xB9,	"U17",	0xBA,	"U18",	0xBC,	"U20",	0xBF,	"U23",
438 	0xC1,	"U25",	0xC2,	"U26",	0xC4,	"U28",	0xC7,	"U31",
439 	0xE0,	"U24",	0xE3,	"U27",	0xE5,	"U29",	0xE6,	"U30"
440 };
441 
442 memlog (m, mcr)
443 	int m;
444 	struct mcr *mcr;
445 {
446 	register i;
447 
448 	switch (cpu) {
449 
450 #if VAX780
451 	case VAX_780:
452 	for (i = 0; i < (sizeof (memlogtab) / sizeof (memlogtab[0])); i++)
453 		if ((u_char)(M780_SYN(mcr)) == memlogtab[i].m_syndrome) {
454 			printf (
455 	"mcr%d: replace %s chip in %s bank of memory board %d (0-15)\n",
456 				m,
457 				memlogtab[i].m_chip,
458 				(M780_ADDR(mcr) & 0x8000) ? "upper" : "lower",
459 				(M780_ADDR(mcr) >> 16));
460 			return;
461 		}
462 	printf ("mcr%d: multiple errors, not traceable\n", m);
463 	break;
464 #endif
465 	}
466 }
467 #endif
468 
469 /*
470  * Invalidate single all pte's in a cluster
471  */
472 tbiscl(v)
473 	unsigned v;
474 {
475 	register caddr_t addr;		/* must be first reg var */
476 	register int i;
477 
478 	asm(".set TBIS,58");
479 	addr = ptob(v);
480 	for (i = 0; i < CLSIZE; i++) {
481 #ifdef lint
482 		mtpr(TBIS, addr);
483 #else
484 		asm("mtpr r11,$TBIS");
485 #endif
486 		addr += NBPG;
487 	}
488 }
489 
490 int	waittime = -1;
491 
492 boot(paniced, arghowto)
493 	int paniced, arghowto;
494 {
495 	register int howto;		/* r11 == how to boot */
496 	register int devtype;		/* r10 == major of root dev */
497 
498 #ifdef lint
499 	howto = 0; devtype = 0;
500 	printf("howto %d, devtype %d\n", arghowto, devtype);
501 #endif
502 	(void) spl1();
503 	howto = arghowto;
504 	if ((howto&RB_NOSYNC)==0 && waittime < 0 && bfreelist[0].b_forw) {
505 		waittime = 0;
506 		update();
507 		printf("syncing disks... ");
508 #ifdef notdef
509 		{ register struct buf *bp;
510 		  int iter, nbusy;
511 
512 		  for (iter = 0; iter < 10; iter++) {
513 			nbusy = 0;
514 			for (bp = &buf[nbuf]; --bp >= buf; )
515 				if (bp->b_flags & B_BUSY)
516 					nbusy++;
517 			if (nbusy == 0)
518 				break;
519 			printf("%d ", nbusy);
520 		  }
521 		}
522 #else
523 		DELAY(10000000);
524 #endif
525 		printf("done\n");
526 	}
527 	splx(0x1f);			/* extreme priority */
528 	devtype = major(rootdev);
529 	if (howto&RB_HALT) {
530 		printf("halting (in tight loop); hit\n\t^P\n\tHALT\n\n");
531 		mtpr(IPL, 0x1f);
532 		for (;;)
533 			;
534 	} else {
535 		if (paniced == RB_PANIC) {
536 			doadump();		/* TXDB_BOOT's itsself */
537 			/*NOTREACHED*/
538 		}
539 		tocons(TXDB_BOOT);
540 	}
541 #if defined(VAX750) || defined(VAX730)
542 	if (cpu != VAX_780)
543 		{ asm("movl r11,r5"); }		/* boot flags go in r5 */
544 #endif
545 	for (;;)
546 		asm("halt");
547 	/*NOTREACHED*/
548 }
549 
550 tocons(c)
551 {
552 
553 	while ((mfpr(TXCS)&TXCS_RDY) == 0)
554 		continue;
555 	mtpr(TXDB, c);
556 }
557 
558 /*
559  * Doadump comes here after turning off memory management and
560  * getting on the dump stack, either when called above, or by
561  * the auto-restart code.
562  */
563 dumpsys()
564 {
565 
566 	rpb.rp_flag = 1;
567 	if ((minor(dumpdev)&07) != 1)
568 		return;
569 	printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
570 	printf("dump ");
571 	switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
572 
573 	case ENXIO:
574 		printf("device bad\n");
575 		break;
576 
577 	case EFAULT:
578 		printf("device not ready\n");
579 		break;
580 
581 	case EINVAL:
582 		printf("area improper\n");
583 		break;
584 
585 	case EIO:
586 		printf("i/o error");
587 		break;
588 
589 	default:
590 		printf("succeeded");
591 		break;
592 	}
593 }
594 
595 /*
596  * Machine check error recovery code.
597  * Print out the machine check frame and then give up.
598  */
599 #if defined(VAX780) || defined(VAX750)
600 char *mc780[] = {
601 	"cp read",	"ctrl str par",	"cp tbuf par",	"cp cache par",
602 	"cp rdtimo", 	"cp rds",	"ucode lost",	0,
603 	0,		0,		"ib tbuf par",	0,
604 	"ib rds",	"ib rd timo",	0,		"ib cache par"
605 };
606 #define	MC780_TBPAR	2
607 #define	MC750_TBPAR	2
608 #endif
609 #if VAX730
610 #define	NMC730	12
611 char *mc730[] = {
612 	"tb par",	"bad retry",	"bad intr id",	"cant write ptem",
613 	"unkn mcr err",	"iib rd err",	"nxm ref",	"cp rds",
614 	"unalgn ioref",	"nonlw ioref",	"bad ioaddr",	"unalgn ubaddr",
615 };
616 #define	MC730_TBPAR	0
617 #endif
618 
619 /*
620  * Frame for each cpu
621  */
622 struct mc780frame {
623 	int	mc8_bcnt;		/* byte count == 0x28 */
624 	int	mc8_summary;		/* summary parameter (as above) */
625 	int	mc8_cpues;		/* cpu error status */
626 	int	mc8_upc;		/* micro pc */
627 	int	mc8_vaviba;		/* va/viba register */
628 	int	mc8_dreg;		/* d register */
629 	int	mc8_tber0;		/* tbuf error reg 0 */
630 	int	mc8_tber1;		/* tbuf error reg 1 */
631 	int	mc8_timo;		/* timeout address divided by 4 */
632 	int	mc8_parity;		/* parity */
633 	int	mc8_sbier;		/* sbi error register */
634 	int	mc8_pc;			/* trapped pc */
635 	int	mc8_psl;		/* trapped psl */
636 };
637 struct mc750frame {
638 	int	mc5_bcnt;		/* byte count == 0x28 */
639 	int	mc5_summary;		/* summary parameter (as above) */
640 	int	mc5_va;			/* virtual address register */
641 	int	mc5_errpc;		/* error pc */
642 	int	mc5_mdr;
643 	int	mc5_svmode;		/* saved mode register */
644 	int	mc5_rdtimo;		/* read lock timeout */
645 	int	mc5_tbgpar;		/* tb group parity error register */
646 	int	mc5_cacherr;		/* cache error register */
647 	int	mc5_buserr;		/* bus error register */
648 	int	mc5_mcesr;		/* machine check status register */
649 	int	mc5_pc;			/* trapped pc */
650 	int	mc5_psl;		/* trapped psl */
651 };
652 struct mc730frame {
653 	int	mc3_bcnt;		/* byte count == 0xc */
654 	int	mc3_summary;		/* summary parameter */
655 	int	mc3_parm[2];		/* parameter 1 and 2 */
656 	int	mc3_pc;			/* trapped pc */
657 	int	mc3_psl;		/* trapped psl */
658 };
659 
660 machinecheck(cmcf)
661 	caddr_t cmcf;
662 {
663 	register u_int type = ((struct mc780frame *)cmcf)->mc8_summary;
664 
665 	printf("machine check %x: ", type);
666 	switch (cpu) {
667 #if VAX780
668 	case VAX_780:
669 #endif
670 #if VAX750
671 	case VAX_750:
672 #endif
673 #if defined(VAX780) || defined(VAX750)
674 		printf("%s%s\n", mc780[type&0xf],
675 		    (type&0xf0) ? " abort" : " fault");
676 		break;
677 #endif
678 #if VAX730
679 	case VAX_730:
680 		if (type < NMC730)
681 			printf("%s", mc730[type]);
682 		printf("\n");
683 		break;
684 #endif
685 	}
686 	switch (cpu) {
687 #if VAX780
688 	case VAX_780: {
689 		register struct mc780frame *mcf = (struct mc780frame *)cmcf;
690 		register int sbifs;
691 		printf("\tcpues %x upc %x va/viba %x dreg %x tber %x %x\n",
692 		   mcf->mc8_cpues, mcf->mc8_upc, mcf->mc8_vaviba,
693 		   mcf->mc8_dreg, mcf->mc8_tber0, mcf->mc8_tber1);
694 		sbifs = mfpr(SBIFS);
695 		printf("\ttimo %x parity %x sbier %x pc %x psl %x sbifs %x\n",
696 		   mcf->mc8_timo*4, mcf->mc8_parity, mcf->mc8_sbier,
697 		   mcf->mc8_pc, mcf->mc8_psl, sbifs);
698 		/* THE FUNNY BITS IN THE FOLLOWING ARE FROM THE ``BLACK */
699 		/* BOOK'' AND SHOULD BE PUT IN AN ``sbi.h'' */
700 		mtpr(SBIFS, sbifs &~ 0x2000000);
701 		mtpr(SBIER, mfpr(SBIER) | 0x70c0);
702 		break;
703 	}
704 #endif
705 #if VAX750
706 	case VAX_750: {
707 		register struct mc750frame *mcf = (struct mc750frame *)cmcf;
708 		printf("\tva %x errpc %x mdr %x smr %x rdtimo %x tbgpar %x cacherr %x\n",
709 		    mcf->mc5_va, mcf->mc5_errpc, mcf->mc5_mdr, mcf->mc5_svmode,
710 		    mcf->mc5_rdtimo, mcf->mc5_tbgpar, mcf->mc5_cacherr);
711 		printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n",
712 		    mcf->mc5_buserr, mcf->mc5_mcesr, mcf->mc5_pc, mcf->mc5_psl,
713 		    mfpr(MCSR));
714 		mtpr(MCESR, 0xf);
715 		if ((type&0xf)==MC750_TBPAR) {
716 			printf("tbuf par!?!: flushing and returning\n");
717 			mtpr(TBIA, 0);
718 			return;
719 		}
720 		break;
721 		}
722 #endif
723 #if VAX730
724 	case VAX_730: {
725 		register struct mc730frame *mcf = (struct mc730frame *)cmcf;
726 		printf("params %x,%x pc %x psl %x mcesr %x\n",
727 		    mcf->mc3_parm[0], mcf->mc3_parm[1],
728 		    mcf->mc3_pc, mcf->mc3_psl, mfpr(MCESR));
729 		mtpr(MCESR, 0xf);
730 		break;
731 		}
732 #endif
733 	}
734 	memerr();
735 	panic("mchk");
736 }
737 
738 #ifdef notdef
739 microtime(tvp)
740 	struct timeval *tvp;
741 {
742 	int s = spl7();
743 
744 	tvp->tv_sec = time.tv_sec;
745 	tvp->tv_usec = (lbolt+1)*16667 + mfpr(ICR);
746 	while (tvp->tv_usec > 1000000) {
747 		tvp->tv_sec++;
748 		tvp->tv_usec -= 1000000;
749 	}
750 	splx(s);
751 }
752 #endif
753 
754 physstrat(bp, strat, prio)
755 	struct buf *bp;
756 	int (*strat)(), prio;
757 {
758 	int s;
759 
760 	(*strat)(bp);
761 	s = spl6();
762 	while ((bp->b_flags & B_DONE) == 0)
763 		sleep((caddr_t)bp, prio);
764 	splx(s);
765 }
766