Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / x86_64-pc / exec / preparecontext.c
blobebceb18c3166504dff568ab0995dd06ce7defdb2
1 #include <exec/types.h>
2 #include <exec/execbase.h>
3 #include <exec/memory.h>
4 #include <utility/tagitem.h>
5 #include <sigcore.h>
6 #include <asm/cpu.h>
7 #include "etask.h"
8 #include "exec_util.h"
10 #define DEBUG 1
12 #include <aros/libcall.h>
13 #include <aros/debug.h>
14 #include <asm/segments.h>
16 #define Regs(t) ((struct regs_t *)(GetIntETask(t)->iet_Context))
18 static UQUAD *PrepareContext_Common(struct Task *task, APTR entryPoint, APTR fallBack,
19 struct TagItem *tagList, struct ExecBase *SysBase)
21 regs_t *regs;
22 IPTR *sp=(IPTR *)task->tc_SPReg;
23 IPTR args[8] = {0};
24 WORD numargs = 0;
26 while(tagList)
28 switch(tagList->ti_Tag)
30 case TAG_MORE:
31 tagList = (struct TagItem *)tagList->ti_Data;
32 continue;
34 case TAG_SKIP:
35 tagList += tagList->ti_Data;
36 break;
38 case TAG_DONE:
39 tagList = NULL;
40 break;
42 #define HANDLEARG(x) \
43 case TASKTAG_ARG ## x: \
44 args[x - 1] = (IPTR)tagList->ti_Data; \
45 if (x > numargs) numargs = x; \
46 break;
48 HANDLEARG(1)
49 HANDLEARG(2)
50 HANDLEARG(3)
51 HANDLEARG(4)
52 HANDLEARG(5)
53 HANDLEARG(6)
54 HANDLEARG(7)
55 HANDLEARG(8)
57 #undef HANDLEARG
60 if (tagList) tagList++;
63 if (!(task->tc_Flags & TF_ETASK) )
64 return NULL;
66 GetIntETask (task)->iet_Context = AllocTaskMem (task
67 , SIZEOF_ALL_REGISTERS
68 , MEMF_PUBLIC|MEMF_CLEAR
71 D(bug("[exec] PrepareContext: iet_Context = %012p\n", GetIntETask (task)->iet_Context));
73 if (!(regs = (ULONG*)GetIntETask (task)->iet_Context))
74 return NULL;
76 if (numargs)
78 switch (numargs)
80 case 8:
81 *--sp = args[7];
82 case 7:
83 *--sp = args[6];
84 case 6:
85 regs->r9 = args[5];
86 case 5:
87 regs->r8 = args[4];
88 case 4:
89 regs->rcx = args[3];
90 case 3:
91 regs->rdx = args[2];
92 case 2:
93 regs->rsi = args[1];
94 case 1:
95 regs->rdi = args[0];
96 break;
100 /* Push fallBack address */
101 *--sp = fallBack;
103 regs->ds = USER_DS;
104 regs->return_rip = (IPTR)entryPoint;
105 regs->return_cs = USER_CS;
106 regs->return_rflags = 0x3202;
107 regs->return_ss = USER_DS;
108 regs->return_rsp = (IPTR)sp;
110 task->tc_SPReg = sp;
112 UBYTE current_xmm[512+16], *curr = current_xmm;
114 curr = (UBYTE*)(((IPTR)curr + 15) & ~15);
115 IPTR sse_ctx = ((IPTR)regs + sizeof(regs_t) + 15) & ~15;
117 asm volatile("fxsave (%0); fninit; fwait; fxsave (%1); fxrstor (%0);"::"r"(curr),"r"(sse_ctx));
119 return sp;
124 AROS_LH4(BOOL, PrepareContext,
125 AROS_LHA(struct Task *, task, A0),
126 AROS_LHA(APTR, entryPoint, A1),
127 AROS_LHA(APTR, fallBack, A2),
128 AROS_LHA(struct TagItem *, tagList, A3),
129 struct ExecBase *, SysBase, 6, Exec)
131 AROS_LIBFUNC_INIT
133 return PrepareContext_Common(task, entryPoint, fallBack, tagList, SysBase) ? TRUE : FALSE;
135 AROS_LIBFUNC_EXIT