Module Name: src Committed By: tsutsui Date: Fri Jan 31 18:24:03 UTC 2014
Modified Files: src/sys/arch/x68k/x68k: locore.s Log Message: Move the startup routine to the beginning of the source as other m68k ports. No particular comments on port-x68k@. To generate a diff of this commit: cvs rdiff -u -r1.111 -r1.112 src/sys/arch/x68k/x68k/locore.s Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x68k/x68k/locore.s diff -u src/sys/arch/x68k/x68k/locore.s:1.111 src/sys/arch/x68k/x68k/locore.s:1.112 --- src/sys/arch/x68k/x68k/locore.s:1.111 Sun Oct 27 02:06:06 2013 +++ src/sys/arch/x68k/x68k/locore.s Fri Jan 31 18:24:03 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.s,v 1.111 2013/10/27 02:06:06 tsutsui Exp $ */ +/* $NetBSD: locore.s,v 1.112 2014/01/31 18:24:03 tsutsui Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -82,6 +82,278 @@ ASLOCAL(tmpstk) /* NOTREACHED */ /* + * Macro to relocate a symbol, used before MMU is enabled. + */ +#define _RELOC(var, ar) \ + lea var,ar; \ + addl %a5,ar + +#define RELOC(var, ar) _RELOC(_C_LABEL(var), ar) +#define ASRELOC(var, ar) _RELOC(_ASM_LABEL(var), ar) + +/* + * Initialization + * + * A4 contains the address of the end of the symtab + * A5 contains physical load point from boot + * VBR contains zero from ROM. Exceptions will continue to vector + * through ROM until MMU is turned on at which time they will vector + * through our table (vectors.s). + */ +BSS(lowram,4) +BSS(esym,4) + +GLOBAL(_verspad) + .word 0 +GLOBAL(boot_version) + .word X68K_BOOTIF_VERS + +ASENTRY_NOPROFILE(start) + movw #PSL_HIGHIPL,%sr | no interrupts + + addql #4,%sp + movel %sp@+,%a5 | firstpa + movel %sp@+,%d5 | fphysize -- last page + movel %sp@,%a4 | esym + + RELOC(vectab,%a0) | set Vector Base Register temporaly + movc %a0,%vbr + +#if 0 /* XXX this should be done by the boot loader */ + RELOC(edata, %a0) | clear out BSS + movl #_C_LABEL(end)-4,%d0 | (must be <= 256 kB) + subl #_C_LABEL(edata),%d0 + lsrl #2,%d0 +1: clrl %a0@+ + dbra %d0,1b +#endif + + ASRELOC(tmpstk, %a0) + movl %a0,%sp | give ourselves a temporary stack + RELOC(esym, %a0) +#if 1 + movl %a4,%a0@ | store end of symbol table +#else + clrl %a0@ | no symbol table, yet +#endif + RELOC(lowram, %a0) + movl %a5,%a0@ | store start of physical memory + + movl #CACHE_OFF,%d0 + movc %d0,%cacr | clear and disable on-chip cache(s) + +/* determine our CPU/MMU combo - check for all regardless of kernel config */ + movl #0x200,%d0 | data freeze bit + movc %d0,%cacr | only exists on 68030 + movc %cacr,%d0 | read it back + tstl %d0 | zero? + jeq Lnot68030 | yes, we have 68020/68040/68060 + jra Lstart1 | no, we have 68030 +Lnot68030: + bset #31,%d0 | data cache enable bit + movc %d0,%cacr | only exists on 68040/68060 + movc %cacr,%d0 | read it back + tstl %d0 | zero? + jeq Lis68020 | yes, we have 68020 + moveq #0,%d0 | now turn it back off + movec %d0,%cacr | before we access any data + .word 0xf4d8 | cinva bc - invalidate caches XXX + bset #30,%d0 | data cache no allocate mode bit + movc %d0,%cacr | only exists on 68060 + movc %cacr,%d0 | read it back + tstl %d0 | zero? + jeq Lis68040 | yes, we have 68040 + RELOC(mmutype, %a0) | no, we have 68060 + movl #MMU_68040,%a0@ | with a 68040 compatible MMU + RELOC(cputype, %a0) + movl #CPU_68060,%a0@ | and a 68060 CPU + jra Lstart1 +Lis68040: + RELOC(mmutype, %a0) + movl #MMU_68040,%a0@ | with a 68040 MMU + RELOC(cputype, %a0) + movl #CPU_68040,%a0@ | and a 68040 CPU + jra Lstart1 +Lis68020: + RELOC(mmutype, %a0) + movl #MMU_68851,%a0@ | we have PMMU + RELOC(cputype, %a0) + movl #CPU_68020,%a0@ | and a 68020 CPU + +Lstart1: +/* initialize source/destination control registers for movs */ + moveq #FC_USERD,%d0 | user space + movc %d0,%sfc | as source + movc %d0,%dfc | and destination of transfers +/* initialize memory sizes (for pmap_bootstrap) */ + movl %d5,%d1 | last page + moveq #PGSHIFT,%d2 + lsrl %d2,%d1 | convert to page (click) number + RELOC(maxmem, %a0) + movl %d1,%a0@ | save as maxmem + movl %a5,%d0 | lowram value from ROM via boot + lsrl %d2,%d0 | convert to page number + subl %d0,%d1 | compute amount of RAM present + RELOC(physmem, %a0) + movl %d1,%a0@ | and physmem +/* configure kernel and lwp0 VA space so we can get going */ +#if NKSYMS || defined(DDB) || defined(LKM) + RELOC(esym,%a0) | end of static kernel test/data/syms + movl %a0@,%d5 + jne Lstart2 +#endif + movl #_C_LABEL(end),%d5 | end of static kernel text/data +Lstart2: + RELOC(setmemrange,%a0) | call setmemrange() + jbsr %a0@ | to probe all memory regions + addl #PAGE_SIZE-1,%d5 + andl #PG_FRAME,%d5 | round to a page + movl %d5,%a4 + addl %a5,%a4 | convert to PA + pea %a5@ | firstpa + pea %a4@ | nextpa + RELOC(pmap_bootstrap,%a0) + jbsr %a0@ | pmap_bootstrap(firstpa, nextpa) + addql #8,%sp + +/* + * Prepare to enable MMU. + * Since the kernel is mapped logical == physical, we just turn it on. + */ + RELOC(Sysseg_pa, %a0) | system segment table addr + movl %a0@,%d1 | read value (a PA) + RELOC(mmutype, %a0) + cmpl #MMU_68040,%a0@ | 68040? + jne Lmotommu1 | no, skip + .long 0x4e7b1807 | movc d1,srp + jra Lstploaddone +Lmotommu1: + RELOC(protorp, %a0) + movl #0x80000202,%a0@ | nolimit + share global + 4 byte PTEs + movl %d1,%a0@(4) | + segtable address + pmove %a0@,%srp | load the supervisor root pointer + movl #0x80000002,%a0@ | reinit upper half for CRP loads +Lstploaddone: + RELOC(mmutype, %a0) + cmpl #MMU_68040,%a0@ | 68040? + jne Lmotommu2 | no, skip +#include "opt_jupiter.h" +#ifdef JUPITER + /* JUPITER-X: set system register "SUPER" bit */ + movl #0x0200a240,%d0 | translate DRAM area transparently + .long 0x4e7b0006 | movc d0,dtt0 + lea 0x00c00000,%a0 | a0: graphic VRAM + lea 0x02c00000,%a1 | a1: graphic VRAM ( not JUPITER-X ) + | DRAM ( JUPITER-X ) + movw %a0@,%d0 + movw %d0,%d1 + notw %d1 + movw %d1,%a1@ + movw %d0,%a0@ + cmpw %a1@,%d1 | JUPITER-X? + jne Ljupiterdone | no, skip + movl #0x0100a240,%d0 | to access system register + .long 0x4e7b0006 | movc d0,dtt0 + movb #0x01,0x01800003 | set "SUPER" bit +Ljupiterdone: +#endif /* JUPITER */ + moveq #0,%d0 | ensure TT regs are disabled + .long 0x4e7b0004 | movc d0,itt0 + .long 0x4e7b0005 | movc d0,itt1 + .long 0x4e7b0006 | movc d0,dtt0 + .long 0x4e7b0007 | movc d0,dtt1 + .word 0xf4d8 | cinva bc + .word 0xf518 | pflusha +#if PGSHIFT == 13 + movl #0xc000,%d0 +#else + movl #0x8000,%d0 +#endif + .long 0x4e7b0003 | movc d0,tc +#ifdef M68060 + RELOC(cputype, %a0) + cmpl #CPU_68060,%a0@ | 68060? + jne Lnot060cache + movl #1,%d0 + .long 0x4e7b0808 | movcl d0,pcr + movl #0xa0808000,%d0 + movc %d0,%cacr | enable store buffer, both caches + jmp Lenab1 +Lnot060cache: +#endif + movl #0x80008000,%d0 + movc %d0,%cacr | turn on both caches + jmp Lenab1 +Lmotommu2: + pflusha +#if PGSHIFT == 13 + movl #0x82d08b00,%sp@- | value to load TC with +#else + movl #0x82c0aa00,%sp@- | value to load TC with +#endif + pmove %sp@,%tc | load it + +/* + * Should be running mapped from this point on + */ +Lenab1: +/* set vector base in virtual address */ + movl #_C_LABEL(vectab),%d0 | set Vector Base Register + movc %d0,%vbr + lea _ASM_LABEL(tmpstk),%sp | temporary stack +/* call final pmap setup */ + jbsr _C_LABEL(pmap_bootstrap_finalize) +/* set kernel stack, user SP */ + movl _C_LABEL(lwp0uarea),%a1 | grab lwp0 uarea + lea %a1@(USPACE-4),%sp | set kernel stack to end of area + movl #USRSTACK-4,%a2 + movl %a2,%usp | init user SP + +/* detect FPU type */ + jbsr _C_LABEL(fpu_probe) + movl %d0,_C_LABEL(fputype) + tstl _C_LABEL(fputype) | Have an FPU? + jeq Lenab2 | No, skip. + clrl %a1@(PCB_FPCTX) | ensure null FP context + movl %a1,%sp@- + jbsr _C_LABEL(m68881_restore) | restore it (does not kill a1) + addql #4,%sp +Lenab2: + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? + jeq Ltbia040 | yes, cache already on + pflusha + tstl _C_LABEL(mmutype) + jpl Lenab3 | 68851 implies no d-cache + movl #CACHE_ON,%d0 + movc %d0,%cacr | clear cache(s) + jra Lenab3 +Ltbia040: + .word 0xf518 +Lenab3: +/* final setup for C code */ + movl %d7,_C_LABEL(boothowto) | save reboot flags + movl %d6,_C_LABEL(bootdev) | and boot device + jbsr _C_LABEL(x68k_init) | additional pre-main initialization + +/* + * Create a fake exception frame so that cpu_lwp_fork() can copy it. + * main() nevers returns; we exit to user mode from a forked process + * later on. + */ + clrw %sp@- | vector offset/frame type + clrl %sp@- | PC - filled in by "execve" + movw #PSL_USER,%sp@- | in user mode + clrl %sp@- | stack adjust count and padding + lea %sp@(-64),%sp | construct space for D0-D7/A0-A7 + lea _C_LABEL(lwp0),%a0 | save pointer to frame + movl %sp,%a0@(L_MD_REGS) | in lwp0.p_md.md_regs + + jra _C_LABEL(main) | main() + + PANIC("main() returned") | Yow! Main returned! + /* NOTREACHED */ + +/* * Trap/interrupt vector routines */ #include <m68k/m68k/trap_subr.s> @@ -242,689 +514,417 @@ Lisaerr: movl #T_ADDRERR,%sp@- | mark address error jra _ASM_LABEL(faultstkadj) | and deal with it Lisberr1: - clrw %sp@ | re-clear pad word -Lisberr: - movl #T_BUSERR,%sp@- | mark bus error - jra _ASM_LABEL(faultstkadj) | and deal with it - -/* - * FP exceptions. - */ -#include "opt_fpu_emulate.h" -ENTRY_NOPROFILE(fpfline) -#if defined(M68040) - cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? - jne Lfp_unimp | no, skip FPSP - cmpw #0x202c,%sp@(6) | format type 2? - jne _C_LABEL(illinst) | no, not an FP emulation -#ifdef FPSP - jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it -#else - clrl %sp@- | stack adjust count - moveml #0xFFFF,%sp@- | save registers - moveq #T_FPEMULI,%d0 | denote as FP emulation trap - jra _ASM_LABEL(fault) | do it -#endif -Lfp_unimp: -#endif -#ifdef FPU_EMULATE - clrl %sp@- | stack adjust count - moveml #0xFFFF,%sp@- | save registers - moveq #T_FPEMULD,%d0 | denote as FP emulation trap - jra _ASM_LABEL(fault) | do it -#else - jra _C_LABEL(illinst) -#endif - -ENTRY_NOPROFILE(fpunsupp) -#if defined(M68040) - cmpl #FPU_68040,_C_LABEL(fputype) | 68040? - jne Lfp_unsupp | no, skip FPSP -#ifdef FPSP - jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it -#else - clrl %sp@- | stack adjust count - moveml #0xFFFF,%sp@- | save registers - moveq #T_FPEMULD,%d0 | denote as FP emulation trap - jra _ASM_LABEL(fault) | do it -#endif -Lfp_unsupp: -#endif -#ifdef FPU_EMULATE - clrl %sp@- | stack adjust count - moveml #0xFFFF,%sp@- | save registers - moveq #T_FPEMULD,%d0 | denote as FP emulation trap - jra _ASM_LABEL(fault) | do it -#else - jra _C_LABEL(illinst) -#endif - -/* - * Handles all other FP coprocessor exceptions. - * Note that since some FP exceptions generate mid-instruction frames - * and may cause signal delivery, we need to test for stack adjustment - * after the trap call. - */ -ENTRY_NOPROFILE(fpfault) - clrl %sp@- | stack adjust count - moveml #0xFFFF,%sp@- | save user registers - movl %usp,%a0 | and save - movl %a0,%sp@(FR_SP) | the user stack pointer - clrl %sp@- | no VA arg - movl _C_LABEL(curpcb),%a0 | current pcb - lea %a0@(PCB_FPCTX),%a0 | address of FP savearea - fsave %a0@ | save state -#if defined(M68040) || defined(M68060) - /* always null state frame on 68040, 68060 */ - cmpl #FPU_68040,_C_LABEL(fputype) - jge Lfptnull -#endif - tstb %a0@ | null state frame? - jeq Lfptnull | yes, safe - clrw %d0 | no, need to tweak BIU - movb %a0@(1),%d0 | get frame size - bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU -Lfptnull: - fmovem %fpsr,%sp@- | push fpsr as code argument - frestore %a0@ | restore state - movl #T_FPERR,%sp@- | push type arg - jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup - -/* - * Other exceptions only cause four and six word stack frame and require - * no post-trap stack adjustment. - */ - -ENTRY_NOPROFILE(badtrap) - moveml #0xC0C0,%sp@- | save scratch regs - movw %sp@(22),%sp@- | push exception vector info - clrw %sp@- - movl %sp@(22),%sp@- | and PC - jbsr _C_LABEL(straytrap) | report - addql #8,%sp | pop args - moveml %sp@+,#0x0303 | restore regs - jra _ASM_LABEL(rei) | all done - -ENTRY_NOPROFILE(trap0) - clrl %sp@- | stack adjust count - moveml #0xFFFF,%sp@- | save user registers - movl %usp,%a0 | save the user SP - movl %a0,%sp@(FR_SP) | in the savearea - movl %d0,%sp@- | push syscall number - jbsr _C_LABEL(syscall) | handle it - addql #4,%sp | pop syscall arg - tstl _C_LABEL(astpending) - jne Lrei2 - tstb _C_LABEL(ssir) - jeq Ltrap1 - movw #SPL1,%sr - tstb _C_LABEL(ssir) - jne Lsir1 -Ltrap1: - movl %sp@(FR_SP),%a0 | grab and restore - movl %a0,%usp | user SP - moveml %sp@+,#0x7FFF | restore most registers - addql #8,%sp | pop SP and stack adjust - rte - -/* - * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD) - * cachectl(command, addr, length) - * command in d0, addr in a1, length in d1 - */ -ENTRY_NOPROFILE(trap12) - movl _C_LABEL(curlwp),%a0 - movl %a0@(L_PROC),%sp@- | push curproc pointer - movl %d1,%sp@- | push length - movl %a1,%sp@- | push addr - movl %d0,%sp@- | push command - jbsr _C_LABEL(cachectl1) | do it - lea %sp@(16),%sp | pop args - jra _ASM_LABEL(rei) | all done - -/* - * Trace (single-step) trap. Kernel-mode is special. - * User mode traps are simply passed on to trap(). - */ -ENTRY_NOPROFILE(trace) - clrl %sp@- | stack adjust count - moveml #0xFFFF,%sp@- - moveq #T_TRACE,%d0 - - | Check PSW and see what happen. - | T=0 S=0 (should not happen) - | T=1 S=0 trace trap from user mode - | T=0 S=1 trace trap on a trap instruction - | T=1 S=1 trace trap from system mode (kernel breakpoint) - - movw %sp@(FR_HW),%d1 | get PSW - notw %d1 | XXX no support for T0 on 680[234]0 - andw #PSL_TS,%d1 | from system mode (T=1, S=1)? - jeq Lkbrkpt | yes, kernel breakpoint - jra _ASM_LABEL(fault) | no, user-mode fault - -/* - * Trap 15 is used for: - * - GDB breakpoints (in user programs) - * - KGDB breakpoints (in the kernel) - * - trace traps for SUN binaries (not fully supported yet) - * User mode traps are simply passed to trap(). - */ -ENTRY_NOPROFILE(trap15) - clrl %sp@- | stack adjust count - moveml #0xFFFF,%sp@- - moveq #T_TRAP15,%d0 - movw %sp@(FR_HW),%d1 | get PSW - andw #PSL_S,%d1 | from system mode? - jne Lkbrkpt | yes, kernel breakpoint - jra _ASM_LABEL(fault) | no, user-mode fault - -Lkbrkpt: | Kernel-mode breakpoint or trace trap. (d0=trap_type) - | Save the system sp rather than the user sp. - movw #PSL_HIGHIPL,%sr | lock out interrupts - lea %sp@(FR_SIZE),%a6 | Save stack pointer - movl %a6,%sp@(FR_SP) | from before trap - - | If were are not on tmpstk switch to it. - | (so debugger can change the stack pointer) - movl %a6,%d1 - cmpl #_ASM_LABEL(tmpstk),%d1 - jls Lbrkpt2 | already on tmpstk - | Copy frame to the temporary stack - movl %sp,%a0 | a0=src - lea _ASM_LABEL(tmpstk)-96,%a1 | a1=dst - movl %a1,%sp | sp=new frame - moveq #FR_SIZE,%d1 -Lbrkpt1: - movl %a0@+,%a1@+ - subql #4,%d1 - jgt Lbrkpt1 - -Lbrkpt2: - | Call the trap handler for the kernel debugger. - | Do not call trap() to do it, so that we can - | set breakpoints in trap() if we want. We know - | the trap type is either T_TRACE or T_BREAKPOINT. - | If we have both DDB and KGDB, let KGDB see it first, - | because KGDB will just return 0 if not connected. - | Save args in d2, a2 - movl %d0,%d2 | trap type - movl %sp,%a2 | frame ptr -#ifdef KGDB - | Let KGDB handle it (if connected) - movl %a2,%sp@- | push frame ptr - movl %d2,%sp@- | push trap type - jbsr _C_LABEL(kgdb_trap) | handle the trap - addql #8,%sp | pop args - cmpl #0,%d0 | did kgdb handle it? - jne Lbrkpt3 | yes, done -#endif -#ifdef DDB - | Let DDB handle it - movl %a2,%sp@- | push frame ptr - movl %d2,%sp@- | push trap type - jbsr _C_LABEL(kdb_trap) | handle the trap - addql #8,%sp | pop args -#if 0 /* not needed on hp300 */ - cmpl #0,%d0 | did ddb handle it? - jne Lbrkpt3 | yes, done -#endif -#endif - /* Sun 3 drops into PROM here. */ -Lbrkpt3: - | The stack pointer may have been modified, or - | data below it modified (by kgdb push call), - | so push the hardware frame at the current sp - | before restoring registers and returning. - - movl %sp@(FR_SP),%a0 | modified sp - lea %sp@(FR_SIZE),%a1 | end of our frame - movl %a1@-,%a0@- | copy 2 longs with - movl %a1@-,%a0@- | ... predecrement - movl %a0,%sp@(FR_SP) | sp = h/w frame - moveml %sp@+,#0x7FFF | restore all but sp - movl %sp@,%sp | ... and sp - rte | all done - -/* Use common m68k sigreturn */ -#include <m68k/m68k/sigreturn.s> + clrw %sp@ | re-clear pad word +Lisberr: + movl #T_BUSERR,%sp@- | mark bus error + jra _ASM_LABEL(faultstkadj) | and deal with it /* - * Provide a generic interrupt dispatcher, only handle hardclock (int6) - * specially, to improve performance + * FP exceptions. */ +#include "opt_fpu_emulate.h" +ENTRY_NOPROFILE(fpfline) +#if defined(M68040) + cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? + jne Lfp_unimp | no, skip FPSP + cmpw #0x202c,%sp@(6) | format type 2? + jne _C_LABEL(illinst) | no, not an FP emulation +#ifdef FPSP + jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it +#else + clrl %sp@- | stack adjust count + moveml #0xFFFF,%sp@- | save registers + moveq #T_FPEMULI,%d0 | denote as FP emulation trap + jra _ASM_LABEL(fault) | do it +#endif +Lfp_unimp: +#endif +#ifdef FPU_EMULATE + clrl %sp@- | stack adjust count + moveml #0xFFFF,%sp@- | save registers + moveq #T_FPEMULD,%d0 | denote as FP emulation trap + jra _ASM_LABEL(fault) | do it +#else + jra _C_LABEL(illinst) +#endif -ENTRY_NOPROFILE(spurintr) /* level 0 */ - addql #1,_C_LABEL(intrcnt)+0 - INTERRUPT_SAVEREG - CPUINFO_INCREMENT(CI_NINTR) - INTERRUPT_RESTOREREG - rte | XXX mfpcure (x680x0 hardware bug) - -ENTRY_NOPROFILE(kbdtimer) - rte - -ENTRY_NOPROFILE(intiotrap) - addql #1,_C_LABEL(idepth) - INTERRUPT_SAVEREG - pea %sp@(16-(FR_HW)) | XXX - jbsr _C_LABEL(intio_intr) - addql #4,%sp - CPUINFO_INCREMENT(CI_NINTR) - INTERRUPT_RESTOREREG - subql #1,_C_LABEL(idepth) - jra rei - -ENTRY_NOPROFILE(lev1intr) -ENTRY_NOPROFILE(lev2intr) -ENTRY_NOPROFILE(lev3intr) -ENTRY_NOPROFILE(lev4intr) -ENTRY_NOPROFILE(lev5intr) -ENTRY_NOPROFILE(lev6intr) - addql #1,_C_LABEL(idepth) - INTERRUPT_SAVEREG -Lnotdma: - lea _C_LABEL(intrcnt),%a0 - movw %sp@(22),%d0 | use vector offset - andw #0xfff,%d0 | sans frame type - addql #1,%a0@(-0x60,%d0:w) | to increment apropos counter - movw %sr,%sp@- | push current SR value - clrw %sp@- | padded to longword - jbsr _C_LABEL(intrhand) | handle interrupt - addql #4,%sp | pop SR - CPUINFO_INCREMENT(CI_NINTR) - INTERRUPT_RESTOREREG - subql #1,_C_LABEL(idepth) - jra _ASM_LABEL(rei) - -ENTRY_NOPROFILE(timertrap) - addql #1,_C_LABEL(idepth) - INTERRUPT_SAVEREG | save scratch registers - addql #1,_C_LABEL(intrcnt)+32 | count hardclock interrupts - lea %sp@(16),%a1 | a1 = &clockframe - movl %a1,%sp@- - jbsr _C_LABEL(hardclock) | hardclock(&frame) - addql #4,%sp - CPUINFO_INCREMENT(CI_NINTR) | chalk up another interrupt - INTERRUPT_RESTOREREG | restore scratch registers - subql #1,_C_LABEL(idepth) - jra _ASM_LABEL(rei) | all done - -ENTRY_NOPROFILE(lev7intr) - addql #1,_C_LABEL(idepth) - addql #1,_C_LABEL(intrcnt)+28 - clrl %sp@- +ENTRY_NOPROFILE(fpunsupp) +#if defined(M68040) + cmpl #FPU_68040,_C_LABEL(fputype) | 68040? + jne Lfp_unsupp | no, skip FPSP +#ifdef FPSP + jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it +#else + clrl %sp@- | stack adjust count moveml #0xFFFF,%sp@- | save registers - movl %usp,%a0 | and save - movl %a0,%sp@(FR_SP) | the user stack pointer - jbsr _C_LABEL(nmihand) | call handler - movl %sp@(FR_SP),%a0 | restore - movl %a0,%usp | user SP - moveml %sp@+,#0x7FFF | and remaining registers - addql #8,%sp | pop SP and stack adjust - subql #1,_C_LABEL(idepth) - jra _ASM_LABEL(rei) | all done + moveq #T_FPEMULD,%d0 | denote as FP emulation trap + jra _ASM_LABEL(fault) | do it +#endif +Lfp_unsupp: +#endif +#ifdef FPU_EMULATE + clrl %sp@- | stack adjust count + moveml #0xFFFF,%sp@- | save registers + moveq #T_FPEMULD,%d0 | denote as FP emulation trap + jra _ASM_LABEL(fault) | do it +#else + jra _C_LABEL(illinst) +#endif /* - * floppy ejection trap + * Handles all other FP coprocessor exceptions. + * Note that since some FP exceptions generate mid-instruction frames + * and may cause signal delivery, we need to test for stack adjustment + * after the trap call. */ - -ENTRY_NOPROFILE(fdeject) - jra _ASM_LABEL(rei) +ENTRY_NOPROFILE(fpfault) + clrl %sp@- | stack adjust count + moveml #0xFFFF,%sp@- | save user registers + movl %usp,%a0 | and save + movl %a0,%sp@(FR_SP) | the user stack pointer + clrl %sp@- | no VA arg + movl _C_LABEL(curpcb),%a0 | current pcb + lea %a0@(PCB_FPCTX),%a0 | address of FP savearea + fsave %a0@ | save state +#if defined(M68040) || defined(M68060) + /* always null state frame on 68040, 68060 */ + cmpl #FPU_68040,_C_LABEL(fputype) + jge Lfptnull +#endif + tstb %a0@ | null state frame? + jeq Lfptnull | yes, safe + clrw %d0 | no, need to tweak BIU + movb %a0@(1),%d0 | get frame size + bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU +Lfptnull: + fmovem %fpsr,%sp@- | push fpsr as code argument + frestore %a0@ | restore state + movl #T_FPERR,%sp@- | push type arg + jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup /* - * Emulation of VAX REI instruction. - * - * This code deals with checking for and servicing ASTs - * (profiling, scheduling) and software interrupts (network, softclock). - * We check for ASTs first, just like the VAX. To avoid excess overhead - * the T_ASTFLT handling code will also check for software interrupts so we - * do not have to do it here. After identifing that we need an AST we - * drop the IPL to allow device interrupts. - * - * This code is complicated by the fact that sendsig may have been called - * necessitating a stack cleanup. + * Other exceptions only cause four and six word stack frame and require + * no post-trap stack adjustment. */ -ASENTRY_NOPROFILE(rei) - tstl _C_LABEL(astpending) | AST pending? - jeq Lchksir | no, go check for SIR -Lrei1: - btst #5,%sp@ | yes, are we returning to user mode? - jne Lchksir | no, go check for SIR - movw #PSL_LOWIPL,%sr | lower SPL - clrl %sp@- | stack adjust - moveml #0xFFFF,%sp@- | save all registers - movl %usp,%a1 | including - movl %a1,%sp@(FR_SP) | the users SP -Lrei2: - clrl %sp@- | VA == none - clrl %sp@- | code == none - movl #T_ASTFLT,%sp@- | type == async system trap - pea %sp@(12) | fp = trap frame address - jbsr _C_LABEL(trap) | go handle it - lea %sp@(16),%sp | pop value args - movl %sp@(FR_SP),%a0 | restore user SP - movl %a0,%usp | from save area - movw %sp@(FR_ADJ),%d0 | need to adjust stack? - jne Laststkadj | yes, go to it - moveml %sp@+,#0x7FFF | no, restore most user regs - addql #8,%sp | toss SP and stack adjust - rte | and do real RTE -Laststkadj: - lea %sp@(FR_HW),%a1 | pointer to HW frame - addql #8,%a1 | source pointer - movl %a1,%a0 | source - addw %d0,%a0 | + hole size = dest pointer - movl %a1@-,%a0@- | copy - movl %a1@-,%a0@- | 8 bytes - movl %a0,%sp@(FR_SP) | new SSP - moveml %sp@+,#0x7FFF | restore user registers - movl %sp@,%sp | and our SP - rte | and do real RTE -Lchksir: - tstb _C_LABEL(ssir) | SIR pending? - jeq Ldorte | no, all done - movl %d0,%sp@- | need a scratch register - movw %sp@(4),%d0 | get SR - andw #PSL_IPL7,%d0 | mask all but IPL - jne Lnosir | came from interrupt, no can do - movl %sp@+,%d0 | restore scratch register -Lgotsir: - movw #SPL1,%sr | prevent others from servicing int - tstb _C_LABEL(ssir) | too late? - jeq Ldorte | yes, oh well... - clrl %sp@- | stack adjust - moveml #0xFFFF,%sp@- | save all registers - movl %usp,%a1 | including - movl %a1,%sp@(FR_SP) | the users SP -Lsir1: - clrl %sp@- | VA == none - clrl %sp@- | code == none - movl #T_SSIR,%sp@- | type == software interrupt - pea %sp@(12) | fp = trap frame address - jbsr _C_LABEL(trap) | go handle it - lea %sp@(16),%sp | pop value args - movl %sp@(FR_SP),%a0 | restore + +ENTRY_NOPROFILE(badtrap) + moveml #0xC0C0,%sp@- | save scratch regs + movw %sp@(22),%sp@- | push exception vector info + clrw %sp@- + movl %sp@(22),%sp@- | and PC + jbsr _C_LABEL(straytrap) | report + addql #8,%sp | pop args + moveml %sp@+,#0x0303 | restore regs + jra _ASM_LABEL(rei) | all done + +ENTRY_NOPROFILE(trap0) + clrl %sp@- | stack adjust count + moveml #0xFFFF,%sp@- | save user registers + movl %usp,%a0 | save the user SP + movl %a0,%sp@(FR_SP) | in the savearea + movl %d0,%sp@- | push syscall number + jbsr _C_LABEL(syscall) | handle it + addql #4,%sp | pop syscall arg + tstl _C_LABEL(astpending) + jne Lrei2 + tstb _C_LABEL(ssir) + jeq Ltrap1 + movw #SPL1,%sr + tstb _C_LABEL(ssir) + jne Lsir1 +Ltrap1: + movl %sp@(FR_SP),%a0 | grab and restore movl %a0,%usp | user SP - moveml %sp@+,#0x7FFF | and all remaining registers + moveml %sp@+,#0x7FFF | restore most registers addql #8,%sp | pop SP and stack adjust rte -Lnosir: - movl %sp@+,%d0 | restore scratch register -Ldorte: - rte | real return /* - * Macro to relocate a symbol, used before MMU is enabled. + * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD) + * cachectl(command, addr, length) + * command in d0, addr in a1, length in d1 */ -#define _RELOC(var, ar) \ - lea var,ar; \ - addl %a5,ar - -#define RELOC(var, ar) _RELOC(_C_LABEL(var), ar) -#define ASRELOC(var, ar) _RELOC(_ASM_LABEL(var), ar) +ENTRY_NOPROFILE(trap12) + movl _C_LABEL(curlwp),%a0 + movl %a0@(L_PROC),%sp@- | push curproc pointer + movl %d1,%sp@- | push length + movl %a1,%sp@- | push addr + movl %d0,%sp@- | push command + jbsr _C_LABEL(cachectl1) | do it + lea %sp@(16),%sp | pop args + jra _ASM_LABEL(rei) | all done /* - * Initialization - * - * A4 contains the address of the end of the symtab - * A5 contains physical load point from boot - * VBR contains zero from ROM. Exceptions will continue to vector - * through ROM until MMU is turned on at which time they will vector - * through our table (vectors.s). + * Trace (single-step) trap. Kernel-mode is special. + * User mode traps are simply passed on to trap(). */ -BSS(lowram,4) -BSS(esym,4) - -GLOBAL(_verspad) - .word 0 -GLOBAL(boot_version) - .word X68K_BOOTIF_VERS - -ASENTRY_NOPROFILE(start) - movw #PSL_HIGHIPL,%sr | no interrupts - - addql #4,%sp - movel %sp@+,%a5 | firstpa - movel %sp@+,%d5 | fphysize -- last page - movel %sp@,%a4 | esym - - RELOC(vectab,%a0) | set Vector Base Register temporaly - movc %a0,%vbr +ENTRY_NOPROFILE(trace) + clrl %sp@- | stack adjust count + moveml #0xFFFF,%sp@- + moveq #T_TRACE,%d0 -#if 0 /* XXX this should be done by the boot loader */ - RELOC(edata, %a0) | clear out BSS - movl #_C_LABEL(end)-4,%d0 | (must be <= 256 kB) - subl #_C_LABEL(edata),%d0 - lsrl #2,%d0 -1: clrl %a0@+ - dbra %d0,1b -#endif + | Check PSW and see what happen. + | T=0 S=0 (should not happen) + | T=1 S=0 trace trap from user mode + | T=0 S=1 trace trap on a trap instruction + | T=1 S=1 trace trap from system mode (kernel breakpoint) - ASRELOC(tmpstk, %a0) - movl %a0,%sp | give ourselves a temporary stack - RELOC(esym, %a0) -#if 1 - movl %a4,%a0@ | store end of symbol table -#else - clrl %a0@ | no symbol table, yet -#endif - RELOC(lowram, %a0) - movl %a5,%a0@ | store start of physical memory + movw %sp@(FR_HW),%d1 | get PSW + notw %d1 | XXX no support for T0 on 680[234]0 + andw #PSL_TS,%d1 | from system mode (T=1, S=1)? + jeq Lkbrkpt | yes, kernel breakpoint + jra _ASM_LABEL(fault) | no, user-mode fault - movl #CACHE_OFF,%d0 - movc %d0,%cacr | clear and disable on-chip cache(s) +/* + * Trap 15 is used for: + * - GDB breakpoints (in user programs) + * - KGDB breakpoints (in the kernel) + * - trace traps for SUN binaries (not fully supported yet) + * User mode traps are simply passed to trap(). + */ +ENTRY_NOPROFILE(trap15) + clrl %sp@- | stack adjust count + moveml #0xFFFF,%sp@- + moveq #T_TRAP15,%d0 + movw %sp@(FR_HW),%d1 | get PSW + andw #PSL_S,%d1 | from system mode? + jne Lkbrkpt | yes, kernel breakpoint + jra _ASM_LABEL(fault) | no, user-mode fault -/* determine our CPU/MMU combo - check for all regardless of kernel config */ - movl #0x200,%d0 | data freeze bit - movc %d0,%cacr | only exists on 68030 - movc %cacr,%d0 | read it back - tstl %d0 | zero? - jeq Lnot68030 | yes, we have 68020/68040/68060 - jra Lstart1 | no, we have 68030 -Lnot68030: - bset #31,%d0 | data cache enable bit - movc %d0,%cacr | only exists on 68040/68060 - movc %cacr,%d0 | read it back - tstl %d0 | zero? - jeq Lis68020 | yes, we have 68020 - moveq #0,%d0 | now turn it back off - movec %d0,%cacr | before we access any data - .word 0xf4d8 | cinva bc - invalidate caches XXX - bset #30,%d0 | data cache no allocate mode bit - movc %d0,%cacr | only exists on 68060 - movc %cacr,%d0 | read it back - tstl %d0 | zero? - jeq Lis68040 | yes, we have 68040 - RELOC(mmutype, %a0) | no, we have 68060 - movl #MMU_68040,%a0@ | with a 68040 compatible MMU - RELOC(cputype, %a0) - movl #CPU_68060,%a0@ | and a 68060 CPU - jra Lstart1 -Lis68040: - RELOC(mmutype, %a0) - movl #MMU_68040,%a0@ | with a 68040 MMU - RELOC(cputype, %a0) - movl #CPU_68040,%a0@ | and a 68040 CPU - jra Lstart1 -Lis68020: - RELOC(mmutype, %a0) - movl #MMU_68851,%a0@ | we have PMMU - RELOC(cputype, %a0) - movl #CPU_68020,%a0@ | and a 68020 CPU +Lkbrkpt: | Kernel-mode breakpoint or trace trap. (d0=trap_type) + | Save the system sp rather than the user sp. + movw #PSL_HIGHIPL,%sr | lock out interrupts + lea %sp@(FR_SIZE),%a6 | Save stack pointer + movl %a6,%sp@(FR_SP) | from before trap -Lstart1: -/* initialize source/destination control registers for movs */ - moveq #FC_USERD,%d0 | user space - movc %d0,%sfc | as source - movc %d0,%dfc | and destination of transfers -/* initialize memory sizes (for pmap_bootstrap) */ - movl %d5,%d1 | last page - moveq #PGSHIFT,%d2 - lsrl %d2,%d1 | convert to page (click) number - RELOC(maxmem, %a0) - movl %d1,%a0@ | save as maxmem - movl %a5,%d0 | lowram value from ROM via boot - lsrl %d2,%d0 | convert to page number - subl %d0,%d1 | compute amount of RAM present - RELOC(physmem, %a0) - movl %d1,%a0@ | and physmem -/* configure kernel and lwp0 VA space so we can get going */ -#if NKSYMS || defined(DDB) || defined(LKM) - RELOC(esym,%a0) | end of static kernel test/data/syms - movl %a0@,%d5 - jne Lstart2 -#endif - movl #_C_LABEL(end),%d5 | end of static kernel text/data -Lstart2: - RELOC(setmemrange,%a0) | call setmemrange() - jbsr %a0@ | to probe all memory regions - addl #PAGE_SIZE-1,%d5 - andl #PG_FRAME,%d5 | round to a page - movl %d5,%a4 - addl %a5,%a4 | convert to PA - pea %a5@ | firstpa - pea %a4@ | nextpa - RELOC(pmap_bootstrap,%a0) - jbsr %a0@ | pmap_bootstrap(firstpa, nextpa) - addql #8,%sp + | If were are not on tmpstk switch to it. + | (so debugger can change the stack pointer) + movl %a6,%d1 + cmpl #_ASM_LABEL(tmpstk),%d1 + jls Lbrkpt2 | already on tmpstk + | Copy frame to the temporary stack + movl %sp,%a0 | a0=src + lea _ASM_LABEL(tmpstk)-96,%a1 | a1=dst + movl %a1,%sp | sp=new frame + moveq #FR_SIZE,%d1 +Lbrkpt1: + movl %a0@+,%a1@+ + subql #4,%d1 + jgt Lbrkpt1 -/* - * Prepare to enable MMU. - * Since the kernel is mapped logical == physical, we just turn it on. - */ - RELOC(Sysseg_pa, %a0) | system segment table addr - movl %a0@,%d1 | read value (a PA) - RELOC(mmutype, %a0) - cmpl #MMU_68040,%a0@ | 68040? - jne Lmotommu1 | no, skip - .long 0x4e7b1807 | movc d1,srp - jra Lstploaddone -Lmotommu1: - RELOC(protorp, %a0) - movl #0x80000202,%a0@ | nolimit + share global + 4 byte PTEs - movl %d1,%a0@(4) | + segtable address - pmove %a0@,%srp | load the supervisor root pointer - movl #0x80000002,%a0@ | reinit upper half for CRP loads -Lstploaddone: - RELOC(mmutype, %a0) - cmpl #MMU_68040,%a0@ | 68040? - jne Lmotommu2 | no, skip -#include "opt_jupiter.h" -#ifdef JUPITER - /* JUPITER-X: set system register "SUPER" bit */ - movl #0x0200a240,%d0 | translate DRAM area transparently - .long 0x4e7b0006 | movc d0,dtt0 - lea 0x00c00000,%a0 | a0: graphic VRAM - lea 0x02c00000,%a1 | a1: graphic VRAM ( not JUPITER-X ) - | DRAM ( JUPITER-X ) - movw %a0@,%d0 - movw %d0,%d1 - notw %d1 - movw %d1,%a1@ - movw %d0,%a0@ - cmpw %a1@,%d1 | JUPITER-X? - jne Ljupiterdone | no, skip - movl #0x0100a240,%d0 | to access system register - .long 0x4e7b0006 | movc d0,dtt0 - movb #0x01,0x01800003 | set "SUPER" bit -Ljupiterdone: -#endif /* JUPITER */ - moveq #0,%d0 | ensure TT regs are disabled - .long 0x4e7b0004 | movc d0,itt0 - .long 0x4e7b0005 | movc d0,itt1 - .long 0x4e7b0006 | movc d0,dtt0 - .long 0x4e7b0007 | movc d0,dtt1 - .word 0xf4d8 | cinva bc - .word 0xf518 | pflusha -#if PGSHIFT == 13 - movl #0xc000,%d0 -#else - movl #0x8000,%d0 +Lbrkpt2: + | Call the trap handler for the kernel debugger. + | Do not call trap() to do it, so that we can + | set breakpoints in trap() if we want. We know + | the trap type is either T_TRACE or T_BREAKPOINT. + | If we have both DDB and KGDB, let KGDB see it first, + | because KGDB will just return 0 if not connected. + | Save args in d2, a2 + movl %d0,%d2 | trap type + movl %sp,%a2 | frame ptr +#ifdef KGDB + | Let KGDB handle it (if connected) + movl %a2,%sp@- | push frame ptr + movl %d2,%sp@- | push trap type + jbsr _C_LABEL(kgdb_trap) | handle the trap + addql #8,%sp | pop args + cmpl #0,%d0 | did kgdb handle it? + jne Lbrkpt3 | yes, done #endif - .long 0x4e7b0003 | movc d0,tc -#ifdef M68060 - RELOC(cputype, %a0) - cmpl #CPU_68060,%a0@ | 68060? - jne Lnot060cache - movl #1,%d0 - .long 0x4e7b0808 | movcl d0,pcr - movl #0xa0808000,%d0 - movc %d0,%cacr | enable store buffer, both caches - jmp Lenab1 -Lnot060cache: +#ifdef DDB + | Let DDB handle it + movl %a2,%sp@- | push frame ptr + movl %d2,%sp@- | push trap type + jbsr _C_LABEL(kdb_trap) | handle the trap + addql #8,%sp | pop args +#if 0 /* not needed on hp300 */ + cmpl #0,%d0 | did ddb handle it? + jne Lbrkpt3 | yes, done #endif - movl #0x80008000,%d0 - movc %d0,%cacr | turn on both caches - jmp Lenab1 -Lmotommu2: - pflusha -#if PGSHIFT == 13 - movl #0x82d08b00,%sp@- | value to load TC with -#else - movl #0x82c0aa00,%sp@- | value to load TC with #endif - pmove %sp@,%tc | load it + /* Sun 3 drops into PROM here. */ +Lbrkpt3: + | The stack pointer may have been modified, or + | data below it modified (by kgdb push call), + | so push the hardware frame at the current sp + | before restoring registers and returning. + + movl %sp@(FR_SP),%a0 | modified sp + lea %sp@(FR_SIZE),%a1 | end of our frame + movl %a1@-,%a0@- | copy 2 longs with + movl %a1@-,%a0@- | ... predecrement + movl %a0,%sp@(FR_SP) | sp = h/w frame + moveml %sp@+,#0x7FFF | restore all but sp + movl %sp@,%sp | ... and sp + rte | all done + +/* Use common m68k sigreturn */ +#include <m68k/m68k/sigreturn.s> /* - * Should be running mapped from this point on + * Provide a generic interrupt dispatcher, only handle hardclock (int6) + * specially, to improve performance */ -Lenab1: -/* set vector base in virtual address */ - movl #_C_LABEL(vectab),%d0 | set Vector Base Register - movc %d0,%vbr - lea _ASM_LABEL(tmpstk),%sp | temporary stack -/* call final pmap setup */ - jbsr _C_LABEL(pmap_bootstrap_finalize) -/* set kernel stack, user SP */ - movl _C_LABEL(lwp0uarea),%a1 | grab lwp0 uarea - lea %a1@(USPACE-4),%sp | set kernel stack to end of area - movl #USRSTACK-4,%a2 - movl %a2,%usp | init user SP -/* detect FPU type */ - jbsr _C_LABEL(fpu_probe) - movl %d0,_C_LABEL(fputype) - tstl _C_LABEL(fputype) | Have an FPU? - jeq Lenab2 | No, skip. - clrl %a1@(PCB_FPCTX) | ensure null FP context +ENTRY_NOPROFILE(spurintr) /* level 0 */ + addql #1,_C_LABEL(intrcnt)+0 + INTERRUPT_SAVEREG + CPUINFO_INCREMENT(CI_NINTR) + INTERRUPT_RESTOREREG + rte | XXX mfpcure (x680x0 hardware bug) + +ENTRY_NOPROFILE(kbdtimer) + rte + +ENTRY_NOPROFILE(intiotrap) + addql #1,_C_LABEL(idepth) + INTERRUPT_SAVEREG + pea %sp@(16-(FR_HW)) | XXX + jbsr _C_LABEL(intio_intr) + addql #4,%sp + CPUINFO_INCREMENT(CI_NINTR) + INTERRUPT_RESTOREREG + subql #1,_C_LABEL(idepth) + jra rei + +ENTRY_NOPROFILE(lev1intr) +ENTRY_NOPROFILE(lev2intr) +ENTRY_NOPROFILE(lev3intr) +ENTRY_NOPROFILE(lev4intr) +ENTRY_NOPROFILE(lev5intr) +ENTRY_NOPROFILE(lev6intr) + addql #1,_C_LABEL(idepth) + INTERRUPT_SAVEREG +Lnotdma: + lea _C_LABEL(intrcnt),%a0 + movw %sp@(22),%d0 | use vector offset + andw #0xfff,%d0 | sans frame type + addql #1,%a0@(-0x60,%d0:w) | to increment apropos counter + movw %sr,%sp@- | push current SR value + clrw %sp@- | padded to longword + jbsr _C_LABEL(intrhand) | handle interrupt + addql #4,%sp | pop SR + CPUINFO_INCREMENT(CI_NINTR) + INTERRUPT_RESTOREREG + subql #1,_C_LABEL(idepth) + jra _ASM_LABEL(rei) + +ENTRY_NOPROFILE(timertrap) + addql #1,_C_LABEL(idepth) + INTERRUPT_SAVEREG | save scratch registers + addql #1,_C_LABEL(intrcnt)+32 | count hardclock interrupts + lea %sp@(16),%a1 | a1 = &clockframe movl %a1,%sp@- - jbsr _C_LABEL(m68881_restore) | restore it (does not kill a1) + jbsr _C_LABEL(hardclock) | hardclock(&frame) addql #4,%sp -Lenab2: - cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? - jeq Ltbia040 | yes, cache already on - pflusha - tstl _C_LABEL(mmutype) - jpl Lenab3 | 68851 implies no d-cache - movl #CACHE_ON,%d0 - movc %d0,%cacr | clear cache(s) - jra Lenab3 -Ltbia040: - .word 0xf518 -Lenab3: -/* final setup for C code */ - movl %d7,_C_LABEL(boothowto) | save reboot flags - movl %d6,_C_LABEL(bootdev) | and boot device - jbsr _C_LABEL(x68k_init) | additional pre-main initialization + CPUINFO_INCREMENT(CI_NINTR) | chalk up another interrupt + INTERRUPT_RESTOREREG | restore scratch registers + subql #1,_C_LABEL(idepth) + jra _ASM_LABEL(rei) | all done + +ENTRY_NOPROFILE(lev7intr) + addql #1,_C_LABEL(idepth) + addql #1,_C_LABEL(intrcnt)+28 + clrl %sp@- + moveml #0xFFFF,%sp@- | save registers + movl %usp,%a0 | and save + movl %a0,%sp@(FR_SP) | the user stack pointer + jbsr _C_LABEL(nmihand) | call handler + movl %sp@(FR_SP),%a0 | restore + movl %a0,%usp | user SP + moveml %sp@+,#0x7FFF | and remaining registers + addql #8,%sp | pop SP and stack adjust + subql #1,_C_LABEL(idepth) + jra _ASM_LABEL(rei) | all done /* - * Create a fake exception frame so that cpu_lwp_fork() can copy it. - * main() nevers returns; we exit to user mode from a forked process - * later on. + * floppy ejection trap */ - clrw %sp@- | vector offset/frame type - clrl %sp@- | PC - filled in by "execve" - movw #PSL_USER,%sp@- | in user mode - clrl %sp@- | stack adjust count and padding - lea %sp@(-64),%sp | construct space for D0-D7/A0-A7 - lea _C_LABEL(lwp0),%a0 | save pointer to frame - movl %sp,%a0@(L_MD_REGS) | in lwp0.p_md.md_regs - jra _C_LABEL(main) | main() +ENTRY_NOPROFILE(fdeject) + jra _ASM_LABEL(rei) - PANIC("main() returned") | Yow! Main returned! - /* NOTREACHED */ +/* + * Emulation of VAX REI instruction. + * + * This code deals with checking for and servicing ASTs + * (profiling, scheduling) and software interrupts (network, softclock). + * We check for ASTs first, just like the VAX. To avoid excess overhead + * the T_ASTFLT handling code will also check for software interrupts so we + * do not have to do it here. After identifing that we need an AST we + * drop the IPL to allow device interrupts. + * + * This code is complicated by the fact that sendsig may have been called + * necessitating a stack cleanup. + */ +ASENTRY_NOPROFILE(rei) + tstl _C_LABEL(astpending) | AST pending? + jeq Lchksir | no, go check for SIR +Lrei1: + btst #5,%sp@ | yes, are we returning to user mode? + jne Lchksir | no, go check for SIR + movw #PSL_LOWIPL,%sr | lower SPL + clrl %sp@- | stack adjust + moveml #0xFFFF,%sp@- | save all registers + movl %usp,%a1 | including + movl %a1,%sp@(FR_SP) | the users SP +Lrei2: + clrl %sp@- | VA == none + clrl %sp@- | code == none + movl #T_ASTFLT,%sp@- | type == async system trap + pea %sp@(12) | fp = trap frame address + jbsr _C_LABEL(trap) | go handle it + lea %sp@(16),%sp | pop value args + movl %sp@(FR_SP),%a0 | restore user SP + movl %a0,%usp | from save area + movw %sp@(FR_ADJ),%d0 | need to adjust stack? + jne Laststkadj | yes, go to it + moveml %sp@+,#0x7FFF | no, restore most user regs + addql #8,%sp | toss SP and stack adjust + rte | and do real RTE +Laststkadj: + lea %sp@(FR_HW),%a1 | pointer to HW frame + addql #8,%a1 | source pointer + movl %a1,%a0 | source + addw %d0,%a0 | + hole size = dest pointer + movl %a1@-,%a0@- | copy + movl %a1@-,%a0@- | 8 bytes + movl %a0,%sp@(FR_SP) | new SSP + moveml %sp@+,#0x7FFF | restore user registers + movl %sp@,%sp | and our SP + rte | and do real RTE +Lchksir: + tstb _C_LABEL(ssir) | SIR pending? + jeq Ldorte | no, all done + movl %d0,%sp@- | need a scratch register + movw %sp@(4),%d0 | get SR + andw #PSL_IPL7,%d0 | mask all but IPL + jne Lnosir | came from interrupt, no can do + movl %sp@+,%d0 | restore scratch register +Lgotsir: + movw #SPL1,%sr | prevent others from servicing int + tstb _C_LABEL(ssir) | too late? + jeq Ldorte | yes, oh well... + clrl %sp@- | stack adjust + moveml #0xFFFF,%sp@- | save all registers + movl %usp,%a1 | including + movl %a1,%sp@(FR_SP) | the users SP +Lsir1: + clrl %sp@- | VA == none + clrl %sp@- | code == none + movl #T_SSIR,%sp@- | type == software interrupt + pea %sp@(12) | fp = trap frame address + jbsr _C_LABEL(trap) | go handle it + lea %sp@(16),%sp | pop value args + movl %sp@(FR_SP),%a0 | restore + movl %a0,%usp | user SP + moveml %sp@+,#0x7FFF | and all remaining registers + addql #8,%sp | pop SP and stack adjust + rte +Lnosir: + movl %sp@+,%d0 | restore scratch register +Ldorte: + rte | real return /* * Use common m68k sigcode.