Release 1.1.5.
[wine/multimedia.git] / server / context_alpha.c
blobdd24c6db2957842c91259f6d2d9dfbd551d730a0
1 /*
2 * Alpha register context support
4 * Copyright (C) 2004 Vincent BĂ©ron
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
23 #ifdef __ALPHA__
25 #include <assert.h>
26 #include <errno.h>
27 #ifdef HAVE_SYS_REG_H
28 # include <sys/reg.h>
29 #endif
30 #include <stdarg.h>
31 #include <unistd.h>
32 #ifdef HAVE_SYS_PTRACE_H
33 # include <sys/ptrace.h>
34 #endif
36 #include "file.h"
37 #include "thread.h"
38 #include "request.h"
40 #if 0 /* no longer used */
42 #ifdef HAVE_SYS_USER_H
43 # include <sys/user.h>
44 #endif
46 /* user definitions from asm/user.h */
47 struct kernel_user_struct
49 unsigned long regs[EF_SIZE/8+32];
50 size_t u_tsize;
51 size_t u_dsize;
52 size_t u_ssize;
53 unsigned long start_code;
54 unsigned long start_data;
55 unsigned long start_stack;
56 long int signal;
57 struct regs * u_ar0;
58 unsigned long magic;
59 char u_comm[32];
62 /* get thread context */
63 static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context )
65 int pid = get_ptrace_pid(thread);
66 if (flags & CONTEXT_FULL)
68 struct kernel_user_struct regs;
69 if (ptrace( PTRACE_GETREGS, pid, 0, &regs ) == -1) goto error;
70 if (flags & CONTEXT_INTEGER)
72 context->IntV0 = regs.regs[EF_V0];
73 context->IntT0 = regs.regs[EF_T0];
74 context->IntT1 = regs.regs[EF_T1];
75 context->IntT2 = regs.regs[EF_T2];
76 context->IntT3 = regs.regs[EF_T3];
77 context->IntT4 = regs.regs[EF_T4];
78 context->IntT5 = regs.regs[EF_T5];
79 context->IntT6 = regs.regs[EF_T6];
80 context->IntT7 = regs.regs[EF_T7];
81 context->IntS0 = regs.regs[EF_S0];
82 context->IntS1 = regs.regs[EF_S1];
83 context->IntS2 = regs.regs[EF_S2];
84 context->IntS3 = regs.regs[EF_S3];
85 context->IntS4 = regs.regs[EF_S4];
86 context->IntS5 = regs.regs[EF_S5];
87 context->IntFp = regs.regs[EF_S6];
88 context->IntA0 = regs.regs[EF_A0];
89 context->IntA1 = regs.regs[EF_A1];
90 context->IntA2 = regs.regs[EF_A2];
91 context->IntA3 = regs.regs[EF_A3];
92 context->IntA4 = regs.regs[EF_A4];
93 context->IntA5 = regs.regs[EF_A5];
94 context->IntT8 = regs.regs[EF_T8];
95 context->IntT9 = regs.regs[EF_T9];
96 context->IntT10 = regs.regs[EF_T10];
97 context->IntT11 = regs.regs[EF_T11];
98 context->IntT12 = regs.regs[EF_T12];
99 context->IntAt = regs.regs[EF_AT];
100 context->IntZero = 0;
102 if (flags & CONTEXT_CONTROL)
104 context->IntRa = regs.regs[EF_RA];
105 context->IntGp = regs.regs[EF_GP];
106 context->IntSp = regs.regs[EF_SP];
107 context->Fir = regs.regs[EF_PC];
108 context->Psr = regs.regs[EF_PS];
110 if (flags & CONTEXT_FLOATING_POINT)
112 context->FltF0 = regs.regs[EF_SIZE/8+0];
113 context->FltF1 = regs.regs[EF_SIZE/8+1];
114 context->FltF2 = regs.regs[EF_SIZE/8+2];
115 context->FltF3 = regs.regs[EF_SIZE/8+3];
116 context->FltF4 = regs.regs[EF_SIZE/8+4];
117 context->FltF5 = regs.regs[EF_SIZE/8+5];
118 context->FltF6 = regs.regs[EF_SIZE/8+6];
119 context->FltF7 = regs.regs[EF_SIZE/8+7];
120 context->FltF8 = regs.regs[EF_SIZE/8+8];
121 context->FltF9 = regs.regs[EF_SIZE/8+9];
122 context->FltF10 = regs.regs[EF_SIZE/8+10];
123 context->FltF11 = regs.regs[EF_SIZE/8+11];
124 context->FltF12 = regs.regs[EF_SIZE/8+12];
125 context->FltF13 = regs.regs[EF_SIZE/8+13];
126 context->FltF14 = regs.regs[EF_SIZE/8+14];
127 context->FltF15 = regs.regs[EF_SIZE/8+15];
128 context->FltF16 = regs.regs[EF_SIZE/8+16];
129 context->FltF17 = regs.regs[EF_SIZE/8+17];
130 context->FltF18 = regs.regs[EF_SIZE/8+18];
131 context->FltF19 = regs.regs[EF_SIZE/8+19];
132 context->FltF20 = regs.regs[EF_SIZE/8+20];
133 context->FltF21 = regs.regs[EF_SIZE/8+21];
134 context->FltF22 = regs.regs[EF_SIZE/8+22];
135 context->FltF23 = regs.regs[EF_SIZE/8+23];
136 context->FltF24 = regs.regs[EF_SIZE/8+24];
137 context->FltF25 = regs.regs[EF_SIZE/8+25];
138 context->FltF26 = regs.regs[EF_SIZE/8+26];
139 context->FltF27 = regs.regs[EF_SIZE/8+27];
140 context->FltF28 = regs.regs[EF_SIZE/8+28];
141 context->FltF29 = regs.regs[EF_SIZE/8+29];
142 context->FltF30 = regs.regs[EF_SIZE/8+30];
143 context->FltF31 = 0;
144 context->Fpcr = regs.regs[EF_SIZE/8+31];
145 context->SoftFpcr = 0; /* FIXME */
147 context->ContextFlags |= flags & CONTEXT_FULL;
149 return;
150 error:
151 file_set_error();
154 /* set a thread context */
155 static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
157 int pid = get_ptrace_pid(thread);
158 if (flags & CONTEXT_FULL)
160 struct kernel_user_struct regs;
161 if (ptrace( PTRACE_GETREGS, pid, 0, &regs ) == -1) goto error;
162 if (flags & CONTEXT_INTEGER)
164 regs.regs[EF_V0] = context->IntV0;
165 regs.regs[EF_T0] = context->IntT0;
166 regs.regs[EF_T1] = context->IntT1;
167 regs.regs[EF_T2] = context->IntT2;
168 regs.regs[EF_T3] = context->IntT3;
169 regs.regs[EF_T4] = context->IntT4;
170 regs.regs[EF_T5] = context->IntT5;
171 regs.regs[EF_T6] = context->IntT6;
172 regs.regs[EF_T7] = context->IntT7;
173 regs.regs[EF_S0] = context->IntS0;
174 regs.regs[EF_S1] = context->IntS1;
175 regs.regs[EF_S2] = context->IntS2;
176 regs.regs[EF_S3] = context->IntS3;
177 regs.regs[EF_S4] = context->IntS4;
178 regs.regs[EF_S5] = context->IntS5;
179 regs.regs[EF_S6] = context->IntFp;
180 regs.regs[EF_A0] = context->IntA0;
181 regs.regs[EF_A1] = context->IntA1;
182 regs.regs[EF_A2] = context->IntA2;
183 regs.regs[EF_A3] = context->IntA3;
184 regs.regs[EF_A4] = context->IntA4;
185 regs.regs[EF_A5] = context->IntA5;
186 regs.regs[EF_T8] = context->IntT8;
187 regs.regs[EF_T9] = context->IntT9;
188 regs.regs[EF_T10] = context->IntT10;
189 regs.regs[EF_T11] = context->IntT11;
190 regs.regs[EF_T12] = context->IntT12;
191 regs.regs[EF_AT] = context->IntAt;
193 if (flags & CONTEXT_CONTROL)
195 regs.regs[EF_RA] = context->IntRa;
196 regs.regs[EF_GP] = context->IntGp;
197 regs.regs[EF_SP] = context->IntSp;
198 regs.regs[EF_PC] = context->Fir;
199 regs.regs[EF_PS] = context->Psr;
201 if (flags & CONTEXT_FLOATING_POINT)
203 regs.regs[EF_SIZE/8+0] = context->FltF0;
204 regs.regs[EF_SIZE/8+1] = context->FltF1;
205 regs.regs[EF_SIZE/8+2] = context->FltF2;
206 regs.regs[EF_SIZE/8+3] = context->FltF3;
207 regs.regs[EF_SIZE/8+4] = context->FltF4;
208 regs.regs[EF_SIZE/8+5] = context->FltF5;
209 regs.regs[EF_SIZE/8+6] = context->FltF6;
210 regs.regs[EF_SIZE/8+7] = context->FltF7;
211 regs.regs[EF_SIZE/8+8] = context->FltF8;
212 regs.regs[EF_SIZE/8+9] = context->FltF9;
213 regs.regs[EF_SIZE/8+10] = context->FltF10;
214 regs.regs[EF_SIZE/8+11] = context->FltF11;
215 regs.regs[EF_SIZE/8+12] = context->FltF12;
216 regs.regs[EF_SIZE/8+13] = context->FltF13;
217 regs.regs[EF_SIZE/8+14] = context->FltF14;
218 regs.regs[EF_SIZE/8+15] = context->FltF15;
219 regs.regs[EF_SIZE/8+16] = context->FltF16;
220 regs.regs[EF_SIZE/8+17] = context->FltF17;
221 regs.regs[EF_SIZE/8+18] = context->FltF18;
222 regs.regs[EF_SIZE/8+19] = context->FltF19;
223 regs.regs[EF_SIZE/8+20] = context->FltF20;
224 regs.regs[EF_SIZE/8+21] = context->FltF21;
225 regs.regs[EF_SIZE/8+22] = context->FltF22;
226 regs.regs[EF_SIZE/8+23] = context->FltF23;
227 regs.regs[EF_SIZE/8+24] = context->FltF24;
228 regs.regs[EF_SIZE/8+25] = context->FltF25;
229 regs.regs[EF_SIZE/8+26] = context->FltF26;
230 regs.regs[EF_SIZE/8+27] = context->FltF27;
231 regs.regs[EF_SIZE/8+28] = context->FltF28;
232 regs.regs[EF_SIZE/8+29] = context->FltF29;
233 regs.regs[EF_SIZE/8+30] = context->FltF30;
234 regs.regs[EF_SIZE/8+31] = context->Fpcr;
236 if (ptrace( PTRACE_SETREGS, pid, 0, &regs ) == -1) goto error;
238 return;
239 error:
240 file_set_error();
243 #endif /* 0 */
245 /* copy a context structure according to the flags */
246 void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
248 flags &= ~CONTEXT_ALPHA; /* get rid of CPU id */
249 if (flags & CONTEXT_CONTROL)
251 to->IntRa = from->IntRa;
252 to->IntGp = from->IntGp;
253 to->IntSp = from->IntSp;
254 to->Fir = from->Fir;
255 to->Psr = from->Psr;
257 if (flags & CONTEXT_INTEGER)
259 to->IntV0 = from->IntV0;
260 to->IntT0 = from->IntT0;
261 to->IntT1 = from->IntT1;
262 to->IntT2 = from->IntT2;
263 to->IntT3 = from->IntT3;
264 to->IntT4 = from->IntT4;
265 to->IntT5 = from->IntT5;
266 to->IntT6 = from->IntT6;
267 to->IntT7 = from->IntT7;
268 to->IntS0 = from->IntS0;
269 to->IntS1 = from->IntS1;
270 to->IntS2 = from->IntS2;
271 to->IntS3 = from->IntS3;
272 to->IntS4 = from->IntS4;
273 to->IntS5 = from->IntS5;
274 to->IntFp = from->IntFp;
275 to->IntA0 = from->IntA0;
276 to->IntA1 = from->IntA1;
277 to->IntA2 = from->IntA2;
278 to->IntA3 = from->IntA3;
279 to->IntA4 = from->IntA4;
280 to->IntA5 = from->IntA5;
281 to->IntT8 = from->IntT8;
282 to->IntT9 = from->IntT9;
283 to->IntT10 = from->IntT10;
284 to->IntT11 = from->IntT11;
285 to->IntT12 = from->IntT12;
286 to->IntAt = from->IntAt;
287 to->IntZero = from->IntZero;
289 if (flags & CONTEXT_FLOATING_POINT)
291 to->FltF0 = from->FltF0;
292 to->FltF1 = from->FltF1;
293 to->FltF2 = from->FltF2;
294 to->FltF3 = from->FltF3;
295 to->FltF4 = from->FltF4;
296 to->FltF5 = from->FltF5;
297 to->FltF6 = from->FltF6;
298 to->FltF7 = from->FltF7;
299 to->FltF8 = from->FltF8;
300 to->FltF9 = from->FltF9;
301 to->FltF10 = from->FltF10;
302 to->FltF11 = from->FltF11;
303 to->FltF12 = from->FltF12;
304 to->FltF13 = from->FltF13;
305 to->FltF14 = from->FltF14;
306 to->FltF15 = from->FltF15;
307 to->FltF16 = from->FltF16;
308 to->FltF17 = from->FltF17;
309 to->FltF18 = from->FltF18;
310 to->FltF19 = from->FltF19;
311 to->FltF20 = from->FltF20;
312 to->FltF21 = from->FltF21;
313 to->FltF22 = from->FltF22;
314 to->FltF23 = from->FltF23;
315 to->FltF24 = from->FltF24;
316 to->FltF25 = from->FltF25;
317 to->FltF26 = from->FltF26;
318 to->FltF27 = from->FltF27;
319 to->FltF28 = from->FltF28;
320 to->FltF29 = from->FltF29;
321 to->FltF30 = from->FltF30;
322 to->FltF31 = from->FltF31;
323 to->Fpcr = from->Fpcr;
324 to->SoftFpcr = from->SoftFpcr;
326 to->ContextFlags |= flags;
329 /* retrieve the current instruction pointer of a context */
330 void *get_context_ip( const CONTEXT *context )
332 return (void *)context->Fir;
335 /* return the context flag that contains the CPU id */
336 unsigned int get_context_cpu_flag(void)
338 return CONTEXT_ALPHA;
341 /* return only the context flags that correspond to system regs */
342 /* (system regs are the ones we can't access on the client side) */
343 unsigned int get_context_system_regs( unsigned int flags )
345 return 0; /* FIXME: implement client-side handling */
348 #endif /* __ALPHA__ */