Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / i386-pc / exec / preparecontext.c
blob9cba06099c089b3eda30f95f69a4a41dab89dbdd
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: i386unix 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 <sigcore.h>
14 #include "etask.h"
15 #include "exec_util.h"
17 #include <aros/libcall.h>
18 #include <asm/ptrace.h>
19 #include <asm/segments.h>
21 #define Regs(t) ((struct pt_regs *)(GetIntETask(t)->iet_Context))
23 static ULONG *PrepareContext_Common(struct Task *task, APTR entryPoint, APTR fallBack,
24 struct TagItem *tagList, struct ExecBase *SysBase)
26 ULONG *regs;
27 IPTR *sp=(IPTR *)task->tc_SPReg;
28 IPTR args[8] = {0};
29 WORD numargs = 0;
31 while(tagList)
33 switch(tagList->ti_Tag)
35 case TAG_MORE:
36 tagList = (struct TagItem *)tagList->ti_Data;
37 continue;
39 case TAG_SKIP:
40 tagList += tagList->ti_Data;
41 break;
43 case TAG_DONE:
44 tagList = NULL;
45 break;
47 #define HANDLEARG(x) \
48 case TASKTAG_ARG ## x: \
49 args[x - 1] = (IPTR)tagList->ti_Data; \
50 if (x > numargs) numargs = x; \
51 break;
53 HANDLEARG(1)
54 HANDLEARG(2)
55 HANDLEARG(3)
56 HANDLEARG(4)
57 HANDLEARG(5)
58 HANDLEARG(6)
59 HANDLEARG(7)
60 HANDLEARG(8)
62 #undef HANDLEARG
65 if (tagList) tagList++;
68 if (!(task->tc_Flags & TF_ETASK) )
69 return NULL;
71 GetIntETask (task)->iet_Context = AllocTaskMem (task
72 , SIZEOF_ALL_REGISTERS
73 , MEMF_PUBLIC|MEMF_CLEAR
76 if (!(regs = (ULONG*)GetIntETask (task)->iet_Context))
77 return NULL;
79 if (numargs)
81 while(numargs--)
83 *--sp = args[numargs];
87 /* Push fallBack address */
89 *--sp = fallBack;
92 /* We have to prepare whole context right now so Dispatch()
93 * would work propertly */
95 *regs++ = 0; /* ebx */
96 *regs++ = 0; /* ecx */
97 *regs++ = 0; /* edx */
98 *regs++ = 0; /* esi */
99 *regs++ = 0; /* edi */
100 *regs++ = 0; /* ebp */
101 *regs++ = 0; /* eax */
102 *regs++ = USER_DS; /* xds */
103 *regs++ = USER_DS; /* xes */
104 *regs++ = (ULONG)entryPoint;/* eip */
105 *regs++ = USER_CS; /* xcs */
106 *regs++ = 0x3202; /* eflags */
107 *regs++ = (ULONG)sp; /* esp */
108 *regs++ = USER_DS; /* xss */
110 task->tc_SPReg = sp;
112 return regs;
115 AROS_LH4(BOOL, PrepareContext,
116 AROS_LHA(struct Task *, task, A0),
117 AROS_LHA(APTR, entryPoint, A1),
118 AROS_LHA(APTR, fallBack, A2),
119 AROS_LHA(struct TagItem *, tagList, A3),
120 struct ExecBase *, SysBase, 6, Exec)
122 AROS_LIBFUNC_INIT
124 return PrepareContext_Common(task, entryPoint, fallBack, tagList, SysBase) ? TRUE : FALSE;
126 AROS_LIBFUNC_EXIT
129 #warning This needs to be fixed/updated if the way library params are passed is changed
131 BOOL Exec_PrepareContext_FPU(struct Task *task, APTR entryPoint, APTR fallBack, struct TagItem *tagList, struct ExecBase *SysBase)
133 ULONG *regs;
134 BOOL retval = FALSE;
136 if ((regs = PrepareContext_Common(task, entryPoint, fallBack, tagList, SysBase)))
138 UBYTE this_fpustate[SIZEOF_FPU_STATE];
140 asm volatile("fnsave %1\n\t"
141 "fwait\n\t"
142 "fninit\n\t"
143 "fnsave %0\n\t"
144 "fwait\n\t"
145 "frstor %1\n\t"
146 "fwait\n\t" : "=m" (*regs), "=m" (this_fpustate) : : "memory");
148 retval = TRUE;
151 return retval;
155 BOOL Exec_PrepareContext_SSE(struct Task *task, APTR entryPoint, APTR fallBack, struct TagItem *tagList, struct ExecBase *SysBase)
157 ULONG *regs;
158 BOOL retval = FALSE;
160 if ((regs = PrepareContext_Common(task, entryPoint, fallBack, tagList, SysBase)))
162 UBYTE this_ssestate[SIZEOF_FPU_STATE + 15], *ptr = this_ssestate;
163 regs = (ULONG*)(((IPTR)regs+15)&~15);
164 ptr = (UBYTE*)(((IPTR)ptr+15)&~15);
166 asm volatile("fxsave (%0)\n\t"
167 "fninit\n\t"
168 "fwait\n\t"
169 "fxsave (%1)\n\t"
170 "fxrstor (%0)\n\t"
172 : "r" (ptr), "r" (regs)
173 : "memory");
175 retval = TRUE;
178 return retval;