Linux-2.6.12-rc2
[linux-2.6] / arch / arm / kernel / arthur.c
1 /*
2  *  linux/arch/arm/kernel/arthur.c
3  *
4  *  Copyright (C) 1998, 1999, 2000, 2001 Philip Blundell
5  *
6  * Arthur personality
7  */
8
9 /*
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version
13  * 2 of the License, or (at your option) any later version.
14  */
15
16 #include <linux/module.h>
17 #include <linux/personality.h>
18 #include <linux/stddef.h>
19 #include <linux/signal.h>
20 #include <linux/init.h>
21
22 #include <asm/ptrace.h>
23
24 /* Arthur doesn't have many signals, and a lot of those that it does
25    have don't map easily to any Linux equivalent.  Never mind.  */
26
27 #define ARTHUR_SIGABRT          1
28 #define ARTHUR_SIGFPE           2
29 #define ARTHUR_SIGILL           3
30 #define ARTHUR_SIGINT           4
31 #define ARTHUR_SIGSEGV          5
32 #define ARTHUR_SIGTERM          6
33 #define ARTHUR_SIGSTAK          7
34 #define ARTHUR_SIGUSR1          8
35 #define ARTHUR_SIGUSR2          9
36 #define ARTHUR_SIGOSERROR       10
37
38 static unsigned long arthur_to_linux_signals[32] = {
39         0,      1,      2,      3,      4,      5,      6,      7,
40         8,      9,      10,     11,     12,     13,     14,     15,
41         16,     17,     18,     19,     20,     21,     22,     23,
42         24,     25,     26,     27,     28,     29,     30,     31
43 };
44
45 static unsigned long linux_to_arthur_signals[32] = {
46         0,              -1,             ARTHUR_SIGINT,  -1,
47         ARTHUR_SIGILL,  5,              ARTHUR_SIGABRT, 7,
48         ARTHUR_SIGFPE,  9,              ARTHUR_SIGUSR1, ARTHUR_SIGSEGV, 
49         ARTHUR_SIGUSR2, 13,             14,             ARTHUR_SIGTERM,
50         16,             17,             18,             19,
51         20,             21,             22,             23,
52         24,             25,             26,             27,
53         28,             29,             30,             31
54 };
55
56 static void arthur_lcall7(int nr, struct pt_regs *regs)
57 {
58         struct siginfo info;
59         info.si_signo = SIGSWI;
60         info.si_errno = nr;
61         /* Bounce it to the emulator */
62         send_sig_info(SIGSWI, &info, current);
63 }
64
65 static struct exec_domain arthur_exec_domain = {
66         .name           = "Arthur",
67         .handler        = arthur_lcall7,
68         .pers_low       = PER_RISCOS,
69         .pers_high      = PER_RISCOS,
70         .signal_map     = arthur_to_linux_signals,
71         .signal_invmap  = linux_to_arthur_signals,
72         .module         = THIS_MODULE,
73 };
74
75 /*
76  * We could do with some locking to stop Arthur being removed while
77  * processes are using it.
78  */
79
80 static int __init arthur_init(void)
81 {
82         return register_exec_domain(&arthur_exec_domain);
83 }
84
85 static void __exit arthur_exit(void)
86 {
87         unregister_exec_domain(&arthur_exec_domain);
88 }
89
90 module_init(arthur_init);
91 module_exit(arthur_exit);