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.