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/] [sh/] [kernel/] [sys_sh.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * linux/arch/sh/kernel/sys_sh.c
3
 *
4
 * This file contains various random system calls that
5
 * have a non-standard calling sequence on the Linux/SuperH
6
 * platform.
7
 *
8
 * Taken from i386 version.
9
 */
10
 
11
#include <linux/errno.h>
12
#include <linux/sched.h>
13
#include <linux/mm.h>
14
#include <linux/smp.h>
15
#include <linux/sem.h>
16
#include <linux/msg.h>
17
#include <linux/shm.h>
18
#include <linux/stat.h>
19
#include <linux/syscalls.h>
20
#include <linux/mman.h>
21
#include <linux/file.h>
22
#include <linux/utsname.h>
23
#include <linux/module.h>
24
#include <linux/fs.h>
25
#include <linux/ipc.h>
26
#include <asm/cacheflush.h>
27
#include <asm/uaccess.h>
28
#include <asm/unistd.h>
29
 
30
/*
31
 * sys_pipe() is the normal C calling standard for creating
32
 * a pipe. It's not the way Unix traditionally does this, though.
33
 */
34
asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
35
        unsigned long r6, unsigned long r7,
36
        struct pt_regs __regs)
37
{
38
        struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
39
        int fd[2];
40
        int error;
41
 
42
        error = do_pipe(fd);
43
        if (!error) {
44
                regs->regs[1] = fd[1];
45
                return fd[0];
46
        }
47
        return error;
48
}
49
 
50
unsigned long shm_align_mask = PAGE_SIZE - 1;   /* Sane caches */
51
 
52
EXPORT_SYMBOL(shm_align_mask);
53
 
54
#ifdef CONFIG_MMU
55
/*
56
 * To avoid cache aliases, we map the shared page with same color.
57
 */
58
#define COLOUR_ALIGN(addr, pgoff)                               \
59
        ((((addr) + shm_align_mask) & ~shm_align_mask) +        \
60
         (((pgoff) << PAGE_SHIFT) & shm_align_mask))
61
 
62
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
63
        unsigned long len, unsigned long pgoff, unsigned long flags)
64
{
65
        struct mm_struct *mm = current->mm;
66
        struct vm_area_struct *vma;
67
        unsigned long start_addr;
68
        int do_colour_align;
69
 
70
        if (flags & MAP_FIXED) {
71
                /* We do not accept a shared mapping if it would violate
72
                 * cache aliasing constraints.
73
                 */
74
                if ((flags & MAP_SHARED) && (addr & shm_align_mask))
75
                        return -EINVAL;
76
                return addr;
77
        }
78
 
79
        if (unlikely(len > TASK_SIZE))
80
                return -ENOMEM;
81
 
82
        do_colour_align = 0;
83
        if (filp || (flags & MAP_SHARED))
84
                do_colour_align = 1;
85
 
86
        if (addr) {
87
                if (do_colour_align)
88
                        addr = COLOUR_ALIGN(addr, pgoff);
89
                else
90
                        addr = PAGE_ALIGN(addr);
91
 
92
                vma = find_vma(mm, addr);
93
                if (TASK_SIZE - len >= addr &&
94
                    (!vma || addr + len <= vma->vm_start))
95
                        return addr;
96
        }
97
 
98
        if (len > mm->cached_hole_size) {
99
                start_addr = addr = mm->free_area_cache;
100
        } else {
101
                mm->cached_hole_size = 0;
102
                start_addr = addr = TASK_UNMAPPED_BASE;
103
        }
104
 
105
full_search:
106
        if (do_colour_align)
107
                addr = COLOUR_ALIGN(addr, pgoff);
108
        else
109
                addr = PAGE_ALIGN(mm->free_area_cache);
110
 
111
        for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
112
                /* At this point:  (!vma || addr < vma->vm_end). */
113
                if (unlikely(TASK_SIZE - len < addr)) {
114
                        /*
115
                         * Start a new search - just in case we missed
116
                         * some holes.
117
                         */
118
                        if (start_addr != TASK_UNMAPPED_BASE) {
119
                                start_addr = addr = TASK_UNMAPPED_BASE;
120
                                mm->cached_hole_size = 0;
121
                                goto full_search;
122
                        }
123
                        return -ENOMEM;
124
                }
125
                if (likely(!vma || addr + len <= vma->vm_start)) {
126
                        /*
127
                         * Remember the place where we stopped the search:
128
                         */
129
                        mm->free_area_cache = addr + len;
130
                        return addr;
131
                }
132
                if (addr + mm->cached_hole_size < vma->vm_start)
133
                        mm->cached_hole_size = vma->vm_start - addr;
134
 
135
                addr = vma->vm_end;
136
                if (do_colour_align)
137
                        addr = COLOUR_ALIGN(addr, pgoff);
138
        }
139
}
140
#endif /* CONFIG_MMU */
141
 
142
static inline long
143
do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
144
         unsigned long flags, int fd, unsigned long pgoff)
145
{
146
        int error = -EBADF;
147
        struct file *file = NULL;
148
 
149
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
150
        if (!(flags & MAP_ANONYMOUS)) {
151
                file = fget(fd);
152
                if (!file)
153
                        goto out;
154
        }
155
 
156
        down_write(&current->mm->mmap_sem);
157
        error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
158
        up_write(&current->mm->mmap_sem);
159
 
160
        if (file)
161
                fput(file);
162
out:
163
        return error;
164
}
165
 
166
asmlinkage int old_mmap(unsigned long addr, unsigned long len,
167
        unsigned long prot, unsigned long flags,
168
        int fd, unsigned long off)
169
{
170
        if (off & ~PAGE_MASK)
171
                return -EINVAL;
172
        return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
173
}
174
 
175
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
176
        unsigned long prot, unsigned long flags,
177
        unsigned long fd, unsigned long pgoff)
178
{
179
        return do_mmap2(addr, len, prot, flags, fd, pgoff);
180
}
181
 
182
/*
183
 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
184
 *
185
 * This is really horribly ugly.
186
 */
187
asmlinkage int sys_ipc(uint call, int first, int second,
188
                       int third, void __user *ptr, long fifth)
189
{
190
        int version, ret;
191
 
192
        version = call >> 16; /* hack for backward compatibility */
193
        call &= 0xffff;
194
 
195
        if (call <= SEMCTL)
196
                switch (call) {
197
                case SEMOP:
198
                        return sys_semtimedop(first, (struct sembuf __user *)ptr,
199
                                              second, NULL);
200
                case SEMTIMEDOP:
201
                        return sys_semtimedop(first, (struct sembuf __user *)ptr,
202
                                              second,
203
                                              (const struct timespec __user *)fifth);
204
                case SEMGET:
205
                        return sys_semget (first, second, third);
206
                case SEMCTL: {
207
                        union semun fourth;
208
                        if (!ptr)
209
                                return -EINVAL;
210
                        if (get_user(fourth.__pad, (void * __user *) ptr))
211
                                return -EFAULT;
212
                        return sys_semctl (first, second, third, fourth);
213
                        }
214
                default:
215
                        return -EINVAL;
216
                }
217
 
218
        if (call <= MSGCTL)
219
                switch (call) {
220
                case MSGSND:
221
                        return sys_msgsnd (first, (struct msgbuf __user *) ptr,
222
                                          second, third);
223
                case MSGRCV:
224
                        switch (version) {
225
                        case 0: {
226
                                struct ipc_kludge tmp;
227
                                if (!ptr)
228
                                        return -EINVAL;
229
 
230
                                if (copy_from_user(&tmp,
231
                                                   (struct ipc_kludge __user *) ptr,
232
                                                   sizeof (tmp)))
233
                                        return -EFAULT;
234
                                return sys_msgrcv (first, tmp.msgp, second,
235
                                                   tmp.msgtyp, third);
236
                                }
237
                        default:
238
                                return sys_msgrcv (first,
239
                                                   (struct msgbuf __user *) ptr,
240
                                                   second, fifth, third);
241
                        }
242
                case MSGGET:
243
                        return sys_msgget ((key_t) first, second);
244
                case MSGCTL:
245
                        return sys_msgctl (first, second,
246
                                           (struct msqid_ds __user *) ptr);
247
                default:
248
                        return -EINVAL;
249
                }
250
        if (call <= SHMCTL)
251
                switch (call) {
252
                case SHMAT:
253
                        switch (version) {
254
                        default: {
255
                                ulong raddr;
256
                                ret = do_shmat (first, (char __user *) ptr,
257
                                                 second, &raddr);
258
                                if (ret)
259
                                        return ret;
260
                                return put_user (raddr, (ulong __user *) third);
261
                        }
262
                        case 1: /* iBCS2 emulator entry point */
263
                                if (!segment_eq(get_fs(), get_ds()))
264
                                        return -EINVAL;
265
                                return do_shmat (first, (char __user *) ptr,
266
                                                  second, (ulong *) third);
267
                        }
268
                case SHMDT:
269
                        return sys_shmdt ((char __user *)ptr);
270
                case SHMGET:
271
                        return sys_shmget (first, second, third);
272
                case SHMCTL:
273
                        return sys_shmctl (first, second,
274
                                           (struct shmid_ds __user *) ptr);
275
                default:
276
                        return -EINVAL;
277
                }
278
 
279
        return -EINVAL;
280
}
281
 
282
asmlinkage int sys_uname(struct old_utsname * name)
283
{
284
        int err;
285
        if (!name)
286
                return -EFAULT;
287
        down_read(&uts_sem);
288
        err = copy_to_user(name, utsname(), sizeof (*name));
289
        up_read(&uts_sem);
290
        return err?-EFAULT:0;
291
}
292
 
293
asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char * buf,
294
                             size_t count, long dummy, loff_t pos)
295
{
296
        return sys_pread64(fd, buf, count, pos);
297
}
298
 
299
asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char * buf,
300
                              size_t count, long dummy, loff_t pos)
301
{
302
        return sys_pwrite64(fd, buf, count, pos);
303
}
304
 
305
asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
306
                                u32 len0, u32 len1, int advice)
307
{
308
#ifdef  __LITTLE_ENDIAN__
309
        return sys_fadvise64_64(fd, (u64)offset1 << 32 | offset0,
310
                                (u64)len1 << 32 | len0, advice);
311
#else
312
        return sys_fadvise64_64(fd, (u64)offset0 << 32 | offset1,
313
                                (u64)len0 << 32 | len1, advice);
314
#endif
315
}
316
 
317
#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A)
318
#define SYSCALL_ARG3    "trapa #0x23"
319
#else
320
#define SYSCALL_ARG3    "trapa #0x13"
321
#endif
322
 
323
/*
324
 * Do a system call from kernel instead of calling sys_execve so we
325
 * end up with proper pt_regs.
326
 */
327
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
328
{
329
        register long __sc0 __asm__ ("r3") = __NR_execve;
330
        register long __sc4 __asm__ ("r4") = (long) filename;
331
        register long __sc5 __asm__ ("r5") = (long) argv;
332
        register long __sc6 __asm__ ("r6") = (long) envp;
333
        __asm__ __volatile__ (SYSCALL_ARG3 : "=z" (__sc0)
334
                        : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6)
335
                        : "memory");
336
        return __sc0;
337
}

powered by: WebSVN 2.1.0

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