summaryrefslogtreecommitdiffstats
path: root/meta/packages/qemu/qemu-0.9.0+cvs20070613/12_signal_powerpc_support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/qemu/qemu-0.9.0+cvs20070613/12_signal_powerpc_support.patch')
-rw-r--r--meta/packages/qemu/qemu-0.9.0+cvs20070613/12_signal_powerpc_support.patch401
1 files changed, 0 insertions, 401 deletions
diff --git a/meta/packages/qemu/qemu-0.9.0+cvs20070613/12_signal_powerpc_support.patch b/meta/packages/qemu/qemu-0.9.0+cvs20070613/12_signal_powerpc_support.patch
deleted file mode 100644
index d8d4198784..0000000000
--- a/meta/packages/qemu/qemu-0.9.0+cvs20070613/12_signal_powerpc_support.patch
+++ /dev/null
@@ -1,401 +0,0 @@
1#DPATCHLEVEL=1
2---
3# linux-user/signal.c | 371 ++++++++++++++++++++++++++++++++++++++++++++++++++++
4# 1 file changed, 371 insertions(+)
5#
6Index: qemu/linux-user/signal.c
7===================================================================
8--- qemu.orig/linux-user/signal.c 2007-06-13 11:51:54.000000000 +0100
9+++ qemu/linux-user/signal.c 2007-06-13 11:51:54.000000000 +0100
10@@ -2,6 +2,7 @@
11 * Emulation of Linux signals
12 *
13 * Copyright (c) 2003 Fabrice Bellard
14+ * Copyright (c) 2005 Josh Triplett <josh@psas.pdx.edu>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18@@ -16,6 +17,12 @@
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22+ *
23+ * Various portions adapted from the Linux kernel:
24+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
25+ * Derived from "arch/i386/kernel/signal.c"
26+ * Copyright (C) 1991, 1992 Linus Torvalds
27+ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
28 */
29 #include <stdlib.h>
30 #include <stdio.h>
31@@ -1964,6 +1971,370 @@ long do_rt_sigreturn(CPUState *env)
32 return -ENOSYS;
33 }
34
35+#elif defined(TARGET_PPC)
36+/* Adapted from the Linux kernel:
37+ * arch/ppc/kernel/signal.c
38+ * include/asm-ppc/elf.h
39+ * include/asm-ppc/ptrace.h
40+ * include/asm-ppc/sigcontext.h
41+ * include/asm-ppc/ucontext.h
42+ */
43+
44+/*
45+ * When we have signals to deliver, we set up on the
46+ * user stack, going down from the original stack pointer:
47+ * a sigregs struct
48+ * a sigcontext struct
49+ * a gap of __SIGNAL_FRAMESIZE bytes
50+ *
51+ * Each of these things must be a multiple of 16 bytes in size.
52+ *
53+ */
54+
55+#define TARGET_ELF_NGREG 48 /* includes nip, msr, lr, etc. */
56+#define TARGET_ELF_NFPREG 33 /* includes fpscr */
57+#define TARGET_ELF_NVRREG 33 /* includes vscr */
58+
59+/* General registers */
60+typedef unsigned long target_elf_greg_t;
61+typedef target_elf_greg_t target_elf_gregset_t[TARGET_ELF_NGREG];
62+
63+/* Floating point registers */
64+typedef double target_elf_fpreg_t;
65+typedef target_elf_fpreg_t target_elf_fpregset_t[TARGET_ELF_NFPREG];
66+
67+/* Altivec registers */
68+/* FIXME: Altivec not supported yet. */
69+/* typedef __vector128 elf_vrreg_t; */
70+typedef uint64_t target_elf_vrreg_t[2];
71+typedef target_elf_vrreg_t target_elf_vrregset_t[TARGET_ELF_NVRREG];
72+
73+struct target_mcontext {
74+ target_elf_gregset_t mc_gregs;
75+ target_elf_fpregset_t mc_fregs;
76+ /* The kernel calls this mc_pad, but does #define tramp mc_pad */
77+ target_ulong tramp[2];
78+ target_elf_vrregset_t mc_vregs __attribute__((__aligned__(16)));
79+};
80+
81+struct target_sigregs {
82+ struct target_mcontext mctx; /* all the register values */
83+ /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
84+ and 18 fp regs below sp before decrementing it. */
85+ int abigap[56];
86+};
87+
88+struct target_sigcontext {
89+ target_ulong _unused[4];
90+ uint32_t signal;
91+ target_ulong handler;
92+ target_ulong oldmask;
93+ struct target_pt_regs *regs;
94+};
95+
96+#define __SIGNAL_FRAMESIZE 64
97+
98+static int
99+save_user_regs(CPUState *env, struct target_mcontext *frame, int sigret)
100+{
101+ /* save general and floating-point registers */
102+#if 0 /* FIXME: handle floating-point, Altivec, SPE */
103+ CHECK_FULL_REGS(regs);
104+ preempt_disable();
105+ if (regs->msr & MSR_FP)
106+ giveup_fpu(current);
107+#ifdef CONFIG_ALTIVEC
108+ if (current->thread.used_vr && (regs->msr & MSR_VEC))
109+ giveup_altivec(current);
110+#endif /* CONFIG_ALTIVEC */
111+#ifdef CONFIG_SPE
112+ if (current->thread.used_spe && (regs->msr & MSR_SPE))
113+ giveup_spe(current);
114+#endif /* CONFIG_ALTIVEC */
115+ preempt_enable();
116+#endif /* 0 */
117+
118+ /* Note: this needs to be in the same order as target_pt_regs */
119+ if(!memcpy(&frame->mc_gregs, env->gpr,
120+ 32*sizeof(target_elf_greg_t))
121+ || __put_user(env->nip, &frame->mc_gregs[32])
122+ || __put_user(do_load_msr(env), &frame->mc_gregs[33])
123+ /* FIXME: || __put_user(orig_gpr3, &frame->mc_gregs[34]) */
124+ || __put_user(env->ctr, &frame->mc_gregs[35])
125+ || __put_user(env->lr, &frame->mc_gregs[36])
126+ || __put_user(do_load_xer(env), &frame->mc_gregs[37])
127+ || __put_user(do_load_cr(env), &frame->mc_gregs[38])
128+ || __put_user(env->spr[SPR_MQ], &frame->mc_gregs[39])
129+ /* FIXME: || __put_user(trap, &frame->mc_gregs[40]) */
130+ || __put_user(env->spr[SPR_DAR], &frame->mc_gregs[41])
131+ || __put_user(env->spr[SPR_DSISR], &frame->mc_gregs[42])
132+ /* FIXME: || __put_user(result, &frame->mc_gregs[43]) */)
133+ return 1;
134+
135+ if(!memcpy(&frame->mc_fregs, env->fpr,
136+ 32*sizeof(target_elf_fpreg_t))
137+ || __put_user(do_load_fpscr(env), &frame->mc_fregs[32]))
138+
139+ do_store_fpscr(env, 0, 0xFF); /* turn off all fp exceptions */
140+
141+#if 0 /* FIXME: handle Altivec, SPE */
142+#ifdef CONFIG_ALTIVEC
143+ /* save altivec registers */
144+ if (current->thread.used_vr) {
145+ if (!memcpy(&frame->mc_vregs, current->thread.vr,
146+ ELF_NVRREG * sizeof(vector128)))
147+ return 1;
148+ /* set MSR_VEC in the saved MSR value to indicate that
149+ frame->mc_vregs contains valid data */
150+ if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR]))
151+ return 1;
152+ }
153+ /* else assert((regs->msr & MSR_VEC) == 0) */
154+
155+ /* We always copy to/from vrsave, it's 0 if we don't have or don't
156+ * use altivec. Since VSCR only contains 32 bits saved in the least
157+ * significant bits of a vector, we "cheat" and stuff VRSAVE in the
158+ * most significant bits of that same vector. --BenH
159+ */
160+ if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
161+ return 1;
162+#endif /* CONFIG_ALTIVEC */
163+
164+#ifdef CONFIG_SPE
165+ /* save spe registers */
166+ if (current->thread.used_spe) {
167+ if (!memcpy(&frame->mc_vregs, current->thread.evr,
168+ ELF_NEVRREG * sizeof(u32)))
169+ return 1;
170+ /* set MSR_SPE in the saved MSR value to indicate that
171+ frame->mc_vregs contains valid data */
172+ if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR]))
173+ return 1;
174+ }
175+ /* else assert((regs->msr & MSR_SPE) == 0) */
176+
177+ /* We always copy to/from spefscr */
178+ if (__put_user(current->thread.spefscr, (u32 *)&frame->mc_vregs + ELF_NEVRREG))
179+ return 1;
180+#endif /* CONFIG_SPE */
181+#endif /* 0 */
182+
183+ if (sigret) {
184+ /* Set up the sigreturn trampoline: li r0,sigret; sc */
185+ if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
186+ || __put_user(0x44000002UL, &frame->tramp[1]))
187+ return 1;
188+#if 0
189+ flush_icache_range((unsigned long) &frame->tramp[0],
190+ (unsigned long) &frame->tramp[2]);
191+#endif
192+ }
193+
194+ return 0;
195+}
196+
197+static int
198+restore_user_regs(CPUState *env, struct target_mcontext *sr, int sig)
199+{
200+ target_ulong save_r2 = 0;
201+ target_ulong saved_xer;
202+ target_ulong saved_cr;
203+ double saved_fpscr;
204+
205+#if 0 /* FIXME: handle Altivec, SPE */
206+#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE)
207+ unsigned long msr;
208+#endif
209+#endif /* 0 */
210+
211+ /* backup/restore the TLS as we don't want it to be modified */
212+ if (!sig)
213+ save_r2 = env->gpr[2];
214+
215+ /* Copy all registers except MSR */
216+ /* Note: this needs to be in the same order as target_pt_regs */
217+ if(!memcpy(env->gpr, &sr->mc_gregs,
218+ 32*sizeof(target_elf_greg_t))
219+ || __get_user(env->nip, &sr->mc_gregs[32])
220+ /* FIXME: || __get_user(orig_gpr3, &sr->mc_gregs[34]) */
221+ || __get_user(env->ctr, &sr->mc_gregs[35])
222+ || __get_user(env->lr, &sr->mc_gregs[36])
223+ || __get_user(saved_xer, &sr->mc_gregs[37])
224+ || __get_user(saved_cr, &sr->mc_gregs[38])
225+ || __get_user(env->spr[SPR_MQ], &sr->mc_gregs[39])
226+ /* FIXME: || __get_user(trap, &sr->mc_gregs[40]) */
227+ || __get_user(env->spr[SPR_DAR], &sr->mc_gregs[41])
228+ || __get_user(env->spr[SPR_DSISR], &sr->mc_gregs[42])
229+ /* FIXME: || __get_user(result, &sr->mc_gregs[43]) */)
230+ return 1;
231+ do_store_xer(env, saved_xer);
232+ do_store_cr(env, saved_cr, 0xFF);
233+
234+ if (!sig)
235+ env->gpr[2] = save_r2;
236+
237+ /* The kernel delays restoring the floating-point registers until the
238+ * thread uses floating-point again. For simplicity, just restore the
239+ * registers now. */
240+ if(!memcpy(env->fpr, &sr->mc_fregs,
241+ 32*sizeof(target_elf_fpreg_t))
242+ || __get_user(saved_fpscr, &sr->mc_fregs[32]))
243+ return 1;
244+ do_store_fpscr(env, saved_fpscr, 0xFF);
245+
246+#if 0 /* FIXME: handle Altivec, SPE */
247+#ifdef CONFIG_ALTIVEC
248+ /* force the process to reload the altivec registers from
249+ current->thread when it next does altivec instructions */
250+ regs->msr &= ~MSR_VEC;
251+ if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
252+ /* restore altivec registers from the stack */
253+ if (!memcpy(current->thread.vr, &sr->mc_vregs,
254+ sizeof(sr->mc_vregs)))
255+ return 1;
256+ } else if (current->thread.used_vr)
257+ memset(&current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
258+
259+ /* Always get VRSAVE back */
260+ if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
261+ return 1;
262+#endif /* CONFIG_ALTIVEC */
263+
264+#ifdef CONFIG_SPE
265+ /* force the process to reload the spe registers from
266+ current->thread when it next does spe instructions */
267+ regs->msr &= ~MSR_SPE;
268+ if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) {
269+ /* restore spe registers from the stack */
270+ if (!memcpy(current->thread.evr, &sr->mc_vregs,
271+ ELF_NEVRREG * sizeof(u32)))
272+ return 1;
273+ } else if (current->thread.used_spe)
274+ memset(&current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
275+
276+ /* Always get SPEFSCR back */
277+ if (__get_user(current->thread.spefscr, (u32 *)&sr->mc_vregs + ELF_NEVRREG))
278+ return 1;
279+#endif /* CONFIG_SPE */
280+#endif /* 0 */
281+
282+#if 0 /* FIXME: handle floating-point, Altivec, SPE */
283+#ifndef CONFIG_SMP
284+ preempt_disable();
285+ if (last_task_used_math == current)
286+ last_task_used_math = NULL;
287+ if (last_task_used_altivec == current)
288+ last_task_used_altivec = NULL;
289+ if (last_task_used_spe == current)
290+ last_task_used_spe = NULL;
291+ preempt_enable();
292+#endif
293+#endif /* 0 */
294+ return 0;
295+}
296+
297+static void setup_frame(int sig, struct emulated_sigaction *ka,
298+ target_sigset_t *oldset, CPUState *env)
299+{
300+ struct target_sigcontext *sc;
301+ struct target_sigregs *frame;
302+ target_ulong origsp = env->gpr[1];
303+ target_ulong newsp = origsp;
304+
305+ /* Set up Signal Frame */
306+ newsp -= sizeof(struct target_sigregs);
307+ frame = (struct target_sigregs *) newsp;
308+
309+ /* Put a sigcontext on the stack */
310+ newsp -= sizeof(*sc);
311+ sc = (struct target_sigcontext *) newsp;
312+
313+ /* create a stack frame for the caller of the handler */
314+ newsp -= __SIGNAL_FRAMESIZE;
315+
316+ if (!access_ok(VERIFY_WRITE, (void *) newsp, origsp - newsp))
317+ goto badframe;
318+
319+#if TARGET_NSIG != 64
320+#error "Please adjust handle_signal()"
321+#endif
322+ if (__put_user((target_ulong) ka->sa._sa_handler, &sc->handler)
323+ || __put_user(oldset->sig[0], &sc->oldmask)
324+ || __put_user(oldset->sig[1], &sc->_unused[3])
325+ || __put_user(frame, (target_ulong *)&sc->regs)
326+ || __put_user(sig, &sc->signal))
327+ goto badframe;
328+
329+ if (save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn))
330+ goto badframe;
331+
332+ if (put_user(env->gpr[1], (unsigned long *)newsp))
333+ goto badframe;
334+ env->gpr[1] = newsp;
335+ env->gpr[3] = sig;
336+ env->gpr[4] = (unsigned long) sc;
337+ env->nip = (unsigned long) ka->sa._sa_handler;
338+ env->lr = (unsigned long) frame->mctx.tramp;
339+ /* FIXME: env->trap = 0; */
340+
341+ return;
342+
343+badframe:
344+#ifdef DEBUG_SIGNAL
345+ fprintf(stderr,
346+ "badframe in handle_signal, frame=%p newsp=%lx\n",
347+ frame, newsp);
348+#endif
349+ force_sig(TARGET_SIGSEGV);
350+}
351+
352+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
353+ target_siginfo_t *info,
354+ target_sigset_t *set, CPUState *env)
355+{
356+ fprintf(stderr, "setup_rt_frame: not implemented\n");
357+}
358+
359+long do_sigreturn(CPUState *env)
360+{
361+ struct target_sigcontext *sc;
362+ struct target_sigcontext sigctx;
363+ struct target_mcontext *sr;
364+ target_sigset_t set;
365+ sigset_t host_set;
366+
367+ /* Always make any pending restarted system calls return -EINTR */
368+#if 0 /* FIXME */
369+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
370+#endif
371+
372+ sc = (struct target_sigcontext *)(env->gpr[1] + __SIGNAL_FRAMESIZE);
373+ if (!memcpy(&sigctx, sc, sizeof(sigctx)))
374+ goto badframe;
375+
376+ set.sig[0] = sigctx.oldmask;
377+ set.sig[1] = sigctx._unused[3];
378+ target_to_host_sigset_internal(&host_set, &set);
379+ sigprocmask(SIG_SETMASK, &host_set, NULL);
380+
381+ sr = (struct target_mcontext *) tswapl((target_ulong)sigctx.regs);
382+ if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
383+ || restore_user_regs(env, sr, 1))
384+ goto badframe;
385+
386+ return 0;
387+
388+badframe:
389+ force_sig(TARGET_SIGSEGV);
390+ return 0;
391+}
392+
393+long do_rt_sigreturn(CPUState *env)
394+{
395+ fprintf(stderr, "do_rt_sigreturn: not implemented\n");
396+ return -ENOSYS;
397+}
398+
399 #else
400
401 static void setup_frame(int sig, struct emulated_sigaction *ka,