2 Copyright © 2015-2017, 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"
19 #if defined(__AROSEXEC_SMP__)
20 extern BOOL
Exec_InitETask(struct Task
*, struct Task
*, struct ExecBase
*);
22 struct Task
*cpu_InitBootStrap(struct ExecBase
*SysBase
)
24 struct ExceptionContext
*bsctx
;
26 #define bstask ((struct Task *)(ml->ml_ME[0].me_Addr))
27 #define bstaskmlsize (sizeof(struct MemList) + sizeof(struct MemEntry))
28 cpuid_t cpunum
= GetCPUNumber();
30 /* Build bootstraps memory list */
31 if ((ml
= AllocMem(bstaskmlsize
, MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
33 bug("[Kernel:%02d] FATAL : Failed to allocate memory for bootstrap task", cpunum
);
37 ml
->ml_NumEntries
= 2;
39 ml
->ml_ME
[0].me_Length
= sizeof(struct Task
);
40 if ((ml
->ml_ME
[0].me_Addr
= AllocMem(sizeof(struct Task
), MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
42 bug("[Kernel:%02d] FATAL : Failed to allocate task for bootstrap", cpunum
);
43 FreeMem(ml
, bstaskmlsize
);
47 /* allocate some stack space for user mode .. */
48 ml
->ml_ME
[1].me_Length
= 15 + (sizeof(IPTR
) * 128);
49 if ((ml
->ml_ME
[1].me_Addr
= AllocMem(ml
->ml_ME
[1].me_Length
, MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
51 bug("[Kernel:%02d] FATAL : Failed to allocate stack for bootstrap task", cpunum
);
52 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
53 FreeMem(ml
, bstaskmlsize
);
56 bstask
->tc_SPLower
= (APTR
)(((unsigned int )ml
->ml_ME
[1].me_Addr
+ 15) & ~0xF);
57 bstask
->tc_SPUpper
= bstask
->tc_SPLower
+ (sizeof(IPTR
) * 128);
59 AddHead(&bstask
->tc_MemEntry
, &ml
->ml_Node
);
61 D(bug("[Kernel:%02d] Bootstrap task @ 0x%p\n", cpunum
, bstask
));
63 if ((bsctx
= KrnCreateContext()) == NULL
)
65 bug("[Kernel:%02d] FATAL : Failed to create the bootstrap Task context\n", cpunum
);
66 FreeMem(ml
->ml_ME
[1].me_Addr
, ml
->ml_ME
[1].me_Length
);
67 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
68 FreeMem(ml
, bstaskmlsize
);
72 D(bug("[Kernel:%02d] CPU Ctx @ 0x%p\n", cpunum
, bsctx
));
74 NEWLIST(&bstask
->tc_MemEntry
);
76 if ((bstask
->tc_Node
.ln_Name
= AllocVec(20, MEMF_CLEAR
)) != NULL
)
78 sprintf(bstask
->tc_Node
.ln_Name
, "CPU #%02d Bootstrap", cpunum
);
80 bstask
->tc_Node
.ln_Type
= NT_TASK
;
81 bstask
->tc_Node
.ln_Pri
= 0;
82 bstask
->tc_State
= TS_READY
;
83 bstask
->tc_SigAlloc
= 0xFFFF;
85 /* Create a ETask structure and attach CPU context */
86 if (!Exec_InitETask(bstask
, NULL
, SysBase
))
88 bug("[Kernel:%02d] FATAL : Failed to initialize bootstrap ETask\n", cpunum
);
89 FreeVec(bstask
->tc_Node
.ln_Name
);
90 FreeMem(ml
->ml_ME
[1].me_Addr
, ml
->ml_ME
[1].me_Length
);
91 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
92 FreeMem(ml
, bstaskmlsize
);
95 bstask
->tc_UnionETask
.tc_ETask
->et_RegFrame
= bsctx
;
97 /* the bootstrap can only run on this CPU */
98 IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuNumber
= cpunum
;
99 IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
= (1 << cpunum
);
102 bsctx
->lr
= SysBase
->TaskExitCode
;
109 void cpu_BootStrap(struct Task
*bstask
, struct ExecBase
*SysBase
)
111 bstask
->tc_State
= TS_RUN
;
112 SET_THIS_TASK(bstask
);