OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [sparc/] [kernel/] [rirq.S] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/* rirq.S: Needed to return from an interrupt on SMP with no
2
 *         locks held or released.
3
 *
4
 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
5
 */
6
 
7
#include 
8
#include 
9
#include 
10
#include 
11
#include 
12
#include 
13
#include 
14
#include 
15
#include 
16
 
17
#define t_psr     l0
18
#define t_pc      l1
19
#define t_npc     l2
20
#define t_wim     l3
21
#define twin_tmp1 l4
22
#define twin_tmp2 l5
23
#define twin_tmp3 l6
24
 
25
        /* 7 WINDOW SPARC PATCH INSTRUCTIONS */
26
        .globl  rirq_7win_patch1, rirq_7win_patch2, rirq_7win_patch3
27
        .globl  rirq_7win_patch4, rirq_7win_patch5
28
rirq_7win_patch1:       srl     %t_wim, 0x6, %twin_tmp2
29
rirq_7win_patch2:       and     %twin_tmp2, 0x7f, %twin_tmp2
30
rirq_7win_patch3:       srl     %g1, 7, %g2
31
rirq_7win_patch4:       srl     %g2, 6, %g2
32
rirq_7win_patch5:       and     %g1, 0x7f, %g1
33
        /* END OF PATCH INSTRUCTIONS */
34
 
35
        .globl  ret_irq_entry, rirq_patch1, rirq_patch2
36
        .globl  rirq_patch3, rirq_patch4, rirq_patch5
37
ret_irq_entry:
38
        ld      [%sp + REGWIN_SZ + PT_PSR], %t_psr
39
        andcc   %t_psr, PSR_PS, %g0
40
        bne     ret_irq_kernel
41
         nop
42
 
43
ret_irq_user:
44
        wr      %t_psr, 0x0, %psr
45
        WRITE_PAUSE
46
 
47
        LOAD_CURRENT(twin_tmp2, twin_tmp1)
48
        ld      [%twin_tmp2 + THREAD_W_SAVED], %twin_tmp1
49
        orcc    %g0, %twin_tmp1, %g0
50
        be      ret_irq_nobufwins
51
         nop
52
 
53
        /* User has toasty windows, must grab klock. */
54
        ENTER_SYSCALL
55
 
56
        wr      %t_psr, PSR_ET, %psr
57
        WRITE_PAUSE
58
 
59
        mov     1, %o1
60
        call    C_LABEL(try_to_clear_window_buffer)
61
         add    %sp, REGWIN_SZ, %o0
62
 
63
        /* We have klock, so we must return just like a normal trap. */
64
        b       ret_trap_entry
65
         nop
66
 
67
ret_irq_nobufwins:
68
        /* Load up the user's out registers so we can pull
69
         * a window from the stack, if necessary.
70
         */
71
        LOAD_PT_INS(sp)
72
 
73
        /* If there are already live user windows in the
74
         * set we can return from trap safely.
75
         */
76
        ld      [%twin_tmp2 + THREAD_UMASK], %twin_tmp1
77
        orcc    %g0, %twin_tmp1, %g0
78
        bne     ret_irq_userwins_ok
79
         nop
80
 
81
                /* Calculate new %wim, we have to pull a register
82
                 * window from the users stack.
83
                 */
84
ret_irq_pull_one_window:
85
                rd      %wim, %t_wim
86
                sll     %t_wim, 0x1, %twin_tmp1
87
rirq_patch1:    srl     %t_wim, 0x7, %twin_tmp2
88
                or      %twin_tmp2, %twin_tmp1, %twin_tmp2
89
rirq_patch2:    and     %twin_tmp2, 0xff, %twin_tmp2
90
 
91
                wr      %twin_tmp2, 0x0, %wim
92
                WRITE_PAUSE
93
 
94
                                /* Here comes the architecture specific
95
                                 * branch to the user stack checking routine
96
                                 * for return from traps.
97
                                 */
98
                                .globl  C_LABEL(rirq_mmu_patchme)
99
C_LABEL(rirq_mmu_patchme):      b       C_LABEL(sun4c_reti_stackchk)
100
                                 andcc  %fp, 0x7, %g0
101
 
102
ret_irq_userwins_ok:
103
        LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
104
        or      %t_pc, %t_npc, %g2
105
        andcc   %g2, 0x3, %g0
106
        bne     ret_irq_unaligned_pc
107
         nop
108
 
109
        LOAD_PT_YREG(sp, g1)
110
        LOAD_PT_GLOBALS(sp)
111
 
112
        wr      %t_psr, 0x0, %psr
113
        WRITE_PAUSE
114
 
115
        jmp     %t_pc
116
        rett    %t_npc
117
 
118
ret_irq_unaligned_pc:
119
        add     %sp, REGWIN_SZ, %o0
120
        ld      [%sp + REGWIN_SZ + PT_PC], %o1
121
        ld      [%sp + REGWIN_SZ + PT_NPC], %o2
122
        ld      [%sp + REGWIN_SZ + PT_PSR], %o3
123
 
124
        wr      %t_wim, 0x0, %wim               ! or else...
125
        WRITE_PAUSE
126
 
127
        /* User has unaligned crap, must grab klock. */
128
        ENTER_SYSCALL
129
 
130
        wr      %t_psr, PSR_ET, %psr
131
        WRITE_PAUSE
132
 
133
        call    C_LABEL(do_memaccess_unaligned)
134
         nop
135
 
136
        /* We have klock, so we must return just like a normal trap. */
137
        b       ret_trap_entry
138
         nop
139
 
140
ret_irq_kernel:
141
        wr      %t_psr, 0x0, %psr
142
        WRITE_PAUSE
143
 
144
                /* Will the rett land us in the invalid window? */
145
                mov     2, %g1
146
                sll     %g1, %t_psr, %g1
147
rirq_patch3:    srl     %g1, 8, %g2
148
                or      %g1, %g2, %g1
149
                rd      %wim, %g2
150
                andcc   %g2, %g1, %g0
151
                be      1f              ! Nope, just return from the trap
152
                 nop
153
 
154
                /* We have to grab a window before returning. */
155
                sll     %g2, 0x1, %g1
156
rirq_patch4:    srl     %g2, 7,  %g2
157
                or      %g1, %g2, %g1
158
rirq_patch5:    and     %g1, 0xff, %g1
159
 
160
        wr      %g1, 0x0, %wim
161
        WRITE_PAUSE
162
 
163
        restore %g0, %g0, %g0
164
        LOAD_WINDOW(sp)
165
        save    %g0, %g0, %g0
166
 
167
        /* Reload the entire frame in case this is from a
168
         * kernel system call or whatever...
169
         */
170
1:
171
        LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
172
 
173
        wr      %t_psr, 0x0, %psr
174
        WRITE_PAUSE
175
 
176
        jmp     %t_pc
177
        rett    %t_npc
178
 
179
ret_irq_user_stack_is_bolixed:
180
        wr      %t_wim, 0x0, %wim
181
        WRITE_PAUSE
182
 
183
        /* User has a toasty window, must grab klock. */
184
        ENTER_SYSCALL
185
 
186
        wr      %t_psr, PSR_ET, %psr
187
        WRITE_PAUSE
188
 
189
        call    C_LABEL(window_ret_fault)
190
         add    %sp, REGWIN_SZ, %o0
191
 
192
        /* We have klock, so we must return just like a normal trap. */
193
        b       ret_trap_entry
194
         nop
195
 
196
        .globl  C_LABEL(sun4c_reti_stackchk)
197
C_LABEL(sun4c_reti_stackchk):
198
        be      1f
199
         and    %fp, 0xfff, %g1         ! delay slot
200
 
201
        b       ret_irq_user_stack_is_bolixed
202
         nop
203
 
204
        /* See if we have to check the sanity of one page or two */
205
1:
206
        add     %g1, 0x38, %g1
207
        sra     %fp, 29, %g2
208
        add     %g2, 0x1, %g2
209
        andncc  %g2, 0x1, %g0
210
        be      1f
211
         andncc %g1, 0xff8, %g0
212
 
213
        /* %sp is in vma hole, yuck */
214
        b       ret_irq_user_stack_is_bolixed
215
         nop
216
 
217
1:
218
        be      sun4c_reti_onepage      /* Only one page to check */
219
         lda    [%fp] ASI_PTE, %g2
220
 
221
sun4c_reti_twopages:
222
        add     %fp, 0x38, %g1
223
        sra     %g1, 29, %g2
224
        add     %g2, 0x1, %g2
225
        andncc  %g2, 0x1, %g0
226
        be      1f
227
         lda    [%g1] ASI_PTE, %g2
228
 
229
        /* Second page is in vma hole */
230
        b       ret_irq_user_stack_is_bolixed
231
         nop
232
 
233
1:
234
        srl     %g2, 29, %g2
235
        andcc   %g2, 0x4, %g0
236
        bne     sun4c_reti_onepage
237
         lda    [%fp] ASI_PTE, %g2
238
 
239
        /* Second page has bad perms */
240
        b       ret_irq_user_stack_is_bolixed
241
         nop
242
 
243
sun4c_reti_onepage:
244
        srl     %g2, 29, %g2
245
        andcc   %g2, 0x4, %g0
246
        bne     1f
247
         nop
248
 
249
        /* A page had bad page permissions, losing... */
250
        b       ret_irq_user_stack_is_bolixed
251
         nop
252
 
253
        /* Whee, things are ok, load the window and continue. */
254
1:
255
        restore %g0, %g0, %g0
256
 
257
        LOAD_WINDOW(sp)
258
 
259
        save    %g0, %g0, %g0
260
        b       ret_irq_userwins_ok
261
         nop
262
 
263
        .globl  C_LABEL(srmmu_reti_stackchk)
264
C_LABEL(srmmu_reti_stackchk):
265
        bne     ret_irq_user_stack_is_bolixed
266
         sethi  %hi(KERNBASE), %g1
267
        cmp     %g1, %fp
268
        bleu    ret_irq_user_stack_is_bolixed
269
         mov    AC_M_SFSR, %g1
270
        lda     [%g1] ASI_M_MMUREGS, %g0
271
 
272
        lda     [%g0] ASI_M_MMUREGS, %g1
273
        or      %g1, 0x2, %g1
274
        sta     %g1, [%g0] ASI_M_MMUREGS
275
 
276
        restore %g0, %g0, %g0
277
 
278
        LOAD_WINDOW(sp)
279
 
280
        save    %g0, %g0, %g0
281
 
282
        andn    %g1, 0x2, %g1
283
        sta     %g1, [%g0] ASI_M_MMUREGS
284
 
285
        mov     AC_M_SFAR, %g2
286
        lda     [%g2] ASI_M_MMUREGS, %g2
287
 
288
        mov     AC_M_SFSR, %g1
289
        lda     [%g1] ASI_M_MMUREGS, %g1
290
        andcc   %g1, 0x2, %g0
291
        bne     ret_irq_user_stack_is_bolixed
292
         nop
293
 
294
        b       ret_irq_userwins_ok
295
         nop

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.