2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Sets up the ExecBase a bit. (Mostly clearing).
9 #include <aros/asmcall.h>
10 #include <aros/debug.h>
11 #include <aros/kernel.h>
12 #include <clib/macros.h>
13 #include <exec/types.h>
14 #include <exec/lists.h>
15 #include <exec/memory.h>
16 #include <exec/memheaderext.h>
17 #include <exec/resident.h>
18 #include <exec/execbase.h>
19 #include <exec/libraries.h>
20 #include <aros/arossupportbase.h>
24 #include <proto/alib.h>
25 #include <proto/exec.h>
26 #include <proto/kernel.h>
28 #include LC_LIBDEFS_FILE
31 #include "exec_util.h"
32 #include "exec_debug.h"
33 #include "exec_intern.h"
35 #undef kprintf /* This can't be used in the code here */
37 extern void *LIBFUNCTABLE[];
39 extern struct Resident Exec_resident; /* Need this for lib_IdString */
41 extern void Exec_TrapHandler(ULONG trapNum);
42 AROS_LD3(ULONG, MakeFunctions,
43 AROS_LDA(APTR, target, A0),
44 AROS_LDA(CONST_APTR, functionArray, A1),
45 AROS_LDA(CONST_APTR, funcDispBase, A2),
46 struct ExecBase *, SysBase, 15, Exec);
48 /* Default finaliser. */
49 static void Exec_TaskFinaliser(void)
51 /* Get rid of current task. */
59 void _aros_not_implemented(char *X)
61 kprintf("Unsupported function at offset -0x%h in %s\n",
62 ABS(*(WORD *)((&X)[-1]-2)),
63 ((struct Library *)(&X)[-2])->lib_Node.ln_Name);
66 struct Library *PrepareAROSSupportBase (struct MemHeader *mh)
68 struct AROSSupportBase *AROSSupportBase;
70 AROSSupportBase = Allocate(mh, sizeof(struct AROSSupportBase));
72 AROSSupportBase->kprintf = (void *)kprintf;
73 AROSSupportBase->rkprintf = (void *)rkprintf;
74 AROSSupportBase->vkprintf = (void *)vkprintf;
76 AROSSupportBase->StdOut = NULL;
77 AROSSupportBase->DebugConfig = NULL;
79 return (struct Library *)AROSSupportBase;
82 BOOL IsSysBaseValid(struct ExecBase *sysbase)
87 if (((IPTR)sysbase) & 0x80000001)
90 if (sysbase->ChkBase != ~(IPTR)sysbase)
92 if (sysbase->SoftVer != VERSION_NUMBER)
95 return GetSysBaseChkSum(sysbase) == 0xffff;
98 UWORD GetSysBaseChkSum(struct ExecBase *sysbase)
101 UWORD *p = (UWORD*)&sysbase->SoftVer;
102 while (p <= &sysbase->ChkSum)
107 void SetSysBaseChkSum(void)
109 SysBase->ChkBase=~(IPTR)SysBase;
111 SysBase->ChkSum = GetSysBaseChkSum(SysBase) ^ 0xffff;
114 static APTR allocmem(struct MemHeader *mh, ULONG size, ULONG attributes)
118 if (mh->mh_Attributes & MEMF_MANAGED)
120 struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh;
123 ret = mhe->mhe_Alloc(mhe, size, &attributes);
129 ret = stdAlloc(mh, NULL, size, attributes, NULL, NULL);
136 * PrepareExecBase() will initialize the ExecBase to default values.
137 * MemHeader and ExecBase itself will already be added to appropriate
138 * lists. You don't need to do this yourself.
140 * WARNING: this routine intentionally sets up global SysBase.
141 * This is done because:
142 * 1. PrepareAROSSupportBase() calls Allocate() which relies on functional SysBase
143 * 2. After PrepareAROSSupportBase() it is possible to call debug output functions
144 * (kprintf() etc). Yes, KernelBase is not set up yet, but remember that kernel.resource
145 * may have patched functions in AROSSupportBase so that KernelBase is not needed there.
146 * 3. Existing ports (at least UNIX-hosted and Windows-hosted) rely on the fact that SysBase is
149 * Resume: please be extremely careful, study existing code, and think five times if you decide to
150 * change this. You WILL break existing ports if you do not modify their code accordingly. There's
151 * nothing really bad in the fact that global SysBase is touched here and changing this does not
152 * really win something.
153 * Pavel Fedin <pavel_fedin@mail.ru>
155 struct ExecBase *PrepareExecBase(struct MemHeader *mh, struct TagItem *msg)
158 VOID **fp = LIBFUNCTABLE;
159 APTR ColdCapture = NULL, CoolCapture = NULL, WarmCapture = NULL;
160 APTR KickMemPtr = NULL, KickTagPtr = NULL, KickCheckSum = NULL;
167 * Copy reset proof pointers if old SysBase is valid.
168 * Additional platform-specific code is needed in order to test
169 * address validity. This routine should zero out SysBase if it is invalid.
171 if (IsSysBaseValid(SysBase))
173 ColdCapture = SysBase->ColdCapture;
174 CoolCapture = SysBase->CoolCapture;
175 WarmCapture = SysBase->WarmCapture;
176 KickMemPtr = SysBase->KickMemPtr;
177 KickTagPtr = SysBase->KickTagPtr;
178 KickCheckSum = SysBase->KickCheckSum;
181 /* Calculate the size of the vector table */
182 while (*fp++ != (VOID *) -1) negsize += LIB_VECTSIZE;
184 /* Align library base */
185 negsize = AROS_ALIGN(negsize);
187 /* Allocate memory for library base */
188 mem = allocmem(mh, negsize + sizeof(struct IntExecBase), MEMF_CLEAR);
192 SysBase = mem + negsize;
194 #ifdef HAVE_PREPAREPLATFORM
195 /* Setup platform-specific data */
196 if (!Exec_PreparePlatform(&PD(SysBase), msg))
200 /* Setup function vectors */
201 AROS_CALL3(ULONG, AROS_SLIB_ENTRY(MakeFunctions, Exec, 15),
202 AROS_UFCA(APTR, SysBase, A0),
203 AROS_UFCA(CONST_APTR, LIBFUNCTABLE, A1),
204 AROS_UFCA(CONST_APTR, NULL, A2),
205 struct ExecBase *, SysBase);
207 /* Set default values */
208 SysBase->LibNode.lib_Node.ln_Type = NT_LIBRARY;
209 SysBase->LibNode.lib_Node.ln_Pri = -100;
210 SysBase->LibNode.lib_Node.ln_Name = (char *)Exec_resident.rt_Name;
211 SysBase->LibNode.lib_IdString = (char *)Exec_resident.rt_IdString;
212 SysBase->LibNode.lib_Version = VERSION_NUMBER;
213 SysBase->LibNode.lib_Revision = REVISION_NUMBER;
214 SysBase->LibNode.lib_OpenCnt = 1;
215 SysBase->LibNode.lib_NegSize = negsize;
216 SysBase->LibNode.lib_PosSize = sizeof(struct IntExecBase);
217 SysBase->LibNode.lib_Flags = LIBF_CHANGED | LIBF_SUMUSED;
219 NEWLIST(&SysBase->MemList);
220 SysBase->MemList.lh_Type = NT_MEMORY;
222 NEWLIST(&SysBase->ResourceList);
223 SysBase->ResourceList.lh_Type = NT_RESOURCE;
225 NEWLIST(&SysBase->DeviceList);
226 SysBase->DeviceList.lh_Type = NT_DEVICE;
228 NEWLIST(&SysBase->IntrList);
229 SysBase->IntrList.lh_Type = NT_INTERRUPT;
231 NEWLIST(&SysBase->LibList);
232 SysBase->LibList.lh_Type = NT_LIBRARY;
234 /* Add exec.library to system library list */
235 ADDHEAD(&SysBase->LibList, &SysBase->LibNode.lib_Node);
237 NEWLIST(&SysBase->PortList);
238 SysBase->PortList.lh_Type = NT_MSGPORT;
240 NEWLIST(&SysBase->TaskReady);
241 SysBase->TaskReady.lh_Type = NT_TASK;
243 NEWLIST(&SysBase->TaskWait);
244 SysBase->TaskWait.lh_Type = NT_TASK;
246 NEWLIST(&SysBase->SemaphoreList);
247 SysBase->SemaphoreList.lh_Type = NT_SEMAPHORE;
249 NEWLIST(&SysBase->ex_MemHandlers);
251 for (i = 0; i < 5; i++)
253 NEWLIST(&SysBase->SoftInts[i].sh_List);
254 SysBase->SoftInts[i].sh_List.lh_Type = NT_INTERRUPT;
257 NEWLIST(&PrivExecBase(SysBase)->ResetHandlers);
258 NEWLIST(&PrivExecBase(SysBase)->AllocMemList);
259 NEWLIST(&PrivExecBase(SysBase)->AllocatorCtxList);
261 InitSemaphore(&PrivExecBase(SysBase)->MemListSem);
262 InitSemaphore(&PrivExecBase(SysBase)->LowMemSem);
264 /* No need to initialize those locks. Just a reminder, if it becomes necessary in the future */
265 //ResetSpin(&PrivExecBase(SysBase)->semaphore_spinlock, 1);
266 //ResetSpin(&PrivExecBase(SysBase)->LibList_spinlock, 1);
268 SysBase->SoftVer = VERSION_NUMBER;
269 SysBase->Quantum = 4;
270 SysBase->TaskTrapCode = Exec_TrapHandler;
271 SysBase->TaskExceptCode = NULL;
272 SysBase->TaskExitCode = Exec_TaskFinaliser;
273 SysBase->TaskSigAlloc = 0xFFFF;
274 SysBase->TaskTrapAlloc = 0;
276 /* Parse some arguments from command line */
277 args = (char *)LibGetTagData(KRN_CmdLine, 0, msg);
283 * Enable mungwall before the first AllocMem().
284 * Yes, we have actually already called stdAlloc() once
285 * in order to allocate memory for SysBase itself, however
286 * this is not a real problem because it is never going
289 * We store mungwall setting in private flags because it must not be
290 * switched at runtime (or hard crash will happen).
292 opts = strcasestr(args, "mungwall");
294 PrivExecBase(SysBase)->IntFlags = EXECF_MungWall;
296 opts = strcasestr(args, "stacksnoop");
298 PrivExecBase(SysBase)->IntFlags = EXECF_StackSnoop;
301 * Parse system runtime debug flags.
302 * These are public. In future they will be editable by prefs program.
303 * However in order to be able to turn them on during early startup,
304 * we apply them also here.
306 opts = strcasestr(args, "sysdebug=");
308 SysBase->ex_DebugFlags = ParseFlags(&opts[9], ExecFlagNames);
311 NEWLIST(&PrivExecBase(SysBase)->TaskStorageSlots);
313 NEWLIST(&PrivExecBase(SysBase)->CPUList);
318 /* Add our initial MemHeader */
319 ADDHEAD(&SysBase->MemList, &mh->mh_Node);
321 /* Bring back saved values (or NULLs) */
322 SysBase->ColdCapture = ColdCapture;
323 SysBase->CoolCapture = CoolCapture;
324 SysBase->WarmCapture = WarmCapture;
325 SysBase->KickMemPtr = KickMemPtr;
326 SysBase->KickTagPtr = KickTagPtr;
327 SysBase->KickCheckSum = KickCheckSum;
329 SysBase->DebugAROSBase = PrepareAROSSupportBase(mh);