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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [sparc64/] [solaris/] [misc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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