Forward compatibility: build relative-base link libraries where needed
[AROS.git] / arch / ppc-sam440 / exec / preparecontext.c
blob706530b2b439ce48052148e21e21393e57a27932
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <exec/execbase.h>
7 #include <exec/memory.h>
8 #include <utility/tagitem.h>
9 #include <asm/amcc440.h>
10 #include <proto/kernel.h>
12 #include "exec_intern.h"
13 #include "exec_util.h"
15 #define DEBUG 0
17 #include <aros/libcall.h>
18 #include <aros/debug.h>
20 BOOL PrepareContext(struct Task *task, APTR entryPoint, APTR fallBack,
21 const struct TagItem *tagList, struct ExecBase *SysBase)
23 context_t *ctx;
24 IPTR *sp=(IPTR *)((IPTR)task->tc_SPReg & 0xfffffff0);
25 IPTR args[8] = {0};
26 WORD numargs = 0;
28 /* Reserve some space for the fallBack routine's stack frame */
29 sp -= 4;
31 /* Mark the end of the stack frames */
32 sp[0] = sp[1] = 0;
34 while(tagList)
36 switch(tagList->ti_Tag)
38 case TAG_MORE:
39 tagList = (const struct TagItem *)tagList->ti_Data;
40 continue;
42 case TAG_SKIP:
43 tagList += tagList->ti_Data;
44 break;
46 case TAG_DONE:
47 tagList = NULL;
48 break;
50 #define HANDLEARG(x) \
51 case TASKTAG_ARG ## x: \
52 args[x - 1] = (IPTR)tagList->ti_Data; \
53 if (x > numargs) numargs = x; \
54 break;
56 HANDLEARG(1)
57 HANDLEARG(2)
58 HANDLEARG(3)
59 HANDLEARG(4)
60 HANDLEARG(5)
61 HANDLEARG(6)
62 HANDLEARG(7)
63 HANDLEARG(8)
65 #undef HANDLEARG
68 if (tagList) tagList++;
71 if (!(task->tc_Flags & TF_ETASK) )
72 return FALSE;
74 /* Get the memory for CPU context. */
75 task->tc_UnionETask.tc_ETask->et_RegFrame = KrnCreateContext();
77 D(bug("[exec] PrepareContext: et_RegFrame = %012p\n", task->tc_UnionETask.tc_ETask->et_RegFrame));
79 if (!(ctx = (context_t *)task->tc_UnionETask.tc_ETask->et_RegFrame))
80 return FALSE;
82 if (numargs)
84 switch (numargs)
86 case 8:
87 ctx->cpu.gpr[10] = args[7];
88 case 7:
89 ctx->cpu.gpr[9] = args[6];
90 case 6:
91 ctx->cpu.gpr[8] = args[5];
92 case 5:
93 ctx->cpu.gpr[7] = args[4];
94 case 4:
95 ctx->cpu.gpr[6] = args[3];
96 case 3:
97 ctx->cpu.gpr[5] = args[2];
98 case 2:
99 ctx->cpu.gpr[4] = args[1];
100 case 1:
101 ctx->cpu.gpr[3] = args[0];
102 break;
106 /* Push fallBack address */
107 ctx->cpu.lr = (IPTR)fallBack;
109 * Task will be started upon interrupt resume. Push entrypoint into SRR0
110 * and the MSR register into SRR1. Enable FPU at the beginning
112 ctx->cpu.srr0 = (IPTR)entryPoint;
113 ctx->cpu.srr1 = MSR_PR | MSR_EE | MSR_CE | MSR_ME;
114 ctx->cpu.srr1 |= MSR_FP;
115 ctx->cpu.gpr[1] = (IPTR)sp;
117 /* We storage SysBase in %r2
118 * This is needed for Parthenope fixup, and is a nice place to store
119 * it anyway, since the PowerPC ABI says this is a 'do not touch'
120 * register.
122 ctx->cpu.gpr[2] = (IPTR)SysBase;
124 task->tc_SPReg = sp;
126 D(bug("[exec] New context:\n[exec] SRR0=%08x, SRR1=%08x\n",ctx->cpu.srr0, ctx->cpu.srr1));
127 D(bug("[exec] GPR00=%08x GPR01=%08x GPR02=%08x GPR03=%08x\n",
128 ctx->cpu.gpr[0],ctx->cpu.gpr[1],ctx->cpu.gpr[2],ctx->cpu.gpr[3]));
129 D(bug("[exec] GPR04=%08x GPR05=%08x GPR06=%08x GPR07=%08x\n",
130 ctx->cpu.gpr[4],ctx->cpu.gpr[5],ctx->cpu.gpr[6],ctx->cpu.gpr[7]));
131 D(bug("[exec] GPR08=%08x GPR09=%08x GPR10=%08x GPR11=%08x\n",
132 ctx->cpu.gpr[8],ctx->cpu.gpr[9],ctx->cpu.gpr[10],ctx->cpu.gpr[11]));
133 D(bug("[exec] GPR12=%08x GPR13=%08x GPR14=%08x GPR15=%08x\n",
134 ctx->cpu.gpr[12],ctx->cpu.gpr[13],ctx->cpu.gpr[14],ctx->cpu.gpr[15]));
136 D(bug("[exec] GPR16=%08x GPR17=%08x GPR18=%08x GPR19=%08x\n",
137 ctx->cpu.gpr[16],ctx->cpu.gpr[17],ctx->cpu.gpr[18],ctx->cpu.gpr[19]));
138 D(bug("[exec] GPR20=%08x GPR21=%08x GPR22=%08x GPR23=%08x\n",
139 ctx->cpu.gpr[20],ctx->cpu.gpr[21],ctx->cpu.gpr[22],ctx->cpu.gpr[23]));
140 D(bug("[exec] GPR24=%08x GPR25=%08x GPR26=%08x GPR27=%08x\n",
141 ctx->cpu.gpr[24],ctx->cpu.gpr[25],ctx->cpu.gpr[26],ctx->cpu.gpr[27]));
142 D(bug("[exec] GPR28=%08x GPR29=%08x GPR30=%08x GPR31=%08x\n",
143 ctx->cpu.gpr[28],ctx->cpu.gpr[29],ctx->cpu.gpr[30],ctx->cpu.gpr[31]));
145 return TRUE;