2 Copyright © 2015, The AROS Development Team. All rights reserved.
6 #include <proto/kernel.h>
7 #include <proto/exec.h>
12 #include "exec_intern.h"
14 #include "kernel_cpu.h"
18 #if defined(__AROSEXEC_SMP__)
19 extern BOOL
Exec_InitETask(struct Task
*, struct ExecBase
*);
21 struct Task
*cpu_InitBootStrap(struct ExecBase
*SysBase
)
23 struct ExceptionContext
*bsctx
;
25 #define bstask ((struct Task *)(ml->ml_ME[0].me_Addr))
26 cpuid_t cpunum
= GetCPUNumber();
28 /* Build bootstraps memory list */
29 if ((ml
= AllocMem(sizeof(struct MemList
), MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
31 bug("[Kernel:%02d] FATAL : Failed to allocate memory for bootstrap task", cpunum
);
35 ml
->ml_NumEntries
= 2;
37 ml
->ml_ME
[0].me_Length
= sizeof(struct Task
);
38 if ((ml
->ml_ME
[0].me_Addr
= AllocMem(sizeof(struct Task
), MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
40 bug("[Kernel:%02d] FATAL : Failed to allocate task for bootstrap", cpunum
);
41 FreeMem(ml
, sizeof(struct MemList
));
45 /* allocate some stack space for user mode .. */
46 ml
->ml_ME
[1].me_Length
= 15 + (sizeof(IPTR
) * 128);
47 if ((ml
->ml_ME
[1].me_Addr
= AllocMem(ml
->ml_ME
[1].me_Length
, MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
49 bug("[Kernel:%02d] FATAL : Failed to allocate stack for bootstrap task", cpunum
);
50 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
51 FreeMem(ml
, sizeof(struct MemList
));
54 bstask
->tc_SPLower
= (APTR
)(((unsigned int )ml
->ml_ME
[1].me_Addr
+ 15) & ~0xF);
55 bstask
->tc_SPUpper
= bstask
->tc_SPLower
+ (sizeof(IPTR
) * 128);
57 AddHead(&bstask
->tc_MemEntry
, &ml
->ml_Node
);
59 D(bug("[Kernel:%02d] Bootstrap task @ 0x%p\n", cpunum
, bstask
));
61 if ((bsctx
= KrnCreateContext()) == NULL
)
63 bug("[Kernel:%02d] FATAL : Failed to create the boostrap Task context\n", cpunum
);
64 FreeMem(ml
->ml_ME
[1].me_Addr
, ml
->ml_ME
[1].me_Length
);
65 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
66 FreeMem(ml
, sizeof(struct MemList
));
70 D(bug("[Kernel:%02d] CPU Ctx @ 0x%p\n", cpunum
, bsctx
));
72 NEWLIST(&bstask
->tc_MemEntry
);
74 if ((bstask
->tc_Node
.ln_Name
= AllocVec(20, MEMF_CLEAR
)) != NULL
)
76 sprintf(bstask
->tc_Node
.ln_Name
, "CPU #%02d Bootstrap", cpunum
);
78 bstask
->tc_Node
.ln_Type
= NT_TASK
;
79 bstask
->tc_Node
.ln_Pri
= 0;
80 bstask
->tc_State
= TS_READY
;
81 bstask
->tc_SigAlloc
= 0xFFFF;
83 /* Create a ETask structure and attach CPU context */
84 if (!Exec_InitETask(bstask
, SysBase
))
86 bug("[Kernel:%02d] FATAL : Failed to initialize boostrap ETask\n", cpunum
);
87 FreeVec(bstask
->tc_Node
.ln_Name
);
88 FreeMem(ml
->ml_ME
[1].me_Addr
, ml
->ml_ME
[1].me_Length
);
89 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
90 FreeMem(ml
, sizeof(struct MemList
));
93 bstask
->tc_UnionETask
.tc_ETask
->et_RegFrame
= bsctx
;
95 /* the boostrap can only run on this cpu */
96 IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuNumber
= cpunum
;
97 IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
= (1 << cpunum
);
100 bsctx
->lr
= SysBase
->TaskExitCode
;
107 void cpu_BootStrap(struct Task
*bstask
, struct ExecBase
*SysBase
)
109 bstask
->tc_State
= TS_RUN
;
110 SET_THIS_TASK(bstask
);