xref: /netbsd-src/sys/arch/m68k/include/signal.h (revision d710132b4b8ce7f7cccaaf660cb16aa16b4077a0)
1 /*	$NetBSD: signal.h,v 1.12 2003/04/28 23:16:20 bjh21 Exp $	*/
2 
3 /*
4  * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)signal.h	7.16 (Berkeley) 3/17/91
36  */
37 
38 #ifndef _M68K_SIGNAL_H_
39 #define _M68K_SIGNAL_H_
40 
41 #include <sys/featuretest.h>
42 
43 typedef int sig_atomic_t;
44 
45 #if defined(_NETBSD_SOURCE)
46 /*
47  * Get the "code" values
48  */
49 #include <machine/trap.h>
50 
51 /*
52  * Information pushed on stack when a signal is delivered.
53  * This is used by the kernel to restore state following
54  * execution of the signal handler.  It is also made available
55  * to the handler to allow it to restore state properly if
56  * a non-standard exit is performed.
57  */
58 #if defined(__LIBC12_SOURCE__) || defined(_KERNEL)
59 struct sigcontext13 {
60 	int	sc_onstack;		/* sigstack state to restore */
61 	int	sc_mask;		/* signal mask to restore (old style) */
62 	int	sc_sp;			/* sp to restore */
63 	int	sc_fp;			/* fp to restore */
64 	int	sc_ap;			/* ap to restore */
65 	int	sc_pc;			/* pc to restore */
66 	int	sc_ps;			/* psl to restore */
67 };
68 #endif /* __LIBC12_SOURCE__ || _KERNEL */
69 
70 struct sigcontext {
71 	int	sc_onstack;		/* sigstack state to restore */
72 	int	__sc_mask13;		/* signal mask to restore (old style) */
73 	int	sc_sp;			/* sp to restore */
74 	int	sc_fp;			/* fp to restore */
75 	int	sc_ap;			/* ap to restore */
76 	int	sc_pc;			/* pc to restore */
77 	int	sc_ps;			/* psl to restore */
78 	sigset_t sc_mask;		/* signal mask to restore (new style) */
79 };
80 
81 /*
82  * The following macros are used to convert from a ucontext to sigcontext,
83  * and vice-versa.  This is for building a sigcontext to deliver to old-style
84  * signal handlers, and converting back (in the event the handler modifies
85  * the context).
86  *
87  * On m68k, we also need the sigstate conversion macros below.
88  */
89 #define	_MCONTEXT_TO_SIGCONTEXT(uc, sc)					\
90 do {									\
91 	(sc)->sc_sp = (uc)->uc_mcontext.__gregs[_REG_A7];		\
92 	(sc)->sc_fp = (uc)->uc_mcontext.__gregs[_REG_A6];		\
93 	/* sc_ap points to sigstate */					\
94 	(sc)->sc_pc = (uc)->uc_mcontext.__gregs[_REG_PC];		\
95 	(sc)->sc_ps = (uc)->uc_mcontext.__gregs[_REG_PS];		\
96 } while (/*CONSTCOND*/0)
97 
98 #define	_SIGCONTEXT_TO_MCONTEXT(sc, uc)					\
99 do {									\
100 	(uc)->uc_mcontext.__gregs[_REG_A7] = (sc)->sc_sp;		\
101 	(uc)->uc_mcontext.__gregs[_REG_A6] = (sc)->sc_fp;		\
102 	(uc)->uc_mcontext.__gregs[_REG_PC] = (sc)->sc_pc;		\
103 	(uc)->uc_mcontext.__gregs[_REG_PS] = (sc)->sc_ps;		\
104 } while (/*CONSTCOND*/0)
105 
106 #if defined(__M68K_SIGNAL_PRIVATE)
107 #include <m68k/frame.h>
108 
109 /*
110  * Register state saved while kernel delivers a signal.
111  */
112 struct sigstate {
113 	int	ss_flags;		/* which of the following are valid */
114 	struct frame ss_frame;		/* original exception frame */
115 	struct fpframe ss_fpstate;	/* 68881/68882 state info */
116 };
117 
118 #define	SS_RTEFRAME	0x01
119 #define	SS_FPSTATE	0x02
120 #define	SS_USERREGS	0x04
121 
122 #ifdef _KERNEL
123 #define	_SIGSTATE_EXFRAMESIZE(fmt)	exframesize[(fmt)]
124 #endif
125 
126 #define	_MCONTEXT_TO_SIGSTATE(uc, ss)					\
127 do {									\
128 	(ss)->ss_flags = SS_USERREGS;					\
129 	memcpy(&(ss)->ss_frame.f_regs, &(uc)->uc_mcontext.__gregs,	\
130 	    16 * sizeof(unsigned int));					\
131 	(ss)->ss_frame.f_pc = (uc)->uc_mcontext.__gregs[_REG_PC];	\
132 	(ss)->ss_frame.f_sr = (uc)->uc_mcontext.__gregs[_REG_PS];	\
133 	(ss)->ss_frame.f_pad = 0;					\
134 	(ss)->ss_frame.f_stackadj = 0;					\
135 	(ss)->ss_frame.f_format =					\
136 	    (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_format;		\
137 	if ((ss)->ss_frame.f_format >= FMT4) {				\
138 		(ss)->ss_flags |= SS_RTEFRAME;				\
139 		(ss)->ss_frame.f_vector =				\
140 		    (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_vector;	\
141 		memcpy(&(ss)->ss_frame.F_u,				\
142 		    &(uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_exframe,\
143 		    _SIGSTATE_EXFRAMESIZE((ss)->ss_frame.f_format));	\
144 	}								\
145 									\
146 	(ss)->ss_fpstate.FPF_u1 =					\
147 	    (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_fpf_u1;		\
148 	if ((uc)->uc_flags & _UC_FPU) { /* non-null FP frame */		\
149 		(ss)->ss_fpstate.FPF_u2 =				\
150 		    (uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_fpf_u2;	\
151 		memcpy(&(ss)->ss_fpstate.fpf_regs,			\
152 		    &(uc)->uc_mcontext.__fpregs.__fp_fpregs,		\
153 		    sizeof((ss)->ss_fpstate.fpf_regs));			\
154 		(ss)->ss_fpstate.fpf_fpcr =				\
155 		    (uc)->uc_mcontext.__fpregs.__fp_pcr;		\
156 		(ss)->ss_fpstate.fpf_fpsr =				\
157 		    (uc)->uc_mcontext.__fpregs.__fp_psr;		\
158 		(ss)->ss_fpstate.fpf_fpiar =				\
159 		    (uc)->uc_mcontext.__fpregs.__fp_piaddr;		\
160 		(ss)->ss_flags |= SS_FPSTATE;				\
161 	}								\
162 } while (/*CONSTCOND*/0)
163 
164 #define	_SIGSTATE_TO_MCONTEXT(ss, uc)					\
165 do {									\
166 	memcpy(&(uc)->uc_mcontext.__gregs, &(ss)->ss_frame.f_regs,	\
167 	    16 * sizeof(unsigned int));					\
168 	(uc)->uc_mcontext.__gregs[_REG_PC] = (ss)->ss_frame.f_pc;	\
169 	(uc)->uc_mcontext.__gregs[_REG_PS] = (ss)->ss_frame.f_sr;	\
170 	(uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_format =		\
171 	    (ss)->ss_frame.f_format;					\
172 	if ((ss)->ss_flags & SS_RTEFRAME) {				\
173 		(uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_vector =	\
174 		    (ss)->ss_frame.f_vector;				\
175 		memcpy(&(uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_exframe,\
176 		    &(ss)->ss_frame.F_u,				\
177 		    _SIGSTATE_EXFRAMESIZE((ss)->ss_frame.f_format));	\
178 	}								\
179 									\
180 	(uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_fpf_u1 =		\
181 	    (ss)->ss_fpstate.FPF_u1;					\
182 	if ((ss)->ss_flags & SS_FPSTATE) {				\
183 		(uc)->uc_mcontext.__mc_pad.__mc_frame.__mcf_fpf_u2 =	\
184 		    (ss)->ss_fpstate.FPF_u2;				\
185 		memcpy(&(uc)->uc_mcontext.__fpregs.__fp_fpregs,		\
186 		    &(ss)->ss_fpstate.fpf_regs,				\
187 		    sizeof((ss)->ss_fpstate.fpf_regs));			\
188 		(uc)->uc_mcontext.__fpregs.__fp_pcr =			\
189 		    (ss)->ss_fpstate.fpf_fpcr;				\
190 		(uc)->uc_mcontext.__fpregs.__fp_psr =			\
191 		    (ss)->ss_fpstate.fpf_fpsr;				\
192 		(uc)->uc_mcontext.__fpregs.__fp_piaddr =		\
193 		    (ss)->ss_fpstate.fpf_fpiar;				\
194 		(uc)->uc_flags |= _UC_FPU;				\
195 	} else								\
196 		(uc)->uc_flags &= ~_UC_FPU;				\
197 } while (/*CONSTCOND*/0)
198 
199 /*
200  * Stack frame layout when delivering a signal.
201  */
202 struct sigframe {
203 	int	sf_ra;			/* handler return address */
204 	int	sf_signum;		/* signal number for handler */
205 	int	sf_code;		/* additional info for handler */
206 	struct sigcontext *sf_scp;	/* context pointer for handler */
207 	struct sigcontext sf_sc;	/* actual context */
208 	struct sigstate sf_state;	/* state of the hardware */
209 };
210 #endif /* _KERNEL && __M68K_SIGNAL_PRIVATE */
211 
212 #endif	/* _NETBSD_SOURCE */
213 #endif	/* !_M68K_SIGNAL_H_ */
214