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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [armnommu/] [kernel/] [sys_arm.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * linux/arch/arm/kernel/sys-arm.c
3
 *
4
 * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c
5
 * Copyright (C) 1995, 1996 Russell King.
6
 *
7
 * This file contains various random system calls that
8
 * have a non-standard calling sequence on the Linux/arm
9
 * platform.
10
 */
11
 
12
#include <linux/module.h>
13
#include <linux/errno.h>
14
#include <linux/sched.h>
15
#include <linux/mm.h>
16
#include <linux/sem.h>
17
#include <linux/msg.h>
18
#include <linux/shm.h>
19
#include <linux/stat.h>
20
#include <linux/mman.h>
21
 
22
#include <asm/segment.h>
23
 
24
/*
25
 * Constant strings used in inlined functions in header files
26
 */
27
/* proc/system.h */
28
const char xchg_str[] = "xchg";
29
/* arch/dma.h */
30
const char dma_str[] = "%s: dma %d not supported\n";
31
 
32
/*
33
 * sys_pipe() is the normal C calling standard for creating
34
 * a pipe. It's not the way unix tranditionally does this, though.
35
 */
36
asmlinkage int sys_pipe(unsigned long * fildes)
37
{
38
        int fd[2];
39
        int error;
40
 
41
        error = verify_area(VERIFY_WRITE,fildes,8);
42
        if (error)
43
                return error;
44
        error = do_pipe(fd);
45
        if (error)
46
                return error;
47
        put_fs_long(fd[0],0+fildes);
48
        put_fs_long(fd[1],1+fildes);
49
        return 0;
50
}
51
 
52
/*
53
 * Perform the select(nd, in, out, ex, tv) and mmap() system
54
 * calls. Linux/i386 didn't use to be able to handle more than
55
 * 4 system call parameters, so these system calls used a memory
56
 * block for parameter passing..
57
 */
58
asmlinkage int old_mmap(unsigned long *buffer)
59
{
60
        int error;
61
        unsigned long flags;
62
        struct file * file = NULL;
63
 
64
        error = verify_area(VERIFY_READ, buffer, 6*sizeof(long));
65
        if (error)
66
                return error;
67
        flags = get_user(buffer+3);
68
        if (!(flags & MAP_ANONYMOUS)) {
69
                unsigned long fd = get_user(buffer+4);
70
                if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
71
                        return -EBADF;
72
        }
73
        return do_mmap(file, get_user(buffer), get_user(buffer+1),
74
                       get_user(buffer+2), flags, get_user(buffer+5));
75
}
76
 
77
 
78
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
79
 
80
asmlinkage int old_select(unsigned long *buffer)
81
{
82
        int n;
83
        fd_set *inp;
84
        fd_set *outp;
85
        fd_set *exp;
86
        struct timeval *tvp;
87
 
88
        n = verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long));
89
        if (n)
90
                return n;
91
        n = get_user(buffer);
92
        inp = (fd_set *) get_user(buffer+1);
93
        outp = (fd_set *) get_user(buffer+2);
94
        exp = (fd_set *) get_user(buffer+3);
95
        tvp = (struct timeval *) get_user(buffer+4);
96
        return sys_select(n, inp, outp, exp, tvp);
97
}
98
 
99
/*
100
 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
101
 *
102
 * This is really horribly ugly.
103
 */
104
asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
105
{
106
        int version;
107
 
108
        version = call >> 16; /* hack for backward compatibility */
109
        call &= 0xffff;
110
 
111
        if (call <= SEMCTL)
112
                switch (call) {
113
                case SEMOP:
114
                        return sys_semop (first, (struct sembuf *)ptr, second);
115
                case SEMGET:
116
                        return sys_semget (first, second, third);
117
                case SEMCTL: {
118
                        union semun fourth;
119
                        int err;
120
                        if (!ptr)
121
                                return -EINVAL;
122
                        if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
123
                                return err;
124
                        fourth.__pad = (void *) get_fs_long(ptr);
125
                        return sys_semctl (first, second, third, fourth);
126
                        }
127
                default:
128
                        return -EINVAL;
129
                }
130
        if (call <= MSGCTL)
131
                switch (call) {
132
                case MSGSND:
133
                        return sys_msgsnd (first, (struct msgbuf *) ptr,
134
                                           second, third);
135
                case MSGRCV:
136
                        switch (version) {
137
                        case 0: {
138
                                struct ipc_kludge tmp;
139
                                int err;
140
                                if (!ptr)
141
                                        return -EINVAL;
142
                                if ((err = verify_area (VERIFY_READ, ptr, sizeof(tmp))))
143
                                        return err;
144
                                memcpy_fromfs (&tmp,(struct ipc_kludge *) ptr,
145
                                               sizeof (tmp));
146
                                return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
147
                                }
148
                        case 1: default:
149
                                return sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
150
                        }
151
                case MSGGET:
152
                        return sys_msgget ((key_t) first, second);
153
                case MSGCTL:
154
                        return sys_msgctl (first, second, (struct msqid_ds *) ptr);
155
                default:
156
                        return -EINVAL;
157
                }
158
        if (call <= SHMCTL)
159
                switch (call) {
160
                case SHMAT:
161
                        switch (version) {
162
                        case 0: default: {
163
                                ulong raddr;
164
                                int err;
165
                                if ((err = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong))))
166
                                        return err;
167
                                err = sys_shmat (first, (char *) ptr, second, &raddr);
168
                                if (err)
169
                                        return err;
170
                                put_fs_long (raddr, (ulong *) third);
171
                                return 0;
172
                                }
173
                        case 1: /* iBCS2 emulator entry point */
174
                                if (get_fs() != get_ds())
175
                                        return -EINVAL;
176
                                return sys_shmat (first, (char *) ptr, second, (ulong *) third);
177
                        }
178
                case SHMDT:
179
                        return sys_shmdt ((char *)ptr);
180
                case SHMGET:
181
                        return sys_shmget (first, second, third);
182
                case SHMCTL:
183
                        return sys_shmctl (first, second, (struct shmid_ds *) ptr);
184
                default:
185
                        return -EINVAL;
186
                }
187
        return -EINVAL;
188
}
189
 
190
static inline unsigned long get_instr(struct pt_regs *regs)
191
{
192
    unsigned long *pcv;
193
 
194
    pcv = (unsigned long *)instruction_pointer(regs);
195
 
196
    return get_user (pcv);
197
}
198
 
199
/*
200
 * Old functions - we used to pass 5 parameters as r0, r1, r2, *r3, *(r3+4)
201
 * Now use r0 - r4.  Note that these will stay for a while until people have upgraded...
202
 * (so that we can still use old binaries).
203
 *
204
 * Eventually these functions will disappear.
205
 */
206
asmlinkage int
207
sys_old_arm_init_module (char *module_name, char *code, unsigned codesize,
208
        struct mod_routines *modr, struct symbol_table *syms)
209
{
210
    extern int sys_init_module (char *, char *, unsigned, struct mod_routines *,
211
                struct symbol_table *);
212
    struct pt_regs *regs;
213
 
214
    __asm__ ("mov %0, r9": "=r" (regs));
215
 
216
    if (get_instr(regs) == 0xe1a0300d) {
217
        unsigned long *__p;
218
        __p = (unsigned long *)modr;
219
        if (!(current->flags & 0x40000000)) {
220
                printk (KERN_NOTICE "%s (%d): Old init_module call\n", current->comm, current->pid);
221
                current->flags |= 0x40000000;
222
        }
223
        return sys_init_module (module_name, code, codesize, (struct mod_routines *)__p[0],
224
                (struct symbol_table *)__p[1]);
225
    }
226
    return sys_init_module (module_name, code, codesize, modr, syms);
227
}
228
 
229
asmlinkage int
230
sys_old_arm_llseek (unsigned int fd, unsigned long offset_high, unsigned long offset_low,
231
                loff_t *result, unsigned int origin)
232
{
233
    extern int sys_llseek (unsigned int, unsigned long, unsigned long, loff_t *, unsigned int);
234
    struct pt_regs *regs;
235
 
236
    __asm__ ("mov %0, r9": "=r" (regs));
237
 
238
    if (get_instr(regs) == 0xe1a0300d) {
239
        unsigned long *__p;
240
        __p = (unsigned long *)result;
241
        if (!(current->flags & 0x20000000)) {
242
                printk (KERN_NOTICE "%s (%d): Old llseek call\n", current->comm, current->pid);
243
                current->flags |= 0x20000000;
244
        }
245
        return sys_llseek (fd, offset_high, offset_low, (loff_t *)__p[0], (unsigned int)__p[1]);
246
    }
247
    return sys_llseek (fd, offset_high, offset_low, result, origin);
248
}
249
 
250
asmlinkage int
251
sys_old_arm_mount (char *devname, char *dirname, char *type, unsigned long flags, void *data)
252
{
253
    extern int sys_mount (char *, char *, char *, unsigned long, void *);
254
    struct pt_regs *regs;
255
 
256
    __asm__ ("mov %0, r9": "=r" (regs));
257
 
258
    if (get_instr(regs) == 0xe1a0300d) {
259
        unsigned long *__p;
260
        __p = (unsigned long *)flags;
261
        if (!(current->flags & 0x10000000)) {
262
                printk (KERN_NOTICE "%s (%d): Old mount call\n", current->comm, current->pid);
263
                current->flags |= 0x10000000;
264
        }
265
        return sys_mount (devname, dirname, type, __p[0], (void *)__p[1]);
266
    }
267
    return sys_mount (devname, dirname, type, flags, data);
268
}

powered by: WebSVN 2.1.0

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