prism2.device: Compiler delint
[AROS.git] / arch / all-linux / kernel / cpu_x86_64.h
blobce195f826eeb16cf6f7cf45ccf9f06614a41d056
1 #ifndef _SIGCORE_H
2 #define _SIGCORE_H
4 /*
5 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
6 $Id$
8 Desc: Macros to handle unix signals, x86_64 version.
9 Lang: english
12 #include <aros/x86_64/cpucontext.h>
14 #ifdef __AROS_EXEC_LIBRARY__
16 struct ucontext;
18 #else
20 /* There's no need for USE_SA_SIGINFO, as we always use SA_SIGINFO
21 on x86_64 - there's no other sane way to get ucontext. */
22 #define SIGCORE_NEED_SA_SIGINFO 1
24 /* Make _GNU_SOURCE work */
25 #undef _FEATURES_H
26 /* We want to use some predefined register names */
27 #define _GNU_SOURCE
29 #include <ucontext.h>
30 #include <signal.h>
31 #include <stddef.h>
32 #include <strings.h>
34 #ifndef _SIGNAL_H
35 #define _SIGNAL_H
36 #endif
37 #ifndef __KERNEL_STRICT_NAMES
38 #define __KERNEL_STRICT_NAMES
39 #endif
40 #include <bits/sigcontext.h>
42 /* name and type of the signal handler */
43 #define SIGHANDLER linux_sighandler
44 #define SIGHANDLER_T __sighandler_t
47 This macro contains some magic necessary to make it work.
48 The problem is that Linux offers no official way to obtain the
49 signals' context. Linux stores the signals' context on the
50 process' stack. It looks like this:
51 Attention: As of version 2.2 of the Linux kernel there is
52 not enough room on the stack anymore to save
53 any registers on it. So everything has to go into
54 the context structure. Previously PC and FP used
55 to be saved on the stack but now this would over-
56 write some return address.
57 The stack you see below is the stack of the last
58 active task within AROS. The linux kernel puts
59 all kinds of other junk on it.
61 | |
62 +--------------------------+
63 | last entry before signal |
64 +--------------------------+
65 | signal context |
66 +--------------------------+
67 | signal number |
68 +--------------------------+
69 | return address |
70 +--------------------------+
71 | |
73 so the address of the signal context is &sig+1.
75 Well, we use the SIGCORE_NEED_SA_SIGINFO approach, so part of
76 the above is only kept for historical reasons.
79 #define GLOBAL_SIGNAL_INIT(sighandler) \
80 static void sighandler ## _gate (int sig, siginfo_t *blub, void *u) \
81 { \
82 sighandler(sig, u); \
86 Macros to access the stack pointer, frame pointer and program
87 counter. The FP is the base address for accesses to arguments
88 and local variables of a function and PC is the current address
89 in the program code.
92 #define SP(uc) ((uc)->uc_mcontext.gregs[REG_RSP])
93 #define FP(uc) ((uc)->uc_mcontext.gregs[REG_RBP])
94 #define PC(uc) ((uc)->uc_mcontext.gregs[REG_RIP])
97 Macros to enable or disable all signals after the signal handler
98 has returned and the normal execution commences.
100 On Linux x86-64 signal mask is restored from uc_sigmask field of ucontext
101 structure.
103 #define SC_DISABLE(uc) uc->uc_sigmask = KernelBase->kb_PlatformData->sig_int_mask
104 #define SC_ENABLE(uc) pd->iface->SigEmptySet(&uc->uc_sigmask)
107 The names of the general purpose registers which are to be saved.
108 Use R and a number as name, no matter what the real name is.
109 General purpose registers (GPRs) are registers which can be
110 modified by the task (ie. data and address registers) and which are
111 not saved by the CPU when an interrupt happens.
113 #define R0(uc) ((uc)->uc_mcontext.gregs[REG_RAX])
114 #define R1(uc) ((uc)->uc_mcontext.gregs[REG_RBX])
115 #define R2(uc) ((uc)->uc_mcontext.gregs[REG_RCX])
116 #define R3(uc) ((uc)->uc_mcontext.gregs[REG_RDX])
117 #define R4(uc) ((uc)->uc_mcontext.gregs[REG_RDI])
118 #define R5(uc) ((uc)->uc_mcontext.gregs[REG_RSI])
119 #define R6(uc) ((uc)->uc_mcontext.gregs[REG_EFL])
120 #define R8(uc) ((uc)->uc_mcontext.gregs[REG_R8])
121 #define R9(uc) ((uc)->uc_mcontext.gregs[REG_R9])
122 #define R10(uc) ((uc)->uc_mcontext.gregs[REG_R10])
123 #define R11(uc) ((uc)->uc_mcontext.gregs[REG_R11])
124 #define R12(uc) ((uc)->uc_mcontext.gregs[REG_R12])
125 #define R13(uc) ((uc)->uc_mcontext.gregs[REG_R13])
126 #define R14(uc) ((uc)->uc_mcontext.gregs[REG_R14])
127 #define R15(uc) ((uc)->uc_mcontext.gregs[REG_R15])
130 Save and restore the CPU GPRs in the CPU context
132 #define SAVE_CPU(cc, sc) \
133 cc.rax = R0(sc); \
134 cc.rbx = R1(sc); \
135 cc.rcx = R2(sc); \
136 cc.rdx = R3(sc); \
137 cc.rdi = R4(sc); \
138 cc.rsi = R5(sc); \
139 cc.rflags = R6(sc); \
140 cc.r8 = R8(sc); \
141 cc.r9 = R9(sc); \
142 cc.r10 = R10(sc); \
143 cc.r11 = R11(sc); \
144 cc.r12 = R12(sc); \
145 cc.r13 = R13(sc); \
146 cc.r14 = R14(sc); \
147 cc.r15 = R15(sc); \
148 cc.rbp = FP(sc); \
149 cc.rip = PC(sc); \
150 cc.rsp = SP(sc);
153 * Restore CPU registers.
154 * Note that we do not restore segment registers because they
155 * are of own use by Linux.
157 #define RESTORE_CPU(cc, sc) \
158 R0(sc) = cc.rax; \
159 R1(sc) = cc.rbx; \
160 R2(sc) = cc.rcx; \
161 R3(sc) = cc.rdx; \
162 R4(sc) = cc.rdi; \
163 R5(sc) = cc.rsi; \
164 R6(sc) = cc.rflags; \
165 R8(sc) = cc.r8; \
166 R9(sc) = cc.r9; \
167 R10(sc) = cc.r10; \
168 R11(sc) = cc.r11; \
169 R12(sc) = cc.r12; \
170 R13(sc) = cc.r13; \
171 R14(sc) = cc.r14; \
172 R15(sc) = cc.r15; \
173 FP(sc) = cc.rbp; \
174 PC(sc) = cc.rip; \
175 SP(sc) = cc.rsp;
178 * Save all registers from UNIX signal context to AROS context.
179 * Save also SSE state if the context has buffer. ECF_FPX will be set
180 * if SSE state was copied.
182 #define SAVEREGS(cc, sc) \
183 SAVE_CPU((cc)->regs, sc); \
184 if (sc->uc_mcontext.fpregs && (cc)->regs.FXData) \
186 (cc)->regs.Flags |= ECF_FPX; \
187 CopyMemQuick(sc->uc_mcontext.fpregs, (cc)->regs.FXData, sizeof(struct FPXContext)); \
191 * Restore all registers from AROS context to UNIX signal context.
192 * Check context flags to decide whether to restore SSE or not.
194 #define RESTOREREGS(cc, sc) \
195 RESTORE_CPU((cc)->regs, sc); \
196 if ((cc)->regs.Flags & ECF_FPX) \
197 CopyMemQuick((cc)->regs.FXData, sc->uc_mcontext.fpregs, sizeof(struct FPXContext));
199 /* Print signal context. Used in crash handler. */
200 #define PRINT_SC(sc) \
201 bug (" RSP=%016lx RBP=%016lx RIP=%016lx\n" \
202 " RAX=%016lx RBX=%016lx RCX=%016lx RDX=%016lx\n" \
203 " RDI=%016lx RSI=%016lx RFLAGS=%016lx\n" \
204 " R8 =%016lx R9 =%016lx R10=%016lx R11=%016lx\n" \
205 " R12=%016lx R13=%016lx R14=%016lx R15=%016lx\n" \
206 , SP(sc), FP(sc), PC(sc) \
207 , R0(sc), R1(sc), R2(sc), R3(sc) \
208 , R4(sc), R5(sc), R6(sc), R8(sc), R9(sc) \
209 , R10(sc), R11(sc), R12(sc), R13(sc), R14(sc), R15(sc) \
212 #endif /* __AROS_EXEC_LIBRARY__ */
214 #define EXCEPTIONS_COUNT 17
216 typedef struct ucontext regs_t;
218 /* Use this structure to save/restore registers */
219 struct AROSCPUContext
221 struct ExceptionContext regs;
222 int errno_backup;
225 #endif /* _SIGCORE_H */