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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [sparc/] [kernel/] [rtrap.S] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1624 jcastillo
/* $Id: rtrap.S,v 1.1 2005-12-20 09:50:43 jcastillo Exp $
2
 * rtrap.S: Return from Sparc trap low-level code.
3
 *
4
 * Copyright (C) 1995 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  rtrap_7win_patch1, rtrap_7win_patch2, rtrap_7win_patch3
27
        .globl  rtrap_7win_patch4, rtrap_7win_patch5
28
rtrap_7win_patch1:      srl     %t_wim, 0x6, %twin_tmp2
29
rtrap_7win_patch2:      and     %twin_tmp2, 0x7f, %twin_tmp2
30
rtrap_7win_patch3:      srl     %g1, 7, %g2
31
rtrap_7win_patch4:      srl     %g2, 6, %g2
32
rtrap_7win_patch5:      and     %g1, 0x7f, %g1
33
        /* END OF PATCH INSTRUCTIONS */
34
 
35
        /* We need to check for a few things which are:
36
         * 1) The need to call schedule() because this
37
         *    processes quantum is up.
38
         * 2) Pending signals for this process, if any
39
         *    exist we need to call do_signal() to do
40
         *    the needy.
41
         *
42
         * Else we just check if the rett would land us
43
         * in an invalid window, if so we need to grab
44
         * it off the user/kernel stack first.
45
         */
46
 
47
        .globl  ret_trap_entry, rtrap_patch1, rtrap_patch2
48
        .globl  rtrap_patch3, rtrap_patch4, rtrap_patch5
49
ret_trap_entry:
50
        ld      [%sp + REGWIN_SZ + PT_PSR], %t_psr
51
        andcc   %t_psr, PSR_PS, %g0
52
        bne     ret_trap_kernel
53
         nop
54
 
55
        sethi   %hi(C_LABEL(need_resched)), %twin_tmp1
56
        ld      [%twin_tmp1 + %lo(C_LABEL(need_resched))], %twin_tmp2
57
 
58
        cmp     %twin_tmp2, 0
59
        be      signal_p
60
         nop
61
 
62
        call    C_LABEL(schedule)
63
         nop
64
 
65
        /* Try to return again... We are a different process,
66
         * most likely so load and then check if going back
67
         * to user or kernel this time.
68
         */
69
        b       ret_trap_entry
70
         nop
71
 
72
signal_p:
73
        /* No signals for swapper. */
74
        LOAD_CURRENT(twin_tmp1, twin_tmp3)
75
        set     C_LABEL(init_task), %twin_tmp3
76
        cmp     %twin_tmp3, %twin_tmp1
77
        be      ret_trap_continue
78
         nop
79
 
80
        ld      [%twin_tmp1 + TASK_SIGNAL], %twin_tmp2
81
        ld      [%twin_tmp1 + TASK_BLOCKED], %o0
82
        andncc  %twin_tmp2, %o0, %g0
83
        be      ret_trap_continue
84
         nop
85
 
86
        call    C_LABEL(do_signal)
87
         add    %sp, REGWIN_SZ, %o1     ! pt_regs ptr
88
 
89
        /* Fall through... */
90
ret_trap_continue:
91
        ld      [%sp + REGWIN_SZ + PT_PSR], %t_psr
92
        wr      %t_psr, 0x0, %psr
93
        WRITE_PAUSE
94
 
95
        LOAD_CURRENT(twin_tmp2, twin_tmp1)
96
        ld      [%twin_tmp2 + THREAD_W_SAVED], %twin_tmp1
97
        orcc    %g0, %twin_tmp1, %g0
98
        be      ret_trap_nobufwins
99
         nop
100
 
101
        wr      %t_psr, PSR_ET, %psr
102
        WRITE_PAUSE
103
 
104
        mov     1, %o1
105
        call    C_LABEL(try_to_clear_window_buffer)
106
         add    %sp, REGWIN_SZ, %o0
107
 
108
        b       ret_trap_entry
109
         nop
110
 
111
ret_trap_nobufwins:
112
        /* Load up the user's out registers so we can pull
113
         * a window from the stack, if necessary.
114
         */
115
        LOAD_PT_INS(sp)
116
 
117
        /* If there are already live user windows in the
118
         * set we can return from trap safely.
119
         */
120
        ld      [%twin_tmp2 + THREAD_UMASK], %twin_tmp1
121
        orcc    %g0, %twin_tmp1, %g0
122
        bne     ret_trap_userwins_ok
123
         nop
124
 
125
                /* Calculate new %wim, we have to pull a register
126
                 * window from the users stack.
127
                 */
128
ret_trap_pull_one_window:
129
                rd      %wim, %t_wim
130
                sll     %t_wim, 0x1, %twin_tmp1
131
rtrap_patch1:   srl     %t_wim, 0x7, %twin_tmp2
132
                or      %twin_tmp2, %twin_tmp1, %twin_tmp2
133
rtrap_patch2:   and     %twin_tmp2, 0xff, %twin_tmp2
134
 
135
                wr      %twin_tmp2, 0x0, %wim
136
                WRITE_PAUSE
137
 
138
                                /* Here comes the architecture specific
139
                                 * branch to the user stack checking routine
140
                                 * for return from traps.
141
                                 */
142
                                .globl  C_LABEL(rtrap_mmu_patchme)
143
C_LABEL(rtrap_mmu_patchme):     b       C_LABEL(sun4c_rett_stackchk)
144
                                 andcc  %fp, 0x7, %g0
145
 
146
ret_trap_userwins_ok:
147
        LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
148
        or      %t_pc, %t_npc, %g2
149
        andcc   %g2, 0x3, %g0
150
        bne     ret_trap_unaligned_pc
151
         nop
152
 
153
        LOAD_PT_YREG(sp, g1)
154
        LOAD_PT_GLOBALS(sp)
155
 
156
        LEAVE_SYSCALL
157
 
158
        wr      %t_psr, 0x0, %psr
159
        WRITE_PAUSE
160
 
161
        jmp     %t_pc
162
        rett    %t_npc
163
 
164
ret_trap_unaligned_pc:
165
        add     %sp, REGWIN_SZ, %o0
166
        ld      [%sp + REGWIN_SZ + PT_PC], %o1
167
        ld      [%sp + REGWIN_SZ + PT_NPC], %o2
168
        ld      [%sp + REGWIN_SZ + PT_PSR], %o3
169
 
170
        wr      %t_wim, 0x0, %wim               ! or else...
171
        WRITE_PAUSE
172
 
173
        wr      %t_psr, PSR_ET, %psr
174
        WRITE_PAUSE
175
 
176
        call    C_LABEL(do_memaccess_unaligned)
177
         nop
178
 
179
        b       ret_trap_entry                  ! maybe signal posted
180
         nop
181
 
182
ret_trap_kernel:
183
        ld      [%sp + REGWIN_SZ + PT_PSR], %t_psr
184
        wr      %t_psr, 0x0, %psr
185
        WRITE_PAUSE
186
 
187
                /* Will the rett land us in the invalid window? */
188
                mov     2, %g1
189
                sll     %g1, %t_psr, %g1
190
rtrap_patch3:   srl     %g1, 8, %g2
191
                or      %g1, %g2, %g1
192
                rd      %wim, %g2
193
                andcc   %g2, %g1, %g0
194
                be      1f              ! Nope, just return from the trap
195
                 nop
196
 
197
                /* We have to grab a window before returning. */
198
                sll     %g2, 0x1, %g1
199
rtrap_patch4:   srl     %g2, 7,  %g2
200
                or      %g1, %g2, %g1
201
rtrap_patch5:   and     %g1, 0xff, %g1
202
 
203
        wr      %g1, 0x0, %wim
204
        WRITE_PAUSE
205
 
206
        restore %g0, %g0, %g0
207
        LOAD_WINDOW(sp)
208
        save    %g0, %g0, %g0
209
 
210
        /* Reload the entire frame in case this is from a
211
         * kernel system call or whatever...
212
         */
213
1:
214
        LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
215
 
216
        LEAVE_SYSCALL
217
 
218
        wr      %t_psr, 0x0, %psr
219
        WRITE_PAUSE
220
 
221
        jmp     %t_pc
222
        rett    %t_npc
223
 
224
ret_trap_user_stack_is_bolixed:
225
        wr      %t_wim, 0x0, %wim
226
        WRITE_PAUSE
227
 
228
        wr      %t_psr, PSR_ET, %psr
229
        WRITE_PAUSE
230
 
231
        call    C_LABEL(window_ret_fault)
232
         add    %sp, REGWIN_SZ, %o0
233
 
234
        b       ret_trap_entry
235
         nop
236
 
237
        .globl  C_LABEL(sun4c_rett_stackchk)
238
C_LABEL(sun4c_rett_stackchk):
239
        be      1f
240
         and    %fp, 0xfff, %g1         ! delay slot
241
 
242
        b       ret_trap_user_stack_is_bolixed
243
         nop
244
 
245
        /* See if we have to check the sanity of one page or two */
246
1:
247
        add     %g1, 0x38, %g1
248
        sra     %fp, 29, %g2
249
        add     %g2, 0x1, %g2
250
        andncc  %g2, 0x1, %g0
251
        be      1f
252
         andncc %g1, 0xff8, %g0
253
 
254
        /* %sp is in vma hole, yuck */
255
        b       ret_trap_user_stack_is_bolixed
256
         nop
257
 
258
1:
259
        be      sun4c_rett_onepage      /* Only one page to check */
260
         lda    [%fp] ASI_PTE, %g2
261
 
262
sun4c_rett_twopages:
263
        add     %fp, 0x38, %g1
264
        sra     %g1, 29, %g2
265
        add     %g2, 0x1, %g2
266
        andncc  %g2, 0x1, %g0
267
        be      1f
268
         lda    [%g1] ASI_PTE, %g2
269
 
270
        /* Second page is in vma hole */
271
        b       ret_trap_user_stack_is_bolixed
272
         nop
273
 
274
1:
275
        srl     %g2, 29, %g2
276
        andcc   %g2, 0x4, %g0
277
        bne     sun4c_rett_onepage
278
         lda    [%fp] ASI_PTE, %g2
279
 
280
        /* Second page has bad perms */
281
        b       ret_trap_user_stack_is_bolixed
282
         nop
283
 
284
sun4c_rett_onepage:
285
        srl     %g2, 29, %g2
286
        andcc   %g2, 0x4, %g0
287
        bne     1f
288
         nop
289
 
290
        /* A page had bad page permissions, losing... */
291
        b       ret_trap_user_stack_is_bolixed
292
         nop
293
 
294
        /* Whee, things are ok, load the window and continue. */
295
1:
296
        restore %g0, %g0, %g0
297
 
298
        LOAD_WINDOW(sp)
299
 
300
        save    %g0, %g0, %g0
301
        b       ret_trap_userwins_ok
302
         nop
303
 
304
        .globl  C_LABEL(srmmu_rett_stackchk)
305
C_LABEL(srmmu_rett_stackchk):
306
        bne     ret_trap_user_stack_is_bolixed
307
         sethi  %hi(KERNBASE), %g1
308
        cmp     %g1, %fp
309
        bleu    ret_trap_user_stack_is_bolixed
310
         mov    AC_M_SFSR, %g1
311
        lda     [%g1] ASI_M_MMUREGS, %g0
312
 
313
        lda     [%g0] ASI_M_MMUREGS, %g1
314
        or      %g1, 0x2, %g1
315
        sta     %g1, [%g0] ASI_M_MMUREGS
316
 
317
        restore %g0, %g0, %g0
318
 
319
        LOAD_WINDOW(sp)
320
 
321
        save    %g0, %g0, %g0
322
 
323
        andn    %g1, 0x2, %g1
324
        sta     %g1, [%g0] ASI_M_MMUREGS
325
 
326
        mov     AC_M_SFAR, %g2
327
        lda     [%g2] ASI_M_MMUREGS, %g2
328
 
329
        mov     AC_M_SFSR, %g1
330
        lda     [%g1] ASI_M_MMUREGS, %g1
331
        andcc   %g1, 0x2, %g0
332
        bne     ret_trap_user_stack_is_bolixed
333
         nop
334
 
335
        b       ret_trap_userwins_ok
336
         nop

powered by: WebSVN 2.1.0

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