Home | History | Annotate | Line # | Download | only in cesfic
      1 /*	$NetBSD: locore.s,v 1.46 2024/01/17 12:33:49 thorpej 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_fpu_emulate.h"
     86 #include "opt_m68k_arch.h"
     87 
     88 #include "ksyms.h"
     89 #include "assym.h"
     90 #include <machine/asm.h>
     91 #include <machine/trap.h>
     92 
     93 /*
     94  * This is for kvm_mkdb, and should be the address of the beginning
     95  * of the kernel text segment (not necessarily the same as kernbase).
     96  */
     97 	.text
     98 GLOBAL(kernel_text)
     99 
    100 /*
    101  * Temporary stack for a variety of purposes.
    102  * Try and make this the first thing is the data segment so it
    103  * is page aligned.  Note that if we overflow here, we run into
    104  * our text segment.
    105  */
    106 	.data
    107 	.space	PAGE_SIZE
    108 ASLOCAL(tmpstk)
    109 
    110 	.text
    111 /*
    112  * Macro to relocate a symbol, used before MMU is enabled.
    113  */
    114 #define	_RELOC(var, ar)		\
    115 	lea	var-KERNBASE,ar;		\
    116 	addl	%a5,ar
    117 
    118 #define	RELOC(var, ar)		_RELOC(_C_LABEL(var), ar)
    119 #define	ASRELOC(var, ar)	_RELOC(_ASM_LABEL(var), ar)
    120 
    121 /*
    122  * Initialization
    123  *
    124  * A4 contains the address of the end of the symtab
    125  * A5 contains physical load point from boot
    126  * VBR contains zero from ROM.  Exceptions will continue to vector
    127  * through ROM until MMU is turned on at which time they will vector
    128  * through our table (vectors.s).
    129  */
    130 
    131 BSS(lowram,4)
    132 BSS(esym,4)
    133 
    134 	.text
    135 ASENTRY_NOPROFILE(start)
    136 	movw	#PSL_HIGHIPL, %sr	| no interrupts
    137 	movl	#CACHE_OFF, %d0
    138 	movc	%d0, %cacr		| clear and disable on-chip cache(s)
    139 
    140 	/* XXX fixed load address */
    141 	movl	#0x20100000, %a5
    142 
    143 	movl	#0x20000000, %a0
    144 	RELOC(edata, %a1)
    145 1:
    146 	movl	%a5@+, %a0@+
    147 	cmpl	%a5, %a1
    148 	bne	1b
    149 
    150 	movl	#0x20000000, %a5
    151 
    152 	ASRELOC(tmpstk, %a0)
    153 	movl	%a0, %sp		| give ourselves a temporary stack
    154 
    155 	RELOC(edata, %a0)
    156 	RELOC(end, %a1)
    157 2:
    158 	clrb	%a0@+
    159 	cmpl	%a0, %a1
    160 	bne	2b
    161 
    162 	RELOC(esym, %a0)
    163 #if 0
    164 	movl	%a4, %a0@		| store end of symbol table
    165 #else
    166 	clrl	%a0@			| no symbol table, yet
    167 #endif
    168 
    169 	RELOC(lowram, %a0)
    170 	movl	%a5, %a0@		| store start of physical memory
    171 
    172 #if 0
    173 	RELOC(boothowto, %a0)		| save reboot flags
    174 	movl	%d7, %a0@
    175 	RELOC(bootdev, %a0)		|   and boot device
    176 	movl	%d6, %a0@
    177 #endif
    178 
    179 	/*
    180 	 * All data registers are now free.  All address registers
    181 	 * except a5 are free.  a5 is used by the RELOC() macro,
    182 	 * and cannot be used until after the MMU is enabled.
    183 	 */
    184 
    185 /* determine our CPU/MMU combo - check for all regardless of kernel config */
    186 	movl	#0x200,%d0		| data freeze bit
    187 	movc	%d0,%cacr		|   only exists on 68030
    188 	movc	%cacr,%d0		| read it back
    189 	tstl	%d0			| zero?
    190 	jeq	Lnot68030		| yes, we have 68020/68040
    191 	RELOC(mmutype, %a0)		| no, we have 68030
    192 	movl	#MMU_68030,%a0@		| set to reflect 68030 PMMU
    193 	RELOC(cputype, %a0)
    194 	movl	#CPU_68030,%a0@		| and 68030 CPU
    195 	jra	Lstart1
    196 Lnot68030:
    197 	bset	#31,%d0			| data cache enable bit
    198 	movc	%d0,%cacr		|   only exists on 68040
    199 	movc	%cacr,%d0		| read it back
    200 	tstl	%d0			| zero?
    201 	beq	Lis68020		| yes, we have 68020
    202 	moveq	#0,%d0			| now turn it back off
    203 	movec	%d0,%cacr		|   before we access any data
    204 	RELOC(mmutype, %a0)
    205 	movl	#MMU_68040,%a0@		| with a 68040 MMU
    206 	RELOC(cputype, %a0)
    207 	movl	#CPU_68040,%a0@		| and a 68040 CPU
    208 	RELOC(fputype, %a0)
    209 	movl	#FPU_68040,%a0@		| ...and FPU
    210 	jra	Lstart1
    211 Lis68020:
    212 	/* impossible */
    213 
    214 Lstart1:
    215 
    216 /* initialize source/destination control registers for movs */
    217 	moveq	#FC_USERD,%d0		| user space
    218 	movc	%d0,%sfc		|   as source
    219 	movc	%d0,%dfc		|   and destination of transfers
    220 
    221 /* initialize memory size (for pmap_bootstrap) */
    222 	movl	0x5c00ac00, %d0
    223 	andb	#0x60, %d0
    224 	jne	Lnot8M
    225 	movl	#0x20800000, %d1	| memory end, 8M
    226 	jra	Lmemok
    227 Lnot8M:
    228 	cmpb	#0x20, %d0
    229 	jne	Lunkmem
    230 	movl	#0x22000000, %d1	| memory end, 32M
    231 	jra	Lmemok
    232 Lunkmem:
    233 	/* ??? */
    234 	movl	#0x20400000, %d1	| memory end, assume at least 4M
    235 
    236 Lmemok:
    237 	moveq	#PGSHIFT,%d2
    238 	lsrl	%d2,%d1			| convert to page (click) number
    239 	movl	%a5,%d0			| lowram value from ROM via boot
    240 	lsrl	%d2,%d0			| convert to page number
    241 	subl	%d0,%d1			| compute amount of RAM present
    242 	RELOC(physmem, %a0)
    243 	movl	%d1,%a0@		| and physmem
    244 /* configure kernel and lwp0 VA space so we can get going */
    245 	.globl	_Sysseg_pa, _pmap_bootstrap, _avail_start
    246 #if NKSYMS || defined(DDB) || defined(MODULAR)
    247 	RELOC(esym,%a0)			| end of static kernel test/data/syms
    248 	movl	%a0@,%d5
    249 	jne	Lstart2
    250 #endif
    251 	movl	#_C_LABEL(end),%d5	| end of static kernel text/data
    252 Lstart2:
    253 	addl	#PAGE_SIZE-1,%d5
    254 	andl	#PG_FRAME,%d5		| round to a page
    255 	movl	%d5,%a4
    256 	addl	%a5,%a4			| convert to PA
    257 	subl	#KERNBASE, %a4
    258 	pea	%a5@			| firstpa
    259 	pea	%a4@			| nextpa
    260 	RELOC(pmap_bootstrap,%a0)
    261 	jbsr	%a0@			| pmap_bootstrap(firstpa, nextpa)
    262 	addql	#8,%sp
    263 
    264 /*
    265  * Prepare to enable MMU.
    266  */
    267 	RELOC(Sysseg_pa, %a0)		| system segment table addr
    268 	movl	%a0@,%d1		| read value (a PA)
    269 	subl	#KERNBASE, %d1
    270 
    271 	RELOC(mmutype, %a0)
    272 	cmpl	#MMU_68040,%a0@		| 68040?
    273 	jne	Lmotommu1		| no, skip
    274 	.long	0x4e7b1807		| movc d1,srp
    275 	jra	Lstploaddone
    276 Lmotommu1:
    277 #ifdef M68030
    278 	RELOC(protorp, %a0)
    279 	movl	%d1,%a0@(4)		| segtable address
    280 	pmove	%a0@,%srp		| load the supervisor root pointer
    281 #endif /* M68030 */
    282 Lstploaddone:
    283 
    284 	RELOC(mmutype, %a0)
    285 	cmpl	#MMU_68040,%a0@		| 68040?
    286 	jne	Lmotommu2		| no, skip
    287 
    288 	movel #0x2000c000, %d0		| double map RAM
    289 	.long	0x4e7b0004		| movc d0,itt0
    290 	.long	0x4e7b0006		| movc d0,dtt0
    291 	moveq	#0, %d0			| ensure TT regs are disabled
    292 	.long	0x4e7b0005		| movc d0,itt1
    293 	.long	0x4e7b0007		| movc d0,dtt1
    294 
    295 	.word	0xf4d8			| cinva bc
    296 	.word	0xf518			| pflusha
    297 
    298 	movl	#MMU40_TCR_BITS, %d0
    299 	.long	0x4e7b0003		| movc d0,tc
    300 	movl	#0x80008000, %d0
    301 	movc	%d0, %cacr		| turn on both caches
    302 
    303 	jmp	Lenab1:l		| avoid pc-relative
    304 Lmotommu2:
    305 	/* XXX do TT here */
    306 	pflusha
    307 	RELOC(prototc, %a2)
    308 	movl	#MMU51_TCR_BITS,%a2@	| value to load TC with
    309 	pmove	%a2@,%tc		| load it
    310 	jmp	Lenab1
    311 
    312 /*
    313  * Should be running mapped from this point on
    314  */
    315 Lenab1:
    316 	.word	0xf4d8			| cinva bc
    317 	.word	0xf518			| pflusha
    318 	nop
    319 	nop
    320 	nop
    321 	nop
    322 	nop
    323 	moveq	#0,%d0			| ensure TT regs are disabled
    324 	.long	0x4e7b0004		| movc d0,itt0
    325 	.long	0x4e7b0005		| movc d0,itt1
    326 	.long	0x4e7b0006		| movc d0,dtt0
    327 	.long	0x4e7b0007		| movc d0,dtt1
    328 
    329 	lea	_ASM_LABEL(tmpstk),%sp	| re-load temporary stack
    330 	jbsr	_C_LABEL(vec_init)	| initialize vector table
    331 /* call final pmap setup */
    332 	jbsr	_C_LABEL(pmap_bootstrap_finalize)
    333 /* set kernel stack, user SP */
    334 	movl	_C_LABEL(lwp0uarea),%a1	| get lwp0 uarea
    335 	lea	%a1@(USPACE-4),%sp	| set kernel stack to end of area
    336 	movl	#USRSTACK-4,%a2
    337 	movl	%a2,%usp		| init user SP
    338 
    339 	tstl	_C_LABEL(fputype)	| Have an FPU?
    340 	jeq	Lenab2			| No, skip.
    341 	clrl	%a1@(PCB_FPCTX)		| ensure null FP context
    342 	movl	%a1,%sp@-
    343 	jbsr	_C_LABEL(m68881_restore)   | restore it (does not kill a1)
    344 	addql	#4,%sp
    345 Lenab2:
    346 
    347 /* flush TLB and turn on caches */
    348 	jbsr	_C_LABEL(_TBIA)		| invalidate TLB
    349 	cmpl	#MMU_68040,_C_LABEL(mmutype)	| 68040?
    350 	jeq	Lnocache0		| yes, cache already on
    351 	movl	#CACHE_ON,%d0
    352 	movc	%d0,%cacr		| clear cache(s)
    353 Lnocache0:
    354 
    355 /* Final setup for call to main(). */
    356 	jbsr	_C_LABEL(fic_init)
    357 
    358 /*
    359  * Create a fake exception frame so that cpu_lwp_fork() can copy it.
    360  * main() nevers returns; we exit to user mode from a forked process
    361  * later on.
    362  */
    363 	clrw	%sp@-			| vector offset/frame type
    364 	clrl	%sp@-			| PC - filled in by "execve"
    365 	movw	#PSL_USER,%sp@-		| in user mode
    366 	clrl	%sp@-			| stack adjust count and padding
    367 	lea	%sp@(-64),%sp		| construct space for D0-D7/A0-A7
    368 	lea	_C_LABEL(lwp0),%a0	| save pointer to frame
    369 	movl	%sp,%a0@(L_MD_REGS)	|   in lwp0.l_md.md_regs
    370 
    371 	jra	_C_LABEL(main)		| main()
    372 
    373 	pea	Lmainreturned		| Yow!  Main returned!
    374 	jbsr	_C_LABEL(panic)
    375 	/* NOTREACHED */
    376 Lmainreturned:
    377 	.asciz	"main() returned"
    378 	.even
    379 
    380 /*
    381  * Trap/interrupt vector routines
    382  */
    383 #include <m68k/m68k/trap_subr.s>
    384 
    385 /*
    386  * Use common m68k bus error and address error handlers.
    387  */
    388 #include <m68k/m68k/busaddrerr.s>
    389 
    390 /*
    391  * FP exceptions.
    392  */
    393 ENTRY_NOPROFILE(fpfline)
    394 #if defined(M68040)
    395 	cmpl	#FPU_68040,_C_LABEL(fputype) | 68040 FPU?
    396 	jne	Lfp_unimp		| no, skip FPSP
    397 	cmpw	#0x202c,%sp@(6)		| format type 2?
    398 	jne	_C_LABEL(illinst)	| no, not an FP emulation
    399 Ldofp_unimp:
    400 #ifdef FPSP
    401 #if 0
    402 	addl	#1, _C_LABEL(evcnt_fpsp_unimp)+EVCNT_COUNT
    403 #endif
    404 	jmp	_ASM_LABEL(fpsp_unimp)	| yes, go handle it
    405 #endif
    406 Lfp_unimp:
    407 #endif /* M68040 */
    408 #ifdef FPU_EMULATE
    409 	clrl	%sp@-			| stack adjust count
    410 	moveml	#0xFFFF,%sp@-		| save registers
    411 	moveq	#T_FPEMULI,%d0		| denote as FP emulation trap
    412 	jra	_ASM_LABEL(fault)	| do it
    413 #else
    414 	jra	_C_LABEL(illinst)
    415 #endif
    416 
    417 ENTRY_NOPROFILE(fpunsupp)
    418 #if defined(M68040)
    419 	cmpl	#FPU_68040,_C_LABEL(fputype) | 68040 FPU?
    420 	jne	_C_LABEL(illinst)	| no, treat as illinst
    421 #ifdef FPSP
    422 #if 0
    423 	addl	#1, _C_LABEL(evcnt_fpsp_unsupp)+EVCNT_COUNT
    424 #endif
    425 	jmp	_ASM_LABEL(fpsp_unsupp)	| yes, go handle it
    426 #endif
    427 Lfp_unsupp:
    428 #endif /* M68040 */
    429 #ifdef FPU_EMULATE
    430 	clrl	%sp@-			| stack adjust count
    431 	moveml	#0xFFFF,%sp@-		| save registers
    432 	moveq	#T_FPEMULD,%d0		| denote as FP emulation trap
    433 	jra	_ASM_LABEL(fault)	| do it
    434 #else
    435 	jra	_C_LABEL(illinst)
    436 #endif
    437 
    438 /*
    439  * Handles all other FP coprocessor exceptions.
    440  * Note that since some FP exceptions generate mid-instruction frames
    441  * and may cause signal delivery, we need to test for stack adjustment
    442  * after the trap call.
    443  */
    444 ENTRY_NOPROFILE(fpfault)
    445 	clrl	%sp@-		| stack adjust count
    446 	moveml	#0xFFFF,%sp@-	| save user registers
    447 	movl	%usp,%a0		| and save
    448 	movl	%a0,%sp@(FR_SP)	|   the user stack pointer
    449 	clrl	%sp@-		| no VA arg
    450 	movl	_C_LABEL(curpcb),%a0 | current pcb
    451 	lea	%a0@(PCB_FPCTX),%a0 | address of FP savearea
    452 	fsave	%a0@		| save state
    453 #if defined(M68040) || defined(M68060)
    454 	/* always null state frame on 68040, 68060 */
    455 	cmpl	#FPU_68040,_C_LABEL(fputype)
    456 	jge	Lfptnull
    457 #endif
    458 	tstb	%a0@		| null state frame?
    459 	jeq	Lfptnull	| yes, safe
    460 	clrw	%d0		| no, need to tweak BIU
    461 	movb	%a0@(1),%d0	| get frame size
    462 	bset	#3,%a0@(0,%d0:w)	| set exc_pend bit of BIU
    463 Lfptnull:
    464 	fmovem	%fpsr,%sp@-	| push %fpsr as code argument
    465 	frestore %a0@		| restore state
    466 	movl	#T_FPERR,%sp@-	| push type arg
    467 	jra	_ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup
    468 
    469 
    470 ENTRY_NOPROFILE(badtrap)
    471 	moveml	#0xC0C0,%sp@-		| save scratch regs
    472 	movw	%sp@(22),%sp@-		| push exception vector info
    473 	clrw	%sp@-
    474 	movl	%sp@(22),%sp@-		| and PC
    475 	jbsr	_C_LABEL(straytrap)	| report
    476 	addql	#8,%sp			| pop args
    477 	moveml	%sp@+,#0x0303		| restore regs
    478 	jra	_ASM_LABEL(rei)		| all done
    479 
    480 ENTRY_NOPROFILE(trap0)
    481 	clrl	%sp@-			| stack adjust count
    482 	moveml	#0xFFFF,%sp@-		| save user registers
    483 	movl	%usp,%a0			| save the user SP
    484 	movl	%a0,%sp@(FR_SP)		|   in the savearea
    485 	movl	%d0,%sp@-			| push syscall number
    486 	jbsr	_C_LABEL(syscall)	| handle it
    487 	addql	#4,%sp			| pop syscall arg
    488 	tstl	_C_LABEL(astpending)
    489 	jne	Lrei2
    490 	tstb	_C_LABEL(ssir)
    491 	jeq	Ltrap1
    492 	movw	#SPL1,%sr
    493 	tstb	_C_LABEL(ssir)
    494 	jne	Lsir1
    495 Ltrap1:
    496 	movl	%sp@(FR_SP),%a0		| grab and restore
    497 	movl	%a0,%usp			|   user SP
    498 	moveml	%sp@+,#0x7FFF		| restore most registers
    499 	addql	#8,%sp			| pop SP and stack adjust
    500 	rte
    501 
    502 /*
    503  * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD)
    504  *	cachectl(command, addr, length)
    505  * command in d0, addr in a1, length in d1
    506  */
    507 ENTRY_NOPROFILE(trap12)
    508 	movl	_C_LABEL(curlwp),%a0
    509 	movl	%a0@(L_PROC),%sp@-	| push current proc pointer
    510 	movl	%d1,%sp@-			| push length
    511 	movl	%a1,%sp@-			| push addr
    512 	movl	%d0,%sp@-			| push command
    513 	jbsr	_C_LABEL(cachectl1)	| do it
    514 	lea	%sp@(16),%sp		| pop args
    515 	jra	_ASM_LABEL(rei)		| all done
    516 
    517 /*
    518  * Trace (single-step) trap.  Kernel-mode is special.
    519  * User mode traps are simply passed on to trap().
    520  */
    521 ENTRY_NOPROFILE(trace)
    522 	clrl	%sp@-			| stack adjust count
    523 	moveml	#0xFFFF,%sp@-
    524 	moveq	#T_TRACE,%d0
    525 
    526 	| Check PSW and see what happen.
    527 	|   T=0 S=0	(should not happen)
    528 	|   T=1 S=0	trace trap from user mode
    529 	|   T=0 S=1	trace trap on a trap instruction
    530 	|   T=1 S=1	trace trap from system mode (kernel breakpoint)
    531 
    532 	movw	%sp@(FR_HW),%d1		| get PSW
    533 	notw	%d1			| XXX no support for T0 on 680[234]0
    534 	andw	#PSL_TS,%d1		| from system mode (T=1, S=1)?
    535 	jeq	Lkbrkpt			| yes, kernel breakpoint
    536 	jra	_ASM_LABEL(fault)	| no, user-mode fault
    537 
    538 
    539 /*
    540  * Trap 15 is used for:
    541  *	- GDB breakpoints (in user programs)
    542  *	- KGDB breakpoints (in the kernel)
    543  *	- trace traps for SUN binaries (not fully supported yet)
    544  * User mode traps are simply passed to trap().
    545  */
    546 ENTRY_NOPROFILE(trap15)
    547 	clrl	%sp@-			| stack adjust count
    548 	moveml	#0xFFFF,%sp@-
    549 	moveq	#T_TRAP15,%d0
    550 	movw	%sp@(FR_HW),%d1		| get PSW
    551 	andw	#PSL_S,%d1		| from system mode?
    552 	jne	Lkbrkpt			| yes, kernel breakpoint
    553 	jra	_ASM_LABEL(fault)	| no, user-mode fault
    554 
    555 Lkbrkpt: | Kernel-mode breakpoint or trace trap. (%d0=trap_type)
    556 	| Save the system sp rather than the user sp.
    557 	movw	#PSL_HIGHIPL,%sr		| lock out interrupts
    558 	lea	%sp@(FR_SIZE),%a6		| Save stack pointer
    559 	movl	%a6,%sp@(FR_SP)		|  from before trap
    560 
    561 	| If were are not on tmpstk switch to it.
    562 	| (so debugger can change the stack pointer)
    563 	movl	%a6,%d1
    564 	cmpl	#_ASM_LABEL(tmpstk),%d1
    565 	jls	Lbrkpt2			| already on tmpstk
    566 	| Copy frame to the temporary stack
    567 	movl	%sp,%a0			| %a0=src
    568 	lea	_ASM_LABEL(tmpstk)-96,%a1 | a1=dst
    569 	movl	%a1,%sp			| %sp=new frame
    570 	moveq	#FR_SIZE,%d1
    571 Lbrkpt1:
    572 	movl	%a0@+,%a1@+
    573 	subql	#4,%d1
    574 	bgt	Lbrkpt1
    575 
    576 Lbrkpt2:
    577 	| Call the trap handler for the kernel debugger.
    578 	| Do not call trap() to do it, so that we can
    579 	| set breakpoints in trap() if we want.  We know
    580 	| the trap type is either T_TRACE or T_BREAKPOINT.
    581 	movl	%d0,%sp@-		| push trap type
    582 	jbsr	_C_LABEL(trap_kdebug)
    583 	addql	#4,%sp			| pop args
    584 
    585 	| The stack pointer may have been modified, or
    586 	| data below it modified (by kgdb push call),
    587 	| so push the hardware frame at the current sp
    588 	| before restoring registers and returning.
    589 
    590 	movl	%sp@(FR_SP),%a0		| modified %sp
    591 	lea	%sp@(FR_SIZE),%a1		| end of our frame
    592 	movl	%a1@-,%a0@-		| copy 2 longs with
    593 	movl	%a1@-,%a0@-		| ... predecrement
    594 	movl	%a0,%sp@(FR_SP)		| %sp = h/w frame
    595 	moveml	%sp@+,#0x7FFF		| restore all but %sp
    596 	movl	%sp@,%sp			| ... and %sp
    597 	rte				| all done
    598 
    599 /*
    600  * Interrupt handlers.
    601  */
    602 
    603 ENTRY_NOPROFILE(lev6intr)	/* Level 6: clock */
    604 	INTERRUPT_SAVEREG
    605 	/* XXX */
    606 	movl _C_LABEL(clockbase), %a0
    607 	movl %a0@, %d0
    608 	movl %d0, %a0@
    609 	btst #2, %d0
    610 	jeq 1f
    611 	addql	#1,_C_LABEL(m68k_intr_evcnt)+CLOCK_INTRCNT
    612 	lea	%sp@(0), %a1		| a1 = &clockframe
    613 	movl	%a1, %sp@-
    614 	jbsr	_C_LABEL(hardclock)	| hardclock(&frame)
    615 	addql	#4, %sp
    616 	jra 2f
    617 1:
    618 	movl	%d0, %sp@-
    619 	jbsr	_C_LABEL(otherclock)
    620 	addql	#4, %sp
    621 2:
    622 	INTERRUPT_RESTOREREG
    623 	jra	_ASM_LABEL(rei)		| all done
    624 
    625 ENTRY_NOPROFILE(lev7intr)	/* level 7: parity errors, reset key */
    626 	addql	#1,_C_LABEL(m68k_intr_evcnt)+NMI_INTRCNT
    627 	clrl	%sp@-
    628 	moveml	#0xFFFF,%sp@-		| save registers
    629 	movl	%usp,%a0			| and save
    630 	movl	%a0,%sp@(FR_SP)		|   the user stack pointer
    631 	jbsr	_C_LABEL(nmihand)	| call handler
    632 	movl	%sp@(FR_SP),%a0		| restore
    633 	movl	%a0,%usp			|   user SP
    634 	moveml	%sp@+,#0x7FFF		| and remaining registers
    635 	addql	#8,%sp			| pop SP and stack adjust
    636 	jra	_ASM_LABEL(rei)		| all done
    637 
    638 /*
    639  * Emulation of VAX REI instruction.
    640  *
    641  * This code deals with checking for and servicing ASTs
    642  * (profiling, scheduling) and software interrupts (network, softclock).
    643  * We check for ASTs first, just like the VAX.  To avoid excess overhead
    644  * the T_ASTFLT handling code will also check for software interrupts so we
    645  * do not have to do it here.  After identifying that we need an AST we
    646  * drop the IPL to allow device interrupts.
    647  *
    648  * This code is complicated by the fact that sendsig may have been called
    649  * necessitating a stack cleanup.
    650  */
    651 BSS(ssir,1)
    652 
    653 ASENTRY_NOPROFILE(rei)
    654 	tstl	_C_LABEL(astpending)	| AST pending?
    655 	jeq	Lchksir			| no, go check for SIR
    656 Lrei1:
    657 	btst	#5,%sp@			| yes, are we returning to user mode?
    658 	jne	Lchksir			| no, go check for SIR
    659 	movw	#PSL_LOWIPL,%sr		| lower SPL
    660 	clrl	%sp@-			| stack adjust
    661 	moveml	#0xFFFF,%sp@-		| save all registers
    662 	movl	%usp,%a1			| including
    663 	movl	%a1,%sp@(FR_SP)		|    the users SP
    664 Lrei2:
    665 	clrl	%sp@-			| VA == none
    666 	clrl	%sp@-			| code == none
    667 	movl	#T_ASTFLT,%sp@-		| type == async system trap
    668 	pea	%sp@(12)		| fp == address of trap frame
    669 	jbsr	_C_LABEL(trap)		| go handle it
    670 	lea	%sp@(16),%sp		| pop value args
    671 	movl	%sp@(FR_SP),%a0		| restore user SP
    672 	movl	%a0,%usp			|   from save area
    673 	movw	%sp@(FR_ADJ),%d0		| need to adjust stack?
    674 	jne	Laststkadj		| yes, go to it
    675 	moveml	%sp@+,#0x7FFF		| no, restore most user regs
    676 	addql	#8,%sp			| toss SP and stack adjust
    677 	rte				| and do real RTE
    678 Laststkadj:
    679 	lea	%sp@(FR_HW),%a1		| pointer to HW frame
    680 	addql	#8,%a1			| source pointer
    681 	movl	%a1,%a0			| source
    682 	addw	%d0,%a0			|  + hole size = dest pointer
    683 	movl	%a1@-,%a0@-		| copy
    684 	movl	%a1@-,%a0@-		|  8 bytes
    685 	movl	%a0,%sp@(FR_SP)		| new SSP
    686 	moveml	%sp@+,#0x7FFF		| restore user registers
    687 	movl	%sp@,%sp			| and our SP
    688 	rte				| and do real RTE
    689 Lchksir:
    690 	tstb	_C_LABEL(ssir)		| SIR pending?
    691 	jeq	Ldorte			| no, all done
    692 	movl	%d0,%sp@-			| need a scratch register
    693 	movw	%sp@(4),%d0		| get SR
    694 	andw	#PSL_IPL7,%d0		| mask all but IPL
    695 	jne	Lnosir			| came from interrupt, no can do
    696 	movl	%sp@+,%d0			| restore scratch register
    697 Lgotsir:
    698 	movw	#SPL1,%sr		| prevent others from servicing int
    699 	tstb	_C_LABEL(ssir)		| too late?
    700 	jeq	Ldorte			| yes, oh well...
    701 	clrl	%sp@-			| stack adjust
    702 	moveml	#0xFFFF,%sp@-		| save all registers
    703 	movl	%usp,%a1			| including
    704 	movl	%a1,%sp@(FR_SP)		|    the users SP
    705 Lsir1:
    706 	clrl	%sp@-			| VA == none
    707 	clrl	%sp@-			| code == none
    708 	movl	#T_SSIR,%sp@-		| type == software interrupt
    709 	pea	%sp@(12)		| fp == address of trap frame
    710 	jbsr	_C_LABEL(trap)		| go handle it
    711 	lea	%sp@(16),%sp		| pop value args
    712 	movl	%sp@(FR_SP),%a0		| restore
    713 	movl	%a0,%usp			|   user SP
    714 	moveml	%sp@+,#0x7FFF		| and all remaining registers
    715 	addql	#8,%sp			| pop SP and stack adjust
    716 	rte
    717 Lnosir:
    718 	movl	%sp@+,%d0			| restore scratch register
    719 Ldorte:
    720 	rte				| real return
    721 
    722 /*
    723  * Primitives
    724  */
    725 
    726 /*
    727  * Use common m68k process/lwp switch and context save subroutines.
    728  */
    729 #define	FPCOPROC	/* XXX: Temporarily required */
    730 #include <m68k/m68k/switch_subr.s>
    731 
    732 
    733 #if defined(M68040)
    734 ENTRY(suline)
    735 	movl	%sp@(4),%a0		| address to write
    736 	movl	_C_LABEL(curpcb),%a1	| current pcb
    737 	movl	#Lslerr,%a1@(PCB_ONFAULT) | where to return to on a fault
    738 	movl	%sp@(8),%a1		| address of line
    739 	movl	%a1@+,%d0			| get lword
    740 	movsl	%d0,%a0@+			| put lword
    741 	nop				| sync
    742 	movl	%a1@+,%d0			| get lword
    743 	movsl	%d0,%a0@+			| put lword
    744 	nop				| sync
    745 	movl	%a1@+,%d0			| get lword
    746 	movsl	%d0,%a0@+			| put lword
    747 	nop				| sync
    748 	movl	%a1@+,%d0			| get lword
    749 	movsl	%d0,%a0@+			| put lword
    750 	nop				| sync
    751 	moveq	#0,%d0			| indicate no fault
    752 	jra	Lsldone
    753 Lslerr:
    754 	moveq	#-1,%d0
    755 Lsldone:
    756 	movl	_C_LABEL(curpcb),%a1	| current pcb
    757 	clrl	%a1@(PCB_ONFAULT) 	| clear fault address
    758 	rts
    759 #endif
    760 
    761 /*
    762  * Set processor priority level calls.  Most are implemented with
    763  * inline asm expansions.  However, spl0 requires special handling
    764  * as we need to check for our emulated software interrupts.
    765  */
    766 
    767 ENTRY(spl0)
    768 	moveq	#0,%d0
    769 	movw	%sr,%d0			| get old SR for return
    770 	movw	#PSL_LOWIPL,%sr		| restore new SR
    771 	tstb	_C_LABEL(ssir)		| software interrupt pending?
    772 	jeq	Lspldone		| no, all done
    773 	subql	#4,%sp			| make room for RTE frame
    774 	movl	%sp@(4),%sp@(2)		| position return address
    775 	clrw	%sp@(6)			| set frame type 0
    776 	movw	#PSL_LOWIPL,%sp@		| and new SR
    777 	jra	Lgotsir			| go handle it
    778 Lspldone:
    779 	rts
    780 
    781 /*
    782  * _delay(u_int N)
    783  *
    784  * Delay for at least (N/256) microseconds.
    785  * This routine depends on the variable:  delay_divisor
    786  * which should be set based on the CPU clock rate.
    787  */
    788 ENTRY_NOPROFILE(_delay)
    789 	| d0 = arg = (usecs << 8)
    790 	movl	%sp@(4),%d0
    791 	| d1 = delay_divisor
    792 	movl	_C_LABEL(delay_divisor),%d1
    793 L_delay:
    794 	subl	%d1,%d0
    795 	jgt	L_delay
    796 	rts
    797 
    798 ENTRY_NOPROFILE(doboot)
    799 	movl #0x5c00c060, %d0		| want phys addressing
    800 	.long	0x4e7b0006		| movc d0,dtt0
    801 	movl	#1, 0x5c00b800		| reset
    802 	stop	#0x2700			| paranoia
    803 
    804 	.data
    805 GLOBAL(mmutype)
    806 	.long	MMU_HP		| default to HP MMU
    807 GLOBAL(cputype)
    808 	.long	CPU_68020	| default to 68020 CPU
    809 GLOBAL(fputype)
    810 	.long	FPU_68881	| default to 68881 FPU
    811 GLOBAL(prototc)
    812 	.long	0		| prototype translation control
    813 
    814 #ifdef DEBUG
    815 	.globl	fulltflush, fullcflush
    816 fulltflush:
    817 	.long	0
    818 fullcflush:
    819 	.long	0
    820 #endif
    821