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