Handle kernel trace traps and breakpoints like the Sun3 port:

- Only pass user trace traps and breakpoints on to trap().
	- Before entering the debugger, switch to a temporary
	  stack so that the debugger can alter the stack pointer.
	- Add glue for KGDB (still not complete).
Clearly mark the MMU enable trampoline code.
This commit is contained in:
thorpej 1996-10-05 07:16:52 +00:00
parent 0ff075f6e7
commit 8499e0131e
1 changed files with 101 additions and 35 deletions

View File

@ -1,6 +1,7 @@
/* $NetBSD: locore.s,v 1.56 1996/10/05 07:06:11 thorpej Exp $ */
/* $NetBSD: locore.s,v 1.57 1996/10/05 07:16:52 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995 Gordon W. Ross
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1980, 1990, 1993
* The Regents of the University of California. All rights reserved.
@ -476,45 +477,100 @@ _trap12:
jra rei | all done
/*
* Trap 15 is used for:
* - KGDB traps
* - trace traps for SUN binaries (not fully supported yet)
* We just pass it on and let trap() sort it all out
*/
_trap15:
clrl sp@-
moveml #0xFFFF,sp@-
#ifdef KGDB
moveq #T_TRAP15,d0
movw sp@(FR_HW),d1 | get PSW
andw #PSL_S,d1 | from user mode?
jeq fault | yes, just a regular fault
movl d0,sp@-
.globl _kgdb_trap_glue
jbsr _kgdb_trap_glue | returns if no debugger
addl #4,sp
#endif
moveq #T_TRAP15,d0
jra fault
/*
* Hit a breakpoint (trap 1 or 2) instruction.
* Push the code and treat as a normal fault.
* Trace (single-step) trap. Kernel-mode is special.
* User mode traps are simply passed on to trap().
*/
_trace:
clrl sp@-
clrl sp@- | stack adjust count
moveml #0xFFFF,sp@-
moveq #T_TRACE,d0
movw sp@(FR_HW),d1 | get PSW
andw #PSL_S,d1 | from system mode?
jne kbrkpt | yes, kernel breakpoint
jra 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().
*/
_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 kbrkpt | yes, kernel breakpoint
jra fault | no, user-mode fault
kbrkpt: | 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 #tmpstk,d1
jls Lbrkpt2 | already on tmpstk
| Copy frame to the temporary stack
movl sp,a0 | a0=src
lea tmpstk-96,a1 | a1=dst
movl a1,sp | sp=new frame
moveq #FR_SIZE,d1
Lbrkpt1:
movl a0@+,a1@+
subql #4,d1
bgt 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
moveq #T_TRACE,d0
movw sp@(FR_HW),d1 | get SSW
andw #PSL_S,d1 | from user mode?
jeq fault | no, regular fault
movl d0,sp@-
jbsr _kgdb_trap_glue | returns if no debugger
addl #4,sp
| Let KGDB handle it (if connected)
movl a2,sp@- | push frame ptr
movl d2,sp@- | push trap type
jbsr _kgdb_trap | handle the trap
addql #8,sp | pop args
cmpl #0,d0 | did kgdb handle it?
jne Lbrkpt3 | yes, done
#endif
moveq #T_TRACE,d0
jra fault
#ifdef DDB
| Let DDB handle it
movl a2,sp@- | push frame ptr
movl d2,sp@- | push trap type
jbsr _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>
@ -916,6 +972,12 @@ Lcodecopy:
jcs Lcodecopy | no, keep going
jmp MAXADDR | go for it!
/*
* BEGIN MMU TRAMPOLINE. This section of code is not
* executed in-place. It's copied to the last page
* of RAM (mapped va == pa) and executed there.
*/
Lhighcode:
RELOC(_mmutype, a0)
tstl a0@ | HP MMU?
@ -949,6 +1011,10 @@ Lhpmmu3:
jmp Lenab1 | jmp to mapped code
Lehighcode:
/*
* END MMU TRAMPOLINE.
*/
/*
* Should be running mapped from this point on
*/