Prevent the system from getting watchdog reset by returning directly to user

mode if restoring the user window traps.  Also reduce the time we run with
%tl>0.
This commit is contained in:
eeh 2000-04-18 02:12:25 +00:00
parent 2aec15d3d3
commit c58f0ee9cd
1 changed files with 193 additions and 119 deletions

View File

@ -1,11 +1,13 @@
/* $NetBSD: locore.s,v 1.54 2000/04/13 18:40:27 eeh Exp $ */
/* $NetBSD: locore.s,v 1.55 2000/04/18 02:12:25 eeh Exp $ */
/*
* Copyright (c) 1996-1999 Eduardo Horvath
* Copyright (c) 1996 Paul Kranenburg
* Copyright (c) 1996
* The President and Fellows of Harvard College. All rights reserved.
* The President and Fellows of Harvard College.
* All rights reserved.
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* The Regents of the University of California.
* All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
@ -24,45 +26,47 @@
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* documentation and/or other materials provided with the
* distribution.
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* This product includes software developed by Harvard University.
* This product includes software developed by Paul Kranenburg.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* 4. Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* @(#)locore.s 8.4 (Berkeley) 12/10/93
*/
#undef NO_VCACHE /* Map w/D$ disabled */
#define TRAPTRACE /* Keep history of all traps (may watchdog) */
#undef FLTRACE /* Keep history of all page faults only */
#define TRAPTRACE /* Keep history of all traps (unsafe) */
#undef FLTRACE /* Keep history of all page faults */
#define TRAPSTATS /* Count traps */
#undef TRAPS_USE_IG /* Use Interrupt Globals for trap handling */
#undef TRAPS_USE_IG /* Use Interrupt Globals for all traps */
#undef LOCKED_PCB /* Lock current proc's PCB in MMU */
#define HWREF /* Handle ref/mod tracking in trap handlers */
#undef MMUDEBUG /* Check use of MMU regs during MMU faults */
#define HWREF /* Track ref/mod bits in trap handlers */
#undef MMUDEBUG /* Check use of regs during MMU faults */
#define VECTORED_INTERRUPTS /* Use interrupt vectors */
#define PMAP_FPSTATE /* Allow nesting of VIS pmap copy/zero */
#define NEW_FPSTATE
#define PMAP_PHYS_PAGE /* Don't use block ld/st for pmap copy/zero */
#define DCACHE_BUG /* Clear D$ line before loads from ASI_PHYS */
#define PMAP_PHYS_PAGE /* Use phys ASIs for pmap copy/zero */
#define DCACHE_BUG /* Flush D$ around ASI_PHYS accesses */
#define NO_TSB /* Don't use TSB */
#undef TICK_IS_TIME /* Keep %tick synchronized with time */
@ -149,8 +153,8 @@
/*
* GNU assembler does not understand `.empty' directive; Sun assembler
* gripes about labels without it. To allow cross-compilation using
* the Sun assembler, and because .empty directives are useful documentation,
* we use this trick.
* the Sun assembler, and because .empty directives are useful
* documentation, we use this trick.
*/
#ifdef SUN_AS
#define EMPTY .empty
@ -298,12 +302,14 @@ _C_LABEL(kgdb_stack):
.space KGDB_STACK_SIZE ! hope this is enough
#endif
#ifdef DEBUG
/*
* This is an emergency stack used when we overflow the normal kernel stack.
* This stack is used when we detect kernel stack corruption.
*/
.space USPACE
.align 16
panicstack:
#endif
/*
* _cpcb points to the current pcb (and hence u. area).
@ -330,8 +336,8 @@ _C_LABEL(cputyp):
.word 1
/*
* _cpumod is the current cpu model, used to distinguish between variants
* in the Sun4 and Sun4M families. See /sys/arch/sparc64/include/param.h for
* possible values.
* in the Sun4 and Sun4M families. See /sys/arch/sparc64/include/param.h
* for possible values.
*/
.globl _C_LABEL(cpumod)
_C_LABEL(cpumod):
@ -385,7 +391,8 @@ _C_LABEL(msgbuf) = KERNBASE
* the window overflow, underflow, and clean window traps which are
* 32 instructions long, large enough to in-line.
*
* The spitfire CPU (Ultra I) has 4 different sets of global registers. (blah blah...)
* The spitfire CPU (Ultra I) has 4 different sets of global registers.
* (blah blah...)
*
* I used to generate these numbers by address arithmetic, but gas's
* expression evaluator has about as much sense as your average slug
@ -396,9 +403,9 @@ _C_LABEL(msgbuf) = KERNBASE
* Hardware interrupt vectors can be `linked'---the linkage is to regular
* C code---or rewired to fast in-window handlers. The latter are good
* for unbuffered hardware like the Zilog serial chip and the AMD audio
* chip, where many interrupts can be handled trivially with pseudo-DMA or
* similar. Only one `fast' interrupt can be used per level, however, and
* direct and `fast' interrupts are incompatible. Routines in intr.c
* chip, where many interrupts can be handled trivially with pseudo-DMA
* or similar. Only one `fast' interrupt can be used per level, however,
* and direct and `fast' interrupts are incompatible. Routines in intr.c
* handle setting these, with optional paranoia.
*/
@ -419,57 +426,70 @@ _C_LABEL(msgbuf) = KERNBASE
/* regular vectored traps */
#ifdef DEBUG
#ifdef TRAPTRACE
#define TRACEME sethi %hi(1f), %g1; ba,pt %icc,traceit; or %g1, %lo(1f), %g1; 1:
#define TRACEME sethi %hi(1f), %g1; ba,pt %icc,traceit;\
or %g1, %lo(1f), %g1; 1:
#if 0
#define TRACEWIN sethi %hi(9f), %l6; ba,pt %icc,traceitwin; or %l6, %lo(9f), %l6; 9:
#define TRACEWIN sethi %hi(9f), %l6; ba,pt %icc,traceitwin;\
or %l6, %lo(9f), %l6; 9:
#endif
#ifdef TRAPS_USE_IG
#define TRACEWIN wrpr %g0, PSTATE_KERN|PSTATE_AG, %pstate; sethi %hi(9f), %g1; ba,pt %icc,traceit; or %g1, %lo(9f), %g1; 9:
#define TRACEWIN wrpr %g0, PSTATE_KERN|PSTATE_AG, %pstate;\
sethi %hi(9f), %g1; ba,pt %icc,traceit; or %g1, %lo(9f), %g1; 9:
#else
#define TRACEWIN wrpr %g0, PSTATE_KERN|PSTATE_IG, %pstate; sethi %hi(9f), %g1; ba,pt %icc,traceit; or %g1, %lo(9f), %g1; 9:
#define TRACEWIN wrpr %g0, PSTATE_KERN|PSTATE_IG, %pstate;\
sethi %hi(9f), %g1; ba,pt %icc,traceit; or %g1, %lo(9f), %g1; 9:
#endif
#define TRACERELOAD32 ba reload32; nop;
#define TRACERELOAD64 ba reload64; nop;
#define TRACEFLT TRACEME
#define VTRAP(type, label) \
sethi %hi(label), %g1; ba,pt %icc,traceit; or %g1, %lo(label), %g1; NOTREACHED; TA8
sethi %hi(label), %g1; ba,pt %icc,traceit;\
or %g1, %lo(label), %g1; NOTREACHED; TA8
#else
#define TRACEME
#define TRACEWIN TRACEME
#define TRACERELOAD32
#define TRACERELOAD64
#ifdef FLTRACE
#define TRACEFLT sethi %hi(1f), %g1; ba,pt %icc,traceit; or %g1, %lo(1f), %g1; 1:
#define TRACEFLT sethi %hi(1f), %g1; ba,pt %icc,traceit;\
or %g1, %lo(1f), %g1; 1:
#else
#define TRACEFLT TRACEME
#endif
#define VTRAP(type, label) \
sethi KERNBASE,%g1; rdpr %tt,%g2; or %g1,0x28,%g1; b label; stx %g2,[%g1]; NOTREACHED; TA8
sethi KERNBASE,%g1; rdpr %tt,%g2; or %g1,0x28,%g1; b label;\
stx %g2,[%g1]; NOTREACHED; TA8
#endif
#else
#ifdef TRAPTRACE
#define TRACEME sethi %hi(1f), %g1; ba,pt %icc,traceit; or %g1, %lo(1f), %g1; 1:
#define TRACEME sethi %hi(1f), %g1; ba,pt %icc,traceit;\
or %g1, %lo(1f), %g1; 1:
#if 0
/* Can't use this macro 'cause we have no clean registers during a spill */
#define TRACEWIN sethi %hi(9f), %l6; ba,pt %icc,traceitwin; or %l6, %lo(9f), %l6; 9:
/* Can't use this 'cause we have no clean registers during a spill */
#define TRACEWIN sethi %hi(9f), %l6; ba,pt %icc,traceitwin;\
or %l6, %lo(9f), %l6; 9:
#endif
#ifdef TRAPS_USE_IG
#define TRACEWIN wrpr %g0, PSTATE_KERN|PSTATE_AG, %pstate; sethi %hi(9f), %g1; ba,pt %icc,traceit; or %g1, %lo(9f), %g1; 9:
#define TRACEWIN wrpr %g0, PSTATE_KERN|PSTATE_AG, %pstate;\
sethi %hi(9f), %g1; ba,pt %icc,traceit; or %g1, %lo(9f), %g1; 9:
#else
#define TRACEWIN wrpr %g0, PSTATE_KERN|PSTATE_IG, %pstate; sethi %hi(9f), %g1; ba,pt %icc,traceit; or %g1, %lo(9f), %g1; 9:
#define TRACEWIN wrpr %g0, PSTATE_KERN|PSTATE_IG, %pstate;\
sethi %hi(9f), %g1; ba,pt %icc,traceit; or %g1, %lo(9f), %g1; 9:
#endif
#define TRACERELOAD32 ba reload32; nop;
#define TRACERELOAD64 ba reload64; nop;
#define TRACEFLT TRACEME
#define VTRAP(type, label) \
sethi %hi(label), %g1; ba,pt %icc,traceit; or %g1, %lo(label), %g1; NOTREACHED; TA8
sethi %hi(label), %g1; ba,pt %icc,traceit;\
or %g1, %lo(label), %g1; NOTREACHED; TA8
#else
#define TRACEME
#define TRACEWIN TRACEME
#define TRACERELOAD32
#define TRACERELOAD64
#ifdef FLTRACE
#define TRACEFLT sethi %hi(1f), %g1; ba,pt %icc,traceit; or %g1, %lo(1f), %g1; 1:
#define TRACEFLT sethi %hi(1f), %g1; ba,pt %icc,traceit;\
or %g1, %lo(1f), %g1; 1:
#else
#define TRACEFLT TRACEME
#endif
@ -508,10 +528,9 @@ _C_LABEL(msgbuf) = KERNBASE
#define BPT_KGDB_EXEC TRAP(T_KGDB_EXEC)
#endif
/* special high-speed 1-instruction-shaved-off traps (get nothing in %l3) */
#define SYSCALL VTRAP(0x100, syscall_setup)
#ifdef notyet
#define ZS_INTERRUPT b zshard; nop; TA8
#define ZS_INTERRUPT ba,a,pt %icc, zshard; nop; TA8
#else
#define ZS_INTERRUPT4U HARDINT4U(12)
#endif
@ -592,7 +611,7 @@ label: \
#define SPILLBOTH(label64,label32,as) \
TRACEWIN; \
andcc %sp, 1, %g0; \
bnz,pt %xcc, label64+4; /* See if it's a v9 stack or v8 */ \
bnz,pt %xcc, label64+4; /* Is it a v9 or v8 stack? */ \
wr %g0, as, %asi; \
ba,pt %xcc, label32+8; \
srl %sp, 0, %sp; /* fixup 32-bit pointers */ \
@ -672,9 +691,6 @@ label: \
.globl start, _C_LABEL(kernel_text)
_C_LABEL(kernel_text) = start ! for kvm_mkdb(8)
start:
/*
* Put sun4u traptable first, since it needs the most stringent aligment (32K)
*/
/* Traps from TL=0 -- traps from user mode */
#define TABLE user_
.globl _C_LABEL(trapbase)
@ -682,13 +698,13 @@ _C_LABEL(trapbase):
b dostart; nop; TA8 ! 000 = reserved -- Use it to boot
/* We should not get the next 5 traps */
UTRAP(0x001) ! 001 = POR Reset -- ROM should get this
UTRAP(0x002) ! 002 = WDR Watchdog -- ROM should get this
UTRAP(0x002) ! 002 = WDR -- ROM should get this
UTRAP(0x003) ! 003 = XIR -- ROM should get this
UTRAP(0x004) ! 004 = SIR -- ROM should get this
UTRAP(0x005) ! 005 = RED state exception
UTRAP(0x006); UTRAP(0x007)
VTRAP(T_INST_EXCEPT, textfault) ! 008 = instr. access exept
VTRAP(T_TEXTFAULT, textfault) ! 009 = instr access MMU miss -- no MMU
VTRAP(T_TEXTFAULT, textfault) ! 009 = instr access MMU miss
VTRAP(T_INST_ERROR, textfault) ! 00a = instr. access err
UTRAP(0x00b); UTRAP(0x00c); UTRAP(0x00d); UTRAP(0x00e); UTRAP(0x00f)
TRAP(T_ILLINST) ! 010 = illegal instruction
@ -766,7 +782,7 @@ _C_LABEL(trapbase):
TRAP(T_PA_WATCHPT) ! 061 = physical address data watchpoint
TRAP(T_VA_WATCHPT) ! 062 = virtual address data watchpoint
UTRAP(T_ECCERR) ! We'll implement this one later
ufast_IMMU_miss: ! 063 = fast instr access MMU miss
ufast_IMMU_miss: ! 064 = fast instr access MMU miss
TRACEFLT ! DEBUG
ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer
ldxa [%g0] ASI_IMMU, %g1 ! Hard coded for unified 8K TSB Load IMMU tag target register
@ -1039,7 +1055,7 @@ kdatafault:
TRAP(T_PA_WATCHPT) ! 061 = physical address data watchpoint
TRAP(T_VA_WATCHPT) ! 062 = virtual address data watchpoint
UTRAP(T_ECCERR) ! We'll implement this one later
kfast_IMMU_miss: ! 063 = fast instr access MMU miss
kfast_IMMU_miss: ! 064 = fast instr access MMU miss
TRACEFLT ! DEBUG
ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer
ldxa [%g0] ASI_IMMU, %g1 ! Hard coded for unified 8K TSB Load IMMU tag target register
@ -2254,30 +2270,9 @@ winfixfill:
#endif
btst TSTATE_PRIV, %g4 ! User mode?
and %g4, CWP, %g5 ! %g4 = %cwp of trap
wrpr %g5, %cwp ! Restore cwp from before fill trap -- regs should now be consisent
#ifdef NOTDEF_DEBUG
set panicstack, %g5
saved
save %g5, -CC64FSZ, %sp
GLOBTOLOC
rdpr %wstate, %l0
wrpr %g0, WSTATE_KERN, %wstate
set 8f, %o0
call printf
mov %fp, %o1
wrpr %l0, 0, %wstate
LOCTOGLOB
restore
ba 9f
nop
8:
.asciz "winfix: fill fixup sp=%p\n"
_ALIGN
9:
#endif
CHKPT(%g5,%g4,0xd)
bz,pt %icc, datafault ! We were in user mode -- normal fault
wrpr %g7, 0, %tt
wrpr %g7, 0, %tt
bz,a,pt %icc, datafault ! We were in user mode -- normal fault
wrpr %g5, %cwp ! Restore cwp from before fill trap -- regs should now be consisent
/*
* We're in a pickle here. We were trying to return to user mode
@ -2300,6 +2295,8 @@ winfixfill:
inc %g7
stw %g7, [%g4]
#endif
#if 0 /* Need to switch over to new stuff to fix WDR bug */
wrpr %g5, %cwp ! Restore cwp from before fill trap -- regs should now be consisent
wrpr %g2, %g0, %tl ! Restore trap level -- we need to reuse it
set return_from_trap, %g4
set CTX_PRIMARY, %g7
@ -2320,6 +2317,58 @@ winfixfill:
! flushw ! DEBUG
ba,pt %icc, datafault
wrpr %g4, 0, %tnpc
#else
wrpr %g2, %g0, %tl ! Restore trap level
cmp %g2, 3
tne %icc, 1
rdpr %tt, %g5
wrpr %g0, 1, %tl ! Revert to TL==1 XXX what if this wasn't in rft_user? Oh well.
wrpr %g5, %g0, %tt ! Set trap type correctly
CHKPT(%g5,%g7,0xe)
/*
* Here we need to implement the beginning of datafault.
* TRAP_SETUP expects to come from either kernel mode or
* user mode with at least one valid register window. It
* will allocate a trap frame, save the out registers, and
* fix the window registers to think we have one user
* register window.
*
* However, under these circumstances we don't have any
* valid register windows, so we need to clean up the window
* registers to prevent garbage from being saved to either
* the user stack or the PCB before calling the datafault
* handler.
*
* We could simply jump to datafault if we could somehow
* make the handler issue a `saved' instruction immediately
* after creating the trapframe.
*
* The fillowing is duplicated from datafault:
*/
wrpr %g0, PSTATE_KERN|PSTATE_AG, %pstate ! We need to save volatile stuff to AG regs
#ifdef TRAPS_USE_IG
wrpr %g0, PSTATE_KERN|PSTATE_IG, %pstate ! We need to save volatile stuff to AG regs
#endif
#ifdef DEBUG
set trapbase, %g7 ! debug
set 0x20, %g6 ! debug
stx %g0, [%g7] ! debug
stb %g6, [%g7 + 0x20] ! debug
CHKPT(%g4,%g7,0xf)
#endif
wr %g0, ASI_DMMU, %asi ! We need to re-load trap info
ldxa [%g0 + TLB_TAG_ACCESS] %asi, %g1 ! Get fault address from tag access register
! nop; nop; nop ! Linux sez we need this after reading TAG_ACCESS
ldxa [SFAR] %asi, %g2 ! sync virt addr; must be read first
ldxa [SFSR] %asi, %g3 ! get sync fault status register
stxa %g0, [SFSR] %asi ! Clear out fault now
membar #Sync ! No real reason for this XXXX
TRAP_SETUP(-CC64FSZ-TF_SIZE)
saved ! Blow away that one register window we didn't ever use.
ba,a,pt %icc, Ldatafault_internal ! Now we should return directly to user mode
nop
#endif
winfixspill:
bne,a,pt %xcc, datafault ! Was not a spill -- handle it normally
wrpr %g2, 0, %tl ! Restore trap level for now XXXX
@ -2510,7 +2559,11 @@ winfixspill:
wrpr %g0, 0, %otherwin
or %lo(2f), %o0, %o0
wrpr %g0, WSTATE_KERN, %wstate
set panicstack-CC64FSZ, %sp
#ifdef DEBUG
set panicstack-CC64FSZ, %sp ! Use panic stack.
#else
set estack0-CC64FSZ, %sp ! Overwrite proc 0's stack.
#endif
ta 1; nop ! This helps out traptrace.
call _C_LABEL(panic) ! This needs to be fixed properly but we should panic here
mov %g1, %o1
@ -2599,7 +2652,7 @@ winfixsave:
dec %g5 ! NWINDOWS-2
wrpr %g5, 0, %cleanwin ! Set cleanwin to max, since we're in-kernel
sub %g5, %g1, %g5 ! NWINDOWS-2-%canrestore
#ifdef TRAPTRACE
#ifdef xTRAPTRACE
wrpr %g5, 0, %cleanwin ! Force cleanwindow faults
#endif
wrpr %g5, 0, %cansave
@ -2654,7 +2707,7 @@ winfixsave:
set 0x11, %g6 ! debug
stb %g6, [%g7 + 0x20] ! debug
CHKPT(%g2,%g1,0x17)
sir
! sir
#endif
ta 1; nop ! Enter debugger
NOTREACHED
@ -2809,8 +2862,8 @@ datafault:
membar #Sync ! No real reason for this XXXX
TRAP_SETUP(-CC64FSZ-TF_SIZE)
Ldatafault_internal:
INCR(_C_LABEL(uvmexp)+V_FAULTS) ! cnt.v_faults++ (clobbers %o0,%o1) should not fault
! ldx [%sp + CC64FSZ + STKB + TF_FAULT], %g1 ! DEBUG make sure this has not changed
mov %g1, %o5 ! Move these to the out regs so we can save the globals
mov %g2, %o1
@ -2965,11 +3018,7 @@ instr_miss:
sethi %hi(_C_LABEL(ctxbusy)), %g4
sllx %g3, (64-13), %g6 ! Mask away address
#ifdef _LP64
ldx [%g4 + %lo(_C_LABEL(ctxbusy))], %g4
#else
lduw [%g4 + %lo(_C_LABEL(ctxbusy))], %g4
#endif
LDPTR [%g4 + %lo(_C_LABEL(ctxbusy))], %g4
srlx %g6, (64-13-3), %g6 ! This is now the offset into ctxbusy
ldx [%g4+%g6], %g4 ! Load up our page table.
@ -3204,7 +3253,11 @@ slowtrap:
cmp %g7, WSTATE_KERN
bnz,pt %icc, 1f ! User stack -- we'll blow it away
nop
#ifdef DEBUG
set panicstack, %sp ! Kernel stack corrupt -- use panicstack
#else
set estack0, %sp ! Kernel stack corrupt -- use estack0
#endif
1:
rdpr %tt, %g4
rdpr %tstate, %g1
@ -3248,12 +3301,13 @@ Lslowtrap_reenter:
clr %g4
! flushw ! DEBUG
wrpr %g0, PSTATE_INTR, %pstate ! traps on again
call _C_LABEL(trap) ! trap(type, pstate, pc, &tf)
wrpr %g0, PSTATE_INTR, %pstate ! traps on again
nop
! wrpr %g0, PSTATE_KERN, %pstate ! traps off again
CHKPT(%o1,%o2,3)
b return_from_trap
ba,a,pt %icc, return_from_trap
nop
NOTREACHED
#if 1
@ -3638,7 +3692,7 @@ return_from_syscall:
CHKPT(%o1,%o2,0x32)
wrpr %g0, 0, %tl ! Return to tl==0
CHKPT(%o1,%o2,4)
b return_from_trap
ba,a,pt %icc, return_from_trap
nop
NOTREACHED
@ -4147,7 +4201,7 @@ intrcmplt:
wrpr %l3, 0, %pil
CHKPT(%o1,%o2,5)
b return_from_trap
ba,a,pt %icc, return_from_trap
nop
@ -4292,30 +4346,27 @@ return_from_trap:
!!
!! Let all pending interrupts drain before returning to userland
!!
wrpr %g0, PSTATE_INTR, %pstate
bnz,pn %icc, 1f ! Returning to userland?
nop
wrpr %g0, PSTATE_INTR, %pstate
wrpr %g0, %g0, %pil ! Lower IPL
1:
wrpr %g0, PSTATE_KERN, %pstate ! Make sure we have normal globals & no IRQs
rdpr %tl, %g1 ! Grab a set of trap registers
inc %g1
wrpr %g1, %g0, %tl
/* First restore normal globals */
ldx [%sp + CC64FSZ + STKB + TF_G + (1*8)], %g1 ! restore g1
ldx [%sp + CC64FSZ + STKB + TF_G + (2*8)], %g2 ! restore g2
ldx [%sp + CC64FSZ + STKB + TF_G + (3*8)], %g3 ! restore g3
ldx [%sp + CC64FSZ + STKB + TF_G + (4*8)], %g4 ! restore g4
ldx [%sp + CC64FSZ + STKB + TF_G + (5*8)], %g5 ! restore g5
ldx [%sp + CC64FSZ + STKB + TF_G + (6*8)], %g6 ! restore g6
ldx [%sp + CC64FSZ + STKB + TF_G + (7*8)], %g7 ! restore g7
/* Then switch to alternate globals and load outs */
/* Restore normal globals */
ldx [%sp + CC64FSZ + STKB + TF_G + (1*8)], %g1
ldx [%sp + CC64FSZ + STKB + TF_G + (2*8)], %g2
ldx [%sp + CC64FSZ + STKB + TF_G + (3*8)], %g3
ldx [%sp + CC64FSZ + STKB + TF_G + (4*8)], %g4
ldx [%sp + CC64FSZ + STKB + TF_G + (5*8)], %g5
ldx [%sp + CC64FSZ + STKB + TF_G + (6*8)], %g6
ldx [%sp + CC64FSZ + STKB + TF_G + (7*8)], %g7
/* Switch to alternate globals and load outs */
wrpr %g0, PSTATE_KERN|PSTATE_AG, %pstate
#ifdef TRAPS_USE_IG
wrpr %g0, PSTATE_KERN|PSTATE_IG, %pstate ! DEBUG
#endif
ldx [%sp + CC64FSZ + STKB + TF_O + (0*8)], %i0 ! tf.tf_out[0], etc
ldx [%sp + CC64FSZ + STKB + TF_O + (0*8)], %i0
ldx [%sp + CC64FSZ + STKB + TF_O + (1*8)], %i1
ldx [%sp + CC64FSZ + STKB + TF_O + (2*8)], %i2
ldx [%sp + CC64FSZ + STKB + TF_O + (3*8)], %i3
@ -4357,6 +4408,9 @@ return_from_trap:
*
*/
rft_kernel:
rdpr %tl, %g4 ! Grab a set of trap registers
inc %g4
wrpr %g4, %g0, %tl
wrpr %g3, 0, %tnpc
wrpr %g2, 0, %tpc
wrpr %g1, 0, %tstate
@ -4439,11 +4493,13 @@ rft_wcnt: .word 0
rft_user:
! sethi %hi(_C_LABEL(want_ast)), %g7 ! (done above)
lduw [%g7 + %lo(_C_LABEL(want_ast))], %g7! want AST trap?
#if 0
/* This is probably necessary */
wrpr %g0, 1, %tl ! Sometimes we get here w/TL=0 (How?)
wrpr %g3, 0, %tnpc
wrpr %g2, 0, %tpc
wrpr %g1, 0, %tstate
#endif
brnz,pn %g7, softtrap ! yes, re-enter trap with type T_AST
mov T_AST, %g4
@ -4529,8 +4585,9 @@ rft_user:
set rft_wcnt, %g4 ! Keep track of all the windows we restored
stw %g7, [%g4]
#endif
brz,a,pt %g7, 5f ! No
restore ! This may fault, but we should return here.
brz,pt %g7, 5f ! No
nop
dec %g7 ! We can do this now or later. Move to last entry
sll %g7, 7, %g5 ! calculate ptr into rw64 array 8*16 == 128 or 7 bits
@ -4624,13 +4681,31 @@ rft_user:
LDPTR [%g5 + %lo(_C_LABEL(cpcb))], %g5
ldub [%g5 + PCB_NSAVED], %g5 ! Any saved reg windows?
tst %g5
wrpr %g0, 0, %tl ! DEBUG
tnz %icc, 1; nop ! Debugger if we still have saved windows
bne,a rft_user ! Try starting over again
sethi %hi(_C_LABEL(want_ast)), %g7
#endif
/*
* Set up our return trapframe so we can recover if we trap from here
* on in.
*/
wrpr %g0, 1, %tl ! Set up the trap state
wrpr %g2, 0, %tpc
wrpr %g3, 0, %tnpc
ba,pt %icc, 6f
wrpr %g1, %g0, %tstate
5:
/*
* Set up our return trapframe so we can recover if we trap from here
* on in.
*/
wrpr %g0, 1, %tl ! Set up the trap state
wrpr %g2, 0, %tpc
wrpr %g3, 0, %tnpc
wrpr %g1, %g0, %tstate
restore
6:
CHKPT(%g4,%g7,0xa)
rdpr %canrestore, %g5
wrpr %g5, 0, %cleanwin ! Force cleanup of kernel windows
@ -4675,11 +4750,9 @@ badregs:
1:
#endif
rdpr %tstate, %g1
rdpr %cwp, %g7 ! Find our cur window
andn %g1, CWP, %g1 ! Clear it from %tstate
wrpr %g0, 1, %tl ! Set up the trap state
wrpr %g2, 0, %tpc
wrpr %g3, 0, %tnpc
wrpr %g1, %g7, %tstate ! Set %tstate with %cwp
CHKPT(%g4,%g7,0xb)
@ -7545,6 +7618,7 @@ ENTRY(proc_trampoline)
GLOBTOLOC
call prom_printf
mov %g2, %o1
LOCTOGLOB
set 3f, %o0
mov %g1, %o1
mov %g2, %o2
@ -7562,8 +7636,8 @@ ENTRY(proc_trampoline)
Debugger()
#endif
CHKPT(%o3,%o4,0x35)
b return_from_trap
wrpr %g0, 1, %tl ! Return to tl==1
ba,a,pt %icc, return_from_trap
nop
/*
* {fu,su}{,i}{byte,word}