2 Copyright © 2017, The AROS Development Team. All rights reserved.
8 #include <aros/config.h>
10 #if defined(__AROSEXEC_SMP__)
11 #include <proto/exec.h>
12 #define __KERNEL_NOLIBBASE__
13 #include <proto/kernel.h>
15 #include <exec/rawfmt.h>
17 #include "kernel_base.h"
18 #include "kernel_intern.h"
19 #include "kernel_debug.h"
22 #define __AROS_KERNEL__
24 #include "exec_intern.h"
28 extern BOOL
Exec_InitETask(struct Task
*, struct Task
*, struct ExecBase
*);
31 void cpu_PrepareExec(struct ExecBase
*SysBase
)
33 struct Task
*currentTask
;
37 * Setup the available CPU Mask in ExecBase,
38 * and mark the boot CPU as available
40 SystemCPUMask
= KrnAllocCPUMask();
41 KrnGetCPUMask(0, SystemCPUMask
);
43 PrivExecBase(SysBase
)->CPUMask
= SystemCPUMask
;
46 * make sure all current tasks have affinity masks
48 currentTask
= FindTask(NULL
);
49 IntETask(currentTask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
= KrnAllocCPUMask();
50 KrnGetCPUMask(0, IntETask(currentTask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
);
52 ForeachNode(&SysBase
->TaskReady
, currentTask
)
54 IntETask(currentTask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
= KrnAllocCPUMask();
55 KrnGetCPUMask(0, IntETask(currentTask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
);
57 ForeachNode(&SysBase
->TaskWait
, currentTask
)
59 IntETask(currentTask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
= KrnAllocCPUMask();
60 KrnGetCPUMask(0, IntETask(currentTask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
);
63 PrivExecBase(SysBase
)->IntFlags
|= EXECF_CPUAffinity
;
66 struct Task
*cpu_InitBootStrap(cpuid_t cpuNo
)
68 struct ExceptionContext
*bsctx
;
70 #define bstask ((struct Task *)(ml->ml_ME[0].me_Addr))
71 #define bstaskmlsize (sizeof(struct MemList) + sizeof(struct MemEntry))
74 /* Build bootstraps memory list */
75 if ((ml
= AllocMem(bstaskmlsize
, MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
77 bug("[Kernel:%03u] FATAL : Failed to allocate memory for bootstrap task", cpuNo
);
81 ml
->ml_NumEntries
= 2;
83 ml
->ml_ME
[0].me_Length
= sizeof(struct Task
);
84 if ((ml
->ml_ME
[0].me_Addr
= AllocMem(sizeof(struct Task
), MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
86 bug("[Kernel:%03u] FATAL : Failed to allocate task for bootstrap", cpuNo
);
87 FreeMem(ml
, bstaskmlsize
);
91 D(bug("[Kernel:%03u] %s: Bootstrap task @ 0x%p\n", cpuNo
, __func__
, bstask
));
93 NEWLIST(&bstask
->tc_MemEntry
);
94 AddHead(&bstask
->tc_MemEntry
, &ml
->ml_Node
);
96 if ((bsctx
= KrnCreateContext()) == NULL
)
98 bug("[Kernel:%03u] FATAL : Failed to create the bootstrap Task context\n", cpuNo
);
99 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
100 FreeMem(ml
, bstaskmlsize
);
104 D(bug("[Kernel:%03u] %s: CPU Ctx @ 0x%p\n", cpuNo
, __func__
, bsctx
));
107 ml
->ml_ME
[1].me_Length
= 20;
108 if ((ml
->ml_ME
[1].me_Addr
= AllocMem(20, MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
110 bug("[Kernel:%03u] FATAL : Failed to allocate the bootstrap Task name\n", cpuNo
);
111 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
112 FreeMem(ml
, bstaskmlsize
);
116 bstask
->tc_Node
.ln_Name
= ml
->ml_ME
[1].me_Addr
;
117 bstNameArg
[0] = cpuNo
;
118 RawDoFmt("CPU #%03u Bootstrap", (RAWARG
)bstNameArg
, RAWFMTFUNC_STRING
, bstask
->tc_Node
.ln_Name
);
120 bstask
->tc_Node
.ln_Type
= NT_TASK
;
121 bstask
->tc_Node
.ln_Pri
= 0;
122 bstask
->tc_State
= TS_READY
;
123 bstask
->tc_SigAlloc
= 0xFFFF;
125 /* Create an ETask structure and attach CPU context */
126 if (!Exec_InitETask(bstask
, NULL
, SysBase
))
128 bug("[Kernel:%03u] FATAL : Failed to initialize bootstrap ETask\n", cpuNo
);
129 FreeMem(ml
->ml_ME
[1].me_Addr
, ml
->ml_ME
[1].me_Length
);
130 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
131 FreeMem(ml
, bstaskmlsize
);
134 bstask
->tc_UnionETask
.tc_ETask
->et_RegFrame
= bsctx
;
136 /* the bootstrap can only run on this CPU */
137 IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuNumber
= cpuNo
;
138 IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
= KrnAllocCPUMask();
139 if (!IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
)
141 bug("[Kernel:%03u] FATAL : Failed to initialize bootstrap CPU Affinity\n", cpuNo
);
142 FreeMem(ml
->ml_ME
[1].me_Addr
, ml
->ml_ME
[1].me_Length
);
143 FreeMem(ml
->ml_ME
[0].me_Addr
, ml
->ml_ME
[0].me_Length
);
144 FreeMem(ml
, bstaskmlsize
);
147 KrnGetCPUMask(cpuNo
, IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuAffinity
);
155 void cpu_BootStrap(struct Task
*bstask
)
157 struct APICData
*apicData
= KernelBase
->kb_PlatformData
->kb_APIC
;
158 cpuid_t cpuNo
= KrnGetCPUNumber();
161 bug("[Kernel:%03u] %s()\n", cpuNo
, __func__
);
163 if (IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuNumber
!= cpuNo
)
164 bug("[Kernel:%03u] %s: bstask running on wrong CPU? (task cpu = %03u)\n", cpuNo
, __func__
, IntETask(bstask
->tc_UnionETask
.tc_ETask
)->iet_CpuNumber
);
167 bstask
->tc_State
= TS_RUN
;
168 SET_THIS_TASK(bstask
);
170 D(bug("[Kernel:%03u] %s: Leaving supervisor mode\n", cpuNo
, __func__
));
172 krnLeaveSupervisorRing(FLAGS_INTENABLED
);
174 D(bug("[Kernel:%03u] %s: Initialising APIC...\n", cpuNo
, __func__
));
175 core_APIC_Init(apicData
, cpuNo
);
178 bug("[Kernel:%03u] %s: Initialising Scheduler...\n", cpuNo
, __func__
);
179 bug("[Kernel:%03u] %s: Enabling Exec Interrupts...\n", cpuNo
, __func__
);
182 /* Let the system know this CPU is available .. */
183 KrnGetCPUMask(cpuNo
, PrivExecBase(SysBase
)->CPUMask
);
185 /* We now start up the interrupts */
189 D(bug("[Kernel:%03u] %s: Creating Idle Task ...\n", cpuNo
, __func__
));
191 Exec_X86CreateIdleTask(SysBase
);
193 D(bug("[Kernel:%03u] %s: Done\n", cpuNo
, __func__
));