\ ========== Copyright Header Begin ==========================================
\ Hypervisor Software File: catchexc.fth
\ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
\ - Do no alter or remove copyright notices
\ - Redistribution and use of this software in source and binary forms, with
\ or without modification, are permitted provided that the following
\ - Redistribution of source code must retain the above copyright notice,
\ this list of conditions and the following disclaimer.
\ - Redistribution 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.
\ Neither the name of Sun Microsystems, Inc. or the names of contributors
\ may be used to endorse or promote products derived from this software
\ without specific prior written permission.
\ This software is provided "AS IS," without a warranty of any kind.
\ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
\ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
\ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
\ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
\ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
\ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
\ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
\ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
\ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
\ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
\ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
\ You acknowledge that this software is not designed, licensed or
\ intended for use in the design, construction, operation or maintenance of
\ ========== Copyright Header End ============================================
id: @(#)catchexc.fth 1.7 07/06/05
copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
copyright: Use is subject to license terms.
\ The allocation of the cpu structs really should be on a page boundary
\ put stuff to do on entry in this chain.
defer enterforth-hook ' enterforth-chain is enterforth-hook
\ Clear any pending L15 Interrupts
last-trap# h# 4f = if 1 h# 0f lshift clear-softint! then
?secure handle-breakpoint
code slave-bp-loop ( -- )
scr rdpstate \ We should not be spinning in
#sync membar \ this loop with IE = 0
scr 2 scr or \ set IE = 1
up sc1 sc2 get-cpu-struct
scr sc2 sc1 stx \ Mark as Parked
\ Wait here until we are restarted OR the master CPU advances us
\ into the wait for lockfree phase
h# 12 %o5 move \ cpu_yield, FN # 0x12
%g0 fast-trap# always htrapif \ Trap into HV and stay there
again nop \ Loop forever while in slave bp loop
\itc : slave-bp-loop slave-bp-loop ;
%g4 %g0 h# 20 %g5 ldxa \ CPU struct PA
%g7 rdtt %g7 %g5 save-reg last-trap#
%g5 %g1 load-reg error-reset-trap
\ Last trap is one of reset
\ non-zero Indicates Error Reset
%g1 %g5 save-reg last-trap#
%g1 %g5 save-reg error-reset-trap
%g5 %g1 load-reg %state-valid
%g1 %g5 save-reg %state-valid
%g0 1 %g6 add \ Full state save
%g5 %g4 move \ CPU struct in %g4
save-cpu-state always brif
\ Cannot rely upon %g's across save-cpu-state!!
%g4 %g0 h# 20 %g4 ldxa \ CPU struct PA
%g0 %g4 %g1 memory-asi stxa \ Stack Fence Off
\ %o's are saved, it is now safe to make hcalls
\ if the size is 0 we skip the tsb save
\ Preserve the TSB Areas, and disable TSBs
0 >cpu-tsb-ctrl-area %g7 set
%g4 %g7 %g7 add \ TSB ctrl base
%g7 0 >tsb-allocation %o0 read-reg \ sizeof tsb ctx0 area
%g7 0 >tsb-buffer-addr %o1 read-reg \ TSB CTX0 - RA
%g0 h# 29 %o5 add \ MMU_TSB_CTX0INFO
%g0 %g7 0 >tsb-saved-size write-reg \ 0 as size (delay)
%o1 %g7 0 >tsb-saved-size write-reg \ Save actual size
%g0 %o1 move \ %o0 is already 0...
%g0 h# 20 %o5 add \ MMU_TSB_CTX0
%g7 /tsb-data >tsb-allocation %o0 read-reg \ sizeof tsb ctxX area
%g7 /tsb-data >tsb-buffer-addr %o1 read-reg \ TSB CTXNON0 - RA
%g0 h# 2a %o5 add \ MMU_TSB_CTXNON0INFO
%g0 %g7 /tsb-data >tsb-saved-size write-reg \ 0 as size (delay)
%o1 %g7 /tsb-data >tsb-saved-size write-reg \ Save actual size
%g0 %o1 move \ %o0 is already 0...
%g0 h# 21 %o5 add \ MMU_TSB_CTXNON0
\ OK we go virtual from here on
up %g4 %g1 get-cpu-struct
%g1 offset-of last-trap# scr ldx
scr h# 17f %g0 subcc \ Breakpoint!
%g0 0 %o0 add \ timeout value
%g0 h# 5 %o5 add \ func # (WD)
\ Save address of this location for later
\ Setup the SP and RP here
\ we install a fence on the existing sp, rp IF:
\ 1. The PC is inside the PROM
\ 2. Primary Context is 0
\ 3. We have not hit a breakpoint.
\ 4. This is the first time we have done this.
%g1 offset-of %state-valid sc5 ldx \ Per CPU state-valid Lock
%g1 offset-of %pcontext scr ldx \ get primary context
%g1 offset-of last-trap# scr ldx
scr h# 17f %g0 subcc \ Breakpoint!
%g1 offset-of %pc scr ldx \ get PC
scr h# f %g0 subcc \ inside OBP space?
sc5 -1 cmp \ State Valid = -1?
sc3 %g1 scr stx \ mark fence as active
0 >return-stack h# 40 /n* + scr set
%g1 scr rp add \ END of RS
rp %g1 scr stx \ Mark rs stackbase
0 >data-stack h# 40 /n* + scr set
%g1 scr sp add \ END of SP
sp %g1 scr stx \ Mark ds stackbase
\ Check State Valid again
scr %g1 offset-of %saved-my-self stx
\ User Area (we only need to save the first few locations)
%g1 scr scr add \ Address of save area
up sc1 move \ Bottom of user area
ua-size sc2 move \ Size of user area
sc3 scr sc2 stx \ Delay slot
\ Account for the presence of the top of stack register
\dtc 'acf enterforth scr set
\itc 'body enterforth scr set
sc1 sc2 sc3 mutex-try-enter prom-lock
\ Initialize the Interpreter Pointer
\dtc 'acf slave-bp-loop scr set
\itc 'body slave-bp-loop scr set
\ We don't want to enable interrupts on CPUs that are in the middle
\ of taking an error reset until later when we have idled all the
\ other CPUs via cross calls.
%g1 offset-of error-reset-trap scr ldx
%g0 h# 14 wrpstate \ PEF=1, PRIV=1
%g0 h# 16 wrpstate \ PEF=1, PRIV=1, IE=1
\ Initialize the Window Registers & Stack Pointer
sp %g7 move \ Save sp and rp so we don't lose them
%g1 window-registers %g4 add
%o6 /entry-frame %o6 save
%g7 sp move \ Restore sp and rp
\ XXX this really belongs in savecpu.fth, to match the small startup
\ FWD refs prevent that working though.
\ %g1 is the structure offset
label small-forth-save-state
\ OK, we have to switch to the original fault-tl and tpc, tnpc
\ we got here from the restore which does a retry at tl=1 having
\ setup the tpc, tnpc to 'return', everything else should be restored
%g2 %g0 h# 20 %g5 ldxa \ CPU struct PA
%g5 %g1 %g5 add \ CPU save area
here 4 - origin - %g4 set
save-state origin- %g1 set
prom-main-task %g4 up setx \ Set User Area Pointer
here 4 - origin - %g4 set
up %g4 %g1 get-cpu-struct
\ %g1 = Base of cpu-state array
\ %g3 = User Pointer (up)
%g4 %g1 offset-of %state-valid stx
%g4 %g1 offset-of error-reset-trap stx
%g4 %g1 offset-of %saved-my-self stx
\ Continue with save-state
save-fstate always brif nop
up %g2 %g7 get-cpu-struct
CPU-STARTED %g1 %g6 %g7 mark-cpu-state
\ After this point we are PHYSICAL access
\ PSTATE.IE = 0, Tl=2, GL=2
%g4 %g0 h# 20 %g5 ldxa \ CPU struct PA
%g0 %g5 save-reg last-trap#
%g0 %g5 save-reg %state-valid
%g1 %g5 save-reg %restartable?
0 >cpu-tsb-ctrl-area %g1 set
%g5 %g1 %g1 add \ control block
%g1 0 >tsb-saved-size %o0 read-reg \ sizeof tsb ctx0 area
%g1 0 >tsb-buffer-addr %o1 read-reg \ TSB CTX0 - RA
%g0 h# 20 %o5 add \ MMU_TSB_CTX0
%g1 /tsb-data >tsb-saved-size %o0 read-reg
%g1 /tsb-data >tsb-buffer-addr %o1 read-reg \ TSB CTXNON0 - RA
%g0 h# 21 %o5 add \ MMU_TSB_CTXNON0
\ restore dev mondo queue
0 >cpu-devmondo-ptr %g1 set
%g5 %g1 %g1 add \ target PA
%g1 0 %g4 read-reg \ get saved value
%g4 %g0 h# 3d0 %asi stxa \ restore original idx
%g0 %g1 0 write-reg \ mark as done
restore-cpu-state always brif
up sc2 sc1 get-cpu-struct
scr sc1 sc2 mutex-exit prom-lock
code wait-for-lock-free ( -- )
up sc1 sc4 get-cpu-struct
CPU-WAIT-RESTART scr sc1 sc4 mark-cpu-state
scr sc1 sc2 sc3 mutex-enter prom-lock
CPU-OBP-WARM scr sc1 sc4 mark-cpu-state
: restart-slave ( -- ) wait-for-lock-free restart ;
code (restart-step ( -- )
' (restart-step is restart-step
: .tt ( n -- ) base @ >r hex <# u# u# u# u#> r> base ! type space ;
: trap" ( trap# n -- ) \ name description"
??cr dup w@ over wa1+ w@ ( apf tt n )
also trap-types definitions
100 80 trap" tt-100 Trap Instruction (Ticc)"
e0 20 trap" tt-0e0 Fill Other 0 - 7"
c0 20 trap" tt-0c0 Fill Normal 0 - 7"
a0 20 trap" tt-0a0 Spill Other 0 - 7"
80 20 trap" tt-080 Spill Normal 0 - 7"
7f 1 trap" tt-07f Non-Resumable Error"
7e 1 trap" tt-07e Resumable Error"
7d 1 trap" tt-07d Device Mondo"
70 1 trap" tt-070 Fast ECC Error"
6c 4 trap" tt-06c Fast Data Access Protection"
68 4 trap" tt-068 Fast Data Access MMU Miss"
64 4 trap" tt-064 Fast Instruction Access MMU Miss"
63 1 trap" tt-063 Corrected ECC Error"
62 1 trap" tt-062 VA Watchpoint"
61 1 trap" tt-061 PA Watchpoint"
60 1 trap" tt-060 Interrupt Vector"
41 f trap" tt-041 Interrupt Level 1 - 15"
37 1 trap" tt-037 Privileged Action"
36 1 trap" tt-036 STDF Memory Address not Aligned"
35 1 trap" tt-035 LDDF Memory Address not Aligned"
34 1 trap" tt-034 Memory Address not Aligned"
32 1 trap" tt-032 Data Access Error"
31 1 trap" tt-031 TSB Data Miss"
30 1 trap" tt-030 Data Access Exception"
28 1 trap" tt-028 Division by Zero"
24 4 trap" tt-024 Clean Window"
23 1 trap" tt-023 TAG Overflow"
22 1 trap" tt-022 FP Exception Other"
21 1 trap" tt-021 FP Exception IEEE 754"
20 1 trap" tt-020 FP Disabled"
11 1 trap" tt-011 Privileged Opcode"
10 1 trap" tt-010 Illegal Instruction"
a 1 trap" tt-00a Instruction Access Error"
9 1 trap" tt-009 TSB Instruction MISS"
8 1 trap" tt-008 Instruction Access Exception"
5 1 trap" tt-005 RED State Exception"
4 1 trap" tt-004 Software Initiated Reset"
3 1 trap" tt-003 Externally Initiated Reset"
2 1 trap" tt-002 Watchdog Reset"
1 1 trap" tt-001 Power On Reset"
previous previous definitions
[ also hidden ] 0 ['] trap-types [ previous ]
begin another-word? while ( alf' voc-acf anf )
name> execute exit? if 2drop exit then
: (last-trap) ( -- ?? fmt$ )
last-trap# dup h# 100 < if ( tt )
dup h# 41 h# 4f between if ( tt )
h# 40 - " Level %d Interrupt" ( n fmt$ )
h# 80 - 2 >> " Spill %d Normal" ( n fmt$ )
h# a0 - 2 >> " Spill %d Other" ( n fmt$ )
h# c0 - 2 >> " Fill %d Normal" ( n fmt$ )
h# e0 - 2 >> " Fill %d Other" ( n fmt$ )
[ also hidden ] ['] trap-types [ previous ] ( alf vacf ) ( r: tt )
begin another-word? while ( alf' vacf anf ) ( r: tt )
name> >body dup w@ r@ = if ( alf' vacf apf ) ( r: tt )
la1+ count " %s" r> drop exit ( str$ fmt$ )
else ( alf' vacf apf ) ( r: tt )
drop ( alf' vacf ) ( r: tt )
then ( alf' vacf ) ( r: tt )
h# 100 - " Trap %x" ( n fmt$ )
cmn-fatal[ " Last Trap: " cmn-append ]cmn-end
cmn-error[ " Last Trap: " cmn-append ]cmn-end
last-trap# 0= last-trap# h# 60 = or if exit then
obp-control-relinquished? if
current-frame$ @ >r 0 current-frame$ !
\ -256 throw \ Do not un-comment this throw.
\ (Comment derived from sun4u/catchexc.fth)
\ The above throw is meant to be caught by some outer intelligent catch
\ that knows how to handle the -256 error code. There is no such catch,
\ and even if there were, this throw would first be intercepted by one of
\ the MANY badly behaving catches in the source tree, who then drive
\ on without first examining the error code.
\ Instead, fall through to caller (breakpoint-message), which falls into
\ quit and takes us back to the ok prompt.
\ The below code flushes the common messaging buffer, so we don't lose any
\ pending error messages before we get to the ok prompt.
' false is breakpoint-trap?
' (do-last-trap) is .exception
stand-init: Install .exception and enable errors
['] (do-last-trap) is .exception