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
);
45 UBYTE
core_APICGetTotal();
46 UBYTE
core_APICGetNumber();
48 AROS_UFP5(void, SoftIntDispatch
,
49 AROS_UFPA(ULONG
, intReady
, D1
),
50 AROS_UFPA(struct Custom
*, custom
, A0
),
51 AROS_UFPA(IPTR
, intData
, A1
),
52 AROS_UFPA(IPTR
, intCode
, A5
),
53 AROS_UFPA(struct ExecBase
*, SysBase
, A6
));
55 AROS_UFP5S(void, IntServer
,
56 AROS_UFPA(ULONG
, intMask
, D0
),
57 AROS_UFPA(struct Custom
*, custom
, A0
),
58 AROS_UFPA(struct List
*, intList
, A1
),
59 AROS_UFPA(APTR
, intCode
, A5
),
60 AROS_UFPA(struct ExecBase
*, SysBase
, A6
));
63 struct TagItem
*krnNextTagItem(const struct TagItem
**tagListPtr
);
64 struct TagItem
*krnFindTagItem(Tag tagValue
, const struct TagItem
*tagList
);
65 IPTR
krnGetTagData(Tag tagValue
, intptr_t defaultVal
, const struct TagItem
*tagList
);
66 void krnSetTagData(Tag tagValue
, intptr_t newtagValue
, const struct TagItem
*tagList
);
69 * First, we will define exec.library (global) to make it usable outside this
72 const char exec_name
[] = "exec.library";
74 /* Now ID string as it will be used in a minute in resident structure. */
75 const char exec_idstring
[] = "$VER: exec 41.11 (16.12.2000)\r\n";
77 /* We would need also version and revision fields placed somewhere here. */
78 const short exec_Version
= 41;
79 const short exec_Revision
= 11;
81 const struct __text Resident Exec_resident
=
83 RTC_MATCHWORD
, /* Magic value used to find resident */
84 &Exec_resident
, /* Points to Resident itself */
85 &Exec_resident
+1, /* Where could we find next Resident? */
86 0, /* There are no flags!! */
88 NT_LIBRARY
, /* Type */
89 126, /* Very high startup priority. */
90 (STRPTR
)exec_name
, /* Pointer to name string */
91 (STRPTR
)exec_idstring
, /* Ditto */
92 exec_main
/* Library initializer (for exec this value is irrelevant since we've jumped there at the begining to bring the system up */
95 extern UBYTE
core_APICGetTotal();
96 extern UBYTE
core_APICGetNumber();
98 /** Screen/Serial Debug **/
101 extern void Exec_SerialRawIOInit();
102 extern void Exec_SerialRawPutChar(UBYTE chr
);
104 void scr_RawPutChars(char *, int);
106 void vesa_init(int width
, int height
, int depth
, void *base
);
112 #define rkprintf(x...) scr_RawPutChars(tab, snprintf(tab, 510, x))
114 static ULONG negsize
= LIB_VECTSIZE
; /* size of vector table */
115 static UBYTE apicready
= 0;
117 void _aros_not_implemented(char *string
) {}
121 const char exec_chipname
[] = "Chip Memory";
122 const char exec_fastname
[] = "Fast Memory";
123 const char exec_sysbasename
[] = "SysBase";
124 const char exec_kernalname
[] = "Kernel Memory";
127 The MMU pages and directories. They are stored at fixed location and may be either reused in the
128 64-bit kernel, or replaced by it. Four PDE directories (PDE2M structures) are enough to map whole
131 static struct PML4E PML4
[512] __attribute__((used
,aligned(4096)));
132 static struct PDPE PDP
[512] __attribute__((used
,aligned(4096)));
133 static struct PDE2M PDE
[4][512] __attribute__((used
,aligned(4096)));
135 void exec_InsertMemory(struct TagItem
*msg
, uintptr_t lower
, uintptr_t upper
)
137 struct ExecBase
*SysBase
= TLS_GET(SysBase
); //*(struct ExecBase **)4UL;
139 uintptr_t kernLow
= krnGetTagData(KRN_KernelLowest
, 0, msg
);
140 uintptr_t kernHigh
= krnGetTagData(KRN_KernelHighest
, 0, msg
);
142 /* Check System Memory bounds */
151 if (lower
>= 0x100000000L
)
154 if (upper
>= 0x100000000L
)
157 if ((upper
- lower
) < 0x1000)
160 /* Scenario 1: Kernel and ExecBase areas outside the affected range. */
161 if ((kernHigh
< lower
|| kernLow
> upper
) &&
162 ((SysBase
+ sizeof(struct ExecBase
)) < lower
|| (SysBase
- negsize
) > upper
))
164 rkprintf("[exec] Adding %012p - %012p\n", lower
, upper
);
166 if (lower
< 0x01000000)
168 AddMemList(upper
-lower
+1,
169 MEMF_CHIP
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
| MEMF_24BITDMA
,
172 (STRPTR
)exec_chipname
);
176 AddMemList(upper
-lower
+1,
177 MEMF_FAST
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
,
180 (STRPTR
)exec_fastname
);
185 /* Scenario 2: Kernel area completely inside the memory region */
186 if (kernLow
>= (lower
+sizeof(struct MemHeader
)+sizeof(struct MemChunk
)) && kernHigh
<= upper
)
188 rkprintf("[exec] Splitting %012p - %012p\n", lower
, upper
);
190 exec_InsertMemory(msg
, lower
, kernLow
- 1);
191 exec_InsertMemory(msg
, kernHigh
+ 1, upper
);
194 /* Scenario 3: Kernel in lower portion of memory region */
195 else if (kernLow
<= (lower
+sizeof(struct MemHeader
)+sizeof(struct MemChunk
)) && kernHigh
<= upper
)
197 lower
= (kernHigh
+ 4096) & ~4095;
199 rkprintf("[exec] Adding Upper region %012p - %012p\n", lower
, upper
);
201 exec_InsertMemory(msg
, lower
, upper
);
204 /* Scenario 4: Kernel in upper portion of memory region */
205 else if (kernLow
>= (lower
+sizeof(struct MemHeader
)+sizeof(struct MemChunk
)) && kernHigh
>= upper
)
207 upper
= (kernLow
- 1) & ~4095;
209 rkprintf("[exec] Adding Lower region %012p - %012p\n", lower
, upper
);
211 exec_InsertMemory(msg
, lower
, upper
);
214 /* Scenario 5: ExecBase completely inside the memory region */
215 else if ((SysBase
- negsize
) >= (lower
+sizeof(struct MemHeader
)+sizeof(struct MemChunk
)) && (SysBase
+ sizeof(struct ExecBase
)) <= upper
)
217 #warning "TODO: Check if sysbase falls within the region being added"
220 /* Scenario 6: ExecBase in lower portion of memory region */
221 else if ((SysBase
- negsize
) <= (lower
+sizeof(struct MemHeader
)+sizeof(struct MemChunk
)) && (SysBase
+ sizeof(struct ExecBase
)) <= upper
)
225 /* Scenario 7: ExecBase in upper portion of memory region */
226 else if ((SysBase
- negsize
) >= (lower
+sizeof(struct MemHeader
)+sizeof(struct MemChunk
)) && (SysBase
+ sizeof(struct ExecBase
)) >= upper
)
232 int exec_main(struct TagItem
*msg
, void *entry
)
234 struct ExecBase
*SysBase
;
236 struct vbe_mode
*mode
;
237 uintptr_t addr_lower
;
241 /* Launched on BSP */
242 addr_lower
= (uintptr_t)(krnGetTagData(KRN_MEMLower
, 0, msg
) * 1024);
244 if ((mode
= (struct vbe_mode
*)krnGetTagData(KRN_VBEModeInfo
, 0, msg
)))
246 vesa_init(mode
->x_resolution
, mode
->y_resolution
,
247 mode
->bits_per_pixel
, (void*)mode
->phys_base
);
251 rkprintf("[exec] AROS64 - The AROS Research OS, 64-bit version\n[exec] Compiled %s\n", __DATE__
);
253 /* Prepare the exec base */
255 void **fp
= Exec_FuncTable
; //LIBFUNCTABLE; /* pointer to a function in the table */
257 rkprintf("[exec] Preparing the ExecBase...\n");
259 /* Calculate the size of the vector table */
260 while (*fp
++ != (APTR
) -1) negsize
+= LIB_VECTSIZE
;
264 addr_lower
= ((addr_lower
- (negsize
+ sizeof(struct ExecBase
))) & ~PAGE_MASK
);
265 SysBase
= (struct ExecBase
*)(addr_lower
+ negsize
);
266 krnSetTagData(KRN_MEMLower
, ((addr_lower
- 1)/1024), msg
);
267 addr_lower
= (krnGetTagData(KRN_MEMLower
, 0, msg
) * 1024);
271 /* Warn that theres no lowmem pages to load execbase into? */
272 SysBase
= (struct ExecBase
*)(0x1000 + negsize
);
275 rkprintf("[exec] Clearing ExecBase [SysBase = %012p]\n", SysBase
);
277 /* How about clearing most of ExecBase structure? */
278 bzero(&SysBase
->IntVects
[0], sizeof(struct ExecBase
) - offsetof(struct ExecBase
, IntVects
[0]));
280 SysBase
->KickMemPtr
= NULL
;
281 SysBase
->KickTagPtr
= NULL
;
282 SysBase
->KickCheckSum
= NULL
;
284 /* How about clearing most of ExecBase structure? */
285 bzero(&SysBase
->IntVects
[0], sizeof(struct ExecBase
) - offsetof(struct ExecBase
, IntVects
[0]));
288 * Now everything is prepared to store ExecBase at the location 4UL and set
289 * it complement in ExecBase structure
292 rkprintf("[exec] Initializing library...\n");
294 //*(struct ExecBase **)4 = SysBase;
295 SysBase
->ChkBase
= ~(ULONG
)SysBase
;
297 /* Store sysbase in TLS */
298 TLS_SET(SysBase
, SysBase
);
300 /* Set up system stack */
301 // tss->ssp = (extmem) ? extmem : locmem; /* Either in FAST or in CHIP */
302 // SysBase->SysStkUpper = (APTR)stack_end;
303 // SysBase->SysStkLower = (APTR)&stack[0]; /* 64KB of system stack */
305 /* Store memory configuration */
306 SysBase
->MaxLocMem
= (IPTR
)0; //locmem;
307 SysBase
->MaxExtMem
= (APTR
)0; //extmem;
310 * Initialize exec lists. This is done through information table which consist
311 * of offset from begining of ExecBase and type of the list.
313 NEWLIST(&SysBase
->MemList
);
314 SysBase
->MemList
.lh_Type
= NT_MEMORY
;
315 NEWLIST(&SysBase
->ResourceList
);
316 SysBase
->ResourceList
.lh_Type
= NT_RESOURCE
;
317 NEWLIST(&SysBase
->DeviceList
);
318 SysBase
->DeviceList
.lh_Type
= NT_DEVICE
;
319 NEWLIST(&SysBase
->LibList
);
320 SysBase
->LibList
.lh_Type
= NT_LIBRARY
;
321 NEWLIST(&SysBase
->PortList
);
322 SysBase
->PortList
.lh_Type
= NT_MSGPORT
;
323 NEWLIST(&SysBase
->TaskReady
);
324 SysBase
->TaskReady
.lh_Type
= NT_TASK
;
325 NEWLIST(&SysBase
->TaskWait
);
326 SysBase
->TaskWait
.lh_Type
= NT_TASK
;
327 NEWLIST(&SysBase
->IntrList
);
328 SysBase
->IntrList
.lh_Type
= NT_INTERRUPT
;
329 NEWLIST(&SysBase
->SemaphoreList
);
330 SysBase
->SemaphoreList
.lh_Type
= NT_SIGNALSEM
;
331 NEWLIST(&SysBase
->ex_MemHandlers
);
335 NEWLIST(&SysBase
->SoftInts
[i
].sh_List
);
336 SysBase
->SoftInts
[i
].sh_List
.lh_Type
= NT_SOFTINT
;
340 * Exec.library initializer. Prepares exec.library for future use. All
341 * lists have to be initialized, some values from ROM are copied.
344 SysBase
->TaskTrapCode
= NULL
; //exec_DefaultTrap;
345 SysBase
->TaskExceptCode
= NULL
; //exec_DefaultTrap;
346 SysBase
->TaskExitCode
= exec_DefaultTaskExit
;
347 SysBase
->TaskSigAlloc
= 0x0000ffff;
348 SysBase
->TaskTrapAlloc
= 0x8000;
350 /* Prepare values for execBase (like name, type, pri and other) */
352 SysBase
->LibNode
.lib_Node
.ln_Type
= NT_LIBRARY
;
353 SysBase
->LibNode
.lib_Node
.ln_Pri
= 0;
354 SysBase
->LibNode
.lib_Node
.ln_Name
= (char *)exec_name
;
355 SysBase
->LibNode
.lib_Flags
= LIBF_CHANGED
| LIBF_SUMUSED
;
356 SysBase
->LibNode
.lib_PosSize
= sizeof(struct ExecBase
);
357 SysBase
->LibNode
.lib_OpenCnt
= 1;
358 SysBase
->LibNode
.lib_IdString
= (char *)exec_idstring
;
359 SysBase
->LibNode
.lib_Version
= exec_Version
;
360 SysBase
->LibNode
.lib_Revision
= exec_Revision
;
362 SysBase
->Quantum
= 4;
363 SysBase
->VBlankFrequency
= 50;
364 SysBase
->PowerSupplyFrequency
= 1;
366 /* Build the jumptable */
367 SysBase
->LibNode
.lib_NegSize
=
368 Exec_MakeFunctions(SysBase
, Exec_FuncTable
, NULL
, SysBase
);
370 SumLibrary((struct Library
*)SysBase
);
372 rkprintf("[exec] Adding memory ..\n");
373 struct mb_mmap
*mmap
;
374 uint32_t len
= krnGetTagData(KRN_MMAPLength
, 0, msg
);
378 rkprintf("[exec] Registering MMAP regions (MMAP Length = %d)\n", len
);
379 mmap
= (struct mb_mmap
*)(krnGetTagData(KRN_MMAPAddress
, 0, msg
));
381 while(len
>= sizeof(struct mb_mmap
))
383 if (mmap
->type
== MMAP_TYPE_RAM
)
385 uintptr_t addr
= (mmap
->addr_low
| ((intptr_t)mmap
->addr_high
<< 32));
386 uintptr_t size
= (mmap
->len_low
| ((intptr_t)mmap
->len_high
<< 32));
389 #warning TODO: Add proper handling of the memory above 4GB!
390 if ((addr_lower
!= 0) &&
391 ((addr_lower
>= addr
) && ((addr_lower
<= (addr
+size
) ))))
393 rkprintf("[exec] Fixup entry for lowpages [size %012p -> ", size
);
394 size
= addr_lower
- addr
;
395 rkprintf("%012p]\n", size
);
398 rkprintf("[exec] %012p - %012p\n", addr
, addr
+size
-1);
400 if (addr
< 0x01000000 && (addr
+size
) <= 0x01000000)
402 exec_InsertMemory(msg
, addr
, addr
+size
-1);
404 else if (addr
< 0x01000000 && (addr
+size
) > 0x01000000)
406 exec_InsertMemory(msg
, addr
, 0x00ffffff);
407 exec_InsertMemory(msg
, 0x01000000, addr
+ size
- 1);
411 exec_InsertMemory(msg
, addr
, addr
+size
-1);
416 mmap
= (struct mb_mmap
*)(mmap
->size
+ (IPTR
)mmap
+4);
421 rkprintf("[exec] Registering mem_lower/mem_upper Memory Region\n");
423 uintptr_t chip_start
, chip_end
, fast_start
, fast_end
, tmp
;
425 uintptr_t addr_upper
= krnGetTagData(KRN_MEMUpper
, 0, msg
);
430 chip_end
= (addr_lower
* 1024) - 1;
432 if (chip_start
< chip_end
)
434 rkprintf("[exec] Registering Lower Mem Range (%012p - %012p)\n", chip_start
, chip_end
);
435 exec_InsertMemory(msg
, chip_start
, chip_end
);
441 fast_start
= 0x0000100000;
442 fast_end
= (addr_upper
* 1024) + (fast_start
- 1);
444 if (fast_start
< fast_end
)
446 if (fast_end
> 0x01000000)
448 rkprintf("[exec] Registering Upper Chip Mem Range (%012p - %012p)\n", fast_start
, 0x00ffffff);
449 exec_InsertMemory(msg
, fast_start
, 0x00ffffff);
450 rkprintf("[exec] Registering Upper Fast Mem Range (%012p - %012p)\n", 0x01000000, fast_end
);
451 exec_InsertMemory(msg
, 0x01000000, fast_end
);
456 rkprintf("[exec] Registering Upper Mem Range (%012p - %012p)\n", fast_start
, fast_end
);
457 exec_InsertMemory(msg
, fast_start
, fast_end
);
463 rkprintf("[exec] MemLists (hopefully!) prepaired\n");
465 SumLibrary((struct Library
*)SysBase
);
467 rkprintf("[exec] SumLibrary on SysBase finished\n");
469 Enqueue(&SysBase
->LibList
,&SysBase
->LibNode
.lib_Node
);
471 rkprintf("[exec] SysBase Enqueued in Exec Liblist\n");
473 if ((SysBase
->DebugAROSBase
= PrepareAROSSupportBase()) == NULL
)
475 rkprintf("[exec] PrepareAROSSupportBase returns NULL!!!\n");
478 rkprintf("[exec] ExecBase=%012p\n", SysBase
);
482 if( (1<<i
) & (INTF_PORTS
|INTF_COPER
|INTF_VERTB
|INTF_EXTER
|INTF_SETCLR
))
484 struct Interrupt
*is
;
485 struct SoftIntList
*sil
;
488 sizeof(struct Interrupt
) + sizeof(struct SoftIntList
),
489 MEMF_CLEAR
| MEMF_PUBLIC
493 rkprintf("[exec] ERROR: Cannot install Interrupt Servers!\n");
495 sil
= (struct SoftIntList
*)((struct Interrupt
*)is
+ 1);
497 is
->is_Code
= &IntServer
;
499 NEWLIST((struct List
*)sil
);
504 struct Interrupt
*is
;
510 sizeof(struct Interrupt
),
511 MEMF_CLEAR
| MEMF_PUBLIC
515 rkprintf("[exec] Error: Cannot install Interrupt Servers!\n");
516 // Alert(AT_DeadEnd | AN_IntrMem);
518 is
->is_Node
.ln_Type
= NT_SOFTINT
; //INTERRUPT;
519 is
->is_Node
.ln_Pri
= 0;
520 is
->is_Node
.ln_Name
= "SW Interrupt Dispatcher";
522 is
->is_Code
= (void *)SoftIntDispatch
;
529 /* Enable interrupts and set int disable level to -1 */
531 SysBase
->TDNestCnt
= -1;
532 SysBase
->IDNestCnt
= -1;
534 /* Now it's time to calculate exec checksum. It will be used
535 * in future to distinguish whether we'd had proper execBase
538 UWORD sum
=0, *ptr
= &SysBase
->SoftVer
;
539 int i
=((IPTR
)&SysBase
->IntVects
[0] - (IPTR
)&SysBase
->SoftVer
) / 2,
542 /* Calculate sum for every static part from SoftVer to ChkSum */
548 SysBase
->ChkSum
= ~sum
;
551 rkprintf("[exec] Registering Special Regions in MemList\n");
553 struct MemHeader
*mh
;
555 if ((mh
= AllocMem(sizeof(struct MemHeader
) + sizeof(struct MemChunk
), MEMF_CLEAR
)) != NULL
)
557 mh
->mh_Node
.ln_Type
=NT_MEMORY
;
558 mh
->mh_Node
.ln_Pri
= -10;
559 mh
->mh_Node
.ln_Name
= exec_sysbasename
;
560 mh
->mh_Attributes
= (MEMF_CHIP
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
| MEMF_24BITDMA
);
561 mh
->mh_First
= mh
+ sizeof(struct MemHeader
);
562 mh
->mh_First
->mc_Next
= NULL
;
563 mh
->mh_First
->mc_Bytes
= (negsize
+ sizeof(struct ExecBase
));
564 mh
->mh_Lower
= (struct MemChunk
*)(SysBase
- negsize
);
565 mh
->mh_Upper
= (APTR
)((UBYTE
*)mh
->mh_Lower
+ mh
->mh_First
->mc_Bytes
);
566 mh
->mh_Free
= 0; /* All used! */
569 Enqueue(&SysBase
->MemList
,&mh
->mh_Node
);
573 if ((mh
= AllocMem(sizeof(struct MemHeader
) + sizeof(struct MemChunk
), MEMF_CLEAR
)) != NULL
)
575 uintptr_t kernLow
= krnGetTagData(KRN_KernelLowest
, 0, msg
);
576 uintptr_t kernHigh
= krnGetTagData(KRN_KernelHighest
, 0, msg
);
578 mh
->mh_Node
.ln_Type
=NT_MEMORY
;
579 mh
->mh_Node
.ln_Pri
= -10;
580 mh
->mh_Node
.ln_Name
= exec_kernalname
;
581 mh
->mh_Attributes
= (MEMF_FAST
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
);
582 mh
->mh_First
= mh
+ sizeof(struct MemHeader
);
583 mh
->mh_First
->mc_Next
= NULL
;
584 mh
->mh_First
->mc_Bytes
= kernHigh
- kernLow
+ 1;
585 mh
->mh_Lower
= kernLow
;
586 mh
->mh_Upper
= kernHigh
;
587 mh
->mh_Free
= 0; /* All used! */
590 Enqueue(&SysBase
->MemList
,&mh
->mh_Node
);
594 rkprintf("[exec] Creating the very first task...\n");
596 /* Create boot task. Sigh, we actually create a Process sized Task,
597 since DOS needs to call things which think it has a Process and
598 we don't want to overwrite memory with something strange do we?
600 We do this until at least we can boot dos more cleanly.
606 ml
= (struct MemList
*)AllocMem(sizeof(struct MemList
), MEMF_PUBLIC
|MEMF_CLEAR
);
607 t
= (struct Task
*) AllocMem(sizeof(struct Process
), MEMF_PUBLIC
|MEMF_CLEAR
);
611 rkprintf("[exec] ERROR: Cannot create Boot Task!\n");
613 ml
->ml_NumEntries
= 1;
614 ml
->ml_ME
[0].me_Addr
= t
;
615 ml
->ml_ME
[0].me_Length
= sizeof(struct Process
);
617 NEWLIST(&t
->tc_MemEntry
);
618 NEWLIST(&((struct Process
*)t
)->pr_MsgPort
.mp_MsgList
);
620 /* It's the boot process that RunCommand()s the boot shell, so we
621 must have this list initialized */
622 NEWLIST((struct List
*)&((struct Process
*)t
)->pr_LocalVars
);
624 AddHead(&t
->tc_MemEntry
,&ml
->ml_Node
);
626 t
->tc_Node
.ln_Name
= exec_name
;
627 t
->tc_Node
.ln_Pri
= 0;
628 t
->tc_Node
.ln_Type
= NT_TASK
;
629 t
->tc_State
= TS_RUN
;
630 t
->tc_SigAlloc
= 0xFFFF;
631 t
->tc_SPLower
= 0; /* This is the system's stack */
632 t
->tc_SPUpper
= (APTR
)~0UL;
633 t
->tc_Flags
|= TF_ETASK
;
635 if (t
->tc_Flags
& TF_ETASK
)
637 t
->tc_UnionETask
.tc_ETask
= AllocVec
639 sizeof(struct IntETask
),
643 if (!t
->tc_UnionETask
.tc_ETask
)
645 rkprintf("[exec] Not enough memory for first task\n");
648 /* Initialise the ETask data. */
649 InitETask(t
, t
->tc_UnionETask
.tc_ETask
);
651 GetIntETask(t
)->iet_Context
= AllocTaskMem(t
652 , SIZEOF_ALL_REGISTERS
653 , MEMF_PUBLIC
|MEMF_CLEAR
656 if (!GetIntETask(t
)->iet_Context
)
658 rkprintf("[exec] Not enough memory for first task\n");
662 SysBase
->ThisTask
= t
;
665 rkprintf("[exec] Done. SysBase->ThisTask = 0x%012p\n[exec] Leaving supervisor mode\n", SysBase
->ThisTask
);
668 "mov %[user_ds],%%ds\n\t" // Load DS and ES
669 "mov %[user_ds],%%es\n\t"
670 "mov %%rsp,%%r12\n\t"
671 "pushq %[ds]\n\t" // SS
672 "pushq %%r12\n\t" // rSP
673 "pushq $0x3002\n\t" // rFLANGS
674 "pushq %[cs]\n\t" // CS
675 "pushq $1f\n\t iretq\n 1:"
676 ::[user_ds
]"r"(USER_DS
),[ds
]"i"(USER_DS
),[cs
]"i"(USER_CS
):"r12");
677 rkprintf("[exec] Done?! Still here?\n");
679 SysBase
->TDNestCnt
++;
684 struct TagItem
*tag
= krnFindTagItem(KRN_CmdLine
, msg
);
689 cmd
= stpblk(tag
->ti_Data
);
692 /* Split the command line */
693 temp
= strcspn(cmd
," ");
694 if (strncmp(cmd
, "DEBUG", 5)==0)
697 SetFunction(&SysBase
->LibNode
, -84*LIB_VECTSIZE
, AROS_SLIB_ENTRY(SerialRawIOInit
, Exec
));
698 SetFunction(&SysBase
->LibNode
, -86*LIB_VECTSIZE
, AROS_SLIB_ENTRY(SerialRawPutChar
, Exec
));
701 cmd
= stpblk(cmd
+temp
);
705 /* Scan for valid RomTags */
706 SysBase
->ResModules
= exec_RomTagScanner(msg
);
709 rkprintf("[exec] InitCode(RTF_SINGLETASK)\n");
714 InitCode(RTF_SINGLETASK
, 0);
717 if ((apictotal
= core_APICGetTotal()) > 1)
719 rkprintf("[exec] Waiting for %d APICs to initialise ..\n", apictotal
-1);
720 while (apicready
< apictotal
)
722 rkprintf("[exec] %d of %d APICs Ready ..\n", apicready
, apictotal
);
726 rkprintf("[exec] InitCode(RTF_COLDSTART)\n");
727 InitCode(RTF_COLDSTART
, 0);
729 rkprintf("[exec] ERROR: System Boot Failed? Halting ...\n");
730 while(1) asm volatile("hlt");
735 UBYTE _APICNO
= core_APICGetNumber();
737 rkprintf("[exec] exec_main[%d]: APIC No. %d Going IDLE (Halting)...\n", _APICNO
, _APICNO
);
738 while(1) asm volatile("hlt");
744 void exec_DefaultTaskExit()
746 struct ExecBase
*SysBase
= TLS_GET(SysBase
); //*(struct ExecBase **)4UL;
747 RemTask(SysBase
->ThisTask
);
751 AROS_LH1(struct ExecBase
*, open
,
752 AROS_LHA(ULONG
, version
, D0
),
753 struct ExecBase
*, SysBase
, 1, Exec
)
757 /* I have one more opener. */
758 SysBase
->LibNode
.lib_OpenCnt
++;
764 AROS_LH0(BPTR
, close
,
765 struct ExecBase
*, SysBase
, 2, Exec
)
769 /* I have one fewer opener. */
770 SysBase
->LibNode
.lib_OpenCnt
--;
776 struct ExecBase
*, SysBase
, 4, Exec
)
786 * This function scans kernel for existing Resident modules. If two modules
787 * with the same name are found, the one with higher version or priority wins.
789 * After building list of kernel modules, the KickTagPtr and KickMemPtr are
790 * checksummed. If checksum is proper and all memory pointed in KickMemPtr may
791 * be allocated, then all modules from KickTagPtr are added to RT list
793 * Afterwards the proper RomTagList is created (see InitCode() for details) and
794 * memory after list and nodes is freed.
800 struct Resident
*module
;
803 IPTR
**exec_RomTagScanner(struct TagItem
*msg
)
805 struct ExecBase
*SysBase
= TLS_GET(SysBase
); //*(struct ExecBase **)4UL;
807 struct List rtList
; /* List of modules */
808 UWORD
*ptr
= (UWORD
*)krnGetTagData(KRN_KernelLowest
, 0, msg
); /* Start looking here */
809 UWORD
*maxptr
= (UWORD
*)krnGetTagData(KRN_KernelHighest
, 0, msg
);
810 struct Resident
*res
; /* module found */
815 /* Initialize list */
818 rkprintf("[exec] Resident modules (addr: pri version name):\n");
820 /* Look in whole kernel for resident modules */
823 /* Do we have RTC_MATCHWORD? */
824 if (*ptr
== RTC_MATCHWORD
)
826 /* Yes, assume we have Resident */
827 res
= (struct Resident
*)ptr
;
829 /* Does rt_MatchTag point to Resident? */
830 if (res
== res
->rt_MatchTag
)
832 /* Yes, it is Resident module */
833 struct rt_node
*node
;
835 /* Check if there is module with such name already */
836 node
= (struct rt_node
*)FindName(&rtList
, res
->rt_Name
);
839 /* Yes, there was such module. It it had lower pri then replace it */
840 if (node
->node
.ln_Pri
<= res
->rt_Pri
)
842 /* If they have the same Pri but new one has higher Version, replace */
843 if ((node
->node
.ln_Pri
== res
->rt_Pri
) &&
844 (node
->module
->rt_Version
< res
->rt_Version
))
846 node
->node
.ln_Pri
= res
->rt_Pri
;
853 /* New module. Allocate some memory for it */
854 node
= (struct rt_node
*)
855 AllocMem(sizeof(struct rt_node
),MEMF_PUBLIC
|MEMF_CLEAR
);
859 node
->node
.ln_Name
= res
->rt_Name
;
860 node
->node
.ln_Pri
= res
->rt_Pri
;
863 Enqueue(&rtList
,(struct Node
*)node
);
866 ptr
+=sizeof(struct Resident
)/sizeof(UWORD
);
871 /* Get next address... */
873 } while (ptr
< maxptr
);
876 * By now we have valid (and sorted) list of kernel resident modules.
878 * Now, we will have to analyze used-defined RomTags (via KickTagPtr and
881 #warning "TODO: Implement external modules!"
883 * Everything is done now. Allocate buffer for normal RomTag and convert
887 ListLength(&rtList
,i
); /* Get length of the list */
889 RomTag
= AllocMem((i
+1)*sizeof(IPTR
),MEMF_PUBLIC
| MEMF_CLEAR
);
898 n
= (struct rt_node
*)RemHead(&rtList
);
899 rkprintf("[exec] + 0x%012lx: %4d %3d \"%s\"\n",
902 n
->module
->rt_Version
,
904 RomTag
[j
] = (IPTR
*)n
->module
;
905 FreeMem(n
, sizeof(struct rt_node
));
916 We temporarily redefine kprintf() so we use the real version in case
917 we have one of these two fn's called before AROSSupportBase is ready.
924 #define kprintf(x...)
925 #define rkprintf(x...)
926 #define vkprintf(x...)
928 struct Library
* PrepareAROSSupportBase(void)
930 struct AROSSupportBase
*AROSSupportBase
;
931 struct ExecBase
*SysBase
= TLS_GET(SysBase
); //*(struct ExecBase **)4UL;
933 if ((AROSSupportBase
= AllocMem(sizeof(struct AROSSupportBase
), MEMF_CLEAR
)) != NULL
)
935 AROSSupportBase
->kprintf
= (void *)kprintf
;
936 AROSSupportBase
->rkprintf
= (void *)rkprintf
;
937 AROSSupportBase
->vkprintf
= (void *)vkprintf
;
939 NEWLIST(&AROSSupportBase
->AllocMemList
);
943 #warning "FIXME What should we do if we fail to allocate AROSSupportBase!?!?"
946 #warning "FIXME Add code to read in the debug options"
948 return (struct Library
*)AROSSupportBase
;
952 This interrupt handler will send an interrupt to a series of queued
953 interrupt servers. Servers should return D0 != 0 (Z clear) if they
954 believe the interrupt was for them, and no further interrupts will
955 be called. This will only check the value in D0 for non-m68k systems,
956 however it SHOULD check the Z-flag on 68k systems.
958 Hmm, in that case I would have to separate it from this file in order
961 AROS_UFH5S(void, IntServer
,
962 AROS_UFHA(ULONG
, intMask
, D0
),
963 AROS_UFHA(struct Custom
*, custom
, A0
),
964 AROS_UFHA(struct List
*, intList
, A1
),
965 AROS_UFHA(APTR
, intCode
, A5
),
966 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
970 struct Interrupt
* irq
;
972 ForeachNode(intList
, irq
)
974 if( AROS_UFC4(int, irq
->is_Code
,
975 AROS_UFCA(struct Custom
*, custom
, A0
),
976 AROS_UFCA(APTR
, irq
->is_Data
, A1
),
977 AROS_UFCA(APTR
, irq
->is_Code
, A5
),
978 AROS_UFCA(struct ExecBase
*, SysBase
, A6
)