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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [mips/] [kernel/] [scall_o32.S] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * This file is subject to the terms and conditions of the GNU General Public
3
 * License.  See the file "COPYING" in the main directory of this archive
4
 * for more details.
5
 *
6
 * Copyright (C) 1997, 1998, 1999, 2000, 2001 by Ralf Baechle
7
 * Copyright (C) 2001 MIPS Technologies, Inc.
8
 */
9
#include 
10
#include 
11
#include 
12
#include 
13
#include 
14
#include 
15
#include 
16
#include 
17
#include 
18
#include 
19
 
20
/* Highest syscall used of any syscall flavour */
21
#define MAX_SYSCALL_NO  __NR_O32_Linux + __NR_O32_Linux_syscalls
22
 
23
        .align  5
24
NESTED(handle_sys, PT_SIZE, sp)
25
        .set    noat
26
        SAVE_SOME
27
        STI
28
        .set    at
29
 
30
        lw      t1, PT_EPC(sp)          # skip syscall on return
31
 
32
        sltiu   t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
33
        addiu   t1, 4                   # skip to next instruction
34
        beqz    t0, illegal_syscall
35
        sw      t1, PT_EPC(sp)
36
 
37
        /* XXX Put both in one cacheline, should save a bit. */
38
        sll     t0, v0, 2
39
        lw      t2, sys_call_table(t0)  # syscall routine
40
        lbu     t3, sys_narg_table(v0)  # number of arguments
41
        beqz    t2, illegal_syscall
42
 
43
        subu    t0, t3, 5               # 5 or more arguments?
44
        sw      a3, PT_R26(sp)          # save a3 for syscall restarting
45
        bgez    t0, stackargs
46
 
47
stack_done:
48
        sw      a3, PT_R26(sp)          # save for syscall restart
49
        lw      t0, TASK_PTRACE($28)    # syscall tracing enabled?
50
        andi    t0, _PT_TRACESYS
51
        bnez    t0, trace_a_syscall
52
 
53
        jalr    t2                      # Do The Real Thing (TM)
54
 
55
        li      t0, -EMAXERRNO - 1      # error?
56
        sltu    t0, t0, v0
57
        sw      t0, PT_R7(sp)           # set error flag
58
        beqz    t0, 1f
59
 
60
        negu    v0                      # error
61
        sw      v0, PT_R0(sp)           # set flag for syscall restarting
62
1:      sw      v0, PT_R2(sp)           # result
63
 
64
fast_ret_from_sys_call:
65
ret_from_schedule:
66
        mfc0    t0, CP0_STATUS          # need_resched and signals atomic test
67
        ori     t0, t0, 1
68
        xori    t0, t0, 1
69
        mtc0    t0, CP0_STATUS
70
        SSNOP; SSNOP; SSNOP
71
 
72
        lw      t2, TASK_NEED_RESCHED($28)
73
        lw      v0, TASK_SIGPENDING($28)
74
        bnez    t2, reschedule
75
        bnez    v0, signal_return
76
restore_all:
77
        RESTORE_SOME
78
        RESTORE_SP_AND_RET
79
 
80
/* ------------------------------------------------------------------------ */
81
 
82
FEXPORT(ret_from_fork)
83
        move    a0, v0                  # prev
84
        jal     schedule_tail
85
        lw      t0, TASK_PTRACE($28)    # syscall tracing enabled?
86
        andi    t0, _PT_TRACESYS
87
        bnez    t0, tracesys_exit
88
 
89
static_ret_from_sys_call:
90
        RESTORE_STATIC
91
        j       fast_ret_from_sys_call
92
 
93
/* ------------------------------------------------------------------------ */
94
 
95
/* ret_from_sys_call should be here but is in entry.S.  */
96
 
97
/* ------------------------------------------------------------------------ */
98
 
99
/* Put this behind restore_all for the sake of the branch prediction.  */
100
signal_return:
101
        .type   signal_return, @function
102
 
103
        mfc0    t0, CP0_STATUS
104
        ori     t0, t0, 1
105
        mtc0    t0, CP0_STATUS
106
 
107
        SAVE_STATIC
108
        move    a0, zero
109
        move    a1, sp
110
        jal     do_signal
111
        RESTORE_STATIC
112
        b       restore_all
113
 
114
/* ------------------------------------------------------------------------ */
115
 
116
reschedule:
117
        jal     schedule
118
        b       ret_from_schedule
119
 
120
/* ------------------------------------------------------------------------ */
121
 
122
trace_a_syscall:
123
        SAVE_STATIC
124
        sw      t2, PT_R1(sp)
125
        jal     syscall_trace
126
        lw      t2, PT_R1(sp)
127
 
128
        lw      a0, PT_R4(sp)           # Restore argument registers
129
        lw      a1, PT_R5(sp)
130
        lw      a2, PT_R6(sp)
131
        lw      a3, PT_R7(sp)
132
        jalr    t2
133
 
134
        li      t0, -EMAXERRNO - 1      # error?
135
        sltu    t0, t0, v0
136
        sw      t0, PT_R7(sp)           # set error flag
137
        beqz    t0, 1f
138
 
139
        negu    v0                      # error
140
        sw      v0, PT_R0(sp)           # set flag for syscall restarting
141
1:      sw      v0, PT_R2(sp)           # result
142
 
143
tracesys_exit:
144
        jal     syscall_trace
145
        j       static_ret_from_sys_call
146
 
147
/* ------------------------------------------------------------------------ */
148
 
149
        /*
150
         * More than four arguments.  Try to deal with it by copying the
151
         * stack arguments from the user stack to the kernel stack.
152
         * This Sucks (TM).
153
         */
154
stackargs:
155
        lw      t0, PT_R29(sp)          # get old user stack pointer
156
        subu    t3, 4
157
        sll     t1, t3, 2               # stack valid?
158
 
159
        addu    t1, t0                  # end address
160
        or      t0, t1
161
        bltz    t0, bad_stack           # -> sp is bad
162
 
163
        lw      t0, PT_R29(sp)          # get old user stack pointer
164
        PTR_LA  t1, 3f                  # copy 1 to 2 arguments
165
        sll     t3, t3, 4
166
        subu    t1, t3
167
        jr      t1
168
 
169
        /* Ok, copy the args from the luser stack to the kernel stack */
170
        /*
171
         * I know Ralf doesn't like nops but this avoids code
172
         * duplication for R3000 targets (and this is the
173
         * only place where ".set reorder" doesn't help).
174
         * Harald.
175
         */
176
        .set    push
177
        .set    noreorder
178
        .set    nomacro
179
1:      lw      t1, 20(t0)              # argument #6 from usp
180
        nop
181
        sw      t1, 20(sp)
182
        nop
183
2:      lw      t1, 16(t0)              # argument #5 from usp
184
        nop
185
        sw      t1, 16(sp)
186
        nop
187
3:      .set    pop
188
 
189
        j       stack_done              # go back
190
 
191
        .section __ex_table,"a"
192
        PTR     1b,bad_stack
193
        PTR     2b,bad_stack
194
        .previous
195
 
196
/* ------------------------------------------------------------------------ */
197
 
198
        /*
199
         * The stackpointer for a call with more than 4 arguments is bad.
200
         * We probably should handle this case a bit more drastic.
201
         */
202
bad_stack:
203
        negu    v0                      # error
204
        sw      v0, PT_R0(sp)
205
        sw      v0, PT_R2(sp)
206
        li      t0, 1                   # set error flag
207
        sw      t0, PT_R7(sp)
208
        j       fast_ret_from_sys_call
209
 
210
/* ------------------------------------------------------------------------ */
211
 
212
        /*
213
         * The system call does not exist in this kernel
214
         */
215
illegal_syscall:
216
        lw      t0, TASK_PTRACE($28)    # syscall tracing enabled?
217
        andi    t0, _PT_TRACESYS
218
        beqz    t0, 1f
219
 
220
        SAVE_STATIC
221
        jal     syscall_trace
222
        li      t0, _PT_TRACESYS
223
 
224
1:      li      v0, ENOSYS              # error
225
        sw      v0, PT_R0(sp)           # set flag for syscall restarting
226
        sw      v0, PT_R2(sp)
227
        li      t1, 1                   # set error flag
228
        sw      t1, PT_R7(sp)
229
        bnez    t0, tracesys_exit
230
 
231
        j       fast_ret_from_sys_call
232
END(handle_sys)
233
 
234
LEAF(mips_atomic_set)
235
        andi    v0, a1, 3               # must be word aligned
236
        bnez    v0, bad_alignment
237
 
238
        lw      v1, THREAD_CURDS($28)   # in legal address range?
239
        addiu   a0, a1, 4
240
        or      a0, a0, a1
241
        and     a0, a0, v1
242
        bltz    a0, bad_address
243
 
244
#ifdef CONFIG_CPU_HAS_LLSC
245
        /* Ok, this is the ll/sc case.  World is sane :-)  */
246
1:      ll      v0, (a1)
247
        move    a0, a2
248
2:      sc      a0, (a1)
249
        beqz    a0, 1b
250
 
251
        .section __ex_table,"a"
252
        PTR     1b, bad_stack
253
        PTR     2b, bad_stack
254
        .previous
255
#else
256
        sw      a1, 16(sp)
257
        sw      a2, 20(sp)
258
 
259
        move    a0, sp
260
        move    a2, a1
261
        li      a1, 1
262
        jal     do_page_fault
263
 
264
        lw      a1, 16(sp)
265
        lw      a2, 20(sp)
266
 
267
        /*
268
         * At this point the page should be readable and writable unless
269
         * there was no more memory available.
270
         */
271
1:      lw      v0, (a1)
272
2:      sw      a2, (a1)
273
 
274
        .section __ex_table,"a"
275
        PTR     1b, no_mem
276
        PTR     2b, no_mem
277
        .previous
278
#endif
279
 
280
        sw      zero, PT_R7(sp)         # success
281
        sw      v0, PT_R2(sp)           # result
282
 
283
        /* Success, so skip usual error handling garbage.  */
284
        lw      t0, TASK_PTRACE($28)    # syscall tracing enabled?
285
        andi    t0, _PT_TRACESYS
286
        beqz    t0, fast_ret_from_sys_call
287
 
288
        SAVE_STATIC
289
        jal     syscall_trace
290
        j       static_ret_from_sys_call
291
 
292
no_mem: li      v0, -ENOMEM
293
        jr      ra
294
 
295
bad_address:
296
        li      v0, -EFAULT
297
        jr      ra
298
 
299
bad_alignment:
300
        li      v0, -EINVAL
301
        jr      ra
302
END(mips_atomic_set)
303
 
304
LEAF(sys_sysmips)
305
        beq     a0, MIPS_ATOMIC_SET, mips_atomic_set
306
        j       _sys_sysmips
307
END(sys_sysmips)
308
 
309
LEAF(sys_syscall)
310
        lw      t0, PT_R29(sp)          # user sp
311
 
312
        sltu    v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
313
        beqz    v0, enosys
314
 
315
        sll     v0, a0, 2
316
        la      v1, sys_syscall
317
        lw      t2, sys_call_table(v0)  # function pointer
318
        lbu     t4, sys_narg_table(a0)  # number of arguments
319
 
320
        li      v0, -EINVAL
321
        beq     t2, v1, out             # do not recurse
322
 
323
        beqz    t2, enosys              # null function pointer?
324
 
325
        andi    v0, t0, 0x3             # unaligned stack pointer?
326
        bnez    v0, sigsegv
327
 
328
        addu    v0, t0, 16              # v0 = usp + 16
329
        addu    t1, v0, 12              # 3 32-bit arguments
330
        lw      v1, THREAD_CURDS($28)
331
        or      v0, v0, t1
332
        and     v1, v1, v0
333
        bltz    v1, efault
334
 
335
        move    a0, a1                  # shift argument registers
336
        move    a1, a2
337
        move    a2, a3
338
 
339
1:      lw      a3, 16(t0)
340
2:      lw      t3, 20(t0)
341
3:      lw      t4, 24(t0)
342
 
343
        .section        __ex_table, "a"
344
        .word   1b, efault
345
        .word   2b, efault
346
        .word   3b, efault
347
        .previous
348
 
349
        sw      t3, 16(sp)              # put into new stackframe
350
        sw      t4, 20(sp)
351
 
352
        bnez    t4, 1f                  # zero arguments?
353
        addu    a0, sp, 32              # then pass sp in a0
354
1:
355
 
356
        sw      t3, 16(sp)
357
        sw      v1, 20(sp)
358
        jr      t2
359
        /* Unreached */
360
 
361
enosys: li      v0, -ENOSYS
362
        b       out
363
 
364
sigsegv:
365
        li      a0, _SIGSEGV
366
        move    a1, $28
367
        jal     force_sig
368
        /* Fall through */
369
 
370
efault: li      v0, -EFAULT
371
 
372
out:    jr      ra
373
END(sys_syscall)

powered by: WebSVN 2.1.0

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