2 #include <utility/tagitem.h>
3 #include <exec/resident.h>
4 #include <exec/nodes.h>
5 #include <exec/execbase.h>
6 #include <exec/memory.h>
8 #include <dos/dosextens.h>
10 #include <aros/arossupportbase.h>
11 #include <aros/libcall.h>
12 #include <aros/asmcall.h>
13 #include <aros/debug.h>
14 #include <aros/kernel.h>
17 #include <asm/segments.h>
19 #include <hardware/intbits.h>
20 #include <hardware/custom.h>
22 #include <proto/exec.h>
23 #include <proto/kernel.h>
28 #include "../bootstrap/multiboot.h"
31 #include "exec_intern.h"
32 #include "exec_util.h"
34 #define __text __attribute__((section(".text")))
35 #define __no_ret __attribute__((noreturn))
36 #define __packed __attribute__((packed))
38 extern struct Library
* PrepareAROSSupportBase (void);
39 extern const APTR LIBFUNCTABLE
[] __text
;
40 extern const APTR Exec_FuncTable
[] __text
;
41 void exec_DefaultTaskExit();
42 extern ULONG
Exec_MakeFunctions(APTR
, APTR
, APTR
, APTR
);
43 IPTR
**exec_RomTagScanner(struct TagItem
*msg
);
44 int exec_main(struct TagItem
*msg
, void *entry
);
46 AROS_UFP5(void, SoftIntDispatch
,
47 AROS_UFPA(ULONG
, intReady
, D1
),
48 AROS_UFPA(struct Custom
*, custom
, A0
),
49 AROS_UFPA(IPTR
, intData
, A1
),
50 AROS_UFPA(IPTR
, intCode
, A5
),
51 AROS_UFPA(struct ExecBase
*, SysBase
, A6
));
53 AROS_UFP5S(void, IntServer
,
54 AROS_UFPA(ULONG
, intMask
, D0
),
55 AROS_UFPA(struct Custom
*, custom
, A0
),
56 AROS_UFPA(struct List
*, intList
, A1
),
57 AROS_UFPA(APTR
, intCode
, A5
),
58 AROS_UFPA(struct ExecBase
*, SysBase
, A6
));
61 struct TagItem
*krnNextTagItem(const struct TagItem
**tagListPtr
);
62 struct TagItem
*krnFindTagItem(Tag tagValue
, const struct TagItem
*tagList
);
63 IPTR
krnGetTagData(Tag tagValue
, intptr_t defaultVal
, const struct TagItem
*tagList
);
66 * First, we will define exec.library (global) to make it usable outside this
69 const char exec_name
[] = "exec.library";
71 /* Now ID string as it will be used in a minute in resident structure. */
72 const char exec_idstring
[] = "$VER: exec 41.11 (16.12.2000)\r\n";
74 /* We would need also version and revision fields placed somewhere here. */
75 const short exec_Version
= 41;
76 const short exec_Revision
= 11;
78 const struct __text Resident Exec_resident
=
80 RTC_MATCHWORD
, /* Magic value used to find resident */
81 &Exec_resident
, /* Points to Resident itself */
82 &Exec_resident
+1, /* Where could we find next Resident? */
83 0, /* There are no flags!! */
85 NT_LIBRARY
, /* Type */
86 126, /* Very high startup priority. */
87 (STRPTR
)exec_name
, /* Pointer to name string */
88 (STRPTR
)exec_idstring
, /* Ditto */
89 exec_main
/* Library initializer (for exec this value is irrelevant since we've jumped there at the begining to bring the system up */
92 void scr_RawPutChars(char *, int);
94 void vesa_init(int width
, int height
, int depth
, void *base
);
100 #define rkprintf(x...) scr_RawPutChars(tab, snprintf(tab, 510, x))
102 void _aros_not_implemented(char *string
) {}
104 const char exec_chipname
[] = "Chip Memory";
105 const char exec_fastname
[] = "Fast Memory";
109 The MMU pages and directories. They are stored at fixed location and may be either reused in the
110 64-bit kernel, or replaced by it. Four PDE directories (PDE2M structures) are enough to map whole
113 static struct PML4E PML4
[512] __attribute__((used
,aligned(4096)));
114 static struct PDPE PDP
[512] __attribute__((used
,aligned(4096)));
115 static struct PDE2M PDE
[4][512] __attribute__((used
,aligned(4096)));
117 void exec_InsertMemory(struct TagItem
*msg
, uintptr_t lower
, uintptr_t upper
)
119 struct ExecBase
*SysBase
= TLS_GET(SysBase
); //*(struct ExecBase **)4UL;
121 uintptr_t kernLow
= krnGetTagData(KRN_KernelLowest
, 0, msg
);
122 uintptr_t kernHigh
= krnGetTagData(KRN_KernelHighest
, 0, msg
);
124 if (lower
>= 0x100000000L
)
127 if (upper
>= 0x100000000L
)
130 /* Scenario 1: Kernel area outside the affected area. */
131 if (kernHigh
< lower
|| kernLow
> upper
)
133 rkprintf("[exec] Adding %012p - %012p\n", lower
, upper
);
135 if (lower
< 0x01000000)
136 AddMemList(upper
-lower
+1,
137 MEMF_CHIP
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
| MEMF_24BITDMA
,
140 (STRPTR
)exec_chipname
);
142 AddMemList(upper
-lower
+1,
143 MEMF_FAST
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
,
146 (STRPTR
)exec_fastname
);
149 /* Scenario 2: Kernel area completely inside the memory region */
150 else if (kernLow
>= (lower
+sizeof(struct MemHeader
)+sizeof(struct MemChunk
)) && kernHigh
<= upper
)
152 rkprintf("[exec] Adding %012p - %012p\n", lower
, upper
);
154 if (lower
< 0x01000000)
155 AddMemList(upper
-lower
+1,
156 MEMF_CHIP
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
| MEMF_24BITDMA
,
159 (STRPTR
)exec_chipname
);
161 AddMemList(upper
-lower
+1,
162 MEMF_FAST
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
,
165 (STRPTR
)exec_fastname
);
166 rkprintf("[exec] rejecting %012p - %012p\n", kernLow
, kernHigh
);
167 AllocAbs(kernHigh
-kernLow
+1, kernLow
);
169 /* Scenario 3: Kernel in lower portion of memory region */
170 else if (kernLow
<= (lower
+sizeof(struct MemHeader
)+sizeof(struct MemChunk
)) && kernHigh
<= upper
)
172 lower
= (kernHigh
+ 4095) & ~4095;
173 rkprintf("[exec] Adding %012p - %012p\n", lower
, upper
);
175 if (lower
< 0x01000000)
176 AddMemList(upper
-lower
+1,
177 MEMF_CHIP
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
| MEMF_24BITDMA
,
180 (STRPTR
)exec_chipname
);
182 AddMemList(upper
-lower
+1,
183 MEMF_FAST
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
,
186 (STRPTR
)exec_fastname
);
188 /* Scenario 3: Kernel in upper portion of memory region */
189 else if (kernLow
>= (lower
+sizeof(struct MemHeader
)+sizeof(struct MemChunk
)) && kernHigh
>= upper
)
191 upper
= kernLow
& ~4095;
192 rkprintf("[exec] Adding %012p - %012p\n", lower
, upper
);
194 if (lower
< 0x01000000)
195 AddMemList(upper
-lower
+1,
196 MEMF_CHIP
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
| MEMF_24BITDMA
,
199 (STRPTR
)exec_chipname
);
201 AddMemList(upper
-lower
+1,
202 MEMF_FAST
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
,
205 (STRPTR
)exec_fastname
);
209 int exec_main(struct TagItem
*msg
, void *entry
)
211 struct ExecBase
*SysBase
;
213 struct vbe_mode
*mode
;
215 if ((mode
=krnGetTagData(KRN_VBEModeInfo
, 0, msg
)))
217 vesa_init(mode
->x_resolution
, mode
->y_resolution
,
218 mode
->bits_per_pixel
, (void*)mode
->phys_base
);
222 rkprintf("[exec] AROS64 - The AROS Research OS, 64-bit version\n[exec] Compiled %s\n",__DATE__
);
224 /* Prepare the exec base */
226 ULONG negsize
= LIB_VECTSIZE
; /* size of vector table */
227 void **fp
= Exec_FuncTable
; //LIBFUNCTABLE; /* pointer to a function in the table */
229 rkprintf("[exec] Preparing the ExecBase...\n");
231 /* Calculate the size of the vector table */
232 while (*fp
++ != (APTR
) -1) negsize
+= LIB_VECTSIZE
;
233 SysBase
= (struct ExecBase
*)(0x1000 + negsize
);
235 rkprintf("[exec] Clearing ExecBase\n");
237 /* How about clearing most of ExecBase structure? */
238 bzero(&SysBase
->IntVects
[0], sizeof(struct ExecBase
) - offsetof(struct ExecBase
, IntVects
[0]));
240 SysBase
->KickMemPtr
= NULL
;
241 SysBase
->KickTagPtr
= NULL
;
242 SysBase
->KickCheckSum
= NULL
;
244 /* How about clearing most of ExecBase structure? */
245 bzero(&SysBase
->IntVects
[0], sizeof(struct ExecBase
) - offsetof(struct ExecBase
, IntVects
[0]));
248 * Now everything is prepared to store ExecBase at the location 4UL and set
249 * it complement in ExecBase structure
252 rkprintf("[exec] Initializing library...\n");
254 //*(struct ExecBase **)4 = SysBase;
255 SysBase
->ChkBase
= ~(ULONG
)SysBase
;
257 /* Store sysbase in TLS */
258 TLS_SET(SysBase
, SysBase
);
260 /* Set up system stack */
261 // tss->ssp = (extmem) ? extmem : locmem; /* Either in FAST or in CHIP */
262 // SysBase->SysStkUpper = (APTR)stack_end;
263 // SysBase->SysStkLower = (APTR)&stack[0]; /* 64KB of system stack */
265 /* Store memory configuration */
266 SysBase
->MaxLocMem
= (IPTR
)0; //locmem;
267 SysBase
->MaxExtMem
= (APTR
)0; //extmem;
270 * Initialize exec lists. This is done through information table which consist
271 * of offset from begining of ExecBase and type of the list.
273 NEWLIST(&SysBase
->MemList
);
274 SysBase
->MemList
.lh_Type
= NT_MEMORY
;
275 NEWLIST(&SysBase
->ResourceList
);
276 SysBase
->ResourceList
.lh_Type
= NT_RESOURCE
;
277 NEWLIST(&SysBase
->DeviceList
);
278 SysBase
->DeviceList
.lh_Type
= NT_DEVICE
;
279 NEWLIST(&SysBase
->LibList
);
280 SysBase
->LibList
.lh_Type
= NT_LIBRARY
;
281 NEWLIST(&SysBase
->PortList
);
282 SysBase
->PortList
.lh_Type
= NT_MSGPORT
;
283 NEWLIST(&SysBase
->TaskReady
);
284 SysBase
->TaskReady
.lh_Type
= NT_TASK
;
285 NEWLIST(&SysBase
->TaskWait
);
286 SysBase
->TaskWait
.lh_Type
= NT_TASK
;
287 NEWLIST(&SysBase
->IntrList
);
288 SysBase
->IntrList
.lh_Type
= NT_INTERRUPT
;
289 NEWLIST(&SysBase
->SemaphoreList
);
290 SysBase
->SemaphoreList
.lh_Type
= NT_SIGNALSEM
;
291 NEWLIST(&SysBase
->ex_MemHandlers
);
295 NEWLIST(&SysBase
->SoftInts
[i
].sh_List
);
296 SysBase
->SoftInts
[i
].sh_List
.lh_Type
= NT_SOFTINT
;
300 * Exec.library initializer. Prepares exec.library for future use. All
301 * lists have to be initialized, some values from ROM are copied.
304 SysBase
->TaskTrapCode
= NULL
; //exec_DefaultTrap;
305 SysBase
->TaskExceptCode
= NULL
; //exec_DefaultTrap;
306 SysBase
->TaskExitCode
= exec_DefaultTaskExit
;
307 SysBase
->TaskSigAlloc
= 0x0000ffff;
308 SysBase
->TaskTrapAlloc
= 0x8000;
310 /* Prepare values for execBase (like name, type, pri and other) */
312 SysBase
->LibNode
.lib_Node
.ln_Type
= NT_LIBRARY
;
313 SysBase
->LibNode
.lib_Node
.ln_Pri
= 0;
314 SysBase
->LibNode
.lib_Node
.ln_Name
= (char *)exec_name
;
315 SysBase
->LibNode
.lib_Flags
= LIBF_CHANGED
| LIBF_SUMUSED
;
316 SysBase
->LibNode
.lib_PosSize
= sizeof(struct ExecBase
);
317 SysBase
->LibNode
.lib_OpenCnt
= 1;
318 SysBase
->LibNode
.lib_IdString
= (char *)exec_idstring
;
319 SysBase
->LibNode
.lib_Version
= exec_Version
;
320 SysBase
->LibNode
.lib_Revision
= exec_Revision
;
322 SysBase
->Quantum
= 4;
323 SysBase
->VBlankFrequency
= 50;
324 SysBase
->PowerSupplyFrequency
= 1;
326 /* Build the jumptable */
327 SysBase
->LibNode
.lib_NegSize
=
328 Exec_MakeFunctions(SysBase
, Exec_FuncTable
, NULL
, SysBase
);
330 SumLibrary((struct Library
*)SysBase
);
332 rkprintf("[exec] Adding memory\n");
333 struct mb_mmap
*mmap
;
334 uint32_t len
= krnGetTagData(KRN_MMAPLength
, 0, msg
);
338 mmap
= (struct mb_mmap
*)(krnGetTagData(KRN_MMAPAddress
, 0, msg
));
340 while(len
>= sizeof(struct mb_mmap
))
342 if (mmap
->type
== MMAP_TYPE_RAM
)
344 uintptr_t addr
= (mmap
->addr_low
| ((intptr_t)mmap
->addr_high
<< 32));
345 uintptr_t size
= (mmap
->len_low
| ((intptr_t)mmap
->len_high
<< 32));
348 #warning TODO: Add proper handling of the memory above 4GB!
351 if (addr
< (uintptr_t)SysBase
)
353 tmp
= ((uintptr_t)SysBase
+sizeof(struct ExecBase
)+ 4095) & ~4095;
357 rkprintf("[exec] %012p - %012p\n", addr
, addr
+size
-1);
359 if (addr
< 0x01000000 && (addr
+size
) <= 0x01000000)
361 exec_InsertMemory(msg
, addr
, addr
+size
-1);
363 else if (addr
< 0x01000000 && (addr
+size
) > 0x01000000)
365 exec_InsertMemory(msg
, addr
, 0x00ffffff);
366 exec_InsertMemory(msg
, 0x01000000, addr
+size
-1);
370 exec_InsertMemory(msg
, addr
, addr
+size
-1);
375 mmap
= (struct mb_mmap
*)(mmap
->size
+ (IPTR
)mmap
+4);
380 SumLibrary((struct Library
*)SysBase
);
382 Enqueue(&SysBase
->LibList
,&SysBase
->LibNode
.lib_Node
);
384 SysBase
->DebugAROSBase
= PrepareAROSSupportBase();
386 rkprintf("[exec] ExecBase=%012p\n", SysBase
);
390 if( (1<<i
) & (INTF_PORTS
|INTF_COPER
|INTF_VERTB
|INTF_EXTER
|INTF_SETCLR
))
392 struct Interrupt
*is
;
393 struct SoftIntList
*sil
;
396 sizeof(struct Interrupt
) + sizeof(struct SoftIntList
),
397 MEMF_CLEAR
| MEMF_PUBLIC
401 rkprintf("[exec] ERROR: Cannot install Interrupt Servers!\n");
403 sil
= (struct SoftIntList
*)((struct Interrupt
*)is
+ 1);
405 is
->is_Code
= &IntServer
;
407 NEWLIST((struct List
*)sil
);
412 struct Interrupt
*is
;
418 sizeof(struct Interrupt
),
419 MEMF_CLEAR
| MEMF_PUBLIC
423 rkprintf("[exec] Error: Cannot install Interrupt Servers!\n");
424 // Alert(AT_DeadEnd | AN_IntrMem);
426 is
->is_Node
.ln_Type
= NT_SOFTINT
; //INTERRUPT;
427 is
->is_Node
.ln_Pri
= 0;
428 is
->is_Node
.ln_Name
= "SW Interrupt Dispatcher";
430 is
->is_Code
= (void *)SoftIntDispatch
;
437 /* Enable interrupts and set int disable level to -1 */
439 SysBase
->TDNestCnt
= -1;
440 SysBase
->IDNestCnt
= -1;
442 /* Now it's time to calculate exec checksum. It will be used
443 * in future to distinguish whether we'd had proper execBase
446 UWORD sum
=0, *ptr
= &SysBase
->SoftVer
;
447 int i
=((IPTR
)&SysBase
->IntVects
[0] - (IPTR
)&SysBase
->SoftVer
) / 2,
450 /* Calculate sum for every static part from SoftVer to ChkSum */
456 SysBase
->ChkSum
= ~sum
;
459 rkprintf("[exec] Creating the very first task...\n");
461 /* Create boot task. Sigh, we actually create a Process sized Task,
462 since DOS needs to call things which think it has a Process and
463 we don't want to overwrite memory with something strange do we?
465 We do this until at least we can boot dos more cleanly.
471 ml
= (struct MemList
*)AllocMem(sizeof(struct MemList
), MEMF_PUBLIC
|MEMF_CLEAR
);
472 t
= (struct Task
*) AllocMem(sizeof(struct Process
), MEMF_PUBLIC
|MEMF_CLEAR
);
476 rkprintf("[exec] ERROR: Cannot create Boot Task!\n");
478 ml
->ml_NumEntries
= 1;
479 ml
->ml_ME
[0].me_Addr
= t
;
480 ml
->ml_ME
[0].me_Length
= sizeof(struct Process
);
482 NEWLIST(&t
->tc_MemEntry
);
483 NEWLIST(&((struct Process
*)t
)->pr_MsgPort
.mp_MsgList
);
485 /* It's the boot process that RunCommand()s the boot shell, so we
486 must have this list initialized */
487 NEWLIST((struct List
*)&((struct Process
*)t
)->pr_LocalVars
);
489 AddHead(&t
->tc_MemEntry
,&ml
->ml_Node
);
491 t
->tc_Node
.ln_Name
= exec_name
;
492 t
->tc_Node
.ln_Pri
= 0;
493 t
->tc_Node
.ln_Type
= NT_TASK
;
494 t
->tc_State
= TS_RUN
;
495 t
->tc_SigAlloc
= 0xFFFF;
496 t
->tc_SPLower
= 0; /* This is the system's stack */
497 t
->tc_SPUpper
= (APTR
)~0UL;
498 t
->tc_Flags
|= TF_ETASK
;
500 if (t
->tc_Flags
& TF_ETASK
)
502 t
->tc_UnionETask
.tc_ETask
= AllocTaskMem(t
, sizeof(struct IntETask
), MEMF_ANY
|MEMF_CLEAR
);
504 if (!t
->tc_UnionETask
.tc_ETask
)
506 rkprintf("[exec] Not enough memory for first task\n");
509 GetIntETask(t
)->iet_Context
= AllocTaskMem(t
510 , SIZEOF_ALL_REGISTERS
511 , MEMF_PUBLIC
|MEMF_CLEAR
514 if (!GetIntETask(t
)->iet_Context
)
516 rkprintf("[exec] Not enough memory for first task\n");
520 SysBase
->ThisTask
= t
;
523 rkprintf("[exec] Done. SysBase->ThisTask = 0x%012p\n[exec] Leaving supervisor mode\n", SysBase
->ThisTask
);
526 "mov %[user_ds],%%ds\n\t" // Load DS and ES
527 "mov %[user_ds],%%es\n\t"
528 "mov %%rsp,%%r12\n\t"
529 "pushq %[ds]\n\t" // SS
530 "pushq %%r12\n\t" // rSP
531 "pushq $0x3002\n\t" // rFLANGS
532 "pushq %[cs]\n\t" // CS
533 "pushq $1f\n\t iretq\n 1:"
534 ::[user_ds
]"r"(USER_DS
),[ds
]"i"(USER_DS
),[cs
]"i"(USER_CS
):"r12");
535 rkprintf("[exec] Done?! Still here?\n");
537 SysBase
->TDNestCnt
++;
540 /* Scan for valid RomTags */
541 SysBase
->ResModules
= exec_RomTagScanner(msg
);
545 rkprintf("[exec] InitCode(RTF_SINGLETASK)\n");
546 InitCode(RTF_SINGLETASK
, 0);
548 rkprintf("[exec] InitCode(RTF_COLDSTART)\n");
549 InitCode(RTF_COLDSTART
, 0);
552 rkprintf("[exec] I should never get here...\n");
553 while(1) asm volatile("nop");
558 void exec_DefaultTaskExit()
560 struct ExecBase
*SysBase
= TLS_GET(SysBase
); //*(struct ExecBase **)4UL;
561 RemTask(SysBase
->ThisTask
);
565 AROS_LH1(struct ExecBase
*, open
,
566 AROS_LHA(ULONG
, version
, D0
),
567 struct ExecBase
*, SysBase
, 1, Exec
)
571 /* I have one more opener. */
572 SysBase
->LibNode
.lib_OpenCnt
++;
578 AROS_LH0(BPTR
, close
,
579 struct ExecBase
*, SysBase
, 2, Exec
)
583 /* I have one fewer opener. */
584 SysBase
->LibNode
.lib_OpenCnt
--;
590 struct ExecBase
*, SysBase
, 4, Exec
)
600 * This function scans kernel for existing Resident modules. If two modules
601 * with the same name are found, the one with higher version or priority wins.
603 * After building list of kernel modules, the KickTagPtr and KickMemPtr are
604 * checksummed. If checksum is proper and all memory pointed in KickMemPtr may
605 * be allocated, then all modules from KickTagPtr are added to RT list
607 * Afterwards the proper RomTagList is created (see InitCode() for details) and
608 * memory after list and nodes is freed.
614 struct Resident
*module
;
617 IPTR
**exec_RomTagScanner(struct TagItem
*msg
)
619 struct ExecBase
*SysBase
= TLS_GET(SysBase
); //*(struct ExecBase **)4UL;
621 struct List rtList
; /* List of modules */
622 UWORD
*ptr
= (UWORD
*)krnGetTagData(KRN_KernelLowest
, 0, msg
); /* Start looking here */
623 UWORD
*maxptr
= (UWORD
*)krnGetTagData(KRN_KernelHighest
, 0, msg
);
624 struct Resident
*res
; /* module found */
629 /* Initialize list */
632 rkprintf("[exec] Resident modules (addr: pri version name):\n");
634 /* Look in whole kernel for resident modules */
637 /* Do we have RTC_MATCHWORD? */
638 if (*ptr
== RTC_MATCHWORD
)
640 /* Yes, assume we have Resident */
641 res
= (struct Resident
*)ptr
;
643 /* Does rt_MatchTag point to Resident? */
644 if (res
== res
->rt_MatchTag
)
646 /* Yes, it is Resident module */
647 struct rt_node
*node
;
649 /* Check if there is module with such name already */
650 node
= (struct rt_node
*)FindName(&rtList
, res
->rt_Name
);
653 /* Yes, there was such module. It it had lower pri then replace it */
654 if (node
->node
.ln_Pri
<= res
->rt_Pri
)
656 /* If they have the same Pri but new one has higher Version, replace */
657 if ((node
->node
.ln_Pri
== res
->rt_Pri
) &&
658 (node
->module
->rt_Version
< res
->rt_Version
))
660 node
->node
.ln_Pri
= res
->rt_Pri
;
667 /* New module. Allocate some memory for it */
668 node
= (struct rt_node
*)
669 AllocMem(sizeof(struct rt_node
),MEMF_PUBLIC
|MEMF_CLEAR
);
673 node
->node
.ln_Name
= res
->rt_Name
;
674 node
->node
.ln_Pri
= res
->rt_Pri
;
677 Enqueue(&rtList
,(struct Node
*)node
);
680 ptr
+=sizeof(struct Resident
)/sizeof(UWORD
);
685 /* Get next address... */
687 } while (ptr
< maxptr
);
690 * By now we have valid (and sorted) list of kernel resident modules.
692 * Now, we will have to analyze used-defined RomTags (via KickTagPtr and
695 #warning "TODO: Implement external modules!"
697 * Everything is done now. Allocate buffer for normal RomTag and convert
701 ListLength(&rtList
,i
); /* Get length of the list */
703 RomTag
= AllocMem((i
+1)*sizeof(IPTR
),MEMF_PUBLIC
| MEMF_CLEAR
);
712 n
= (struct rt_node
*)RemHead(&rtList
);
713 rkprintf("[exec] + 0x%012lx: %4d %3d \"%s\"\n",
716 n
->module
->rt_Version
,
718 RomTag
[j
] = (IPTR
*)n
->module
;
719 FreeMem(n
, sizeof(struct rt_node
));
730 We temporarily redefine kprintf() so we use the real version in case
731 we have one of these two fn's called before AROSSupportBase is ready.
738 #define kprintf(x...)
739 #define rkprintf(x...)
740 #define vkprintf(x...)
742 struct Library
* PrepareAROSSupportBase(void)
744 struct ExecBase
*SysBase
= TLS_GET(SysBase
); //*(struct ExecBase **)4UL;
746 struct AROSSupportBase
*AROSSupportBase
=
747 AllocMem(sizeof(struct AROSSupportBase
), MEMF_CLEAR
);
749 AROSSupportBase
->kprintf
= (void *)kprintf
;
750 AROSSupportBase
->rkprintf
= (void *)rkprintf
;
751 AROSSupportBase
->vkprintf
= (void *)vkprintf
;
753 NEWLIST(&AROSSupportBase
->AllocMemList
);
755 #warning "FIXME Add code to read in the debug options"
757 return (struct Library
*)AROSSupportBase
;
761 This interrupt handler will send an interrupt to a series of queued
762 interrupt servers. Servers should return D0 != 0 (Z clear) if they
763 believe the interrupt was for them, and no further interrupts will
764 be called. This will only check the value in D0 for non-m68k systems,
765 however it SHOULD check the Z-flag on 68k systems.
767 Hmm, in that case I would have to separate it from this file in order
770 AROS_UFH5S(void, IntServer
,
771 AROS_UFHA(ULONG
, intMask
, D0
),
772 AROS_UFHA(struct Custom
*, custom
, A0
),
773 AROS_UFHA(struct List
*, intList
, A1
),
774 AROS_UFHA(APTR
, intCode
, A5
),
775 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
779 struct Interrupt
* irq
;
781 ForeachNode(intList
, irq
)
783 if( AROS_UFC4(int, irq
->is_Code
,
784 AROS_UFCA(struct Custom
*, custom
, A0
),
785 AROS_UFCA(APTR
, irq
->is_Data
, A1
),
786 AROS_UFCA(APTR
, irq
->is_Code
, A5
),
787 AROS_UFCA(struct ExecBase
*, SysBase
, A6
)