add the common pc IRQTYPE definitions, and copy them for both the 32bit and 64bit...
[AROS.git] / arch / all-pc / kernel / smp_exec.c
blob41ec78cd83f89bf0c3936ecea40f1319af7f996a
1 /*
2 Copyright © 2017, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
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"
20 #include "apic.h"
22 #define __AROS_KERNEL__
24 #include "exec_intern.h"
26 #include "etask.h"
28 extern BOOL Exec_InitETask(struct Task *, struct Task *, struct ExecBase *);
31 void cpu_PrepareExec(struct ExecBase *SysBase)
33 struct Task *currentTask;
34 void *SystemCPUMask;
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;
69 struct MemList *ml;
70 #define bstask ((struct Task *)(ml->ml_ME[0].me_Addr))
71 #define bstaskmlsize (sizeof(struct MemList) + sizeof(struct MemEntry))
72 IPTR bstNameArg[1];
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);
78 return NULL;
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);
88 return NULL;
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);
101 return NULL;
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);
113 return NULL;
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);
132 return NULL;
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);
145 return NULL;
147 KrnGetCPUMask(cpuNo, IntETask(bstask->tc_UnionETask.tc_ETask)->iet_CpuAffinity);
149 bsctx->Flags = 0;
151 return bstask;
152 #undef bstask
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 */
186 Permit();
187 Enable();
189 D(bug("[Kernel:%03u] %s: Creating Idle Task ...\n", cpuNo, __func__));
191 Exec_X86CreateIdleTask(SysBase);
193 if (apicData->flags & APF_TIMER)
194 ictl_enable_irq((APIC_IRQ_HEARTBEAT - HW_IRQ_BASE), KernelBase);
196 D(bug("[Kernel:%03u] %s: Done\n", cpuNo, __func__));
198 #endif