2 Copyright © 2015-2016, 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 #define bstaskmlsize (sizeof(struct MemList) + sizeof(struct MemEntry))
27 cpuid_t cpunum
= GetCPUNumber();
29 /* Build bootstraps memory list */
30 if ((ml
= AllocMem(bstaskmlsize
, MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
32 bug("[Kernel:%02d] FATAL : Failed to allocate memory for bootstrap task", cpunum
);
36 ml
->ml_NumEntries
= 2;
38 ml
->ml_ME
[0].me_Length
= sizeof(struct Task
);
39 if ((ml
->ml_ME
[0].me_Addr
= AllocMem(sizeof(struct Task
), MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
41 bug("[Kernel:%02d] FATAL : Failed to allocate task for bootstrap", cpunum
);
42 FreeMem(ml
, bstaskmlsize
);
46 /* allocate some stack space for user mode .. */
47 ml
->ml_ME
[1].me_Length
= 15 + (sizeof(IPTR
) * 128);
48 if ((ml
->ml_ME
[1].me_Addr
= AllocMem(ml
->ml_ME
[1].me_Length
, MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
50 bug("[Kernel:%02d] FATAL : Failed to allocate stack for bootstrap task", cpunum
);
51 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
52 FreeMem(ml
, bstaskmlsize
);
55 bstask
->tc_SPLower
= (APTR
)(((unsigned int )ml
->ml_ME
[1].me_Addr
+ 15) & ~0xF);
56 bstask
->tc_SPUpper
= bstask
->tc_SPLower
+ (sizeof(IPTR
) * 128);
58 AddHead(&bstask
->tc_MemEntry
, &ml
->ml_Node
);
60 D(bug("[Kernel:%02d] Bootstrap task @ 0x%p\n", cpunum
, bstask
));
62 if ((bsctx
= KrnCreateContext()) == NULL
)
64 bug("[Kernel:%02d] FATAL : Failed to create the bootstrap Task context\n", cpunum
);
65 FreeMem(ml
->ml_ME
[1].me_Addr
, ml
->ml_ME
[1].me_Length
);
66 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
67 FreeMem(ml
, bstaskmlsize
);
71 D(bug("[Kernel:%02d] CPU Ctx @ 0x%p\n", cpunum
, bsctx
));
73 NEWLIST(&bstask
->tc_MemEntry
);
75 if ((bstask
->tc_Node
.ln_Name
= AllocVec(20, MEMF_CLEAR
)) != NULL
)
77 sprintf(bstask
->tc_Node
.ln_Name
, "CPU #%02d Bootstrap", cpunum
);
79 bstask
->tc_Node
.ln_Type
= NT_TASK
;
80 bstask
->tc_Node
.ln_Pri
= 0;
81 bstask
->tc_State
= TS_READY
;
82 bstask
->tc_SigAlloc
= 0xFFFF;
84 /* Create a ETask structure and attach CPU context */
85 if (!Exec_InitETask(bstask
, SysBase
))
87 bug("[Kernel:%02d] FATAL : Failed to initialize bootstrap ETask\n", cpunum
);
88 FreeVec(bstask
->tc_Node
.ln_Name
);
89 FreeMem(ml
->ml_ME
[1].me_Addr
, ml
->ml_ME
[1].me_Length
);
90 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
91 FreeMem(ml
, bstaskmlsize
);
94 bstask
->tc_UnionETask
.tc_ETask
->et_RegFrame
= bsctx
;
96 /* the bootstrap can only run on this CPU */
97 IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuNumber
= cpunum
;
98 IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
= (1 << cpunum
);
101 bsctx
->lr
= SysBase
->TaskExitCode
;
108 void cpu_BootStrap(struct Task
*bstask
, struct ExecBase
*SysBase
)
110 bstask
->tc_State
= TS_RUN
;
111 SET_THIS_TASK(bstask
);