xref: /netbsd-src/sys/arch/hp300/hp300/locore.s (revision 96c646f762cb6f483f3c55939207c109ca9fc03b)
1/*	$NetBSD: locore.s,v 1.186 2024/02/04 18:52:35 andvar Exp $	*/
2
3/*
4 * Copyright (c) 1980, 1990, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer
9 * Science Department.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * from: Utah $Hdr: locore.s 1.66 92/12/22$
36 *
37 *	@(#)locore.s	8.6 (Berkeley) 5/27/94
38 */
39
40/*
41 * Copyright (c) 1994, 1995 Gordon W. Ross
42 * Copyright (c) 1988 University of Utah.
43 *
44 * This code is derived from software contributed to Berkeley by
45 * the Systems Programming Group of the University of Utah Computer
46 * Science Department.
47 *
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions
50 * are met:
51 * 1. Redistributions of source code must retain the above copyright
52 *    notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright
54 *    notice, this list of conditions and the following disclaimer in the
55 *    documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software
57 *    must display the following acknowledgement:
58 *	This product includes software developed by the University of
59 *	California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors
61 *    may be used to endorse or promote products derived from this software
62 *    without specific prior written permission.
63 *
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE.
75 *
76 * from: Utah $Hdr: locore.s 1.66 92/12/22$
77 *
78 *	@(#)locore.s	8.6 (Berkeley) 5/27/94
79 */
80
81#include "opt_compat_netbsd.h"
82#include "opt_compat_sunos.h"
83#include "opt_ddb.h"
84#include "opt_fpsp.h"
85#include "opt_kgdb.h"
86#include "opt_lockdebug.h"
87#include "opt_fpu_emulate.h"
88#include "opt_m68k_arch.h"
89
90#include "assym.h"
91#include <machine/asm.h>
92#include <machine/trap.h>
93
94#include "opt_useleds.h"
95#ifdef USELEDS
96#include <hp300/hp300/leds.h>
97#endif
98
99#include "audio.h"
100#include "ksyms.h"
101
102#define MMUADDR(ar)	movl	_C_LABEL(MMUbase),ar
103#define CLKADDR(ar)	movl	_C_LABEL(CLKbase),ar
104
105/*
106 * This is for kvm_mkdb, and should be the address of the beginning
107 * of the kernel text segment (not necessarily the same as kernbase).
108 */
109	.text
110GLOBAL(kernel_text)
111
112/*
113 * Clear and skip the first page of text; it will not be mapped at
114 * VA 0.
115 *
116 * The bootloader places the bootinfo in this page, and we allocate
117 * a VA for it and map it later.
118 */
119	.fill	PAGE_SIZE/4,4,0
120
121/*
122 * Temporary stack for a variety of purposes.
123 * Try and make this the first thing is the data segment so it
124 * is page aligned.  Note that if we overflow here, we run into
125 * our text segment.
126 */
127	.data
128	.space	PAGE_SIZE
129ASLOCAL(tmpstk)
130
131/*
132 * Macro to relocate a symbol, used before MMU is enabled.
133 */
134#define	IMMEDIATE		#
135#define	_RELOC(var, ar)			\
136	movel	IMMEDIATE var,ar;	\
137	addl	%a5,ar
138
139#define	RELOC(var, ar)		_RELOC(_C_LABEL(var), ar)
140#define	ASRELOC(var, ar)	_RELOC(_ASM_LABEL(var), ar)
141
142/*
143 * Final bits of grunt work required to reboot the system.  The MMU
144 * must be disabled when this is invoked.
145 */
146#define DOREBOOT						\
147	/* Reset Vector Base Register to what PROM expects. */  \
148	movl	#0,%d0;						\
149	movc	%d0,%vbr;					\
150	/* Jump to REQ_REBOOT */				\
151	jmp	0x1A4;
152
153/*
154 * Initialization
155 *
156 * A4 contains the address of the end of the symtab
157 * A5 contains physical load point from boot
158 * VBR contains zero from ROM.  Exceptions will continue to vector
159 * through ROM until MMU is turned on at which time they will vector
160 * through our table (vectors.s).
161 */
162
163BSS(lowram,4)
164BSS(esym,4)
165
166ASENTRY_NOPROFILE(start)
167	movw	#PSL_HIGHIPL,%sr	| no interrupts
168	ASRELOC(tmpstk, %a0)
169	movl	%a0,%sp			| give ourselves a temporary stack
170	RELOC(esym, %a0)
171	movl	%a4,%a0@		| store end of symbol table
172	RELOC(lowram, %a0)
173	movl	%a5,%a0@		| store start of physical memory
174	movl	#CACHE_OFF,%d0
175	movc	%d0,%cacr		| clear and disable on-chip cache(s)
176
177/* check for internal HP-IB in SYSFLAG */
178	btst	#5,0xfffffed2		| internal HP-IB?
179	jeq	Lhaveihpib		| yes, have HP-IB just continue
180	RELOC(internalhpib, %a0)
181	movl	#0,%a0@			| no, clear associated address
182Lhaveihpib:
183
184	RELOC(boothowto, %a0)		| save reboot flags
185	movl	%d7,%a0@
186	RELOC(bootdev, %a0)		|   and boot device
187	movl	%d6,%a0@
188
189	/*
190	 * All data registers are now free.  All address registers
191	 * except %a5 are free.  %a5 is used by the RELOC() macro,
192	 * and cannot be used until after the MMU is enabled.
193	 */
194
195/* determine our CPU/MMU combo - check for all regardless of kernel config */
196	movl	#INTIOBASE+MMUBASE,%a1
197	movl	#DC_FREEZE,%d0		| data freeze bit
198	movc	%d0,%cacr		|   only exists on 68030
199	movc	%cacr,%d0		| read it back
200	tstl	%d0			| zero?
201	jeq	Lnot68030		| yes, we have 68020/68040
202
203	/*
204	 * 68030 models
205	 */
206
207	RELOC(mmutype, %a0)		| no, we have 68030
208	movl	#MMU_68030,%a0@		| set to reflect 68030 PMMU
209	RELOC(cputype, %a0)
210	movl	#CPU_68030,%a0@		| and 68030 CPU
211	RELOC(machineid, %a0)
212	movl	#0x80,%a1@(MMUCMD)	| set magic cookie
213	movl	%a1@(MMUCMD),%d0	| read it back
214	btst	#7,%d0			| cookie still on?
215	jeq	Lnot370			| no, 360, 362 or 375
216	movl	#0,%a1@(MMUCMD)		| clear magic cookie
217	movl	%a1@(MMUCMD),%d0	| read it back
218	btst	#7,%d0			| still on?
219	jeq	Lisa370			| no, must be a 370
220	movl	#HP_340,%a0@		| yes, must be a 340
221	jra	Lstart1
222Lnot370:
223	movl	#HP_360,%a0@		| type is at least a 360
224	movl	#0,%a1@(MMUCMD)		| clear magic cookie2
225	movl	%a1@(MMUCMD),%d0	| read it back
226	btst	#16,%d0			| still on?
227	jeq	Lisa36x			| no, must be a 360 or a 362
228	RELOC(mmuid, %a0)		| save MMU ID
229	lsrl	#MMUID_SHIFT,%d0
230	andl	#MMUID_MASK,%d0
231	movl	%d0,%a0@
232	RELOC(machineid, %a0)
233	cmpb	#MMUID_345,%d0		| are we a 345?
234	beq	Lisa345
235	cmpb	#MMUID_375,%d0		| how about a 375?
236	beq	Lisa375
237	movl	#HP_400,%a0@		| must be a 400
238	jra	Lhaspac
239Lisa36x:
240	/*
241	 * If we found a 360, we need to check for a 362 (neither the 360
242	 * nor the 362 have a nonzero mmuid). Identify 362 by checking
243	 * on-board VRX framebuffer which has secid 0x11 at dio scode 132.
244	 */
245	movl	#DIOII_BASE,%a0		| probe dio scode 132
246	ASRELOC(phys_badaddr,%a3)
247	jbsr	%a3@
248	tstl	%d0			| device at scode 132?
249	jne	Lstart1			| no, not 362, assume 360
250	movb	%a0@(DIO_IDOFF),%d0
251	cmpb	#DIO_DEVICE_ID_FRAMEBUFFER,%d0	| framebuffer?
252	jne	Lstart1			| no, not 362, assume 360
253	movb	%a0@(DIO_SECIDOFF),%d0
254	cmpb	#0x11,%d0		| VRX sti on 362?
255	jne	Lstart1			| no, not 362, assume 360
256	RELOC(machineid,%a0)
257	movl	#HP_362,%a0@
258	jra	Lstart1
259Lisa345:
260	movl	#HP_345,%a0@
261	jra	Lhaspac
262Lisa375:
263	movl	#HP_375,%a0@
264	jra	Lhaspac
265Lisa370:
266	movl	#HP_370,%a0@		| set to 370
267Lhaspac:
268	RELOC(ectype, %a0)
269	movl	#EC_PHYS,%a0@		| also has a physical address cache
270	jra	Lstart1
271
272	/*
273	 * End of 68030 section
274	 */
275
276Lnot68030:
277	bset	#31,%d0			| data cache enable bit
278	movc	%d0,%cacr		|   only exists on 68040
279	movc	%cacr,%d0		| read it back
280	tstl	%d0			| zero?
281	beq	Lis68020		| yes, we have 68020
282	moveq	#0,%d0			| now turn it back off
283	movec	%d0,%cacr		|   before we access any data
284
285	/*
286	 * 68040 models
287	 */
288
289	RELOC(mmutype, %a0)
290	movl	#MMU_68040,%a0@		| with a 68040 MMU
291	RELOC(cputype, %a0)
292	movl	#CPU_68040,%a0@		| and a 68040 CPU
293	RELOC(fputype, %a0)
294	movl	#FPU_68040,%a0@		| ...and FPU
295	RELOC(ectype, %a0)
296	movl	#EC_NONE,%a0@		| and no cache (for now XXX)
297	RELOC(mmuid,%a0)		| save MMU ID
298	movl	%a1@(MMUCMD),%d0
299	lsrl	#MMUID_SHIFT,%d0
300	andl	#MMUID_MASK,%d0
301	movl	%d0,%a0@
302	RELOC(machineid, %a0)
303	cmpb	#MMUID_425_T,%d0	| are we a 425t?
304	jeq	Lisa425
305	cmpb	#MMUID_425_S,%d0	| how about 425s?
306	jeq	Lisa425
307	cmpb	#MMUID_425_E,%d0	| or maybe a 425e?
308	jeq	Lisa425
309	cmpb	#MMUID_433_T,%d0	| or a 433t?
310	jeq	Lisa433
311	cmpb	#MMUID_433_S,%d0	| or a 433s?
312	jeq	Lisa433
313	cmpb	#MMUID_385,%d0		| or a 385?
314	jeq	Lisa385
315	cmpb	#MMUID_382,%d0		| or a 382?
316	jeq	Lisa382
317	movl	#HP_380,%a0@		| guess we're a 380
318	jra	Lstart1
319Lisa425:
320	movl	#HP_425,%a0@
321	jra	Lstart1
322Lisa433:
323	movl	#HP_433,%a0@
324	jra	Lstart1
325Lisa385:
326	movl	#HP_385,%a0@
327	jra	Lstart1
328Lisa382:
329	movl	#HP_382,%a0@
330	jra	Lstart1
331
332	/*
333	 * End of 68040 section
334	 */
335
336	/*
337	 * 68020 models
338	 */
339
340Lis68020:
341	RELOC(fputype, %a0)		| all of the 68020 systems
342	movl	#FPU_68881,%a0@		|   have a 68881 FPU
343	movl	#1,%a1@(MMUCMD)		| a 68020, write HP MMU location
344	movl	%a1@(MMUCMD),%d0	| read it back
345	btst	#0,%d0			| non-zero?
346	jne	Lishpmmu		| yes, we have HP MMU
347	RELOC(mmutype, %a0)
348	movl	#MMU_68851,%a0@		| no, we have PMMU
349	RELOC(machineid, %a0)
350	movl	#HP_330,%a0@		| and 330 CPU
351	jra	Lstart1
352Lishpmmu:
353	RELOC(ectype, %a0)		| 320 or 350
354	movl	#EC_VIRT,%a0@		| both have a virtual address cache
355	movl	#0x80,%a1@(MMUCMD)	| set magic cookie
356	movl	%a1@(MMUCMD),%d0	| read it back
357	btst	#7,%d0			| cookie still on?
358	jeq	Lis320			| no, just a 320
359	RELOC(machineid, %a0)
360	movl	#HP_350,%a0@		| yes, a 350
361	jra	Lstart1
362Lis320:
363	RELOC(machineid, %a0)
364	movl	#HP_320,%a0@
365
366	/*
367	 * End of 68020 section
368	 */
369
370Lstart1:
371	movl	#0,%a1@(MMUCMD)		| clear out MMU again
372/* initialize source/destination control registers for movs */
373	moveq	#FC_USERD,%d0		| user space
374	movc	%d0,%sfc		|   as source
375	movc	%d0,%dfc		|   and destination of transfers
376/* save the first PA as bootinfo_pa to map it to a virtual address later. */
377	movl	%a5,%d0			| lowram value from ROM via boot
378	RELOC(bootinfo_pa, %a0)
379	movl	%d0,%a0@		| save the lowram as bootinfo PA
380/* initialize memory sizes (for pmap_bootstrap) */
381	movl	#MAXADDR,%d1		| last page
382	moveq	#PGSHIFT,%d2
383	lsrl	%d2,%d1			| convert to page (click) number
384	RELOC(maxmem, %a0)
385	movl	%d1,%a0@		| save as maxmem
386	lsrl	%d2,%d0			| convert the lowram to page number
387	subl	%d0,%d1			| compute amount of RAM present
388	RELOC(physmem, %a0)
389	movl	%d1,%a0@		| and physmem
390
391/* configure kernel and lwp0 VA space so we can get going */
392#if NKSYMS || defined(DDB) || defined(MODULAR)
393	RELOC(esym,%a0)			| end of static kernel test/data/syms
394	movl	%a0@,%d5
395	jne	Lstart3
396#endif
397	movl	#_C_LABEL(end),%d5	| end of static kernel text/data
398Lstart3:
399	addl	#PAGE_SIZE-1,%d5
400	andl	#PG_FRAME,%d5		| round to a page
401	movl	%d5,%a4
402	addl	%a5,%a4			| convert to PA
403	pea	%a5@			| firstpa
404	pea	%a4@			| nextpa
405	RELOC(pmap_bootstrap,%a0)
406	jbsr	%a0@			| pmap_bootstrap(firstpa, nextpa)
407	addql	#8,%sp
408
409/*
410 * Prepare to enable MMU.
411 * Since the kernel is not mapped logical == physical we must insure
412 * that when the MMU is turned on, all prefetched addresses (including
413 * the PC) are valid.  In order guarantee that, we use the last physical
414 * page (which is conveniently mapped == VA) and load it up with enough
415 * code to defeat the prefetch, then we execute the jump back to here.
416 *
417 * Is this all really necessary, or am I paranoid??
418 */
419	RELOC(Sysseg_pa, %a0)		| system segment table addr
420	movl	%a0@,%d1		| read value (a PA)
421	RELOC(mmutype, %a0)
422	tstl	%a0@			| HP MMU?
423	jeq	Lhpmmu2			| yes, skip
424	cmpl	#MMU_68040,%a0@		| 68040?
425	jne	Lmotommu1		| no, skip
426	.long	0x4e7b1807		| movc %d1,%srp
427	jra	Lstploaddone
428Lmotommu1:
429	RELOC(protorp, %a0)
430	movl	%d1,%a0@(4)		| segtable address
431	pmove	%a0@,%srp		| load the supervisor root pointer
432	jra	Lstploaddone		| done
433Lhpmmu2:
434	moveq	#PGSHIFT,%d2
435	lsrl	%d2,%d1			| convert to page frame
436	movl	%d1,INTIOBASE+MMUBASE+MMUSSTP | load in sysseg table register
437Lstploaddone:
438	lea	MAXADDR,%a2		| PA of last RAM page
439#if 0
440	ASRELOC(Lhighcode, %a1)		| addr of high code
441	ASRELOC(Lehighcode, %a3)	| end addr
442#else
443	/* don't want pc-relative addressing */
444	.word	0x43f9			| lea Lhighcode, %a1
445	.long	Lhighcode
446	addl	%a5, %a1
447	.word	0x47f9			| lea Lehighcode, %a3
448	.long	Lehighcode
449	addl	%a5, %a3
450#endif
451Lcodecopy:
452	movw	%a1@+,%a2@+		| copy a word
453	cmpl	%a3,%a1			| done yet?
454	jcs	Lcodecopy		| no, keep going
455	jmp	MAXADDR			| go for it!
456
457	/*
458	 * BEGIN MMU TRAMPOLINE.  This section of code is not
459	 * executed in-place.  It's copied to the last page
460	 * of RAM (mapped va == pa) and executed there.
461	 */
462
463Lhighcode:
464	RELOC(mmutype, %a0)
465	tstl	%a0@			| HP MMU?
466	jeq	Lhpmmu3			| yes, skip
467	cmpl	#MMU_68040,%a0@		| 68040?
468	jne	Lmotommu2		| no, skip
469	movw	#0,INTIOBASE+MMUBASE+MMUCMD+2
470	movw	#MMU_IEN+MMU_CEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD+2
471					| enable FPU and caches
472	moveq	#0,%d0			| ensure TT regs are disabled
473	.long	0x4e7b0004		| movc %d0,%itt0
474	.long	0x4e7b0005		| movc %d0,%itt1
475	.long	0x4e7b0006		| movc %d0,%dtt0
476	.long	0x4e7b0007		| movc %d0,%dtt1
477	.word	0xf4d8			| cinva bc
478	.word	0xf518			| pflusha
479	movl	#MMU40_TCR_BITS,%d0
480	.long	0x4e7b0003		| movc %d0,%tc
481	movl	#CACHE40_ON,%d0
482	movc	%d0,%cacr		| turn on both caches
483	jmp	Lenab1:l		| forced not be pc-relative
484Lmotommu2:
485	movl	#MMU_IEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD
486					| enable 68881 and i-cache
487	pflusha
488	RELOC(prototc, %a2)
489	movl	#MMU51_TCR_BITS,%a2@	| value to load TC with
490	pmove	%a2@,%tc		| load it
491	jmp	Lenab1:l		| forced not be pc-relative
492Lhpmmu3:
493	movl	#0,INTIOBASE+MMUBASE+MMUCMD		| clear external cache
494	movl	#MMU_ENAB,INTIOBASE+MMUBASE+MMUCMD	| turn on MMU
495	jmp	Lenab1:l		| forced not be pc-relative
496Lehighcode:
497
498	/*
499	 * END MMU TRAMPOLINE.  Address register %a5 is now free.
500	 */
501
502/*
503 * Should be running mapped from this point on
504 */
505Lenab1:
506	lea	_ASM_LABEL(tmpstk),%sp	| re-load the temporary stack
507	jbsr	_C_LABEL(vec_init)	| initialize the vector table
508/* call final pmap setup */
509	jbsr	_C_LABEL(pmap_bootstrap_finalize)
510/* set kernel stack, user SP */
511	movl	_C_LABEL(lwp0uarea),%a1	| get lwp0 uarea
512	lea	%a1@(USPACE-4),%sp	| set kernel stack to end of area
513	movl	#USRSTACK-4,%a2
514	movl	%a2,%usp		| init user SP
515
516	jbsr	_C_LABEL(fpu_probe)
517	movl	%d0,_C_LABEL(fputype)
518	tstl	_C_LABEL(fputype)	| Have an FPU?
519	jeq	Lenab2			| No, skip.
520	clrl	%a1@(PCB_FPCTX)		| ensure null FP context
521	movl	%a1,%sp@-
522	jbsr	_C_LABEL(m68881_restore) | restore it (does not kill %a1)
523	addql	#4,%sp
524Lenab2:
525/* flush TLB and turn on caches */
526	jbsr	_C_LABEL(_TBIA)		| invalidate TLB
527	cmpl	#MMU_68040,_C_LABEL(mmutype) | 68040?
528	jeq	Lnocache0		| yes, cache already on
529	movl	#CACHE_ON,%d0
530	movc	%d0,%cacr		| clear cache(s)
531	tstl	_C_LABEL(ectype)
532	jeq	Lnocache0
533	MMUADDR(%a0)
534	orl	#MMU_CEN,%a0@(MMUCMD)	| turn on external cache
535Lnocache0:
536/* Final setup for call to main(). */
537	jbsr	_C_LABEL(hp300_init)
538
539/*
540 * Create a fake exception frame so that cpu_lwp_fork() can copy it.
541 * main() nevers returns; we exit to user mode from a forked process
542 * later on.
543 */
544	clrw	%sp@-			| vector offset/frame type
545	clrl	%sp@-			| PC - filled in by "execve"
546	movw	#PSL_USER,%sp@-		| in user mode
547	clrl	%sp@-			| stack adjust count and padding
548	lea	%sp@(-64),%sp		| construct space for D0-D7/A0-A7
549	lea	_C_LABEL(lwp0),%a0	| save pointer to frame
550	movl	%sp,%a0@(L_MD_REGS)	|   in lwp0.l_md.md_regs
551
552	jra	_C_LABEL(main)		| main()
553	PANIC("main() returned")
554	/* NOTREACHED */
555
556/*
557 * Trap/interrupt vector routines
558 */
559#include <m68k/m68k/trap_subr.s>
560
561/*
562 * Use common m68k bus error and address error handlers.
563 */
564#include <m68k/m68k/busaddrerr.s>
565
566/*
567 * FP exceptions.
568 */
569ENTRY_NOPROFILE(fpfline)
570#if defined(M68040)
571	cmpl	#FPU_68040,_C_LABEL(fputype) | 68040 FPU?
572	jne	Lfp_unimp		| no, skip FPSP
573	cmpw	#0x202c,%sp@(6)		| format type 2?
574	jne	_C_LABEL(illinst)	| no, not an FP emulation
575Ldofp_unimp:
576#ifdef FPSP
577	jmp	_ASM_LABEL(fpsp_unimp)	| yes, go handle it
578#endif
579Lfp_unimp:
580#endif /* M68040 */
581#ifdef FPU_EMULATE
582	clrl	%sp@-			| stack adjust count
583	moveml	#0xFFFF,%sp@-		| save registers
584	moveq	#T_FPEMULI,%d0		| denote as FP emulation trap
585	jra	_ASM_LABEL(fault)	| do it
586#else
587	jra	_C_LABEL(illinst)
588#endif
589
590ENTRY_NOPROFILE(fpunsupp)
591#if defined(M68040)
592	cmpl	#FPU_68040,_C_LABEL(fputype) | 68040 FPU?
593	jne	_C_LABEL(illinst)	| no, treat as illinst
594#ifdef FPSP
595	jmp	_ASM_LABEL(fpsp_unsupp)	| yes, go handle it
596#endif
597Lfp_unsupp:
598#endif /* M68040 */
599#ifdef FPU_EMULATE
600	clrl	%sp@-			| stack adjust count
601	moveml	#0xFFFF,%sp@-		| save registers
602	moveq	#T_FPEMULD,%d0		| denote as FP emulation trap
603	jra	_ASM_LABEL(fault)	| do it
604#else
605	jra	_C_LABEL(illinst)
606#endif
607
608/*
609 * Handles all other FP coprocessor exceptions.
610 * Note that since some FP exceptions generate mid-instruction frames
611 * and may cause signal delivery, we need to test for stack adjustment
612 * after the trap call.
613 */
614ENTRY_NOPROFILE(fpfault)
615	clrl	%sp@-			| stack adjust count
616	moveml	#0xFFFF,%sp@-		| save user registers
617	movl	%usp,%a0		| and save
618	movl	%a0,%sp@(FR_SP)		|   the user stack pointer
619	clrl	%sp@-			| no VA arg
620	movl	_C_LABEL(curpcb),%a0	| current pcb
621	lea	%a0@(PCB_FPCTX),%a0	| address of FP savearea
622	fsave	%a0@			| save state
623#if defined(M68040) || defined(M68060)
624	/* always null state frame on 68040, 68060 */
625	cmpl	#FPU_68040,_C_LABEL(fputype)
626	jge	Lfptnull
627#endif
628	tstb	%a0@			| null state frame?
629	jeq	Lfptnull		| yes, safe
630	clrw	%d0			| no, need to tweak BIU
631	movb	%a0@(1),%d0		| get frame size
632	bset	#3,%a0@(0,%d0:w)	| set exc_pend bit of BIU
633Lfptnull:
634	fmovem	%fpsr,%sp@-		| push %fpsr as code argument
635	frestore %a0@			| restore state
636	movl	#T_FPERR,%sp@-		| push type arg
637	jra	_ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup
638
639/*
640 * Other exceptions only cause four and six word stack frame and require
641 * no post-trap stack adjustment.
642 */
643
644ENTRY_NOPROFILE(badtrap)
645	moveml	#0xC0C0,%sp@-		| save scratch regs
646	movw	%sp@(22),%sp@-		| push exception vector info
647	clrw	%sp@-
648	movl	%sp@(22),%sp@-		| and PC
649	jbsr	_C_LABEL(straytrap)	| report
650	addql	#8,%sp			| pop args
651	moveml	%sp@+,#0x0303		| restore regs
652	jra	_ASM_LABEL(rei)		| all done
653
654ENTRY_NOPROFILE(trap0)
655	clrl	%sp@-			| stack adjust count
656	moveml	#0xFFFF,%sp@-		| save user registers
657	movl	%usp,%a0		| save the user SP
658	movl	%a0,%sp@(FR_SP)		|   in the savearea
659	movl	%d0,%sp@-		| push syscall number
660	jbsr	_C_LABEL(syscall)	| handle it
661	addql	#4,%sp			| pop syscall arg
662	tstl	_C_LABEL(astpending)	| AST pending?
663	jne	Lrei			| yes, handle it via trap
664	movl	%sp@(FR_SP),%a0		| grab and restore
665	movl	%a0,%usp		|   user SP
666	moveml	%sp@+,#0x7FFF		| restore most registers
667	addql	#8,%sp			| pop SP and stack adjust
668	rte
669
670/*
671 * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD)
672 *	cachectl(command, addr, length)
673 * command in %d0, addr in %a1, length in %d1
674 */
675ENTRY_NOPROFILE(trap12)
676	movl	_C_LABEL(curlwp),%a0
677	movl	%a0@(L_PROC),%sp@-	| push current proc pointer
678	movl	%d1,%sp@-		| push length
679	movl	%a1,%sp@-		| push addr
680	movl	%d0,%sp@-		| push command
681	jbsr	_C_LABEL(cachectl1)	| do it
682	lea	%sp@(16),%sp		| pop args
683	jra	_ASM_LABEL(rei)		| all done
684
685/*
686 * Trace (single-step) trap.  Kernel-mode is special.
687 * User mode traps are simply passed on to trap().
688 */
689ENTRY_NOPROFILE(trace)
690	clrl	%sp@-			| stack adjust count
691	moveml	#0xFFFF,%sp@-
692	moveq	#T_TRACE,%d0
693
694	| Check PSW and see what happen.
695	|   T=0 S=0	(should not happen)
696	|   T=1 S=0	trace trap from user mode
697	|   T=0 S=1	trace trap on a trap instruction
698	|   T=1 S=1	trace trap from system mode (kernel breakpoint)
699
700	movw	%sp@(FR_HW),%d1		| get PSW
701	notw	%d1			| XXX no support for T0 on 680[234]0
702	andw	#PSL_TS,%d1		| from system mode (T=1, S=1)?
703	jeq	Lkbrkpt			| yes, kernel breakpoint
704	jra	_ASM_LABEL(fault)	| no, user-mode fault
705
706/*
707 * Trap 15 is used for:
708 *	- GDB breakpoints (in user programs)
709 *	- KGDB breakpoints (in the kernel)
710 *	- trace traps for SUN binaries (not fully supported yet)
711 * User mode traps are simply passed to trap().
712 */
713ENTRY_NOPROFILE(trap15)
714	clrl	%sp@-			| stack adjust count
715	moveml	#0xFFFF,%sp@-
716	moveq	#T_TRAP15,%d0
717	movw	%sp@(FR_HW),%d1		| get PSW
718	andw	#PSL_S,%d1		| from system mode?
719	jne	Lkbrkpt			| yes, kernel breakpoint
720	jra	_ASM_LABEL(fault)	| no, user-mode fault
721
722Lkbrkpt: | Kernel-mode breakpoint or trace trap. (%d0=trap_type)
723	| Save the system sp rather than the user sp.
724	movw	#PSL_HIGHIPL,%sr	| lock out interrupts
725	lea	%sp@(FR_SIZE),%a6	| Save stack pointer
726	movl	%a6,%sp@(FR_SP)		|  from before trap
727
728	| If were are not on tmpstk switch to it.
729	| (so debugger can change the stack pointer)
730	movl	%a6,%d1
731	cmpl	#_ASM_LABEL(tmpstk),%d1
732	jls	Lbrkpt2			| already on tmpstk
733	| Copy frame to the temporary stack
734	movl	%sp,%a0			| %a0=src
735	lea	_ASM_LABEL(tmpstk)-96,%a1 | %a1=dst
736	movl	%a1,%sp			| %sp=new frame
737	moveq	#FR_SIZE,%d1
738Lbrkpt1:
739	movl	%a0@+,%a1@+
740	subql	#4,%d1
741	jgt	Lbrkpt1
742
743Lbrkpt2:
744	| Call the trap handler for the kernel debugger.
745	| Do not call trap() to do it, so that we can
746	| set breakpoints in trap() if we want.  We know
747	| the trap type is either T_TRACE or T_BREAKPOINT.
748	| If we have both DDB and KGDB, let KGDB see it first,
749	| because KGDB will just return 0 if not connected.
750	| Save args in %d2, %a2
751	movl	%d0,%d2			| trap type
752	movl	%sp,%a2			| frame ptr
753#ifdef KGDB
754	| Let KGDB handle it (if connected)
755	movl	%a2,%sp@-		| push frame ptr
756	movl	%d2,%sp@-		| push trap type
757	jbsr	_C_LABEL(kgdb_trap)	| handle the trap
758	addql	#8,%sp			| pop args
759	cmpl	#0,%d0			| did kgdb handle it?
760	jne	Lbrkpt3			| yes, done
761#endif
762#ifdef DDB
763	| Let DDB handle it
764	movl	%a2,%sp@-		| push frame ptr
765	movl	%d2,%sp@-		| push trap type
766	jbsr	_C_LABEL(kdb_trap)	| handle the trap
767	addql	#8,%sp			| pop args
768#if 0	/* not needed on hp300 */
769	cmpl	#0,%d0			| did ddb handle it?
770	jne	Lbrkpt3			| yes, done
771#endif
772#endif
773	/* Sun 3 drops into PROM here. */
774Lbrkpt3:
775	| The stack pointer may have been modified, or
776	| data below it modified (by kgdb push call),
777	| so push the hardware frame at the current sp
778	| before restoring registers and returning.
779
780	movl	%sp@(FR_SP),%a0		| modified %sp
781	lea	%sp@(FR_SIZE),%a1	| end of our frame
782	movl	%a1@-,%a0@-		| copy 2 longs with
783	movl	%a1@-,%a0@-		| ... predecrement
784	movl	%a0,%sp@(FR_SP)		| %sp = h/w frame
785	moveml	%sp@+,#0x7FFF		| restore all but %sp
786	movl	%sp@,%sp		| ... and %sp
787	rte				| all done
788
789/*
790 * Interrupt handlers.
791 * All device interrupts are auto-vectored.  The CPU provides
792 * the vector 0x18+level.  Note we count spurious interrupts, but
793 * we don't do anything else with them.
794 */
795
796/* 64-bit evcnt counter increments */
797#define EVCNT_COUNTER(ipl)					\
798	_C_LABEL(m68k_intr_evcnt) + (ipl)*SIZEOF_EVCNT + EV_COUNT
799#define EVCNT_INCREMENT(ipl)					\
800	clrl	%d0;						\
801	addql	#1,EVCNT_COUNTER(ipl)+4;			\
802	movel	EVCNT_COUNTER(ipl),%d1;				\
803	addxl	%d0,%d1;					\
804	movel	%d1,EVCNT_COUNTER(ipl)
805
806ENTRY_NOPROFILE(lev6intr)	/* level 6: clock */
807	addql	#1,_C_LABEL(intr_depth)	| entering interrupt
808	INTERRUPT_SAVEREG
809	CLKADDR(%a0)
810	movb	%a0@(CLKSR),%d0		| read clock status
811Lclkagain:
812	btst	#0,%d0			| clear timer1 int immediately to
813	jeq	Lnotim1			|  minimize chance of losing another
814	movpw	%a0@(CLKMSB1),%d1	|  due to statintr processing delay
815	movl	_C_LABEL(clkint),%d1	| clkcounter += clkint
816	addl	%d1,_C_LABEL(clkcounter)
817Lnotim1:
818	btst	#2,%d0			| timer3 interrupt?
819	jeq	Lnotim3			| no, skip statclock
820	movpw	%a0@(CLKMSB3),%d1	| clear timer3 interrupt
821	lea	%sp@(0),%a1		| a1 = &clockframe
822	movl	%d0,%sp@-		| save status
823	movl	%a1,%sp@-
824	jbsr	_C_LABEL(statintr)	| statintr(&frame)
825	addql	#4,%sp
826	movl	%sp@+,%d0		| restore pre-statintr status
827	CLKADDR(%a0)
828Lnotim3:
829	btst	#0,%d0			| timer1 interrupt?
830	jeq	Lrecheck		| no, skip hardclock
831	EVCNT_INCREMENT(6)
832	lea	%sp@(0),%a1		| a1 = &clockframe
833	movl	%a1,%sp@-
834#ifdef USELEDS
835	tstl	_C_LABEL(ledaddr)	| using LEDs?
836	jeq	Lnoleds0		| no, skip this code
837	movl	_ASM_LABEL(heartbeat),%d0 | get tick count
838	addql	#1,%d0			|  increment
839	movl	_C_LABEL(hz),%d1
840	addl	#50,%d1			| get the timing a little closer
841	tstb	_ASM_LABEL(beatstatus)	| time to slow down?
842	jeq	Lslowthrob		| yes, slow down
843	lsrl	#3,%d1			| no, fast throb
844Lslowthrob:
845	lsrl	#1,%d1			| slow throb
846	cmpl	%d0,%d1			| are we there yet?
847	jne	Lnoleds1		| no, nothing to do
848	addqb	#1,_ASM_LABEL(beatstatus) | incr beat status
849	cmpb	#3,_ASM_LABEL(beatstatus) | time to reset?
850	jle	Ltwinkle		  | no, twinkle the lights
851	movb	#0,_ASM_LABEL(beatstatus) | reset the status indicator
852Ltwinkle:
853	movl	#LED_PULSE,%sp@-
854	movl	#LED_DISK+LED_LANRCV+LED_LANXMT,%sp@-
855	clrl	%sp@-
856	jbsr	_C_LABEL(ledcontrol)	| toggle pulse, turn all others off
857	lea	%sp@(12),%sp
858	movql	#0,%d0
859Lnoleds1:
860	movl	%d0,_ASM_LABEL(heartbeat)
861Lnoleds0:
862#endif /* USELEDS */
863	jbsr	_C_LABEL(hardclock)	| hardclock(&frame)
864	addql	#4,%sp
865Lrecheck:
866	CPUINFO_INCREMENT(CI_NINTR)	| chalk up another interrupt
867	CLKADDR(%a0)
868	movb	%a0@(CLKSR),%d0		| see if anything happened
869	jmi	Lclkagain		|  while we were in hardclock/statintr
870#if NAUDIO >0
871	jbsr	_C_LABEL(m68k_intr_autovec) | call dispatch routine
872					    |  in case the audio device
873					    |  generated the interrupt
874#endif
875	INTERRUPT_RESTOREREG
876	subql	#1,_C_LABEL(intr_depth)	| exiting from interrupt
877	jra	_ASM_LABEL(rei)		| all done
878
879ENTRY_NOPROFILE(lev7intr)	/* level 7: parity errors, reset key */
880	clrl	%sp@-
881	moveml	#0xFFFF,%sp@-		| save registers
882	EVCNT_INCREMENT(7)
883	movl	%usp,%a0		| and save
884	movl	%a0,%sp@(FR_SP)		|   the user stack pointer
885	jbsr	_C_LABEL(nmihand)	| call handler
886	movl	%sp@(FR_SP),%a0		| restore
887	movl	%a0,%usp		|   user SP
888	moveml	%sp@+,#0x7FFF		| and remaining registers
889	addql	#8,%sp			| pop SP and stack adjust
890	jra	_ASM_LABEL(rei)		| all done
891
892/*
893 * Emulation of VAX REI instruction.
894 *
895 * This code deals with checking for and servicing
896 * ASTs (profiling, scheduling).
897 * After identifying that we need an AST we drop the IPL
898 * to allow device interrupts.
899 *
900 * This code is complicated by the fact that sendsig may have been called
901 * necessitating a stack cleanup.
902 */
903
904ASENTRY_NOPROFILE(rei)
905	tstl	_C_LABEL(astpending)	| AST pending?
906	jne	1f			| no, done
907	rte
9081:
909	btst	#5,%sp@			| yes, are we returning to user mode?
910	jeq	2f			| no, done
911	rte
9122:
913	movw	#PSL_LOWIPL,%sr		| lower SPL
914	clrl	%sp@-			| stack adjust
915	moveml	#0xFFFF,%sp@-		| save all registers
916	movl	%usp,%a1		| including
917	movl	%a1,%sp@(FR_SP)		|    the users SP
918Lrei:
919	clrl	%sp@-			| VA == none
920	clrl	%sp@-			| code == none
921	movl	#T_ASTFLT,%sp@-		| type == async system trap
922	pea	%sp@(12)		| fp == address of trap frame
923	jbsr	_C_LABEL(trap)		| go handle it
924	lea	%sp@(16),%sp		| pop value args
925	movl	%sp@(FR_SP),%a0		| restore user SP
926	movl	%a0,%usp		|   from save area
927	movw	%sp@(FR_ADJ),%d0	| need to adjust stack?
928	jne	Laststkadj		| yes, go to it
929	moveml	%sp@+,#0x7FFF		| no, restore most user regs
930	addql	#8,%sp			| toss SP and stack adjust
931	rte				| and do real RTE
932Laststkadj:
933	lea	%sp@(FR_HW),%a1		| pointer to HW frame
934	addql	#8,%a1			| source pointer
935	movl	%a1,%a0			| source
936	addw	%d0,%a0			|  + hole size = dest pointer
937	movl	%a1@-,%a0@-		| copy
938	movl	%a1@-,%a0@-		|  8 bytes
939	movl	%a0,%sp@(FR_SP)		| new SSP
940	moveml	%sp@+,#0x7FFF		| restore user registers
941	movl	%sp@,%sp		| and our SP
942	rte				| and do real RTE
943
944/*
945 * Primitives
946 */
947
948/*
949 * Use common m68k process/lwp switch and context save subroutines.
950 */
951#define FPCOPROC	/* XXX: Temp. reqd. */
952#include <m68k/m68k/switch_subr.s>
953
954
955#if defined(M68040)
956ENTRY(suline)
957	movl	%sp@(4),%a0		| address to write
958	movl	_C_LABEL(curpcb),%a1	| current pcb
959	movl	#Lslerr,%a1@(PCB_ONFAULT) | where to return to on a fault
960	movl	%sp@(8),%a1		| address of line
961	movl	%a1@+,%d0		| get lword
962	movsl	%d0,%a0@+		| put lword
963	nop				| sync
964	movl	%a1@+,%d0		| get lword
965	movsl	%d0,%a0@+		| put lword
966	nop				| sync
967	movl	%a1@+,%d0		| get lword
968	movsl	%d0,%a0@+		| put lword
969	nop				| sync
970	movl	%a1@+,%d0		| get lword
971	movsl	%d0,%a0@+		| put lword
972	nop				| sync
973	moveq	#0,%d0			| indicate no fault
974	jra	Lsldone
975Lslerr:
976	moveq	#-1,%d0
977Lsldone:
978	movl	_C_LABEL(curpcb),%a1	| current pcb
979	clrl	%a1@(PCB_ONFAULT)	| clear fault address
980	rts
981#endif
982
983ENTRY(ecacheon)
984	tstl	_C_LABEL(ectype)
985	jeq	Lnocache7
986	MMUADDR(%a0)
987	orl	#MMU_CEN,%a0@(MMUCMD)
988Lnocache7:
989	rts
990
991ENTRY(ecacheoff)
992	tstl	_C_LABEL(ectype)
993	jeq	Lnocache8
994	MMUADDR(%a0)
995	andl	#~MMU_CEN,%a0@(MMUCMD)
996Lnocache8:
997	rts
998
999/*
1000 * _delay(u_int N)
1001 *
1002 * Delay for at least (N/256) microseconds.
1003 * This routine depends on the variable:  delay_divisor
1004 * which should be set based on the CPU clock rate.
1005 */
1006ENTRY_NOPROFILE(_delay)
1007	| %d0 = arg = (usecs << 8)
1008	movl	%sp@(4),%d0
1009	| %d1 = delay_divisor
1010	movl	_C_LABEL(delay_divisor),%d1
1011	jra	L_delay			/* Jump into the loop! */
1012
1013	/*
1014	 * Align the branch target of the loop to a half-line (8-byte)
1015	 * boundary to minimize cache effects.  This guarantees both
1016	 * that there will be no prefetch stalls due to cache line burst
1017	 * operations and that the loop will run from a single cache
1018	 * half-line.
1019	 */
1020	.align	8
1021L_delay:
1022	subl	%d1,%d0
1023	jgt	L_delay
1024	rts
1025
1026/*
1027 * Probe a memory address, and see if it causes a bus error.
1028 * This function is only to be used in physical mode, and before our
1029 * trap vectors are initialized.
1030 * Invoke with address to probe in %a0.
1031 * Alters: %a3 %d0
1032 */
1033#define BUSERR  0xfffffffc
1034ASLOCAL(phys_badaddr)
1035	ASRELOC(_bsave,%a3)
1036	movl	BUSERR,%a3@		| save ROM bus error handler
1037	ASRELOC(_ssave,%a3)
1038	movl	%sp,%a3@		| and current stack pointer
1039	ASRELOC(catchbad,%a3)
1040	movl	%a3,BUSERR		| plug in our handler
1041	movb	%a0@,%d0		| access address
1042	ASRELOC(_bsave,%a3)		| no fault!
1043	movl	%a3@,BUSERR
1044	clrl	%d0			| return success
1045	rts
1046ASLOCAL(catchbad)
1047	ASRELOC(_bsave,%a3)		| got a bus error, so restore handler
1048	movl	%a3@,BUSERR
1049	ASRELOC(_ssave,%a3)
1050	movl	%a3@,%sp		| and stack
1051	moveq	#1,%d0			| return fault
1052	rts
1053#undef	BUSERR
1054
1055	.data
1056ASLOCAL(_bsave)
1057	.long   0
1058ASLOCAL(_ssave)
1059	.long   0
1060	.text
1061
1062/*
1063 * Handle the nitty-gritty of rebooting the machine.
1064 * Basically we just turn off the MMU and jump to the appropriate ROM routine.
1065 * Note that we must be running in an address range that is mapped one-to-one
1066 * logical to physical so that the PC is still valid immediately after the MMU
1067 * is turned off.  We have conveniently mapped the last page of physical
1068 * memory this way.
1069 */
1070ENTRY_NOPROFILE(doboot)
1071#if defined(M68040)
1072	cmpl	#MMU_68040,_C_LABEL(mmutype) | 68040?
1073	jeq	Lnocache5		| yes, skip
1074#endif
1075	movl	#CACHE_OFF,%d0
1076	movc	%d0,%cacr		| disable on-chip cache(s)
1077	tstl	_C_LABEL(ectype)	| external cache?
1078	jeq	Lnocache5		| no, skip
1079	MMUADDR(%a0)
1080	andl	#~MMU_CEN,%a0@(MMUCMD)	| disable external cache
1081Lnocache5:
1082	lea	MAXADDR,%a0		| last page of physical memory
1083	movl	_C_LABEL(boothowto),%a0@+ | store howto
1084	movl	_C_LABEL(bootdev),%a0@+	| and devtype
1085	lea	Lbootcode,%a1		| start of boot code
1086	lea	Lebootcode,%a3		| end of boot code
1087Lbootcopy:
1088	movw	%a1@+,%a0@+		| copy a word
1089	cmpl	%a3,%a1			| done yet?
1090	jcs	Lbootcopy		| no, keep going
1091#if defined(M68040)
1092	cmpl	#MMU_68040,_C_LABEL(mmutype) | 68040?
1093	jne	LmotommuE		| no, skip
1094	.word	0xf4f8			| cpusha bc
1095LmotommuE:
1096#endif
1097	jmp	MAXADDR+8		| jump to last page
1098
1099Lbootcode:
1100	lea	MAXADDR+0x800,%sp	| physical SP in case of NMI
1101#if defined(M68040)
1102	cmpl	#MMU_68040,_C_LABEL(mmutype) | 68040?
1103	jne	LmotommuF		| no, skip
1104	movl	#0,%d0
1105	movc	%d0,%cacr		| caches off
1106	.long	0x4e7b0003		| movc %d0,%tc
1107	movl	%d2,MAXADDR+PAGE_SIZE-4	| restore old high page contents
1108	DOREBOOT
1109LmotommuF:
1110#endif
1111#if defined(M68K_MMU_MOTOROLA)
1112	tstl	_C_LABEL(mmutype)	| HP MMU?
1113	jeq	LhpmmuB			| yes, skip
1114	movl	#0,%a0@			| value for pmove to TC (turn off MMU)
1115	pmove	%a0@,%tc		| disable MMU
1116	DOREBOOT
1117LhpmmuB:
1118#endif
1119#if defined(M68K_MMU_HP)
1120	MMUADDR(%a0)
1121	movl	#0xFFFF0000,%a0@(MMUCMD)	| totally disable MMU
1122	movl	%d2,MAXADDR+PAGE_SIZE-4	| restore old high page contents
1123	DOREBOOT
1124#endif
1125Lebootcode:
1126
1127/*
1128 * Misc. global variables.
1129 */
1130	.data
1131GLOBAL(machineid)
1132	.long	HP_320			| default to 320
1133
1134GLOBAL(mmuid)
1135	.long	0			| default to nothing
1136
1137GLOBAL(mmutype)
1138	.long	MMU_HP			| default to HP MMU
1139
1140GLOBAL(cputype)
1141	.long	CPU_68020		| default to 68020 CPU
1142
1143GLOBAL(ectype)
1144	.long	EC_NONE			| external cache type, default to none
1145
1146GLOBAL(fputype)
1147	.long	FPU_68882		| default to 68882 FPU
1148
1149GLOBAL(prototc)
1150	.long	0			| prototype translation control
1151
1152GLOBAL(internalhpib)
1153	.long	1			| has internal HP-IB, default to yes
1154
1155GLOBAL(intiobase)
1156	.long	0			| KVA of base of internal IO space
1157
1158GLOBAL(intiolimit)
1159	.long	0			| KVA of end of internal IO space
1160
1161GLOBAL(extiobase)
1162	.long	0			| KVA of base of external IO space
1163
1164GLOBAL(CLKbase)
1165	.long	0			| KVA of base of clock registers
1166
1167GLOBAL(MMUbase)
1168	.long	0			| KVA of base of HP MMU registers
1169
1170#ifdef USELEDS
1171ASLOCAL(heartbeat)
1172	.long	0			| clock ticks since last heartbeat
1173
1174ASLOCAL(beatstatus)
1175	.long	0			| for determining a fast or slow throb
1176#endif
1177
1178#ifdef DEBUG
1179ASGLOBAL(fulltflush)
1180	.long	0
1181
1182ASGLOBAL(fullcflush)
1183	.long	0
1184#endif
1185