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/] [sparc64/] [solaris/] [misc.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/* $Id: misc.c,v 1.36 2002/02/09 19:49:31 davem Exp $
2
 * misc.c: Miscellaneous syscall emulation for Solaris
3
 *
4
 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5
 */
6
 
7
#include <linux/module.h> 
8
#include <linux/types.h>
9
#include <linux/utsname.h>
10
#include <linux/limits.h>
11
#include <linux/mm.h>
12
#include <linux/smp.h>
13
#include <linux/tty.h>
14
#include <linux/mman.h>
15
#include <linux/file.h>
16
#include <linux/timex.h>
17
#include <linux/major.h>
18
#include <linux/compat.h>
19
 
20
#include <asm/uaccess.h>
21
#include <asm/string.h>
22
#include <asm/oplib.h>
23
#include <asm/idprom.h>
24
#include <asm/smp.h>
25
#include <asm/prom.h>
26
 
27
#include "conv.h"
28
 
29
/* Conversion from Linux to Solaris errnos. 0-34 are identity mapped.
30
   Some Linux errnos (EPROCLIM, EDOTDOT, ERREMOTE, EUCLEAN, ENOTNAM,
31
   ENAVAIL, EISNAM, EREMOTEIO, ENOMEDIUM, EMEDIUMTYPE) have no Solaris
32
   equivalents. I return EINVAL in that case, which is very wrong. If
33
   someone suggest a better value for them, you're welcomed.
34
   On the other side, Solaris ECANCELED and ENOTSUP have no Linux equivalents,
35
   but that doesn't matter here. --jj */
36
int solaris_err_table[] = {
37
/* 0 */  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
38
/* 10 */  10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
39
/* 20 */  20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
40
/* 30 */  30, 31, 32, 33, 34, 22, 150, 149, 95, 96,
41
/* 40 */  97, 98, 99, 120, 121, 122, 123, 124, 125, 126,
42
/* 50 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,
43
/* 60 */ 145, 146, 90, 78, 147, 148, 93, 22, 94, 49,
44
/* 70 */ 151, 66, 60, 62, 63, 35, 77, 36, 45, 46,
45
/* 80 */ 64, 22, 67, 68, 69, 70, 71, 74, 22, 82,
46
/* 90 */ 89, 92, 79, 81, 37, 38, 39, 40, 41, 42,
47
/* 100 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
48
/* 110 */ 87, 61, 84, 65, 83, 80, 91, 22, 22, 22,
49
/* 120 */ 22, 22, 88, 86, 85, 22, 22,
50
};
51
 
52
#define SOLARIS_NR_OPEN 256
53
 
54
static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 off)
55
{
56
        struct file *file = NULL;
57
        unsigned long retval, ret_type;
58
 
59
        /* Do we need it here? */
60
        set_personality(PER_SVR4);
61
        if (flags & MAP_NORESERVE) {
62
                static int cnt;
63
 
64
                if (cnt < 5) {
65
                        printk("%s:  unimplemented Solaris MAP_NORESERVE mmap() flag\n",
66
                               current->comm);
67
                        cnt++;
68
                }
69
                flags &= ~MAP_NORESERVE;
70
        }
71
        retval = -EBADF;
72
        if(!(flags & MAP_ANONYMOUS)) {
73
                if(fd >= SOLARIS_NR_OPEN)
74
                        goto out;
75
                file = fget(fd);
76
                if (!file)
77
                        goto out;
78
                else {
79
                        struct inode * inode = file->f_path.dentry->d_inode;
80
                        if(imajor(inode) == MEM_MAJOR &&
81
                           iminor(inode) == 5) {
82
                                flags |= MAP_ANONYMOUS;
83
                                fput(file);
84
                                file = NULL;
85
                        }
86
                }
87
        }
88
 
89
        retval = -EINVAL;
90
        len = PAGE_ALIGN(len);
91
        if(!(flags & MAP_FIXED))
92
                addr = 0;
93
        else if (len > STACK_TOP32 || addr > STACK_TOP32 - len)
94
                goto out_putf;
95
        ret_type = flags & _MAP_NEW;
96
        flags &= ~_MAP_NEW;
97
 
98
        down_write(&current->mm->mmap_sem);
99
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
100
        retval = do_mmap(file,
101
                         (unsigned long) addr, (unsigned long) len,
102
                         (unsigned long) prot, (unsigned long) flags, off);
103
        up_write(&current->mm->mmap_sem);
104
        if(!ret_type)
105
                retval = ((retval < STACK_TOP32) ? 0 : retval);
106
 
107
out_putf:
108
        if (file)
109
                fput(file);
110
out:
111
        return (u32) retval;
112
}
113
 
114
asmlinkage u32 solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off)
115
{
116
        return do_solaris_mmap(addr, len, prot, flags, fd, (u64) off);
117
}
118
 
119
asmlinkage u32 solaris_mmap64(struct pt_regs *regs, u32 len, u32 prot, u32 flags, u32 fd, u32 offhi)
120
{
121
        u32 offlo;
122
 
123
        if (regs->u_regs[UREG_G1]) {
124
                if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x5c)))
125
                        return -EFAULT;
126
        } else {
127
                if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x60)))
128
                        return -EFAULT;
129
        }
130
        return do_solaris_mmap((u32)regs->u_regs[UREG_I0], len, prot, flags, fd, (((u64)offhi)<<32)|offlo);
131
}
132
 
133
asmlinkage int solaris_brk(u32 brk)
134
{
135
        int (*sunos_brk)(u32) = (int (*)(u32))SUNOS(17);
136
 
137
        return sunos_brk(brk);
138
}
139
 
140
static int __set_utsfield(char __user *to, int to_size,
141
                          const char *from, int from_size,
142
                          int dotchop, int countfrom)
143
{
144
        int len = countfrom ? (to_size > from_size ?
145
                               from_size : to_size) : to_size;
146
        int off;
147
 
148
        if (copy_to_user(to, from, len))
149
                return -EFAULT;
150
 
151
        off = len < to_size? len: len - 1;
152
        if (dotchop) {
153
                const char *p = strnchr(from, len, '.');
154
                if (p) off = p - from;
155
        }
156
 
157
        if (__put_user('\0', to + off))
158
                return -EFAULT;
159
 
160
        return 0;
161
}
162
 
163
#define set_utsfield(to, from, dotchop, countfrom) \
164
        __set_utsfield((to), sizeof(to), \
165
                       (from), sizeof(from), \
166
                       (dotchop), (countfrom))
167
 
168
struct sol_uname {
169
        char sysname[9];
170
        char nodename[9];
171
        char release[9];
172
        char version[9];
173
        char machine[9];
174
};
175
 
176
struct sol_utsname {
177
        char sysname[257];
178
        char nodename[257];
179
        char release[257];
180
        char version[257];
181
        char machine[257];
182
};
183
 
184
static char *machine(void)
185
{
186
        switch (sparc_cpu_model) {
187
        case sun4: return "sun4";
188
        case sun4c: return "sun4c";
189
        case sun4e: return "sun4e";
190
        case sun4m: return "sun4m";
191
        case sun4d: return "sun4d";
192
        case sun4u: return "sun4u";
193
        default: return "sparc";
194
        }
195
}
196
 
197
static char *platform(char *buffer, int sz)
198
{
199
        struct device_node *dp = of_find_node_by_path("/");
200
        int len;
201
 
202
        *buffer = 0;
203
        len = strlen(dp->name);
204
        if (len > sz)
205
                len = sz;
206
        memcpy(buffer, dp->name, len);
207
        buffer[len] = 0;
208
        if (*buffer) {
209
                char *p;
210
 
211
                for (p = buffer; *p; p++)
212
                        if (*p == '/' || *p == ' ') *p = '_';
213
                return buffer;
214
        }
215
 
216
        return "sun4u";
217
}
218
 
219
static char *serial(char *buffer, int sz)
220
{
221
        struct device_node *dp = of_find_node_by_path("/options");
222
        int len;
223
 
224
        *buffer = 0;
225
        if (dp) {
226
                const char *val =
227
                        of_get_property(dp, "system-board-serial#", &len);
228
 
229
                if (val && len > 0) {
230
                        if (len > sz)
231
                                len = sz;
232
                        memcpy(buffer, val, len);
233
                        buffer[len] = 0;
234
                }
235
        }
236
        if (!*buffer)
237
                return "4512348717234";
238
        else
239
                return buffer;
240
}
241
 
242
asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
243
{
244
        struct sol_uname __user *v = A(buf);
245
        int err;
246
 
247
        switch (which) {
248
        case 0:  /* old uname */
249
                /* Let's cheat */
250
                err  = set_utsfield(v->sysname, "SunOS", 1, 0);
251
                down_read(&uts_sem);
252
                err |= set_utsfield(v->nodename, utsname()->nodename,
253
                                    1, 1);
254
                up_read(&uts_sem);
255
                err |= set_utsfield(v->release, "2.6", 0, 0);
256
                err |= set_utsfield(v->version, "Generic", 0, 0);
257
                err |= set_utsfield(v->machine, machine(), 0, 0);
258
                return (err ? -EFAULT : 0);
259
        case 2: /* ustat */
260
                return -ENOSYS;
261
        case 3: /* fusers */
262
                return -ENOSYS;
263
        default:
264
                return -ENOSYS;
265
        }
266
}
267
 
268
asmlinkage int solaris_utsname(u32 buf)
269
{
270
        struct sol_utsname __user *v = A(buf);
271
        int err;
272
 
273
        /* Why should we not lie a bit? */
274
        down_read(&uts_sem);
275
        err  = set_utsfield(v->sysname, "SunOS", 0, 0);
276
        err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1);
277
        err |= set_utsfield(v->release, "5.6", 0, 0);
278
        err |= set_utsfield(v->version, "Generic", 0, 0);
279
        err |= set_utsfield(v->machine, machine(), 0, 0);
280
        up_read(&uts_sem);
281
 
282
        return (err ? -EFAULT : 0);
283
}
284
 
285
#define SI_SYSNAME              1       /* return name of operating system */
286
#define SI_HOSTNAME             2       /* return name of node */
287
#define SI_RELEASE              3       /* return release of operating system */
288
#define SI_VERSION              4       /* return version field of utsname */
289
#define SI_MACHINE              5       /* return kind of machine */
290
#define SI_ARCHITECTURE         6       /* return instruction set arch */
291
#define SI_HW_SERIAL            7       /* return hardware serial number */
292
#define SI_HW_PROVIDER          8       /* return hardware manufacturer */
293
#define SI_SRPC_DOMAIN          9       /* return secure RPC domain */
294
#define SI_PLATFORM             513     /* return platform identifier */
295
 
296
asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
297
{
298
        char *p, *q, *r;
299
        char buffer[256];
300
        int len;
301
 
302
        /* Again, we cheat :)) */
303
        switch (cmd) {
304
        case SI_SYSNAME: r = "SunOS"; break;
305
        case SI_HOSTNAME:
306
                r = buffer + 256;
307
                down_read(&uts_sem);
308
                for (p = utsname()->nodename, q = buffer;
309
                     q < r && *p && *p != '.'; *q++ = *p++);
310
                up_read(&uts_sem);
311
                *q = 0;
312
                r = buffer;
313
                break;
314
        case SI_RELEASE: r = "5.6"; break;
315
        case SI_MACHINE: r = machine(); break;
316
        case SI_ARCHITECTURE: r = "sparc"; break;
317
        case SI_HW_PROVIDER: r = "Sun_Microsystems"; break;
318
        case SI_HW_SERIAL: r = serial(buffer, sizeof(buffer)); break;
319
        case SI_PLATFORM: r = platform(buffer, sizeof(buffer)); break;
320
        case SI_SRPC_DOMAIN: r = ""; break;
321
        case SI_VERSION: r = "Generic"; break;
322
        default: return -EINVAL;
323
        }
324
        len = strlen(r) + 1;
325
        if (count < len) {
326
                if (copy_to_user(A(buf), r, count - 1) ||
327
                    __put_user(0, (char __user *)A(buf) + count - 1))
328
                        return -EFAULT;
329
        } else {
330
                if (copy_to_user(A(buf), r, len))
331
                        return -EFAULT;
332
        }
333
        return len;
334
}
335
 
336
#define SOLARIS_CONFIG_NGROUPS                  2
337
#define SOLARIS_CONFIG_CHILD_MAX                3
338
#define SOLARIS_CONFIG_OPEN_FILES               4
339
#define SOLARIS_CONFIG_POSIX_VER                5
340
#define SOLARIS_CONFIG_PAGESIZE                 6
341
#define SOLARIS_CONFIG_CLK_TCK                  7
342
#define SOLARIS_CONFIG_XOPEN_VER                8
343
#define SOLARIS_CONFIG_PROF_TCK                 10
344
#define SOLARIS_CONFIG_NPROC_CONF               11
345
#define SOLARIS_CONFIG_NPROC_ONLN               12
346
#define SOLARIS_CONFIG_AIO_LISTIO_MAX           13
347
#define SOLARIS_CONFIG_AIO_MAX                  14
348
#define SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX       15
349
#define SOLARIS_CONFIG_DELAYTIMER_MAX           16
350
#define SOLARIS_CONFIG_MQ_OPEN_MAX              17
351
#define SOLARIS_CONFIG_MQ_PRIO_MAX              18
352
#define SOLARIS_CONFIG_RTSIG_MAX                19
353
#define SOLARIS_CONFIG_SEM_NSEMS_MAX            20
354
#define SOLARIS_CONFIG_SEM_VALUE_MAX            21
355
#define SOLARIS_CONFIG_SIGQUEUE_MAX             22
356
#define SOLARIS_CONFIG_SIGRT_MIN                23
357
#define SOLARIS_CONFIG_SIGRT_MAX                24
358
#define SOLARIS_CONFIG_TIMER_MAX                25
359
#define SOLARIS_CONFIG_PHYS_PAGES               26
360
#define SOLARIS_CONFIG_AVPHYS_PAGES             27
361
 
362
asmlinkage int solaris_sysconf(int id)
363
{
364
        switch (id) {
365
        case SOLARIS_CONFIG_NGROUPS:    return NGROUPS_MAX;
366
        case SOLARIS_CONFIG_CHILD_MAX:
367
                return current->signal->rlim[RLIMIT_NPROC].rlim_cur;
368
        case SOLARIS_CONFIG_OPEN_FILES:
369
                return current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
370
        case SOLARIS_CONFIG_POSIX_VER:  return 199309;
371
        case SOLARIS_CONFIG_PAGESIZE:   return PAGE_SIZE;
372
        case SOLARIS_CONFIG_XOPEN_VER:  return 3;
373
        case SOLARIS_CONFIG_CLK_TCK:
374
        case SOLARIS_CONFIG_PROF_TCK:
375
                return sparc64_get_clock_tick(smp_processor_id());
376
#ifdef CONFIG_SMP       
377
        case SOLARIS_CONFIG_NPROC_CONF: return NR_CPUS;
378
        case SOLARIS_CONFIG_NPROC_ONLN: return num_online_cpus();
379
#else
380
        case SOLARIS_CONFIG_NPROC_CONF: return 1;
381
        case SOLARIS_CONFIG_NPROC_ONLN: return 1;
382
#endif
383
        case SOLARIS_CONFIG_SIGRT_MIN:          return 37;
384
        case SOLARIS_CONFIG_SIGRT_MAX:          return 44;
385
        case SOLARIS_CONFIG_PHYS_PAGES:
386
        case SOLARIS_CONFIG_AVPHYS_PAGES:
387
                {
388
                        struct sysinfo s;
389
 
390
                        si_meminfo(&s);
391
                        if (id == SOLARIS_CONFIG_PHYS_PAGES)
392
                                return s.totalram >>= PAGE_SHIFT;
393
                        else
394
                                return s.freeram >>= PAGE_SHIFT;
395
                }
396
        /* XXX support these as well -jj */
397
        case SOLARIS_CONFIG_AIO_LISTIO_MAX:     return -EINVAL;
398
        case SOLARIS_CONFIG_AIO_MAX:            return -EINVAL;
399
        case SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX: return -EINVAL;
400
        case SOLARIS_CONFIG_DELAYTIMER_MAX:     return -EINVAL;
401
        case SOLARIS_CONFIG_MQ_OPEN_MAX:        return -EINVAL;
402
        case SOLARIS_CONFIG_MQ_PRIO_MAX:        return -EINVAL;
403
        case SOLARIS_CONFIG_RTSIG_MAX:          return -EINVAL;
404
        case SOLARIS_CONFIG_SEM_NSEMS_MAX:      return -EINVAL;
405
        case SOLARIS_CONFIG_SEM_VALUE_MAX:      return -EINVAL;
406
        case SOLARIS_CONFIG_SIGQUEUE_MAX:       return -EINVAL;
407
        case SOLARIS_CONFIG_TIMER_MAX:          return -EINVAL;
408
        default: return -EINVAL;
409
        }
410
}
411
 
412
asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
413
{
414
        int ret;
415
 
416
        switch (cmd) {
417
        case 0: /* getpgrp */
418
                return task_pgrp_nr(current);
419
        case 1: /* setpgrp */
420
                {
421
                        int (*sys_setpgid)(pid_t,pid_t) =
422
                                (int (*)(pid_t,pid_t))SYS(setpgid);
423
 
424
                        /* can anyone explain me the difference between
425
                           Solaris setpgrp and setsid? */
426
                        ret = sys_setpgid(0, 0);
427
                        if (ret) return ret;
428
                        proc_clear_tty(current);
429
                        return task_pgrp_nr(current);
430
                }
431
        case 2: /* getsid */
432
                {
433
                        int (*sys_getsid)(pid_t) = (int (*)(pid_t))SYS(getsid);
434
                        return sys_getsid(pid);
435
                }
436
        case 3: /* setsid */
437
                {
438
                        int (*sys_setsid)(void) = (int (*)(void))SYS(setsid);
439
                        return sys_setsid();
440
                }
441
        case 4: /* getpgid */
442
                {
443
                        int (*sys_getpgid)(pid_t) = (int (*)(pid_t))SYS(getpgid);
444
                        return sys_getpgid(pid);
445
                }
446
        case 5: /* setpgid */
447
                {
448
                        int (*sys_setpgid)(pid_t,pid_t) =
449
                                (int (*)(pid_t,pid_t))SYS(setpgid);
450
                        return sys_setpgid(pid,pgid);
451
                }
452
        }
453
        return -EINVAL;
454
}
455
 
456
asmlinkage int solaris_gettimeofday(u32 tim)
457
{
458
        int (*sys_gettimeofday)(struct timeval *, struct timezone *) =
459
                (int (*)(struct timeval *, struct timezone *))SYS(gettimeofday);
460
 
461
        return sys_gettimeofday((struct timeval *)(u64)tim, NULL);
462
}
463
 
464
#define RLIM_SOL_INFINITY32     0x7fffffff
465
#define RLIM_SOL_SAVED_MAX32    0x7ffffffe
466
#define RLIM_SOL_SAVED_CUR32    0x7ffffffd
467
#define RLIM_SOL_INFINITY       ((u64)-3)
468
#define RLIM_SOL_SAVED_MAX      ((u64)-2)
469
#define RLIM_SOL_SAVED_CUR      ((u64)-1)
470
#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
471
#define RLIMIT_SOL_NOFILE       5
472
#define RLIMIT_SOL_VMEM         6
473
 
474
struct rlimit32 {
475
        u32     rlim_cur;
476
        u32     rlim_max;
477
};
478
 
479
asmlinkage int solaris_getrlimit(unsigned int resource, struct rlimit32 __user *rlim)
480
{
481
        struct rlimit r;
482
        int ret;
483
        mm_segment_t old_fs = get_fs ();
484
        int (*sys_getrlimit)(unsigned int, struct rlimit *) =
485
                (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
486
 
487
        if (resource > RLIMIT_SOL_VMEM)
488
                return -EINVAL;
489
        switch (resource) {
490
        case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
491
        case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
492
        default: break;
493
        }
494
        set_fs (KERNEL_DS);
495
        ret = sys_getrlimit(resource, &r);
496
        set_fs (old_fs);
497
        if (!ret) {
498
                if (r.rlim_cur == RLIM_INFINITY)
499
                        r.rlim_cur = RLIM_SOL_INFINITY32;
500
                else if ((u64)r.rlim_cur > RLIM_SOL_INFINITY32)
501
                        r.rlim_cur = RLIM_SOL_SAVED_CUR32;
502
                if (r.rlim_max == RLIM_INFINITY)
503
                        r.rlim_max = RLIM_SOL_INFINITY32;
504
                else if ((u64)r.rlim_max > RLIM_SOL_INFINITY32)
505
                        r.rlim_max = RLIM_SOL_SAVED_MAX32;
506
                ret = put_user (r.rlim_cur, &rlim->rlim_cur);
507
                ret |= __put_user (r.rlim_max, &rlim->rlim_max);
508
        }
509
        return ret;
510
}
511
 
512
asmlinkage int solaris_setrlimit(unsigned int resource, struct rlimit32 __user *rlim)
513
{
514
        struct rlimit r, rold;
515
        int ret;
516
        mm_segment_t old_fs = get_fs ();
517
        int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
518
                (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
519
        int (*sys_setrlimit)(unsigned int, struct rlimit __user *) =
520
                (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit);
521
 
522
        if (resource > RLIMIT_SOL_VMEM)
523
                return -EINVAL;
524
        switch (resource) {
525
        case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
526
        case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
527
        default: break;
528
        }
529
        if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
530
            __get_user (r.rlim_max, &rlim->rlim_max))
531
                return -EFAULT;
532
        set_fs (KERNEL_DS);
533
        ret = sys_getrlimit(resource, &rold);
534
        if (!ret) {
535
                if (r.rlim_cur == RLIM_SOL_INFINITY32)
536
                        r.rlim_cur = RLIM_INFINITY;
537
                else if (r.rlim_cur == RLIM_SOL_SAVED_CUR32)
538
                        r.rlim_cur = rold.rlim_cur;
539
                else if (r.rlim_cur == RLIM_SOL_SAVED_MAX32)
540
                        r.rlim_cur = rold.rlim_max;
541
                if (r.rlim_max == RLIM_SOL_INFINITY32)
542
                        r.rlim_max = RLIM_INFINITY;
543
                else if (r.rlim_max == RLIM_SOL_SAVED_CUR32)
544
                        r.rlim_max = rold.rlim_cur;
545
                else if (r.rlim_max == RLIM_SOL_SAVED_MAX32)
546
                        r.rlim_max = rold.rlim_max;
547
                ret = sys_setrlimit(resource, &r);
548
        }
549
        set_fs (old_fs);
550
        return ret;
551
}
552
 
553
asmlinkage int solaris_getrlimit64(unsigned int resource, struct rlimit __user *rlim)
554
{
555
        struct rlimit r;
556
        int ret;
557
        mm_segment_t old_fs = get_fs ();
558
        int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
559
                (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
560
 
561
        if (resource > RLIMIT_SOL_VMEM)
562
                return -EINVAL;
563
        switch (resource) {
564
        case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
565
        case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
566
        default: break;
567
        }
568
        set_fs (KERNEL_DS);
569
        ret = sys_getrlimit(resource, &r);
570
        set_fs (old_fs);
571
        if (!ret) {
572
                if (r.rlim_cur == RLIM_INFINITY)
573
                        r.rlim_cur = RLIM_SOL_INFINITY;
574
                if (r.rlim_max == RLIM_INFINITY)
575
                        r.rlim_max = RLIM_SOL_INFINITY;
576
                ret = put_user (r.rlim_cur, &rlim->rlim_cur);
577
                ret |= __put_user (r.rlim_max, &rlim->rlim_max);
578
        }
579
        return ret;
580
}
581
 
582
asmlinkage int solaris_setrlimit64(unsigned int resource, struct rlimit __user *rlim)
583
{
584
        struct rlimit r, rold;
585
        int ret;
586
        mm_segment_t old_fs = get_fs ();
587
        int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
588
                (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
589
        int (*sys_setrlimit)(unsigned int, struct rlimit __user *) =
590
                (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit);
591
 
592
        if (resource > RLIMIT_SOL_VMEM)
593
                return -EINVAL;
594
        switch (resource) {
595
        case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
596
        case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
597
        default: break;
598
        }
599
        if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
600
            __get_user (r.rlim_max, &rlim->rlim_max))
601
                return -EFAULT;
602
        set_fs (KERNEL_DS);
603
        ret = sys_getrlimit(resource, &rold);
604
        if (!ret) {
605
                if (r.rlim_cur == RLIM_SOL_INFINITY)
606
                        r.rlim_cur = RLIM_INFINITY;
607
                else if (r.rlim_cur == RLIM_SOL_SAVED_CUR)
608
                        r.rlim_cur = rold.rlim_cur;
609
                else if (r.rlim_cur == RLIM_SOL_SAVED_MAX)
610
                        r.rlim_cur = rold.rlim_max;
611
                if (r.rlim_max == RLIM_SOL_INFINITY)
612
                        r.rlim_max = RLIM_INFINITY;
613
                else if (r.rlim_max == RLIM_SOL_SAVED_CUR)
614
                        r.rlim_max = rold.rlim_cur;
615
                else if (r.rlim_max == RLIM_SOL_SAVED_MAX)
616
                        r.rlim_max = rold.rlim_max;
617
                ret = sys_setrlimit(resource, &r);
618
        }
619
        set_fs (old_fs);
620
        return ret;
621
}
622
 
623
struct sol_ntptimeval {
624
        struct compat_timeval time;
625
        s32 maxerror;
626
        s32 esterror;
627
};
628
 
629
struct sol_timex {
630
        u32 modes;
631
        s32 offset;
632
        s32 freq;
633
        s32 maxerror;
634
        s32 esterror;
635
        s32 status;
636
        s32 constant;
637
        s32 precision;
638
        s32 tolerance;
639
        s32 ppsfreq;
640
        s32 jitter;
641
        s32 shift;
642
        s32 stabil;
643
        s32 jitcnt;
644
        s32 calcnt;
645
        s32 errcnt;
646
        s32 stbcnt;
647
};
648
 
649
asmlinkage int solaris_ntp_gettime(struct sol_ntptimeval __user *ntp)
650
{
651
        int (*sys_adjtimex)(struct timex __user *) =
652
                (int (*)(struct timex __user *))SYS(adjtimex);
653
        struct timex t;
654
        int ret;
655
        mm_segment_t old_fs = get_fs();
656
 
657
        set_fs(KERNEL_DS);
658
        t.modes = 0;
659
        ret = sys_adjtimex(&t);
660
        set_fs(old_fs);
661
        if (ret < 0)
662
                return ret;
663
        ret = put_user (t.time.tv_sec, &ntp->time.tv_sec);
664
        ret |= __put_user (t.time.tv_usec, &ntp->time.tv_usec);
665
        ret |= __put_user (t.maxerror, &ntp->maxerror);
666
        ret |= __put_user (t.esterror, &ntp->esterror);
667
        return ret;
668
}
669
 
670
asmlinkage int solaris_ntp_adjtime(struct sol_timex __user *txp)
671
{
672
        int (*sys_adjtimex)(struct timex __user *) =
673
                (int (*)(struct timex __user *))SYS(adjtimex);
674
        struct timex t;
675
        int ret, err;
676
        mm_segment_t old_fs = get_fs();
677
 
678
        ret = get_user (t.modes, &txp->modes);
679
        ret |= __get_user (t.offset, &txp->offset);
680
        ret |= __get_user (t.freq, &txp->freq);
681
        ret |= __get_user (t.maxerror, &txp->maxerror);
682
        ret |= __get_user (t.esterror, &txp->esterror);
683
        ret |= __get_user (t.status, &txp->status);
684
        ret |= __get_user (t.constant, &txp->constant);
685
        set_fs(KERNEL_DS);
686
        ret = sys_adjtimex(&t);
687
        set_fs(old_fs);
688
        if (ret < 0)
689
                return ret;
690
        err = put_user (t.offset, &txp->offset);
691
        err |= __put_user (t.freq, &txp->freq);
692
        err |= __put_user (t.maxerror, &txp->maxerror);
693
        err |= __put_user (t.esterror, &txp->esterror);
694
        err |= __put_user (t.status, &txp->status);
695
        err |= __put_user (t.constant, &txp->constant);
696
        err |= __put_user (t.precision, &txp->precision);
697
        err |= __put_user (t.tolerance, &txp->tolerance);
698
        err |= __put_user (t.ppsfreq, &txp->ppsfreq);
699
        err |= __put_user (t.jitter, &txp->jitter);
700
        err |= __put_user (t.shift, &txp->shift);
701
        err |= __put_user (t.stabil, &txp->stabil);
702
        err |= __put_user (t.jitcnt, &txp->jitcnt);
703
        err |= __put_user (t.calcnt, &txp->calcnt);
704
        err |= __put_user (t.errcnt, &txp->errcnt);
705
        err |= __put_user (t.stbcnt, &txp->stbcnt);
706
        if (err)
707
                return -EFAULT;
708
        return ret;
709
}
710
 
711
asmlinkage int do_sol_unimplemented(struct pt_regs *regs)
712
{
713
        printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08x\n",
714
                        (int)regs->u_regs[UREG_G1],
715
                        (int)regs->u_regs[UREG_I0],
716
                        (int)regs->u_regs[UREG_I1],
717
                        (int)regs->u_regs[UREG_I2],
718
                        (int)regs->u_regs[UREG_I3]);
719
        return -ENOSYS;
720
}
721
 
722
asmlinkage void solaris_register(void)
723
{
724
        set_personality(PER_SVR4);
725
}
726
 
727
extern long solaris_to_linux_signals[], linux_to_solaris_signals[];
728
 
729
struct exec_domain solaris_exec_domain = {
730
        .name =         "Solaris",
731
        .handler =      NULL,
732
        .pers_low =     1,              /* PER_SVR4 personality */
733
        .pers_high =    1,
734
        .signal_map =   solaris_to_linux_signals,
735
        .signal_invmap =linux_to_solaris_signals,
736
        .module =       THIS_MODULE,
737
        .next =         NULL
738
};
739
 
740
extern int init_socksys(void);
741
 
742
MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");
743
MODULE_DESCRIPTION("Solaris binary emulation module");
744
MODULE_LICENSE("GPL");
745
 
746
extern u32 tl0_solaris[8];
747
#define update_ttable(x)                                                                                \
748
        tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000;                       \
749
        wmb();          \
750
        __asm__ __volatile__ ("flush %0" : : "r" (&tl0_solaris[3]))
751
 
752
extern u32 solaris_sparc_syscall[];
753
extern u32 solaris_syscall[];
754
extern void cleanup_socksys(void);
755
 
756
extern u32 entry64_personality_patch;
757
 
758
static int __init solaris_init(void)
759
{
760
        int ret;
761
 
762
        SOLDD(("Solaris module at %p\n", solaris_sparc_syscall));
763
        register_exec_domain(&solaris_exec_domain);
764
        if ((ret = init_socksys())) {
765
                unregister_exec_domain(&solaris_exec_domain);
766
                return ret;
767
        }
768
        update_ttable(solaris_sparc_syscall);
769
        entry64_personality_patch |=
770
                (offsetof(struct task_struct, personality) +
771
                 (sizeof(unsigned long) - 1));
772
        wmb();
773
        __asm__ __volatile__("flush %0"
774
                             : : "r" (&entry64_personality_patch));
775
        return 0;
776
}
777
 
778
static void __exit solaris_exit(void)
779
{
780
        update_ttable(solaris_syscall);
781
        cleanup_socksys();
782
        unregister_exec_domain(&solaris_exec_domain);
783
}
784
 
785
module_init(solaris_init);
786
module_exit(solaris_exit);

powered by: WebSVN 2.1.0

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