xref: /netbsd/sys/arch/mac68k/mac68k/macrom.c (revision bf9ec67e)
1 /*	$NetBSD: macrom.c,v 1.48 2001/11/20 03:19:43 chs Exp $	*/
2 
3 /*-
4  * Copyright (C) 1994	Bradley A. Grantham
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Bradley A. Grantham.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Mac ROM Glue
35  *
36  * This allows MacBSD to access (in a limited fashion) routines included
37  * in the Mac ROMs, like ADBReInit.
38  *
39  * As a (fascinating) side effect, this glue allows ROM code (or any other
40  * MacOS code) to call MacBSD kernel routines, like NewPtr.
41  *
42  * Uncleaned-up weirdness,
43  *	This doesn't work on a lot of machines.  Perhaps the IIsi stuff
44  * can be generalized somewhat for others.  It looks like most machines
45  * are similar to the IIsi ("Universal ROMs"?).
46  */
47 
48 #include "opt_adb.h"
49 #include "opt_ddb.h"
50 
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/lock.h>
54 #include <sys/malloc.h>
55 #include <sys/queue.h>
56 
57 #include <uvm/uvm_extern.h>
58 
59 #include <machine/cpu.h>
60 #include <machine/frame.h>
61 #include <machine/viareg.h>
62 
63 #include <mac68k/mac68k/macrom.h>
64 #include <mac68k/dev/adbvar.h>
65 
66 	/* trap modifiers (put it macrom.h) */
67 #define TRAP_TOOLBOX(a)	((a) & 0x800)
68 #define TRAP_PASSA0(a)	((a) & 0x100)
69 #define TRAP_NUM(a)	(TRAP_TOOLBOX(a) ? (a) & 0x3ff : (a) & 0xff)
70 #define TRAP_SYS(a)	((a) & 0x400)
71 #define TRAP_CLEAR(a)	((a) & 0x200)
72 
73 
74 	/* Mac Rom Glue global variables */
75 /*
76  * ADB Storage.  Is 512 bytes enough?  Too much?
77  */
78 u_char mrg_adbstore[512];
79 u_char mrg_adbstore2[512];
80 u_char mrg_adbstore3[512];
81 u_char mrg_ExpandMem[512];			/* 0x1ea Bytes minimum */
82 u_char mrg_adbstore4[32];			/* 0x16 bytes was the largest I found yet */
83 u_char mrg_adbstore5[80];			/* 0x46 bytes minimum */
84 
85 /*
86  * InitEgret in the AV ROMs requires a low memory global at 0x2010 to be
87  * pointed at this jump table, which can be found at 0x40803280. It's
88  * included here so we can do mrg_fixupROMBase on it.
89  */
90 
91 u_int32_t mrg_AVInitEgretJT[] = {
92 	0x408055D0, 0x4083985A, 0x40839AB6, 0x4080F180,
93 	0x4080C0B6, 0x4080C30A, 0x4080C380, 0x4080C482,
94 	0x4080C496, 0x4080C82E, 0x4080C9FE, 0x4080CA16,
95 	0x4081D1D6, 0x4085CDDE, 0x4080DF28, 0x4080DFC6,
96 	0x4080E292, 0x4080E2C0, 0x4080E348, 0x4080E600,
97 	0x4080E632, 0x4080E6B8, 0x4080E6E4, 0x4080E750,
98 	0x4080E776, 0x4080E7B4, 0x408B90E0, 0x40852490,
99 	0x40852280, 0x40852410, 0x4080E8F0, 0x4080E940,
100 	0x4080E960, 0x4080E9B0, 0x4080E9E0, 0x4080EA50,
101 	0x4080EA70, 0x4080EB14, 0x4080EBC0, 0x4081D1D6,
102 	0x40810AB0, 0x40810BDA, 0x40810CCA, 0x40810FF2,
103 	0x4080FF8C, 0x40810292, 0x40812CE2, 0x40813AAE,
104 	0x40813AE0, 0x408113DE, 0x40811EB0, 0x40811FA0,
105 	0x40811DD0, 0x4083B720, 0x408412E0, 0x40841300,
106 	0x40841380, 0x4083A390, 0x408411F0
107 };
108 
109 caddr_t	mrg_romadbintr = (caddr_t)0;	/* ROM ADB interrupt */
110 caddr_t	mrg_rompmintr = 0;		/* ROM PM (?) interrupt */
111 char	*mrg_romident = NULL;		/* ident string for ROMs */
112 caddr_t	mrg_ADBAlternateInit = 0;
113 caddr_t	mrg_InitEgret = 0;
114 caddr_t	mrg_ADBIntrPtr = (caddr_t)0x0;	/* ADB interrupt taken from MacOS vector table*/
115 caddr_t	ROMResourceMap = 0;
116 extern romvec_t *mrg_MacOSROMVectors;
117 #if defined(MRG_TEST) || defined(MRG_DEBUG)
118 caddr_t	ResHndls[] = {
119 	0, 0, 0, 0, 0, 0, 0, 0,
120 	0, 0, 0, 0, 0, 0, 0, 0,
121 	0, 0, 0, 0, 0, 0, 0, 0,
122 	0, 0, 0, 0, 0, 0, 0, 0,
123 	0, 0, 0, 0, 0, 0
124 };
125 #else
126 caddr_t	ResHndls[] = {
127 	0, 0, 0, 0, 0, 0, 0, 0,
128 	0, 0, 0, 0, 0, 0, 0, 0,
129 	0, 0, 0, 0
130 };
131 #endif
132 
133 /*
134  * Last straw functions; we didn't set them up, so freak out!
135  * When someone sees these called, we can finally go back and
136  * bother to implement them.
137  */
138 
139 int
140 mrg_Delay()
141 {
142 #define TICK_DURATION 16625
143 	u_int32_t ticks;
144 
145 	__asm __volatile ("movl	%%a0,%0"	/* get arguments */
146 		: "=g" (ticks)
147 		:
148 		: "a0");
149 
150 #if defined(MRG_DEBUG)
151 	printf("mrg: mrg_Delay(%d) = %d ms\n", ticks, ticks * 60);
152 #endif
153 	delay(ticks * TICK_DURATION);
154 
155 	/*
156 	 * The number of ticks since startup should be
157 	 * returned here. Until someone finds a need for
158 	 * this, we just return the requested number
159 	 * of ticks
160 	 */
161 	return (ticks);
162 }
163 
164 /*
165  * Handle the Deferred Task manager here
166  *
167  */
168 static caddr_t	mrg_DTList = NULL;
169 
170 void
171 mrg_DTInstall()
172 {
173 	caddr_t	ptr, prev;
174 
175 	__asm __volatile ("movl %%a0,%0" : "=g" (ptr));
176 
177 	(caddr_t *)prev = &mrg_DTList;
178 	while (*prev != NULL)
179 		prev = *(caddr_t *)prev;
180 	*(caddr_t *)ptr = NULL;
181 	*(caddr_t *)prev = ptr;
182 	setsoftdtmgr();
183 
184 	__asm __volatile ("clrl %%d0" : : : "d0");
185 }
186 
187 void
188 mrg_execute_deferred()
189 {
190 	caddr_t ptr;
191 	int s;
192 
193 	while (mrg_DTList != NULL) {
194 		s = splhigh();
195 		ptr = *(caddr_t *)mrg_DTList;
196 		mrg_DTList = *(caddr_t *)ptr;
197 		splx(s);
198 
199 		__asm __volatile ("
200 			moveml %%a0-%%a6/%%d1-%%d7,%%sp@-
201 			movl %0,%%a0
202 			movl %%a0@(8),%%a2
203 			movl %%a0@(12),%%a1
204 			jsr %%a2@
205 			moveml %%sp@+,%%a0-%%a6/%%d1-%%d7" : : "g" (ptr));
206 	}
207 }
208 
209 void
210 mrg_VBLQueue()
211 {
212 #define qLink 0
213 #define qType 4
214 #define vblAddr 6
215 #define vblCount 10
216 #define vblPhase 12
217 	caddr_t vbltask;
218 	caddr_t last_vbltask;
219 
220 	last_vbltask = (caddr_t)&VBLQueue_head;
221 	vbltask = VBLQueue_head;
222 	while (0 != vbltask) {
223 		if (0 != *((u_int16_t *)(vbltask + vblPhase)))
224 			*((u_int16_t *)(vbltask + vblPhase)) -= 1;
225 		else if (0 != *((u_int16_t *)(vbltask + vblCount)))
226 			*((u_int16_t *)(vbltask + vblCount)) -= 1;
227 		else {
228 #if defined(MRG_DEBUG)
229 			printf("mrg: mrg_VBLQueue: calling VBL task at 0x%x with VBLTask block at %p\n",
230 			    *((u_int32_t *)(vbltask + vblAddr)), vbltask);
231 #endif
232 			__asm __volatile("
233 				movml	#0xfffe,%%sp@-
234 				movl	%0,%%a0
235 				movl	%1,%%a1
236 				jbsr	%%a1@
237 				movml	%%sp@+,#0x7fff"
238 				: : "g" (vbltask),
239 				    "g" (*((caddr_t)(vbltask + vblAddr)))
240 				: "a0","a1");
241 #if defined(MRG_DEBUG)
242 			printf("mrg: mrg_VBLQueue: back from VBL task\n");
243 #endif
244 			if (0 == *((u_int16_t *)(vbltask + vblCount))) {
245 #if defined(MRG_DEBUG)
246 				printf("mrg: mrg_VBLQueue: removing VBLTask block at %p\n",
247 				    vbltask);
248 #endif
249 				*((u_int32_t *)(last_vbltask + qLink)) =
250 				    *((u_int32_t *)(vbltask + qLink));
251 				/*
252 				 * can't free memory from VBLTask block as
253 				 * we don't know where it came from
254 				 */
255 				if (vbltask == VBLQueue_tail)
256 					VBLQueue_tail = last_vbltask;
257 			}
258 		}
259 		last_vbltask = vbltask;
260 		vbltask = (caddr_t) *((u_int32_t *)(vbltask + qLink));
261 	}
262 }
263 
264 void
265 mrg_init_stub_1()
266 {
267 	__asm __volatile ("movml #0xffff,%sp@-");
268 	printf("mrg: hit mrg_init_stub_1\n");
269   	__asm __volatile ("movml %sp@+, #0xffff");
270 }
271 
272 void
273 mrg_init_stub_2()
274 {
275 	panic("mrg: hit mrg_init_stub_2\n");
276 }
277 
278 short
279 Count_Resources(u_int32_t rsrc_type)
280 {
281 	rsrc_t *rsrc = (rsrc_t *)ROMResourceMap;
282 	short count = 0;
283 
284 #if defined(MRG_DEBUG)
285 	printf("Count_Resources looking for 0x%08lx at 0x%08lx\n",
286 	    (long)rsrc_type, (long)rsrc);
287 #endif
288 	/*
289 	 * Return a Count of all the ROM Resouces of the requested type.
290 	 */
291 	if (ROMResourceMap == 0)
292 		panic("Oops! Need ROM Resource Map ListHead address!\n");
293 
294 	while (rsrc != 0) {
295 #if defined(MRG_DEBUG)
296 		if (rsrc_type == 0)
297 			printf("0x%08lx: %04x %04x %04x %04x %08x %08x %08x %04x\n",
298 			    (long)rsrc, rsrc->unknown[0], rsrc->unknown[1],
299 			    rsrc->unknown[2], rsrc->unknown[3], rsrc->next,
300 			    rsrc->body, rsrc->name, rsrc->index);
301 #endif
302 		if (rsrc_type == 0 || (rsrc_type == rsrc->name))
303 			count++;
304 		rsrc = rsrc->next == 0 ? 0 : (rsrc_t *)(rsrc->next + ROMBase);
305 	}
306 
307 #if defined(MRG_DEBUG)
308 	printf("Count_Resources found %d\n", count);
309 #endif
310 	return count;
311 }
312 
313 caddr_t *
314 Get_Ind_Resource(u_int32_t rsrc_type, u_int16_t rsrc_ind)
315 {
316 	rsrc_t *rsrc = (rsrc_t *)ROMResourceMap;
317 	short i = 0;
318 
319 	/*
320 	 * This routine return the "Handle" to a ROM Resource.  Since few
321 	 * ROM Resources are called for in NetBSD we keep a small table
322 	 * for the Handles we return. (Can't reuse the Handle without
323 	 * defeating the purpose for a Handle in the first place!)  If
324 	 * we get more requests than we have space for, we panic.
325 	 */
326 	if (ROMResourceMap == 0)
327 		panic("Oops! Need ROM Resource Map ListHead address!\n");
328 
329 	while (rsrc != 0) {
330 		if (rsrc_type == rsrc->name) {
331 			rsrc_ind--;
332 			if (rsrc_ind == 0) {
333 				for (i = 0;
334 				    i < sizeof(ResHndls) / sizeof(caddr_t); i++)
335 					if ((ResHndls[i] == 0) ||
336 					    (ResHndls[i] == (caddr_t)(rsrc->next + ROMBase))) {
337 						ResHndls[i] = (caddr_t)(rsrc->body + ROMBase);
338 						return (caddr_t *)&ResHndls[i];
339 					}
340 				panic("ResHndls table too small!\n");
341 			}
342 		}
343 		rsrc = rsrc->next == 0 ? 0 : (rsrc_t *)(rsrc->next + ROMBase);
344 	}
345 	return (caddr_t *)0;
346 }
347 
348 void
349 mrg_FixDiv()
350 {
351 	panic("Oops! Need ROM address of _FixDiv for this system!\n");
352 }
353 
354 void
355 mrg_FixMul()
356 {
357 	panic("Oops! Need ROM address of _FixMul for this system!\n");
358 }
359 
360 void
361 mrg_1sec_timer_tick()
362 {
363 	/* The timer tick from the Egret chip triggers this routine via
364 	 * Lvl1DT[0] (addr 0x192) once every second.
365 	 */
366 }
367 
368 void
369 mrg_lvl1dtpanic()		/* Lvl1DT stopper */
370 {
371 	printf("Agh!  I was called from Lvl1DT!!!\n");
372 #ifdef DDB
373 	Debugger();
374 #endif
375 }
376 
377 void
378 mrg_lvl2dtpanic()		/* Lvl2DT stopper */
379 {
380 	panic("Agh!  I was called from Lvl2DT!!!\n");
381 }
382 
383 void
384 mrg_jadbprocpanic()	/* JADBProc stopper */
385 {
386 	panic("Agh!  Called JADBProc!\n");
387 }
388 
389 void
390 mrg_jswapmmupanic()	/* jSwapMMU stopper */
391 {
392 	panic("Agh!  Called jSwapMMU!\n");
393 }
394 
395 void
396 mrg_jkybdtaskpanic()	/* JKybdTask stopper */
397 {
398 	panic("Agh!  Called JKybdTask!\n");
399 }
400 
401 #ifdef MRG_ADB
402 /*
403  * mrg_adbintr() and mrg_pmintr() are defined in adb_direct.c if we
404  * not using the MRG method of accessing the ADB/PRAM/RTC.
405  */
406 
407 long
408 mrg_adbintr()	/* Call ROM ADB Interrupt */
409 {
410 	if (mrg_romadbintr != NULL) {
411 #if defined(MRG_TRACE)
412 		tron();
413 #endif
414 
415 		/* Gotta load a1 with VIA address. */
416 		/* ADB int expects it from Mac intr routine. */
417 		__asm __volatile ("
418 			movml	#0xffff,%%sp@-
419 			movl	%0,%%a0
420 			movl	" ___STRING(_C_LABEL(VIA)) ",%%a1
421 			jbsr	%%a0@
422 			movml	%%sp@+,#0xffff"
423 			:
424 			: "g" (mrg_romadbintr)
425 			: "a0","a1");
426 
427 #if defined(MRG_TRACE)
428 		troff();
429 #endif
430 
431 	}
432 	return (1);
433 }
434 
435 long
436 mrg_pmintr()	/* Call ROM PM Interrupt */
437 {
438 	if (mrg_rompmintr != NULL) {
439 #if defined(MRG_TRACE)
440 		tron();
441 #endif
442 
443 		/* Gotta load a1 with VIA address. */
444 		/* ADB int expects it from Mac intr routine. */
445 		__asm __volatile ("
446 			movml	#0xffff,%%sp@-
447 			movl	%0,%%a0
448 			movl	" ___STRING(_C_LABEL(VIA)) ",%%a1
449 			jbsr	%%a0@
450 			movml	%%sp@+,#0xffff"
451 			:
452 			: "g" (mrg_rompmintr)
453 			: "a0","a1");
454 
455 #if defined(MRG_TRACE)
456 		troff();
457 #endif
458 	}
459 	return (1);
460 }
461 #endif	/* MRG_ADB */
462 
463 
464 void
465 mrg_notrap()
466 {
467 	printf("Aigh!\n");
468 	panic("mrg_notrap: We're doomed!\n");
469 }
470 
471 int
472 myowntrap()
473 {
474 	printf("Oooo!  My Own Trap Routine!\n");
475 	return (50);
476 }
477 
478 int
479 mrg_NewPtr()
480 {
481 	int result = noErr;
482 	u_int numbytes;
483 /*	u_int32_t trapword; */
484 	caddr_t ptr;
485 
486 	__asm __volatile ("movl	%%d0,%0" : "=g" (numbytes) : : "d0");
487 
488 #if defined(MRG_SHOWTRAPS)
489 	printf("mrg: NewPtr(%d bytes, ? clear, ? sys)", numbytes);
490 #endif
491 
492 		/* plus 4 for size */
493 	ptr = malloc(numbytes + 4 , M_DEVBUF, M_NOWAIT); /* ?? */
494 		/* We ignore "Sys;" where else would it come from? */
495 		/* plus, (I think), malloc clears block for us */
496 
497 	if (ptr == NULL) {
498 		result = memFullErr;
499 #if defined(MRG_SHOWTRAPS)
500 		printf(" failed.\n");
501 #endif
502 	}else{
503 #if defined(MRG_SHOWTRAPS)
504 		printf(" succeded = %p.\n", ptr);
505 #endif
506 		*(u_int32_t *)ptr = numbytes;
507 		ptr += 4;
508 		bzero(ptr, numbytes); /* NewPtr, Clear ! */
509 	}
510 
511 	__asm __volatile("movl	%0,%%a0" :  : "g" (ptr) : "a0");
512 	return (result);
513 }
514 
515 int
516 mrg_DisposPtr()
517 {
518 	int result = noErr;
519 	caddr_t ptr;
520 
521 	__asm __volatile("movl	%%a0,%0" : "=g" (ptr) : : "a0");
522 
523 #if defined(MRG_SHOWTRAPS)
524 	printf("mrg: DisposPtr(%p)\n", ptr);
525 #endif
526 
527 	if (ptr == 0)
528 		result = memWZErr;
529 	else
530 		free(ptr - 4, M_DEVBUF);
531 
532 	return (result);
533 }
534 
535 int
536 mrg_GetPtrSize()
537 {
538 	caddr_t ptr;
539 
540 	__asm __volatile("movl	%%a0,%0" : "=g" (ptr) : : "a0");
541 
542 #if defined(MRG_SHOWTRAPS)
543 	printf("mrg: GetPtrSize(%p)\n", ptr);
544 #endif
545 
546 	if (ptr == 0)
547 		return (memWZErr);
548 	else
549 		return (*(int *)(ptr - 4));
550 }
551 
552 int
553 mrg_SetPtrSize()
554 {
555 	caddr_t ptr;
556 	int newbytes;
557 
558 	__asm __volatile("
559 		movl	%%a0,%0
560 		movl	%%d0,%1"
561 		: "=g" (ptr), "=g" (newbytes) : : "d0","a0");
562 
563 #if defined(MRG_SHOWTRAPS)
564 	printf("mrg: SetPtrSize(%p, %d) failed\n", ptr, newbytes);
565 #endif
566 
567 	return (memFullErr);	/* How would I handle this, anyway? */
568 }
569 
570 int
571 mrg_PostEvent()
572 {
573 	return 0;
574 }
575 
576 void
577 mrg_StripAddress()
578 {
579 }
580 
581 int
582 mrg_SetTrapAddress()
583 {
584 	extern caddr_t mrg_OStraps[];
585 	caddr_t ptr;
586 	int trap_num;
587 
588 	__asm __volatile("
589 		movl %%a0,%0
590 		movl %%d0,%1"
591 		: "=g" (ptr), "=g" (trap_num) : : "d0","a0");
592 
593 #if defined(MRG_DEBUG)
594 	printf("mrg: trap 0x%x set to 0x%lx\n", trap_num, (long)ptr);
595 #endif
596 	mrg_OStraps[trap_num] = ptr;
597 /*
598  * If the Trap for Egret was changed, we'd better remember it!
599  */
600 	if (trap_num == 0x92) {
601 #if defined(MRG_DEBUG)
602 		printf("mrg: reconfigured Egret address from 0x%lx to 0x%lx\n",
603 		    (long)jEgret, (long)ptr);
604 #endif
605 		jEgret = (void (*))ptr;
606 	}
607 	return 0;
608 }
609 
610 /*
611  * trap jump address tables (different per machine?)
612  * Can I just use the tables stored in the ROMs?
613  * *Is* there a table stored in the ROMs?
614  * We only initialize the A-Traps for the routines we have
615  *  provided ourselves.  The routines we will be trying to
616  *  use out of the MacROMs will be initialized at run-time.
617  * I did this to make the code easier to follow and to keep
618  *  from taking an unexpected side trip into the MacROMs on
619  *  those systems we don't have fully decoded.
620  */
621 caddr_t mrg_OStraps[256] = {
622 #ifdef __GNUC__
623 		/* God, I love gcc.  see GCC2 manual, section 2.17, */
624 		/* "labeled elements in initializers." */
625 	[0x1e]	(caddr_t)mrg_NewPtr,
626 		(caddr_t)mrg_DisposPtr,
627 		(caddr_t)mrg_SetPtrSize,
628 		(caddr_t)mrg_GetPtrSize,
629 	[0x2f]	(caddr_t)mrg_PostEvent,
630 	[0x3b]	(caddr_t)mrg_Delay,
631 	[0x47]	(caddr_t)mrg_SetTrapAddress,
632 	[0x55]	(caddr_t)mrg_StripAddress,
633 	[0x82]	(caddr_t)mrg_DTInstall,
634 #else
635 #error "Using a GNU C extension."
636 #endif
637 };
638 
639 caddr_t mrg_ToolBoxtraps[1024] = {
640 	[0x19c] (caddr_t)mrg_CountResources,
641 	[0x19d] (caddr_t)mrg_GetIndResource,
642 	[0x1a0] (caddr_t)mrg_GetResource,
643 	[0x1af] (caddr_t)mrg_ResError,
644 };
645 
646 /*
647  * Handle a supervisor mode A-line trap.
648  */
649 void
650 mrg_aline_super(struct frame *frame)
651 {
652 	caddr_t trapaddr;
653 	u_short trapword;
654 	int isOStrap;
655 	int trapnum;
656 	int a0passback;
657 	u_int32_t a0bucket, d0bucket;
658 	int danprint=0; /* This shouldn't be necessary, but seems to be.  */
659 
660 #if defined(MRG_DEBUG)
661 	printf("mrg: a super");
662 #endif
663 
664 	trapword = *(u_short *)frame->f_pc;
665 
666 	if (trapword == 0xa71e)
667 		danprint = 1;
668 
669 #if defined(MRG_DEBUG)
670 	printf(" wd 0x%lx", (long)trapword);
671 #endif
672 	isOStrap = ! TRAP_TOOLBOX(trapword);
673 	trapnum = TRAP_NUM(trapword);
674 
675 	if (danprint) {
676 		/*
677 		 * Without these print statements, ADBReInit fails on IIsi
678 		 * It is unclear why--perhaps a compiler bug?  delay()s do not
679 		 * work, nor does some assembly similar to the  printf calls.
680 		 * A printf(""); is sufficient, but gcc -Wall is noisy about
681 		 * it, so I figured backspace is harmless enough...
682 		 */
683 		printf(" "); printf("\010");
684 	}
685 
686 #if defined(MRG_DEBUG)
687 	printf(" %s # 0x%x", isOStrap? "OS" :
688 		"ToolBox", trapnum);
689 #endif
690 
691 	/*
692 	 * Only OS Traps come to us; alinetrap() takes care of ToolBox
693 	 * traps, which are a horrible Frankenstein-esque abomination.
694 	 */
695 
696 	trapaddr = mrg_OStraps[trapnum];
697 #if defined(MRG_DEBUG)
698 	printf(" addr 0x%lx\n", (long)trapaddr);
699  	printf("    got:    d0 = 0x%8x,  a0 = 0x%8x, called from: 0x%8x\n",
700 		frame->f_regs[0], frame->f_regs[8], frame->f_pc	);
701 #endif
702 	if (trapaddr == NULL) {
703 		printf("unknown %s trap 0x%x, no trap address available\n",
704 			isOStrap ? "OS" : "ToolBox", trapword);
705 		panic("mrg_aline_super()");
706 	}
707 	a0passback = TRAP_PASSA0(trapword);
708 
709 #if defined(MRG_TRACE)
710 	tron();
711 #endif
712 
713 /* 	put a0 in a0 */
714 /* 	put a1 in a1 */
715 /* 	put d0 in d0 */
716 /* 	put d1 in d1 */
717 /*	put trapaddr in a2 */
718 /* save a6 */
719 /* 	call the damn routine */
720 /* restore a6 */
721 /* 	store d0 in d0bucket */
722 /* 	store a0 in d0bucket */
723 /* This will change a2,a1,d1,d0,a0 and possibly a6 */
724 
725 	__asm __volatile ("
726 		movl	%2@,%%d0
727 		movl	%2@(4),%%d1
728 		movl	%2@(32),%%a0
729 		movl	%2@(36),%%a1
730 		movl	%3,%%a2
731 		jbsr	%%a2@
732 		movl	%%a0,%0
733 		movl	%%d0,%1"
734 
735 		: "=g" (a0bucket), "=g" (d0bucket)
736 
737 		: "a" (&frame->f_regs), "g" (trapaddr)
738 
739 		: "d0","d1","a0","a1","a2",
740 #ifdef __ELF__
741 			  "fp"
742 #else
743 			  "a6"
744 #endif
745 );
746 
747 #if defined(MRG_TRACE)
748 	troff();
749 #endif
750 #if defined(MRG_DEBUG)
751 	printf("    result: d0 = 0x%8x,  a0 = 0x%8x\n",
752 		d0bucket, a0bucket );
753  	printf(" bk");
754 #endif
755 
756 	frame->f_regs[0] = d0bucket;
757 	if (a0passback)
758 		frame->f_regs[8] = a0bucket;
759 
760 	frame->f_pc += 2;	/* skip offending instruction */
761 
762 #if defined(MRG_DEBUG)
763 	printf(" exit\n");
764 #endif
765 }
766 
767 extern u_int32_t traceloopstart[];
768 extern u_int32_t traceloopend;
769 extern u_int32_t *traceloopptr;
770 
771 void
772 dumptrace()
773 {
774 #if defined(MRG_TRACE)
775 	u_int32_t *traceindex;
776 
777 	printf("instruction trace:\n");
778 	traceindex = traceloopptr + 1;
779 	while (traceindex != traceloopptr) {
780 		printf("    %08x\n", *traceindex++);
781 		if (traceindex == &traceloopend)
782 			traceindex = &traceloopstart[0];
783 	}
784 #else
785 	printf("mrg: no trace functionality enabled\n");
786 #endif
787 }
788 
789 	/* To find out if we're okay calling ROM vectors */
790 int
791 mrg_romready()
792 {
793 	return (mrg_romident != NULL);
794 }
795 
796 extern unsigned long	IOBase;
797 extern volatile u_char	*sccA;
798 
799 	/* initialize Mac ROM Glue */
800 void
801 mrg_init()
802 {
803 	char *findername = "MacBSD FakeFinder";
804 	int i;
805 #if defined(MRG_TEST)
806 	caddr_t ptr;
807 	short rcnt;
808 	int sizeptr;
809 	extern short mrg_ResErr;
810 	caddr_t *handle;
811 #endif
812 
813 	/*
814 	 * Clear the VBLQueue.
815 	 */
816 	VBLQueue = (u_int16_t) 0;
817 	VBLQueue_head = (caddr_t) 0;
818 	VBLQueue_tail = (caddr_t) 0;
819 
820 #if defined(MRG_TEST)
821 	if (ROMResourceMap) {
822 		printf("mrg: testing CountResources\n");
823 		__asm __volatile ("
824 			clrl    %%sp@-
825 			clrl    %%sp@-
826 			.word   0xa99c
827 			movw    %%sp@+,%0"
828 			: "=g" (rcnt));
829 		printf("mrg: found %d resources in ROM\n", rcnt);
830 		__asm __volatile ("
831 			clrl    %%sp@-
832 			movl    #0x44525652,%%sp@-
833 			.word   0xa99c
834 			movw    %%sp@+,%0"
835 			: "=g" (rcnt));
836 		printf("mrg: %d are DRVR resources\n", rcnt);
837 		if (rcnt == 0)
838 			panic("Oops! No DRVR Resources found in ROM\n");
839 	}
840 #endif
841 #if defined(MRG_TEST)
842 	if (ROMResourceMap) {
843 		printf("mrg: testing GetIndResource\n");
844 		__asm __volatile ("
845 			clrl    %%sp@-
846 			movl    #0x44525652,%%sp@-
847 			movw    #0x01,%%sp@-
848 			.word   0xa99d
849 			movl    %%sp@+,%0"
850 			: "=g" (handle));
851 		printf("Handle to first DRVR resource is 0x%p\n", handle);
852 		printf("DRVR: 0x%08lx -> 0x%08lx -> 0x%08lx\n",
853 		    (long)Get_Ind_Resource(0x44525652, 1),
854 		    (long)*Get_Ind_Resource(0x44525652, 1),
855 		    (long)*((u_int32_t *)*Get_Ind_Resource(0x44525652, 1)));
856 		__asm __volatile ("
857 			clrl    %%sp@-
858 			movl    #0x44525652,%%sp@-
859 			movw    #0x02,%%sp@-
860 			.word   0xa99d
861 			movl    %%sp@+,%0"
862 			: "=g" (handle));
863 		printf("Handle to second DRVR resource is 0x%p\n", handle);
864 		printf("DRVR: 0x%08lx -> 0x%08lx -> 0x%08lx\n",
865 		    (long)Get_Ind_Resource(0x44525652, 2),
866 		    (long)*Get_Ind_Resource(0x44525652, 2),
867 		    (long)*((u_int32_t *)*Get_Ind_Resource(0x44525652, 2)));
868 	}
869 #endif
870 	if (mrg_romready()) {
871 		printf("mrg: '%s' ROM glue", mrg_romident);
872 
873 #if defined(MRG_TRACE)
874 #if defined(MRG_FOLLOW)
875 		printf(", tracing on (verbose)");
876 #else /* ! defined (MRG_FOLLOW) */
877 		printf(", tracing on (silent)");
878 #endif /* defined(MRG_FOLLOW) */
879 #else /* !defined(MRG_TRACE) */
880 		printf(", tracing off");
881 #endif	/* defined(MRG_TRACE) */
882 
883 #if defined(MRG_DEBUG)
884 		printf(", debug on");
885 #else /* !defined(MRG_DEBUG) */
886 		printf(", debug off");
887 #endif /* defined(MRG_DEBUG) */
888 
889 #if defined(MRG_SHOWTRAPS)
890 		printf(", verbose traps");
891 #else /* !defined(MRG_SHOWTRAPS) */
892 		printf(", silent traps");
893 #endif /* defined(MRG_SHOWTRAPS) */
894 	}else{
895 		printf("mrg: kernel has no ROM vectors for this machine!\n");
896 		return;
897 	}
898 
899 	printf("\n");
900 
901 #if defined(MRG_DEBUG)
902 	printf("mrg: start init\n");
903 #endif
904 		/* expected globals */
905 	ExpandMem = &mrg_ExpandMem[0];
906 	*((u_int16_t *)(mrg_ExpandMem + 0x00) ) = 0x0123;	/* magic (word) */
907 	*((u_int32_t *)(mrg_ExpandMem + 0x02) ) = 0x000001ea;	/* Length of table (long) */
908 	*((u_int32_t *)(mrg_ExpandMem + 0x1e0)) = (u_int32_t) &mrg_adbstore4[0];
909 
910 	*((u_int32_t *)(mrg_adbstore4 + 0x8)) = (u_int32_t) mrg_init_stub_1;
911 	*((u_int32_t *)(mrg_adbstore4 + 0xc)) = (u_int32_t) mrg_init_stub_2;
912 	*((u_int32_t *)(mrg_adbstore4 + 0x4)) = (u_int32_t) &mrg_adbstore5[0];
913 
914 	*((u_int32_t *)(mrg_adbstore5 + 0x08)) = (u_int32_t) 0x00100000;
915 	*((u_int32_t *)(mrg_adbstore5 + 0x0c)) = (u_int32_t) 0x00100000;
916 	*((u_int32_t *)(mrg_adbstore5 + 0x16)) = (u_int32_t) 0x00480000;
917 
918 	ADBBase = &mrg_adbstore[0];
919 	ADBState = &mrg_adbstore2[0];
920 	ADBYMM = &mrg_adbstore3[0];
921 	MinusOne = 0xffffffff;
922 	Lo3Bytes = 0x00ffffff;
923 	VIA = (caddr_t)Via1Base;
924 	MMU32Bit = 1; /* ?means MMU is in 32 bit mode? */
925   	if (TimeDBRA == 0)
926 		TimeDBRA = 0xa3b;		/* BARF default is Mac II */
927   	if (ROMBase == 0)
928 		panic("ROMBase not set in mrg_init()!\n");
929 
930 	strcpy(&FinderName[1], findername);
931 	FinderName[0] = (u_char) strlen(findername);
932 #if defined(MRG_DEBUG)
933 	printf("After setting globals\n");
934 #endif
935 
936 		/* Fake jump points */
937 	for (i = 0; i < 8; i++) /* Set up fake Lvl1DT */
938 		Lvl1DT[i] = mrg_lvl1dtpanic;
939 	for (i = 0; i < 8; i++) /* Set up fake Lvl2DT */
940 		Lvl2DT[i] = mrg_lvl2dtpanic;
941 	Lvl1DT[0] = (void (*)(void))mrg_1sec_timer_tick;
942 	Lvl1DT[2] = (void (*)(void))mrg_romadbintr;
943 	Lvl1DT[4] = (void (*)(void))mrg_rompmintr;
944 	JADBProc = mrg_jadbprocpanic;	/* Fake JADBProc for the time being */
945 	jSwapMMU = mrg_jswapmmupanic;	/* Fake jSwapMMU for the time being */
946 	JKybdTask = mrg_jkybdtaskpanic;	/* Fake JKybdTask for the time being */
947 
948 	/* probably very dangerous */
949 	jADBOp = (void (*)(void))mrg_OStraps[0x7c];
950 
951 	mrg_VIA2 = (caddr_t)(Via1Base + VIA2 * 0x2000);	/* see via.h */
952 	SCCRd = (caddr_t)sccA;		/* ser.c ; we run before serinit */
953 
954 	jDTInstall = (caddr_t)mrg_DTInstall;
955 
956 	/* AV ROMs want this low memory vector to point to a jump table */
957 	InitEgretJTVec = (u_int32_t **)&mrg_AVInitEgretJT;
958 
959 	switch (mach_cputype()) {
960 		case MACH_68020:	CPUFlag = 2;	break;
961 		case MACH_68030:	CPUFlag = 3;	break;
962 		case MACH_68040:	CPUFlag = 4;	break;
963 		default:
964 			printf("mrg: unknown CPU type; cannot set CPUFlag\n");
965 			break;
966 	}
967 
968 #if defined(MRG_TEST)
969 	printf("Allocating a pointer...\n");
970 	ptr = (caddr_t)NewPtr(1024);
971 	printf("Result is 0x%lx.\n", (long)ptr);
972 	sizeptr = GetPtrSize((Ptr)ptr);
973 	printf("Pointer size is %d\n", sizeptr);
974 	printf("Freeing the pointer...\n");
975 	DisposPtr((Ptr)ptr);
976 	printf("Free'd.\n");
977 
978 	for (i = 0; i < 500000; i++)
979 		if ((i % 100000) == 0)printf(".");
980 	printf("\n");
981 
982 	mrg_ResErr = 0xdead;	/* set an error we know */
983 	printf("Getting error code...\n");
984 	i = ResError();
985 	printf("Result code (0xdeadbaaf): %x\n", i);
986 	printf("Getting an ADBS Resource...\n");
987 	handle = GetResource(0x41244253, 2);
988 	printf("Handle result from GetResource: 0x%lx\n", (long)handle);
989 	printf("Getting error code...\n");
990 	i = ResError();
991 	printf("Result code (-192?) : %d\n", i);
992 
993 	for (i = 0; i < 500000; i++)
994 		if ((i % 100000) == 0)printf(".");
995 	printf("\n");
996 
997 #if defined(MRG_TRACE)
998 	printf("Turning on a trace\n");
999 	tron();
1000 	printf("We are now tracing\n");
1001 	troff();
1002 	printf("Turning off trace\n");
1003 	dumptrace();
1004 #endif /* MRG_TRACE */
1005 
1006 	for (i = 0; i < 500000; i++)
1007 		if ((i % 100000) == 0)
1008 			printf(".");
1009 	printf("\n");
1010 #endif /* MRG_TEST */
1011 
1012 #if defined(MRG_DEBUG)
1013 	printf("after setting jump points\n");
1014 	printf("mrg: end init\n");
1015 #endif
1016 
1017 	if (1) {
1018 		/*
1019 		 * For the bloody Mac II ROMs, we have to map this space
1020 		 * so that the PRam functions will work.
1021 		 * Gee, Apple, is that a hard-coded hardware address in
1022 		 * your code?  I think so! (_ReadXPRam + 0x0062 on the
1023 		 * II)  We map the VIAs in here.  The C610 apparently
1024 		 * needs it, too, which means that a bunch of 040s do, too.
1025 		 * Once again, I regret the mapping changes I made...  -akb
1026 		 */
1027 #ifdef DIAGNOSTIC
1028 		printf("mrg: I/O map kludge for ROMs that use hardware %s",
1029 			"addresses directly.\n");
1030 #endif
1031 		pmap_map(0x50f00000, 0x50f00000, 0x50f00000 + 0x4000,
1032 			 VM_PROT_READ|VM_PROT_WRITE);
1033 	}
1034 }
1035 
1036 #ifdef MRG_ADB
1037 static void	setup_egret __P((void));
1038 
1039 static void
1040 setup_egret(void)
1041 {
1042 	if (0 != mrg_InitEgret) {
1043 
1044 	/* This initializes ADBState (mrg_ADBStore2) and
1045 	   enables interrupts */
1046 		__asm __volatile ("
1047 			movml	%%a0-%%a2,%%sp@-
1048 			movl	%1,%%a0		/* ADBState, mrg_adbstore2 */
1049 			movl	%0,%%a1
1050 			jbsr	%%a1@
1051 			movml	%%sp@+,%%a0-%%a2 "
1052 			:
1053 			: "g" (mrg_InitEgret), "g" (ADBState)
1054 			: "a0","a1");
1055 		jEgret = (void (*)) mrg_OStraps[0x92]; /* may have been set in asm() */
1056 	}
1057 	else printf("Help ...  No vector for InitEgret!!\n");
1058 
1059 #if defined(MRG_DEBUG)
1060 	printf("mrg: ADBIntrVector: 0x%8lx,  mrg_ADBIntrVector: 0x%8lx\n",
1061 			(long) mrg_romadbintr,
1062 			*((long *) 0x19a));
1063 	printf("mrg: EgretOSTrap: 0x%8lx\n",
1064 			(long) mrg_OStraps[0x92]);
1065 #endif
1066 }
1067 #endif
1068 
1069 void
1070 mrg_initadbintr()
1071 {
1072 	if (mac68k_machine.do_graybars)
1073 		printf("Got following HwCfgFlags: 0x%4x, 0x%8x, 0x%8x, 0x%8x\n",
1074 				HwCfgFlags, HwCfgFlags2, HwCfgFlags3, ADBReInit_JTBL);
1075 
1076 	if ((HwCfgFlags == 0) && (HwCfgFlags2 == 0) && (HwCfgFlags3 == 0)) {
1077 		printf("Caution: No HwCfgFlags from Booter, please "
1078 			"use at least booter version 1.8.\n");
1079 
1080 		if (current_mac_model->class == MACH_CLASSIIsi) {
1081 			printf("     ...  Using defaults for IIsi.\n");
1082 
1083 			/* Egret and ADBReInit look into these HwCfgFlags */
1084 			HwCfgFlags = 0xfc00;
1085 			HwCfgFlags2 = 0x0000773F;
1086 			HwCfgFlags3 = 0x000001a6;
1087 		}
1088 
1089 		printf("Using HwCfgFlags: 0x%4x, 0x%8x, 0x%8x\n",
1090 			HwCfgFlags, HwCfgFlags2, HwCfgFlags3);
1091 	}
1092 
1093 #ifdef MRG_ADB
1094 	/*
1095 	 * If we think there is an Egret in the machine, attempt to
1096 	 * set it up.  If not, just enable the interrupts (only on
1097 	 * some machines, others are already on from ADBReInit?).
1098 	 */
1099 	if (   ((HwCfgFlags3 & 0x0e) == 0x06 )
1100 	    || ((HwCfgFlags3 & 0x70) == 0x20 )) {
1101 		if (mac68k_machine.do_graybars)
1102 			printf("mrg: setup_egret:\n");
1103 
1104 		setup_egret();
1105 
1106 		if (mac68k_machine.do_graybars)
1107 			printf("mrg: setup_egret: done.\n");
1108 
1109 	} else {
1110 
1111 		if (mac68k_machine.do_graybars)
1112 			printf("mrg: Not setting up egret.\n");
1113 
1114 		via_reg(VIA1, vIFR) = 0x4;
1115 		via_reg(VIA1, vIER) = 0x84;
1116 
1117 		if (mac68k_machine.do_graybars)
1118 			printf("mrg: ADB interrupts enabled.\n");
1119 	}
1120 #else
1121 	/* Extra Egret setup required only for MRG ADB functions. */
1122 	printf("mrg: skipping egret setup\n");
1123 #endif /* MRG_ADB */
1124 }
1125 
1126 /*
1127  * NOTE:  By eliminating the setvectors routine and moving it's function
1128  *        to here we only have to deal with re-locating MacOS Addresses
1129  *        once and all in one place.
1130  */
1131 void
1132 mrg_fixupROMBase(obase, nbase)
1133 	caddr_t obase;
1134 	caddr_t nbase;
1135 {
1136 	u_int32_t oldbase, newbase;
1137 	romvec_t *rom;
1138 	int i;
1139 
1140 	oldbase = (u_int32_t) obase;
1141 	newbase = (u_int32_t) nbase;
1142 
1143 	/*
1144 	 * Grab the pointer to the Mac ROM Glue Vector table
1145 	 */
1146 	rom = mrg_MacOSROMVectors;
1147 
1148 	if (rom == NULL)
1149 		return;		/* whoops!  ROM vectors not defined! */
1150 
1151 	mrg_romident = rom->romident;
1152 
1153 	if (0 != mrg_ADBIntrPtr) {
1154 		mrg_romadbintr = mrg_ADBIntrPtr;
1155 		printf("mrg_fixup: using ADBIntrPtr from booter: 0x%08lx\n",
1156 		    (long)mrg_ADBIntrPtr);
1157 	} else
1158 		mrg_romadbintr = rom->adbintr == 0 ?
1159 		    0 : rom->adbintr - oldbase + newbase;
1160 
1161 	mrg_rompmintr = rom->pmintr == 0 ?
1162 	    0 : rom->pmintr - oldbase + newbase;
1163 	mrg_ADBAlternateInit = rom->ADBAlternateInit == 0 ?
1164 	    0 : rom->ADBAlternateInit - oldbase + newbase;
1165 
1166 	/*
1167 	 * mrg_adbstore becomes ADBBase
1168 	 */
1169 	*((u_int32_t *)(mrg_adbstore + 0x130)) = rom->adb130intr == 0 ?
1170 	    0 : (u_int32_t) rom->adb130intr - oldbase + newbase;
1171 
1172 	mrg_OStraps[0x77] = rom->CountADBs == 0 ?
1173 	    0 : rom->CountADBs - oldbase + newbase;
1174 	mrg_OStraps[0x78] = rom->GetIndADB == 0 ?
1175 	    0 : rom->GetIndADB - oldbase + newbase;
1176 	mrg_OStraps[0x79] = rom-> GetADBInfo == 0 ?
1177 	    0 : rom->GetADBInfo - oldbase + newbase;
1178 	mrg_OStraps[0x7a] = rom->SetADBInfo == 0 ?
1179 	    0 : rom->SetADBInfo - oldbase + newbase;
1180 	mrg_OStraps[0x7b] = rom->ADBReInit == 0 ?
1181 	    0 : rom->ADBReInit - oldbase + newbase;
1182 	mrg_OStraps[0x7c] = rom->ADBOp == 0 ?
1183 	    0 : rom->ADBOp - oldbase + newbase;
1184 	mrg_OStraps[0x85] = rom->PMgrOp == 0 ?
1185 	    0 : rom->PMgrOp - oldbase + newbase;
1186 	mrg_OStraps[0x51] = rom->ReadXPRam == 0 ?
1187 	    0 : rom->ReadXPRam - oldbase + newbase;
1188 	mrg_OStraps[0x38] = rom->WriteParam == 0 ?
1189 	    0 : rom->WriteParam - oldbase + newbase;/* WriteParam*/
1190 	mrg_OStraps[0x3a] = rom->SetDateTime == 0 ?
1191 	    0 : rom->SetDateTime - oldbase + newbase;/*SetDateTime*/
1192 	mrg_OStraps[0x3f] = rom->InitUtil == 0 ?
1193 	    0 : rom->InitUtil - oldbase + newbase;  /* InitUtil */
1194 	mrg_OStraps[0x51] = rom->ReadXPRam == 0 ?
1195 	    0 : rom->ReadXPRam - oldbase + newbase; /* ReadXPRam */
1196 	mrg_OStraps[0x52] = rom->WriteXPRam == 0 ?
1197 	    0 : rom->WriteXPRam - oldbase + newbase;/* WriteXPRam */
1198 
1199 	if (rom->Egret == 0) {
1200 		jEgret = 0;
1201 		mrg_OStraps[0x92] = 0;
1202 	} else {
1203 		jEgret = (void (*))(rom->Egret - oldbase + newbase);
1204 		mrg_OStraps[0x92] = rom->Egret - oldbase + newbase;
1205 	}
1206 	mrg_InitEgret = rom->InitEgret == 0 ?
1207 	    0 : rom->InitEgret - oldbase + newbase;
1208 
1209 	if (rom->jClkNoMem == 0) {
1210 		printf("WARNING: don't have a value for jClkNoMem, ");
1211 		printf("please contact:  walter@ghpc8.ihf.rwth-aachen.de\n");
1212 		printf("Can't read RTC without it. Using MacOS boot time.\n");
1213 		jClkNoMem = 0;
1214 	} else
1215 		jClkNoMem = (void (*))(rom->jClkNoMem - oldbase + newbase);
1216 	/*
1217 	 * Get the ToolBox Routines we may need.  These are
1218 	 * used in the ADB Initialization of some systems.
1219 	 * If we don't have the ROM addresses for these routines
1220 	 * we'll setup to catch the calls in our own dummy
1221 	 * routines. That way we can politely tell the user
1222 	 * what we'll need to complete initialization on the system.
1223 	 */
1224 	mrg_ToolBoxtraps[0x04d] = rom->FixDiv == 0 ?
1225 	    (caddr_t)mrg_FixDiv : rom->FixDiv - oldbase + newbase;
1226 	mrg_ToolBoxtraps[0x068] = rom->FixMul == 0 ?
1227 	    (caddr_t)mrg_FixMul : rom->FixMul - oldbase + newbase;
1228 
1229 	/*
1230 	 * Some systems also require this to be setup for use in
1231 	 * ADB Initialization.  Use whatever address was provided
1232 	 * to us in the romvec table for this system. This may
1233 	 * cause a problem on some systems, and may need a better
1234 	 * Trap handler in the future.
1235 	 */
1236 	ADBReInit_JTBL = rom->ADBReInit_JTBL == 0 ?
1237 	   0 : (u_int32_t)rom->ADBReInit_JTBL - oldbase + newbase;
1238 
1239 	/*
1240 	 * Setup to trap unexpected access to ADBProc which is used in
1241 	 * ADB Initialization on some systems. If the correct entry
1242 	 * point in the ADBInit code is selected, this address is
1243 	 * re-configured by the ROM during initialization. This feature
1244 	 * is not currently used by NetBSD.
1245 	 */
1246 	JADBProc = mrg_jadbprocpanic;
1247 
1248 	/*
1249 	 * Get the address of the first (top) Resource in the ROM.
1250 	 * This will be the head of a linked list of all Resources
1251 	 * in the ROM which will be mapped in mrg_InitResources.
1252 	 */
1253 	ROMResourceMap = rom->ROMResourceMap == 0 ?
1254 	    0 : (void (*))(rom->ROMResourceMap - oldbase + newbase);
1255 
1256 	for (i = 0; i < sizeof(mrg_AVInitEgretJT) / sizeof(mrg_AVInitEgretJT[0]); i++)
1257 		mrg_AVInitEgretJT[i] = mrg_AVInitEgretJT[i] == 0 ?
1258 		    0 : mrg_AVInitEgretJT[i] - oldbase + newbase;
1259 
1260 #if defined(MRG_DEBUG)
1261 	printf("mrg: ROM adbintr 0x%08lx -> 0x%08lx\n",
1262 	    (long)rom->adbintr, (long)mrg_romadbintr);
1263 	printf("mrg: ROM pmintr 0x%08lx -> 0x%08lx\n",
1264 	    (long)rom->pmintr, (long)mrg_rompmintr);
1265 	printf("mrg: OS trap 0x77 (CountADBs) = 0x%08lx -> 0x%08lx\n",
1266 	    (long)rom->CountADBs, (long)mrg_OStraps[0x77]);
1267 	printf("mrg: OS trap 0x78 (GetIndADB) = 0x%08lx -> 0x%08lx\n",
1268 	    (long)rom->GetIndADB, (long)mrg_OStraps[0x78]);
1269 	printf("mrg: OS trap 0x79 (GetADBInfo) = 0x%08lx -> 0x%08lx\n",
1270 	    (long)rom->GetADBInfo, (long)mrg_OStraps[0x79]);
1271 	printf("mrg: OS trap 0x7a (SetADBInfo) = 0x%08lx -> 0x%08lx\n",
1272 	    (long)rom->SetADBInfo, (long)mrg_OStraps[0x7a]);
1273 	printf("mrg: OS trap 0x7b (ADBReInit) = 0x%08lx -> 0x%08lx\n",
1274 	    (long)rom->ADBReInit, (long)mrg_OStraps[0x7b]);
1275 	printf("mrg: OS trap 0x7c (ADBOp) = 0x%08lx -> 0x%08lx\n",
1276 	    (long)rom->ADBOp, (long)mrg_OStraps[0x7c]);
1277 	printf("mrg: OS trap 0x85 (PMgrOp) = 0x%08lx -> 0x%08lx\n",
1278 	    (long)rom->PMgrOp, (long)mrg_OStraps[0x85]);
1279 	printf("mrg: OS trap 0x92 (Egret) = 0x%08lx -> 0x%08lx\n",
1280 	    (long)rom->Egret, (long)mrg_OStraps[0x92]);
1281 	printf("mrg: ROM ADBAltInit 0x%08lx -> 0x%08lx\n",
1282 	    (long)rom->ADBAlternateInit, (long)mrg_ADBAlternateInit);
1283 	printf("mrg: ROM ADBReInit_JTBL 0x%08lx -> 0x%08lx\n",
1284 	    (long)rom->ADBReInit_JTBL, (long)ADBReInit_JTBL);
1285 	printf("mrg: ROM InitEgret  0x%08lx -> 0x%08lx\n",
1286 	    (long)rom->InitEgret, (long)mrg_InitEgret);
1287 	printf("mrg: ROM Resource list-head 0x%08lx -> 0x%08lx\n",
1288 	    (long)rom->ROMResourceMap, (long)ROMResourceMap);
1289 #endif
1290 }
1291 
1292 #ifdef MRG_ADB
1293 void
1294 ADBAlternateInit(void)
1295 {
1296 	if (0 == mrg_ADBAlternateInit) {
1297 		ADBReInit();
1298 	} else {
1299  		__asm __volatile ("
1300 			movml	%%a0-%%a6/%%d0-%%d7,%%sp@-
1301 			movl	%0,%%a1
1302 			movl	%1,%%a3
1303 			jbsr	%%a1@
1304 			movml	%%sp@+,%%a0-%%a6/%%d0-%%d7"
1305 			:
1306 			: "g" (mrg_ADBAlternateInit), "g" (ADBBase)
1307 			: "a1","a3");
1308 	}
1309 }
1310 #endif /* MRG_ADB */
1311