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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [mips/] [kernel/] [syscall.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
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) 1995, 1996, 1997, 2000, 2001, 05 by Ralf Baechle
7
 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8
 * Copyright (C) 2001 MIPS Technologies, Inc.
9
 */
10
#include <linux/a.out.h>
11
#include <linux/capability.h>
12
#include <linux/errno.h>
13
#include <linux/linkage.h>
14
#include <linux/mm.h>
15
#include <linux/fs.h>
16
#include <linux/smp.h>
17
#include <linux/mman.h>
18
#include <linux/ptrace.h>
19
#include <linux/sched.h>
20
#include <linux/string.h>
21
#include <linux/syscalls.h>
22
#include <linux/file.h>
23
#include <linux/slab.h>
24
#include <linux/utsname.h>
25
#include <linux/unistd.h>
26
#include <linux/sem.h>
27
#include <linux/msg.h>
28
#include <linux/shm.h>
29
#include <linux/compiler.h>
30
#include <linux/module.h>
31
#include <linux/ipc.h>
32
 
33
#include <asm/branch.h>
34
#include <asm/cachectl.h>
35
#include <asm/cacheflush.h>
36
#include <asm/asm-offsets.h>
37
#include <asm/signal.h>
38
#include <asm/sim.h>
39
#include <asm/shmparam.h>
40
#include <asm/sysmips.h>
41
#include <asm/uaccess.h>
42
 
43
asmlinkage int sys_pipe(nabi_no_regargs volatile struct pt_regs regs)
44
{
45
        int fd[2];
46
        int error, res;
47
 
48
        error = do_pipe(fd);
49
        if (error) {
50
                res = error;
51
                goto out;
52
        }
53
        regs.regs[3] = fd[1];
54
        res = fd[0];
55
out:
56
        return res;
57
}
58
 
59
unsigned long shm_align_mask = PAGE_SIZE - 1;   /* Sane caches */
60
 
61
EXPORT_SYMBOL(shm_align_mask);
62
 
63
#define COLOUR_ALIGN(addr,pgoff)                                \
64
        ((((addr) + shm_align_mask) & ~shm_align_mask) +        \
65
         (((pgoff) << PAGE_SHIFT) & shm_align_mask))
66
 
67
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
68
        unsigned long len, unsigned long pgoff, unsigned long flags)
69
{
70
        struct vm_area_struct * vmm;
71
        int do_color_align;
72
        unsigned long task_size;
73
 
74
        task_size = STACK_TOP;
75
 
76
        if (len > task_size)
77
                return -ENOMEM;
78
 
79
        if (flags & MAP_FIXED) {
80
                /* Even MAP_FIXED mappings must reside within task_size.  */
81
                if (task_size - len < addr)
82
                        return -EINVAL;
83
 
84
                /*
85
                 * We do not accept a shared mapping if it would violate
86
                 * cache aliasing constraints.
87
                 */
88
                if ((flags & MAP_SHARED) && (addr & shm_align_mask))
89
                        return -EINVAL;
90
                return addr;
91
        }
92
 
93
        do_color_align = 0;
94
        if (filp || (flags & MAP_SHARED))
95
                do_color_align = 1;
96
        if (addr) {
97
                if (do_color_align)
98
                        addr = COLOUR_ALIGN(addr, pgoff);
99
                else
100
                        addr = PAGE_ALIGN(addr);
101
                vmm = find_vma(current->mm, addr);
102
                if (task_size - len >= addr &&
103
                    (!vmm || addr + len <= vmm->vm_start))
104
                        return addr;
105
        }
106
        addr = TASK_UNMAPPED_BASE;
107
        if (do_color_align)
108
                addr = COLOUR_ALIGN(addr, pgoff);
109
        else
110
                addr = PAGE_ALIGN(addr);
111
 
112
        for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
113
                /* At this point:  (!vmm || addr < vmm->vm_end). */
114
                if (task_size - len < addr)
115
                        return -ENOMEM;
116
                if (!vmm || addr + len <= vmm->vm_start)
117
                        return addr;
118
                addr = vmm->vm_end;
119
                if (do_color_align)
120
                        addr = COLOUR_ALIGN(addr, pgoff);
121
        }
122
}
123
 
124
/* common code for old and new mmaps */
125
static inline unsigned long
126
do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
127
        unsigned long flags, unsigned long fd, unsigned long pgoff)
128
{
129
        unsigned long error = -EBADF;
130
        struct file * file = NULL;
131
 
132
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
133
        if (!(flags & MAP_ANONYMOUS)) {
134
                file = fget(fd);
135
                if (!file)
136
                        goto out;
137
        }
138
 
139
        down_write(&current->mm->mmap_sem);
140
        error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
141
        up_write(&current->mm->mmap_sem);
142
 
143
        if (file)
144
                fput(file);
145
out:
146
        return error;
147
}
148
 
149
asmlinkage unsigned long
150
old_mmap(unsigned long addr, unsigned long len, int prot,
151
        int flags, int fd, off_t offset)
152
{
153
        unsigned long result;
154
 
155
        result = -EINVAL;
156
        if (offset & ~PAGE_MASK)
157
                goto out;
158
 
159
        result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
160
 
161
out:
162
        return result;
163
}
164
 
165
asmlinkage unsigned long
166
sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
167
          unsigned long flags, unsigned long fd, unsigned long pgoff)
168
{
169
        if (pgoff & (~PAGE_MASK >> 12))
170
                return -EINVAL;
171
 
172
        return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
173
}
174
 
175
save_static_function(sys_fork);
176
static int __used noinline
177
_sys_fork(nabi_no_regargs struct pt_regs regs)
178
{
179
        return do_fork(SIGCHLD, regs.regs[29], &regs, 0, NULL, NULL);
180
}
181
 
182
save_static_function(sys_clone);
183
static int __used noinline
184
_sys_clone(nabi_no_regargs struct pt_regs regs)
185
{
186
        unsigned long clone_flags;
187
        unsigned long newsp;
188
        int __user *parent_tidptr, *child_tidptr;
189
 
190
        clone_flags = regs.regs[4];
191
        newsp = regs.regs[5];
192
        if (!newsp)
193
                newsp = regs.regs[29];
194
        parent_tidptr = (int __user *) regs.regs[6];
195
#ifdef CONFIG_32BIT
196
        /* We need to fetch the fifth argument off the stack.  */
197
        child_tidptr = NULL;
198
        if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) {
199
                int __user *__user *usp = (int __user *__user *) regs.regs[29];
200
                if (regs.regs[2] == __NR_syscall) {
201
                        if (get_user (child_tidptr, &usp[5]))
202
                                return -EFAULT;
203
                }
204
                else if (get_user (child_tidptr, &usp[4]))
205
                        return -EFAULT;
206
        }
207
#else
208
        child_tidptr = (int __user *) regs.regs[8];
209
#endif
210
        return do_fork(clone_flags, newsp, &regs, 0,
211
                       parent_tidptr, child_tidptr);
212
}
213
 
214
/*
215
 * sys_execve() executes a new program.
216
 */
217
asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs)
218
{
219
        int error;
220
        char * filename;
221
 
222
        filename = getname((char __user *) (long)regs.regs[4]);
223
        error = PTR_ERR(filename);
224
        if (IS_ERR(filename))
225
                goto out;
226
        error = do_execve(filename, (char __user *__user *) (long)regs.regs[5],
227
                          (char __user *__user *) (long)regs.regs[6], &regs);
228
        putname(filename);
229
 
230
out:
231
        return error;
232
}
233
 
234
/*
235
 * Compacrapability ...
236
 */
237
asmlinkage int sys_uname(struct old_utsname __user * name)
238
{
239
        if (name && !copy_to_user(name, utsname(), sizeof (*name)))
240
                return 0;
241
        return -EFAULT;
242
}
243
 
244
/*
245
 * Compacrapability ...
246
 */
247
asmlinkage int sys_olduname(struct oldold_utsname __user * name)
248
{
249
        int error;
250
 
251
        if (!name)
252
                return -EFAULT;
253
        if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
254
                return -EFAULT;
255
 
256
        error = __copy_to_user(&name->sysname, &utsname()->sysname,
257
                               __OLD_UTS_LEN);
258
        error -= __put_user(0, name->sysname + __OLD_UTS_LEN);
259
        error -= __copy_to_user(&name->nodename, &utsname()->nodename,
260
                                __OLD_UTS_LEN);
261
        error -= __put_user(0, name->nodename + __OLD_UTS_LEN);
262
        error -= __copy_to_user(&name->release, &utsname()->release,
263
                                __OLD_UTS_LEN);
264
        error -= __put_user(0, name->release + __OLD_UTS_LEN);
265
        error -= __copy_to_user(&name->version, &utsname()->version,
266
                                __OLD_UTS_LEN);
267
        error -= __put_user(0, name->version + __OLD_UTS_LEN);
268
        error -= __copy_to_user(&name->machine, &utsname()->machine,
269
                                __OLD_UTS_LEN);
270
        error = __put_user(0, name->machine + __OLD_UTS_LEN);
271
        error = error ? -EFAULT : 0;
272
 
273
        return error;
274
}
275
 
276
asmlinkage int sys_set_thread_area(unsigned long addr)
277
{
278
        struct thread_info *ti = task_thread_info(current);
279
 
280
        ti->tp_value = addr;
281
        if (cpu_has_userlocal)
282
                write_c0_userlocal(addr);
283
 
284
        return 0;
285
}
286
 
287
asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
288
{
289
        switch (cmd) {
290
        case MIPS_ATOMIC_SET:
291
                printk(KERN_CRIT "How did I get here?\n");
292
                return -EINVAL;
293
 
294
        case MIPS_FIXADE:
295
                if (arg1 & ~3)
296
                        return -EINVAL;
297
 
298
                if (arg1 & 1)
299
                        set_thread_flag(TIF_FIXADE);
300
                else
301
                        clear_thread_flag(TIF_FIXADE);
302
                if (arg1 & 2)
303
                        set_thread_flag(TIF_LOGADE);
304
                else
305
                        clear_thread_flag(TIF_FIXADE);
306
 
307
                return 0;
308
 
309
        case FLUSH_CACHE:
310
                __flush_cache_all();
311
                return 0;
312
        }
313
 
314
        return -EINVAL;
315
}
316
 
317
/*
318
 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
319
 *
320
 * This is really horribly ugly.
321
 */
322
asmlinkage int sys_ipc(unsigned int call, int first, int second,
323
                       unsigned long third, void __user *ptr, long fifth)
324
{
325
        int version, ret;
326
 
327
        version = call >> 16; /* hack for backward compatibility */
328
        call &= 0xffff;
329
 
330
        switch (call) {
331
        case SEMOP:
332
                return sys_semtimedop(first, (struct sembuf __user *)ptr,
333
                                      second, NULL);
334
        case SEMTIMEDOP:
335
                return sys_semtimedop(first, (struct sembuf __user *)ptr,
336
                                      second,
337
                                      (const struct timespec __user *)fifth);
338
        case SEMGET:
339
                return sys_semget(first, second, third);
340
        case SEMCTL: {
341
                union semun fourth;
342
                if (!ptr)
343
                        return -EINVAL;
344
                if (get_user(fourth.__pad, (void __user *__user *) ptr))
345
                        return -EFAULT;
346
                return sys_semctl(first, second, third, fourth);
347
        }
348
 
349
        case MSGSND:
350
                return sys_msgsnd(first, (struct msgbuf __user *) ptr,
351
                                  second, third);
352
        case MSGRCV:
353
                switch (version) {
354
                case 0: {
355
                        struct ipc_kludge tmp;
356
                        if (!ptr)
357
                                return -EINVAL;
358
 
359
                        if (copy_from_user(&tmp,
360
                                           (struct ipc_kludge __user *) ptr,
361
                                           sizeof(tmp)))
362
                                return -EFAULT;
363
                        return sys_msgrcv(first, tmp.msgp, second,
364
                                          tmp.msgtyp, third);
365
                }
366
                default:
367
                        return sys_msgrcv(first,
368
                                          (struct msgbuf __user *) ptr,
369
                                          second, fifth, third);
370
                }
371
        case MSGGET:
372
                return sys_msgget((key_t) first, second);
373
        case MSGCTL:
374
                return sys_msgctl(first, second,
375
                                  (struct msqid_ds __user *) ptr);
376
 
377
        case SHMAT:
378
                switch (version) {
379
                default: {
380
                        unsigned long raddr;
381
                        ret = do_shmat(first, (char __user *) ptr, second,
382
                                       &raddr);
383
                        if (ret)
384
                                return ret;
385
                        return put_user(raddr, (unsigned long __user *) third);
386
                }
387
                case 1: /* iBCS2 emulator entry point */
388
                        if (!segment_eq(get_fs(), get_ds()))
389
                                return -EINVAL;
390
                        return do_shmat(first, (char __user *) ptr, second,
391
                                        (unsigned long *) third);
392
                }
393
        case SHMDT:
394
                return sys_shmdt((char __user *)ptr);
395
        case SHMGET:
396
                return sys_shmget(first, second, third);
397
        case SHMCTL:
398
                return sys_shmctl(first, second,
399
                                  (struct shmid_ds __user *) ptr);
400
        default:
401
                return -ENOSYS;
402
        }
403
}
404
 
405
/*
406
 * No implemented yet ...
407
 */
408
asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
409
{
410
        return -ENOSYS;
411
}
412
 
413
/*
414
 * If we ever come here the user sp is bad.  Zap the process right away.
415
 * Due to the bad stack signaling wouldn't work.
416
 */
417
asmlinkage void bad_stack(void)
418
{
419
        do_exit(SIGSEGV);
420
}
421
 
422
/*
423
 * Do a system call from kernel instead of calling sys_execve so we
424
 * end up with proper pt_regs.
425
 */
426
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
427
{
428
        register unsigned long __a0 asm("$4") = (unsigned long) filename;
429
        register unsigned long __a1 asm("$5") = (unsigned long) argv;
430
        register unsigned long __a2 asm("$6") = (unsigned long) envp;
431
        register unsigned long __a3 asm("$7");
432
        unsigned long __v0;
433
 
434
        __asm__ volatile ("                                     \n"
435
        "       .set    noreorder                               \n"
436
        "       li      $2, %5          # __NR_execve           \n"
437
        "       syscall                                         \n"
438
        "       move    %0, $2                                  \n"
439
        "       .set    reorder                                 \n"
440
        : "=&r" (__v0), "=r" (__a3)
441
        : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve)
442
        : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
443
          "memory");
444
 
445
        if (__a3 == 0)
446
                return __v0;
447
 
448
        return -__v0;
449
}

powered by: WebSVN 2.1.0

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