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. */
52 RemTask(SysBase
->ThisTask
);
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;
115 * PrepareExecBase() will initialize the ExecBase to default values.
116 * MemHeader and ExecBase itself will already be added to appropriate
117 * lists. You don't need to do this yourself.
119 * WARNING: this routine intentionally sets up global SysBase.
120 * This is done because:
121 * 1. PrepareAROSSupportBase() calls Allocate() which relies on functional SysBase
122 * 2. After PrepareAROSSupportBase() it is possible to call debug output functions
123 * (kprintf() etc). Yes, KernelBase is not set up yet, but remember that kernel.resource
124 * may have patched functions in AROSSupportBase so that KernelBase is not needed there.
125 * 3. Existing ports (at least UNIX-hosted and Windows-hosted) rely on the fact that SysBase is
128 * Resume: please be extremely careful, study existing code, and think five times if you decide to
129 * change this. You WILL break existing ports if you do not modify their code accordingly. There's
130 * nothing really bad in the fact that global SysBase is touched here and changing this does not
131 * really win something.
132 * Pavel Fedin <pavel_fedin@mail.ru>
134 struct ExecBase
*PrepareExecBase(struct MemHeader
*mh
, struct TagItem
*msg
)
137 VOID
**fp
= LIBFUNCTABLE
;
138 APTR ColdCapture
= NULL
, CoolCapture
= NULL
, WarmCapture
= NULL
;
139 APTR KickMemPtr
= NULL
, KickTagPtr
= NULL
, KickCheckSum
= NULL
;
145 * Copy reset proof pointers if old SysBase is valid.
146 * Additional platform-specific code is needed in order to test
147 * address validity. This routine should zero out SysBase if it is invalid.
149 if (IsSysBaseValid(SysBase
))
151 ColdCapture
= SysBase
->ColdCapture
;
152 CoolCapture
= SysBase
->CoolCapture
;
153 WarmCapture
= SysBase
->WarmCapture
;
154 KickMemPtr
= SysBase
->KickMemPtr
;
155 KickTagPtr
= SysBase
->KickTagPtr
;
156 KickCheckSum
= SysBase
->KickCheckSum
;
159 /* Calculate the size of the vector table */
160 while (*fp
++ != (VOID
*) -1) negsize
+= LIB_VECTSIZE
;
162 /* Align library base */
163 negsize
= AROS_ALIGN(negsize
);
165 /* Allocate memory for library base */
166 mem
= stdAlloc(mh
, negsize
+ sizeof(struct IntExecBase
), MEMF_CLEAR
, NULL
, NULL
);
170 SysBase
= mem
+ negsize
;
172 #ifdef HAVE_PREPAREPLATFORM
173 /* Setup platform-specific data */
174 if (!Exec_PreparePlatform(&PD(SysBase
), msg
))
178 /* Setup function vectors */
179 AROS_CALL3(ULONG
, AROS_SLIB_ENTRY(MakeFunctions
, Exec
, 15),
180 AROS_UFCA(APTR
, SysBase
, A0
),
181 AROS_UFCA(CONST_APTR
, LIBFUNCTABLE
, A1
),
182 AROS_UFCA(CONST_APTR
, NULL
, A2
),
183 struct ExecBase
*, SysBase
);
185 /* Set default values */
186 SysBase
->LibNode
.lib_Node
.ln_Type
= NT_LIBRARY
;
187 SysBase
->LibNode
.lib_Node
.ln_Pri
= -100;
188 SysBase
->LibNode
.lib_Node
.ln_Name
= (char *)Exec_resident
.rt_Name
;
189 SysBase
->LibNode
.lib_IdString
= (char *)Exec_resident
.rt_IdString
;
190 SysBase
->LibNode
.lib_Version
= VERSION_NUMBER
;
191 SysBase
->LibNode
.lib_Revision
= REVISION_NUMBER
;
192 SysBase
->LibNode
.lib_OpenCnt
= 1;
193 SysBase
->LibNode
.lib_NegSize
= negsize
;
194 SysBase
->LibNode
.lib_PosSize
= sizeof(struct IntExecBase
);
195 SysBase
->LibNode
.lib_Flags
= LIBF_CHANGED
| LIBF_SUMUSED
;
197 NEWLIST(&SysBase
->MemList
);
198 SysBase
->MemList
.lh_Type
= NT_MEMORY
;
200 NEWLIST(&SysBase
->ResourceList
);
201 SysBase
->ResourceList
.lh_Type
= NT_RESOURCE
;
203 NEWLIST(&SysBase
->DeviceList
);
204 SysBase
->DeviceList
.lh_Type
= NT_DEVICE
;
206 NEWLIST(&SysBase
->IntrList
);
207 SysBase
->IntrList
.lh_Type
= NT_INTERRUPT
;
209 NEWLIST(&SysBase
->LibList
);
210 SysBase
->LibList
.lh_Type
= NT_LIBRARY
;
212 /* Add exec.library to system library list */
213 ADDHEAD(&SysBase
->LibList
, &SysBase
->LibNode
.lib_Node
);
215 NEWLIST(&SysBase
->PortList
);
216 SysBase
->PortList
.lh_Type
= NT_MSGPORT
;
218 NEWLIST(&SysBase
->TaskReady
);
219 SysBase
->TaskReady
.lh_Type
= NT_TASK
;
221 NEWLIST(&SysBase
->TaskWait
);
222 SysBase
->TaskWait
.lh_Type
= NT_TASK
;
224 NEWLIST(&SysBase
->SemaphoreList
);
225 SysBase
->TaskWait
.lh_Type
= NT_SEMAPHORE
;
227 NEWLIST(&SysBase
->ex_MemHandlers
);
229 for (i
= 0; i
< 5; i
++)
231 NEWLIST(&SysBase
->SoftInts
[i
].sh_List
);
232 SysBase
->SoftInts
[i
].sh_List
.lh_Type
= NT_INTERRUPT
;
235 NEWLIST(&PrivExecBase(SysBase
)->ResetHandlers
);
236 NEWLIST(&PrivExecBase(SysBase
)->AllocMemList
);
238 InitSemaphore(&PrivExecBase(SysBase
)->MemListSem
);
239 InitSemaphore(&PrivExecBase(SysBase
)->LowMemSem
);
241 SysBase
->SoftVer
= VERSION_NUMBER
;
242 SysBase
->Quantum
= 4;
243 SysBase
->TaskTrapCode
= Exec_TrapHandler
;
244 SysBase
->TaskExceptCode
= NULL
;
245 SysBase
->TaskExitCode
= Exec_TaskFinaliser
;
246 SysBase
->TaskSigAlloc
= 0xFFFF;
247 SysBase
->TaskTrapAlloc
= 0;
249 /* Parse some arguments from command line */
250 args
= (char *)LibGetTagData(KRN_CmdLine
, 0, msg
);
256 * Enable mungwall before the first AllocMem().
257 * Yes, we have actually already called stdAlloc() once
258 * in order to allocate memory for SysBase itself, however
259 * this is not a real problem because it is never going
262 * We store mungwall setting in private flags because it must not be
263 * switched at runtime (or hard crash will happen).
265 opts
= strcasestr(args
, "mungwall");
267 PrivExecBase(SysBase
)->IntFlags
= EXECF_MungWall
;
269 opts
= strcasestr(args
, "stacksnoop");
271 PrivExecBase(SysBase
)->IntFlags
= EXECF_StackSnoop
;
274 * Parse system runtime debug flags.
275 * These are public. In future they will be editable by prefs program.
276 * However in order to be able to turn them on during early startup,
277 * we apply them also here.
279 opts
= strcasestr(args
, "sysdebug=");
281 SysBase
->ex_DebugFlags
= ParseFlags(&opts
[9], ExecFlagNames
);
284 PrivExecBase(SysBase
)->TaskStorageSize
= sizeof(struct IntETask
) + TASKSTORAGEPUDDLE
;
285 NEWLIST(&PrivExecBase(SysBase
)->TaskStorageSlots
);
289 /* Add our initial MemHeader */
290 ADDHEAD(&SysBase
->MemList
, &mh
->mh_Node
);
292 /* Bring back saved values (or NULLs) */
293 SysBase
->ColdCapture
= ColdCapture
;
294 SysBase
->CoolCapture
= CoolCapture
;
295 SysBase
->WarmCapture
= WarmCapture
;
296 SysBase
->KickMemPtr
= KickMemPtr
;
297 SysBase
->KickTagPtr
= KickTagPtr
;
298 SysBase
->KickCheckSum
= KickCheckSum
;
300 SysBase
->DebugAROSBase
= PrepareAROSSupportBase(mh
);