Build fix.
[AROS.git] / arch / i386-pc / exec / preparecontext.c
blobfb5cc4031fd97d059d4a18be151182ec20ce75f9
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: i386 native version of PrepareContext().
6 Lang: english
7 */
9 #include <exec/types.h>
10 #include <exec/execbase.h>
11 #include <exec/memory.h>
12 #include <utility/tagitem.h>
13 #include "etask.h"
14 #include "exec_util.h"
16 #include <aros/libcall.h>
17 #include <asm/ptrace.h>
18 #include <asm/segments.h>
20 #define Regs(t) ((struct pt_regs *)(GetIntETask(t)->iet_Context))
22 static ULONG *PrepareContext_Common(struct Task *task, APTR entryPoint, APTR fallBack,
23 struct TagItem *tagList, struct ExecBase *SysBase)
25 ULONG *regs;
26 IPTR *sp=(IPTR *)task->tc_SPReg;
27 IPTR args[8] = {0};
28 WORD numargs = 0;
30 while(tagList)
32 switch(tagList->ti_Tag)
34 case TAG_MORE:
35 tagList = (struct TagItem *)tagList->ti_Data;
36 continue;
38 case TAG_SKIP:
39 tagList += tagList->ti_Data;
40 break;
42 case TAG_DONE:
43 tagList = NULL;
44 break;
46 #define HANDLEARG(x) \
47 case TASKTAG_ARG ## x: \
48 args[x - 1] = (IPTR)tagList->ti_Data; \
49 if (x > numargs) numargs = x; \
50 break;
52 HANDLEARG(1)
53 HANDLEARG(2)
54 HANDLEARG(3)
55 HANDLEARG(4)
56 HANDLEARG(5)
57 HANDLEARG(6)
58 HANDLEARG(7)
59 HANDLEARG(8)
61 #undef HANDLEARG
64 if (tagList) tagList++;
67 if (!(task->tc_Flags & TF_ETASK) )
68 return NULL;
70 GetIntETask (task)->iet_Context = AllocTaskMem (task
71 , SIZEOF_ALL_REGISTERS
72 , MEMF_PUBLIC|MEMF_CLEAR
75 if (!(regs = (ULONG*)GetIntETask (task)->iet_Context))
76 return NULL;
78 if (numargs)
80 while(numargs--)
82 *--sp = args[numargs];
86 /* Push fallBack address */
88 *--sp = (IPTR)fallBack;
91 /* We have to prepare whole context right now so Dispatch()
92 * would work propertly */
94 *regs++ = 0; /* ebx */
95 *regs++ = 0; /* ecx */
96 *regs++ = 0; /* edx */
97 *regs++ = 0; /* esi */
98 *regs++ = 0; /* edi */
99 *regs++ = 0; /* ebp */
100 *regs++ = 0; /* eax */
101 *regs++ = USER_DS; /* xds */
102 *regs++ = USER_DS; /* xes */
103 *regs++ = (ULONG)entryPoint;/* eip */
104 *regs++ = USER_CS; /* xcs */
105 *regs++ = 0x3202; /* eflags */
106 *regs++ = (ULONG)sp; /* esp */
107 *regs++ = USER_DS; /* xss */
109 task->tc_SPReg = sp;
111 return regs;
114 AROS_LH4(BOOL, PrepareContext,
115 AROS_LHA(struct Task *, task, A0),
116 AROS_LHA(APTR, entryPoint, A1),
117 AROS_LHA(APTR, fallBack, A2),
118 AROS_LHA(struct TagItem *, tagList, A3),
119 struct ExecBase *, SysBase, 6, Exec)
121 AROS_LIBFUNC_INIT
123 return PrepareContext_Common(task, entryPoint, fallBack, tagList, SysBase) ? TRUE : FALSE;
125 AROS_LIBFUNC_EXIT
128 /* FIXME: This needs to be fixed/updated if the way library params are passed is changed */
129 AROS_LH4(BOOL, PrepareContext_FPU,
130 AROS_LHA(struct Task *, task, A0),
131 AROS_LHA(APTR, entryPoint, A1),
132 AROS_LHA(APTR, fallBack, A2),
133 AROS_LHA(struct TagItem *, tagList, A3),
134 struct ExecBase *, SysBase, 6, Exec)
136 AROS_LIBFUNC_INIT
138 ULONG *regs;
139 BOOL retval = FALSE;
141 if ((regs = PrepareContext_Common(task, entryPoint, fallBack, tagList, SysBase)))
143 UBYTE this_fpustate[SIZEOF_FPU_STATE];
145 asm volatile("fnsave %1\n\t"
146 "fwait\n\t"
147 "fninit\n\t"
148 "fnsave %0\n\t"
149 "fwait\n\t"
150 "frstor %1\n\t"
151 "fwait\n\t" : "=m" (*regs), "=m" (this_fpustate) : : "memory");
153 retval = TRUE;
156 return retval;
158 AROS_LIBFUNC_EXIT
161 AROS_LH4(BOOL, PrepareContext_SSE,
162 AROS_LHA(struct Task *, task, A0),
163 AROS_LHA(APTR, entryPoint, A1),
164 AROS_LHA(APTR, fallBack, A2),
165 AROS_LHA(struct TagItem *, tagList, A3),
166 struct ExecBase *, SysBase, 6, Exec)
168 AROS_LIBFUNC_INIT
170 ULONG *regs;
171 BOOL retval = FALSE;
173 if ((regs = PrepareContext_Common(task, entryPoint, fallBack, tagList, SysBase)))
175 UBYTE this_ssestate[SIZEOF_FPU_STATE + 15], *ptr = this_ssestate;
176 regs = (ULONG*)(((IPTR)regs+15)&~15);
177 ptr = (UBYTE*)(((IPTR)ptr+15)&~15);
179 asm volatile("fxsave (%0)\n\t"
180 "fninit\n\t"
181 "fwait\n\t"
182 "fxsave (%1)\n\t"
183 "fxrstor (%0)\n\t"
185 : "r" (ptr), "r" (regs)
186 : "memory");
188 retval = TRUE;
191 return retval;
193 AROS_LIBFUNC_EXIT