* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / arch / sparc64 / kernel / rtrap.S
blobbb6d7398e5fb4127c82d052f8f2ffb0bdb34cd64
1 /* $Id: rtrap.S,v 1.47 1999/07/30 09:35:23 davem Exp $
2  * rtrap.S: Preparing for return from trap on Sparc V9.
3  *
4  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
6  */
8 #include <asm/asi.h>
9 #include <asm/pstate.h>
10 #include <asm/ptrace.h>
11 #include <asm/spitfire.h>
12 #include <asm/head.h>
13 #include <asm/visasm.h>
14 #include <asm/processor.h>
16 #define         PTREGS_OFF              (STACK_BIAS + REGWIN_SZ)
18                 .text
19                 .align                  32
20                 .globl                  rtrap_clr_l6, rtrap
21 rtrap_clr_l6:   clr                     %l6
22                 /* Fall through */
23 rtrap:          sethi                   %hi(bh_active), %l2
24                 sethi                   %hi(bh_mask), %l1
25                 ldx                     [%l2 + %lo(bh_active)], %l4
26                 ldx                     [%l1 + %lo(bh_mask)], %l7
28                 andcc                   %l4, %l7, %g0
29                 be,pt                   %xcc, 2f
30                  nop
31                 call                    do_bottom_half
32                  nop
33 2:              ldx                     [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
34                 sethi                   %hi(0xf << 20), %l4
35                 andcc                   %l1, TSTATE_PRIV, %l3
37                 and                     %l1, %l4, %l4
38                 rdpr                    %pstate, %l7
39                 andn                    %l1, %l4, %l1
40                 be,pt                   %icc, to_user
41                  andn                   %l7, PSTATE_IE, %l7
43                 ldub                    [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5
44                 brz,pt                  %l5, rt_continue
45                  srl                    %l5, 1, %o0
46                 add                     %g6, AOFF_task_thread + AOFF_thread_fpsaved, %l6
47                 ldub                    [%l6 + %o0], %l2
48                 sub                     %l5, 2, %l5
49                 add                     %g6, AOFF_task_thread + AOFF_thread_gsr, %o1
50                 andcc                   %l2, (FPRS_FEF|FPRS_DU), %g0
51                 be,pt                   %icc, 2f
52                  and                    %l2, FPRS_DL, %l6
53                 andcc                   %l2, FPRS_FEF, %g0
54                 be,pn                   %icc, 5f
55                  sll                    %o0, 3, %o5
56                 rd                      %fprs, %g5
57                 wr                      %g5, FPRS_FEF, %fprs
58                 ldub                    [%o1 + %o0], %g5
59                 add                     %g6, AOFF_task_thread + AOFF_thread_xfsr, %o1
60                 membar                  #StoreLoad | #LoadLoad
61                 sll                     %o0, 8, %o2
62                 add                     %g6, AOFF_task_fpregs, %o3
63                 brz,pn                  %l6, 1f
64                  add                    %g6, AOFF_task_fpregs+0x40, %o4
65                 ldda                    [%o3 + %o2] ASI_BLK_P, %f0
66                 ldda                    [%o4 + %o2] ASI_BLK_P, %f16
67 1:              andcc                   %l2, FPRS_DU, %g0
68                 be,pn                   %icc, 1f
69                  wr                     %g5, 0, %gsr
70                 add                     %o2, 0x80, %o2
71                 ldda                    [%o3 + %o2] ASI_BLK_P, %f32
72                 ldda                    [%o4 + %o2] ASI_BLK_P, %f48
73 1:              membar                  #Sync
74                 ldx                     [%o1 + %o5], %fsr
75 2:              stb                     %l5, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth]
76 rt_continue:    ldx                     [%sp + PTREGS_OFF + PT_V9_G1], %g1
77                 ldx                     [%sp + PTREGS_OFF + PT_V9_G2], %g2
78                 ldx                     [%sp + PTREGS_OFF + PT_V9_G3], %g3
79                 mov                     %g6, %o5
80                 ldx                     [%sp + PTREGS_OFF + PT_V9_G4], %g4
81                 ldx                     [%sp + PTREGS_OFF + PT_V9_G5], %g5
82                 ldx                     [%sp + PTREGS_OFF + PT_V9_G6], %g6
83                 ldx                     [%sp + PTREGS_OFF + PT_V9_G7], %g7
85                 wrpr                    %l7, PSTATE_AG, %pstate
86                 ldx                     [%sp + PTREGS_OFF + PT_V9_I0], %i0
87                 ldx                     [%sp + PTREGS_OFF + PT_V9_I1], %i1
88                 ldx                     [%sp + PTREGS_OFF + PT_V9_I2], %i2
89                 ldx                     [%sp + PTREGS_OFF + PT_V9_I3], %i3
90                 ldx                     [%sp + PTREGS_OFF + PT_V9_I4], %i4
91                 ldx                     [%sp + PTREGS_OFF + PT_V9_I5], %i5
92                 ldx                     [%sp + PTREGS_OFF + PT_V9_I6], %i6
94                 ldx                     [%sp + PTREGS_OFF + PT_V9_I7], %i7
95                 ld                      [%sp + PTREGS_OFF + PT_V9_Y], %o3
96                 ldx                     [%sp + PTREGS_OFF + PT_V9_TPC], %l2
97                 ldx                     [%sp + PTREGS_OFF + PT_V9_TNPC], %o2
98                 wr                      %o3, %g0, %y
99                 srl                     %l4, 20, %l4
100                 wrpr                    %l4, 0x0, %pil
101                 wrpr                    %g0, 0x1, %tl
103                 wrpr                    %l1, %g0, %tstate
104                 wrpr                    %l2, %g0, %tpc
105                 wrpr                    %o2, %g0, %tnpc
106                 brnz,pn                 %l3, kern_rtt
107                  mov                    PRIMARY_CONTEXT, %l7
108                 ldxa                    [%l7 + %l7] ASI_DMMU, %l0
109                 stxa                    %l0, [%l7] ASI_DMMU
110                 flush                   %o5
112                 rdpr                    %wstate, %l1
113                 rdpr                    %otherwin, %l2
114                 srl                     %l1, 3, %l1
115                 wrpr                    %l2, %g0, %canrestore
116                 wrpr                    %l1, %g0, %wstate
117                 wrpr                    %g0, %g0, %otherwin
118                 restore
119                 rdpr                    %canrestore, %g1
121                 wrpr                    %g1, 0x0, %cleanwin
122                 retry
123 kern_rtt:       restore
124                 retry
125 to_user:        ldx                     [%g6 + AOFF_task_need_resched], %l0
126                 wrpr                    %l7, PSTATE_IE, %pstate
127                 orcc                    %g0, %l0, %g0
128                 be,a,pt                 %xcc, check_signal
130                  lduw                   [%g6 + AOFF_task_sigpending], %l0
131                 call                    schedule
132                  nop
133                 lduw                    [%g6 + AOFF_task_sigpending], %l0
134 check_signal:   brz,a,pt                %l0, check_user_wins
135                  nop
136                 clr                     %o0
137                 mov                     %l5, %o2  
138                 mov                     %l6, %o3
139                 call                    do_signal
140                  add                    %sp, STACK_BIAS + REGWIN_SZ, %o1
141                 clr                     %l6
143                 /* We must not take any traps between here and the actual
144                  * return to user-space.  If we do we risk having windows
145                  * saved to the thread struct between the test and the
146                  * actual return from trap.  --DaveM
147                  */
148 check_user_wins:
149                 wrpr                    %l7, 0x0, %pstate
150                 ldub                    [%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2
151                 brz,pt                  %o2, 1f
152                  sethi                  %hi(TSTATE_PEF), %l6
154                 wrpr                    %l7, PSTATE_IE, %pstate
155                 call                    fault_in_user_windows
156                  add                    %sp, STACK_BIAS + REGWIN_SZ, %o0
157                 /* It is OK to leave interrupts on now because if
158                  * fault_in_user_windows has returned it has left us
159                  * with a clean user stack state.
160                  */
162 #if 0
163                 call                    rtrap_check
164                  add                    %sp, STACK_BIAS + REGWIN_SZ, %o0
165 #endif
166                 ldub                    [%g6 + AOFF_task_thread + AOFF_thread_flags], %l5
167                 andcc                   %l5, SPARC_FLAG_PERFCTR, %g0
168                 be,pt                   %xcc, 1f
169                  nop
171                 /* Don't forget to preserve user window invariants. */
172                 wrpr                    %l7, PSTATE_IE, %pstate
173                 call                    update_perfctrs
174                  nop
175                 wrpr                    %l7, 0x0, %pstate
176                 ldub                    [%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2
177                 brz,pt                  %o2, 1f
178                  sethi                  %hi(TSTATE_PEF), %l6
179                 wrpr                    %l7, PSTATE_IE, %pstate
180                 call                    fault_in_user_windows
181                  add                    %sp, STACK_BIAS + REGWIN_SZ, %o0
184                 andcc                   %l1, %l6, %g0
185                 be,pt                   %xcc, rt_continue
186                  stb                    %g0, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth] ! This is neccessary for non-syscall rtraps only
188                 rd                      %fprs, %l5
189                 andcc                   %l5, FPRS_FEF, %g0
190                 be,a,pn                 %icc, rt_continue
191                  andn                   %l1, %l6, %l1
192                 ba,pt                   %xcc, rt_continue
193                  nop
195 5:              wr                      %g0, FPRS_FEF, %fprs
196                 membar                  #StoreLoad | #LoadLoad
197                 sll                     %o0, 8, %o2
198                 add                     %g6, AOFF_task_fpregs+0x80, %o3
199                 add                     %g6, AOFF_task_fpregs+0xc0, %o4
200                 ldda                    [%o3 + %o2] ASI_BLK_P, %f32
201                 ldda                    [%o4 + %o2] ASI_BLK_P, %f48
202 1:              membar                  #Sync
203                 wr                      %g0, FPRS_DU, %fprs
204                 ba,pt                   %xcc, rt_continue
205                  stb                    %l5, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth]
207 #undef PTREGS_OFF