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:
parent
2aec15d3d3
commit
c58f0ee9cd
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue