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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [sparc/] [kernel/] [sys_sparc.c] - Blame information for rev 1777

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

Line No. Rev Author Line
1 1624 jcastillo
/* $Id: sys_sparc.c,v 1.1 2005-12-20 09:50:43 jcastillo Exp $
2
 * linux/arch/sparc/kernel/sys_sparc.c
3
 *
4
 * This file contains various random system calls that
5
 * have a non-standard calling sequence on the Linux/sparc
6
 * platform.
7
 */
8
 
9
#include <linux/errno.h>
10
#include <linux/sched.h>
11
#include <linux/mm.h>
12
#include <linux/sem.h>
13
#include <linux/msg.h>
14
#include <linux/shm.h>
15
#include <linux/stat.h>
16
#include <linux/mman.h>
17
 
18
#include <asm/segment.h>
19
 
20
/* XXX Make this per-binary type, this way we can detect the type of
21
 * XXX a binary.  Every Sparc executable calls this very early on.
22
 */
23
asmlinkage unsigned long sys_getpagesize(void)
24
{
25
        return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */
26
}
27
 
28
/*
29
 * sys_pipe() is the normal C calling standard for creating
30
 * a pipe. It's not the way unix traditionally does this, though.
31
 */
32
asmlinkage int sparc_pipe(struct pt_regs *regs)
33
{
34
        int fd[2];
35
        int error;
36
 
37
        error = do_pipe(fd);
38
        if (error) {
39
                return error;
40
        } else {
41
                regs->u_regs[UREG_I1] = fd[1];
42
                return fd[0];
43
        }
44
}
45
 
46
/* Note most sanity checking already done in sclow.S code. */
47
asmlinkage int quick_sys_write(unsigned int fd, char *buf, unsigned int count)
48
{
49
        struct file *file = current->files->fd[fd];
50
        struct inode *inode = file->f_inode;
51
        int error;
52
 
53
        error = verify_area(VERIFY_READ, buf, count);
54
        if(error)
55
                return error;
56
        /*
57
         * If data has been written to the file, remove the setuid and
58
         * the setgid bits. We do it anyway otherwise there is an
59
         * extremely exploitable race - does your OS get it right |->
60
         *
61
         * Set ATTR_FORCE so it will always be changed.
62
         */
63
        if (!suser() && (inode->i_mode & (S_ISUID | S_ISGID))) {
64
                struct iattr newattrs;
65
                newattrs.ia_mode = inode->i_mode & ~(S_ISUID | S_ISGID);
66
                newattrs.ia_valid = ATTR_CTIME | ATTR_MODE | ATTR_FORCE;
67
                notify_change(inode, &newattrs);
68
        }
69
 
70
        down(&inode->i_sem);
71
        error = file->f_op->write(inode,file,buf,count);
72
        up(&inode->i_sem);
73
        return error;
74
}
75
 
76
/* XXX do we need this crap? XXX */
77
 
78
/*
79
 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
80
 *
81
 * This is really horribly ugly.
82
 */
83
asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
84
{
85
        int version;
86
 
87
        version = call >> 16; /* hack for backward compatibility */
88
        call &= 0xffff;
89
 
90
        if (call <= SEMCTL)
91
                switch (call) {
92
                case SEMOP:
93
                        return sys_semop (first, (struct sembuf *)ptr, second);
94
                case SEMGET:
95
                        return sys_semget (first, second, third);
96
                case SEMCTL: {
97
                        union semun fourth;
98
                        int err;
99
                        if (!ptr)
100
                                return -EINVAL;
101
                        if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
102
                                return err;
103
                        fourth.__pad = (void *) get_fs_long(ptr);
104
                        return sys_semctl (first, second, third, fourth);
105
                        }
106
                default:
107
                        return -EINVAL;
108
                }
109
        if (call <= MSGCTL)
110
                switch (call) {
111
                case MSGSND:
112
                        return sys_msgsnd (first, (struct msgbuf *) ptr,
113
                                           second, third);
114
                case MSGRCV:
115
                        switch (version) {
116
                        case 0: {
117
                                struct ipc_kludge tmp;
118
                                int err;
119
                                if (!ptr)
120
                                        return -EINVAL;
121
                                if ((err = verify_area (VERIFY_READ, ptr, sizeof(tmp))))
122
                                        return err;
123
                                memcpy_fromfs (&tmp,(struct ipc_kludge *) ptr,
124
                                               sizeof (tmp));
125
                                return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
126
                                }
127
                        case 1: default:
128
                                return sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
129
                        }
130
                case MSGGET:
131
                        return sys_msgget ((key_t) first, second);
132
                case MSGCTL:
133
                        return sys_msgctl (first, second, (struct msqid_ds *) ptr);
134
                default:
135
                        return -EINVAL;
136
                }
137
        if (call <= SHMCTL)
138
                switch (call) {
139
                case SHMAT:
140
                        switch (version) {
141
                        case 0: default: {
142
                                ulong raddr;
143
                                int err;
144
                                if ((err = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong))))
145
                                        return err;
146
                                err = sys_shmat (first, (char *) ptr, second, &raddr);
147
                                if (err)
148
                                        return err;
149
                                put_fs_long (raddr, (ulong *) third);
150
                                return 0;
151
                                }
152
                        case 1: /* iBCS2 emulator entry point */
153
                                if (get_fs() != get_ds())
154
                                        return -EINVAL;
155
                                return sys_shmat (first, (char *) ptr, second, (ulong *) third);
156
                        }
157
                case SHMDT:
158
                        return sys_shmdt ((char *)ptr);
159
                case SHMGET:
160
                        return sys_shmget (first, second, third);
161
                case SHMCTL:
162
                        return sys_shmctl (first, second, (struct shmid_ds *) ptr);
163
                default:
164
                        return -EINVAL;
165
                }
166
        return -EINVAL;
167
}
168
 
169
unsigned long get_sparc_unmapped_area(unsigned long len)
170
{
171
        unsigned long addr = 0xE8000000UL;
172
        struct vm_area_struct * vmm;
173
 
174
        if (len > TASK_SIZE)
175
                return 0;
176
        for (vmm = find_vma(current, addr); ; vmm = vmm->vm_next) {
177
                /* At this point:  (!vmm || addr < vmm->vm_end). */
178
                if (TASK_SIZE - len < addr)
179
                        return 0;
180
                if (!vmm || addr + len <= vmm->vm_start)
181
                        return addr;
182
                addr = vmm->vm_end;
183
        }
184
}
185
 
186
/* Linux version of mmap */
187
asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
188
        unsigned long prot, unsigned long flags, unsigned long fd,
189
        unsigned long off)
190
{
191
        struct file * file = NULL;
192
        long retval;
193
 
194
        if (!(flags & MAP_ANONYMOUS)) {
195
                if (fd >= NR_OPEN || !(file = current->files->fd[fd])){
196
                        return -EBADF;
197
            }
198
        }
199
        if(!(flags & MAP_FIXED) && !addr) {
200
                addr = get_sparc_unmapped_area(len);
201
                if(!addr){
202
                        return -ENOMEM;
203
                }
204
        }
205
        retval = do_mmap(file, addr, len, prot, flags, off);
206
        return retval;
207
}

powered by: WebSVN 2.1.0

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