2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: m68k-amiga bootstrap to exec.
9 #include <aros/kernel.h>
10 #include <aros/debug.h>
11 #include <exec/memory.h>
12 #include <exec/resident.h>
13 #include <exec/execbase.h>
14 #include <proto/exec.h>
15 #include <hardware/cpu/memory.h>
19 #include "kernel_romtags.h"
20 #include "kernel_base.h"
22 #include "exec_intern.h"
24 #include "amiga_hwreg.h"
25 #include "amiga_irq.h"
30 #define SS_STACK_SIZE 0x02000
32 /* Must match with AROSBootstrap.c! */
33 #define ABS_BOOT_MAGIC 0x4d363802
37 struct TagItem
*kerneltags
;
41 LONG magicfastmemsize
;
44 static struct BootStruct
*GetBootStruct(struct ExecBase
*eb
)
47 struct BootStruct
*BootS
= (struct BootStruct
*)eb
->DebugData
;
48 if (BootS
->magic
== ABS_BOOT_MAGIC
)
54 extern const struct Resident Exec_resident
;
55 extern struct ExecBase
*AbsExecBase
;
57 static void protectKick(struct MemHeader
*mh
, struct MemList
*ml
, ULONG
*mask
);
59 extern void __attribute__((interrupt
)) Exec_Supervisor_Trap (void);
61 #define _AS_STRING(x) #x
62 #define AS_STRING(x) _AS_STRING(x)
64 /* Create a sign extending call stub:
66 * jsr AROS_SLIB_ENTRY(funcname, libname, funcid)
68 * ext.w %d0 // EXT_BYTE only
70 * ext.l %d0 // EXT_BYTE and EXT_WORD
75 #define EXT_BYTE(lib, libname, funcname, funcid) \
77 void libname##_##funcname##_Wrapper(void) \
79 "jsr " AS_STRING(AROS_SLIB_ENTRY(funcname, libname, funcid)) "\n" \
83 /* Insert into the library's jumptable */ \
84 __AROS_SETVECADDR(lib, funcid, libname##_##funcname##_Wrapper); \
86 #define EXT_WORD(lib, libname, funcname, funcid) \
88 void libname##_##funcname##_Wrapper(void) \
90 "jsr " AS_STRING(AROS_SLIB_ENTRY(funcname, libname, funcid)) "\n" \
93 /* Insert into the library's jumptable */ \
94 __AROS_SETVECADDR(lib, funcid, libname##_##funcname##_Wrapper); \
97 * Create a register preserving call stub:
99 * movem.l %d0-%d1/%a0-%a1,%sp@-
101 * jsr AROS_SLIB_ENTRY(funcname, libname, funcid)
103 * movem.l %sp@+,%d0-%d1/%d0-%a1
108 #define PRESERVE_ALL(lib, libname, funcname, funcid) \
110 void libname##_##funcname##_Wrapper(void) \
112 "movem.l %d0-%d1/%a0-%a1,%sp@-\n" \
113 "jsr " AS_STRING(AROS_SLIB_ENTRY(funcname, libname, funcid)) "\n" \
114 "movem.l %sp@+,%d0-%d1/%a0-%a1\n" \
116 /* Insert into the library's jumptable */ \
117 __AROS_SETVECADDR(lib, funcid, libname##_##funcname##_Wrapper); \
119 /* Inject arbitrary code into the jump table
120 * Used for GetCC and nano-stubs
122 #define FAKE_IT(lib, libname, funcname, funcid, ...) \
124 UWORD *asmcall = (UWORD *)__AROS_GETJUMPVEC(lib, funcid); \
125 const UWORD code[] = { __VA_ARGS__ }; \
126 asmcall[0] = code[0]; \
127 asmcall[1] = code[1]; \
128 asmcall[2] = code[2]; \
130 /* Inject a 'move.w #value,%d0; rts" sequence into the
131 * jump table, to fake an private syscall.
133 #define FAKE_ID(lib, libname, funcname, funcid, value) \
134 FAKE_IT(lib, libname, funcname, funcid, 0x303c, value, 0x4e75)
136 extern void SuperstackSwap(void);
137 /* This calls the register-ABI library
138 * routine Exec/InitCode, for use in NewStackSwap()
140 static LONG
doInitCode(struct BootStruct
*BootS
)
142 /* Attempt to allocate a new supervisor stack */
147 if (BootS
&& BootS
->ss_address
) {
148 ss_stack
= BootS
->ss_address
;
149 ss_stack_size
= BootS
->ss_size
;
151 ss_stack
= AllocMem(SS_STACK_SIZE
, MEMF_ANY
| MEMF_CLEAR
| MEMF_REVERSE
);
152 if (ss_stack
&& ((ULONG
)ss_stack
& (PAGE_SIZE
- 1))) {
153 /* Normally ss_stack is page aligned because it is first MEMF_REVERSE
154 * allocation. But we must check it because enabled mungwall or expansion
155 * boot rom code can allocate some memory.
157 FreeMem(ss_stack
, SS_STACK_SIZE
);
158 ss_stack
= AllocMem(SS_STACK_SIZE
+ PAGE_SIZE
- 1, MEMF_ANY
| MEMF_CLEAR
| MEMF_REVERSE
);
159 ss_stack
= (APTR
)(((ULONG
)ss_stack
+ PAGE_SIZE
- 1) & PAGE_MASK
);
161 ss_stack_size
= SS_STACK_SIZE
;
163 DEBUGPUTHEX(("SS lower", (ULONG
)ss_stack
));
164 DEBUGPUTHEX(("SS upper", (ULONG
)ss_stack
+ ss_stack_size
- 1));
165 if (ss_stack
== NULL
) {
166 DEBUGPUTS(("Strange. Can't allocate a new system stack\n"));
167 Early_Alert(CODE_ALLOC_FAIL
);
170 SysBase
->SysStkLower
= ss_stack
;
171 SysBase
->SysStkUpper
= ss_stack
+ ss_stack_size
;
174 Supervisor((ULONG_FUNC
)SuperstackSwap
);
177 InitCode(RTF_COLDSTART
, 0);
182 extern BYTE _rom_start
;
183 extern BYTE _rom_end
;
184 extern BYTE _ext_start
;
185 extern BYTE _ext_end
;
189 /* Protect the 'ROM' if it is actually in RAM.
191 static APTR
protectAlloc(struct MemHeader
*mh
, APTR start
, APTR end
, const UBYTE
*name
, BOOL pagealign
)
197 start
= (APTR
)((ULONG
)start
& PAGE_MASK
);
198 length
= (end
- start
+ PAGE_SIZE
- 1) & PAGE_MASK
;
200 length
= end
- start
;
202 tmp
= Early_AllocAbs(mh
, start
, length
);
207 DEBUGPUTS(("<no name>"));
210 DEBUGPUTHEX(("\nStart ", (ULONG
)start
));
211 DEBUGPUTHEX(("End ", (ULONG
)end
- 1));
212 DEBUGPUTHEX(("Size ", length
));
215 static void protectROM(struct MemHeader
*mh
)
217 DEBUGPUTHEX(("Protect", (IPTR
)mh
));
218 protectAlloc(mh
, &_ss
, &_ss_end
, "SS", FALSE
);
219 DEBUGPUTHEX(("First ", (IPTR
)mh
->mh_First
));
220 DEBUGPUTHEX(("Bytes ", (IPTR
)mh
->mh_First
->mc_Bytes
));
223 static struct MemHeader
*addmemoryregion(ULONG startaddr
, ULONG size
, struct MemList
*ml
, ULONG
*mask
, BOOL magicfast
)
228 krnCreateMemHeader("magic fast memory", -8,
229 (APTR
)startaddr
, size
,
230 MEMF_FAST
| MEMF_PUBLIC
| ((startaddr
& 0xff000000) == 0 ? MEMF_24BITDMA
: 0));
231 } else if (startaddr
< 0x00c00000) {
232 krnCreateMemHeader("chip memory", -10,
233 (APTR
)startaddr
, size
,
234 MEMF_CHIP
| MEMF_KICK
| MEMF_PUBLIC
| MEMF_LOCAL
| MEMF_24BITDMA
);
236 krnCreateMemHeader("memory", -5,
237 (APTR
)startaddr
, size
,
238 MEMF_FAST
| MEMF_KICK
| MEMF_PUBLIC
| MEMF_LOCAL
| ((startaddr
& 0xff000000) == 0 ? MEMF_24BITDMA
: 0));
241 /* Must be done first, in case SS is in it */
242 protectKick((struct MemHeader
*)startaddr
, ml
, mask
);
244 protectROM((struct MemHeader
*)startaddr
);
245 return (struct MemHeader
*)startaddr
;
248 static BOOL
IsSysBaseValidNoVersion(struct ExecBase
*sysbase
)
250 if (sysbase
== NULL
|| (((ULONG
)sysbase
) & 0x80000001))
252 if (sysbase
->ChkBase
!= ~(IPTR
)sysbase
)
254 return GetSysBaseChkSum(sysbase
) == 0xffff;
257 /* In the following functions, we use bit 0 of the
258 * MemEntry->me_Addr to indicate whether or not
259 * that MemEntry in the MemList has been 'locked down'
261 * (addr & 1) = unallocated
262 * !(addr & 1) = allocated
265 /* Remove all bit 0 marks
267 /* We support up to 32 KickMemPtr tags in pre-expansion.library RAM */
268 static void markKick(struct MemList
*ml
, ULONG
*mask
)
271 for (ndx
= 0; ml
; ml
= (struct MemList
*)ml
->ml_Node
.ln_Succ
) {
273 for (i
= 0; i
< ml
->ml_NumEntries
; i
++, ndx
++) {
275 (*mask
) |= (1 << ndx
);
280 static void protectKick(struct MemHeader
*mh
, struct MemList
*ml
, ULONG
*mask
)
283 ULONG protectKickBits
= *mask
;
285 DEBUGPUTHEX(("protectKick", (IPTR
)ml
));
292 for (i
= 0; i
< ml
->ml_NumEntries
; i
++, ndx
++) {
293 APTR start
= (APTR
)((IPTR
)ml
->ml_ME
[i
].me_Addr
& ~1);
294 APTR end
= start
+ ml
->ml_ME
[i
].me_Length
;
296 /* Already allocated? */
297 if (ndx
>= 32 || !(protectKickBits
& (1 << ndx
)))
300 if ((mh
->mh_Lower
> start
) ||
301 (mh
->mh_Upper
< end
))
304 if (protectAlloc(mh
, start
, end
, ml
->ml_Node
.ln_Name
, FALSE
)) {
305 protectKickBits
&= ~(1 << ndx
);
308 ml
= (struct MemList
*)ml
->ml_Node
.ln_Succ
;
311 *mask
= protectKickBits
;
315 void InitKickMemDiag(void)
317 struct MemList
*ml
= PrivExecBase(SysBase
)->PlatformData
.ep_KickMemPtr
;
318 DEBUGPUTS(("KickMem allocation phase 2/2\n"));
321 for (i
= 0; i
< ml
->ml_NumEntries
; i
++) {
322 APTR start
= ml
->ml_ME
[i
].me_Addr
;
323 ULONG len
= ml
->ml_ME
[i
].me_Length
;
325 DEBUGPUTHEX(("Addr", (IPTR
)start
));
326 DEBUGPUTHEX(("Len", len
));
328 /* Simply attempt to allocate everything again */
329 if (InternalAllocAbs(start
, len
, SysBase
))
330 DEBUGPUTS(("-> Allocated\n"));
332 ml
= (struct MemList
*)ml
->ml_Node
.ln_Succ
;
336 static BOOL
InitKickMem(ULONG
*mask
, struct ExecBase
*SysBase
)
339 struct MemList
*ml
= SysBase
->KickMemPtr
;
340 ULONG protectKickBits
= *mask
;
343 DEBUGPUTHEX(("KickMemPtr", (IPTR
)ml
));
347 for (i
= 0; i
< ml
->ml_NumEntries
; i
++,ndx
++) {
348 APTR start
= ml
->ml_ME
[i
].me_Addr
;
349 ULONG len
= ml
->ml_ME
[i
].me_Length
;
351 /* Already allocated? */
352 if (ndx
< 32 && !(protectKickBits
& (1 << ndx
)))
355 DEBUGPUTHEX(("Addr", (IPTR
)start
));
356 DEBUGPUTHEX(("Len", len
));
358 if (TypeOfMem(start
) == 0) {
359 /* Do not stop if memory is not in memory list yet */
360 DEBUGPUTS(("-> unavailable\n"));
365 /* Use the non-mungwalling AllocAbs */
366 if (!InternalAllocAbs(start
, len
, SysBase
))
369 protectKickBits
|= (1 << ndx
);
371 ml
= (struct MemList
*)ml
->ml_Node
.ln_Succ
;
374 *mask
= protectKickBits
;
378 #if 0 // debug stuff, do not remove
379 static ULONG
SumKickDataX(struct ExecBase
*sb
)
383 struct ExecBase
*sysbase
= sb
;
385 if (sysbase
->KickTagPtr
) {
386 IPTR
*list
= sysbase
->KickTagPtr
;
389 chksum
+= (ULONG
)*list
;
390 DEBUGPUTHEX(("LIST", (ULONG
)list
));
391 DEBUGPUTHEX(("LISTP", (ULONG
)*list
));
392 DEBUGPUTHEX(("CHK", chksum
));
393 /* on amiga, if bit 31 is set then this points to another list of
394 * modules rather than pointing to a single module. bit 31 is
395 * inconvenient on architectures where code may be loaded above
396 * 2GB. on these platforms we assume aligned pointers and use bit
399 if(*list
& 0x80000000) { list
= (IPTR
*)(*list
& 0x7fffffff); continue; }
401 if(*list
& 0x1) { list
= (IPTR
*)(*list
& ~(IPTR
)0x1); continue; }
408 if (sysbase
->KickMemPtr
) {
409 struct MemList
*ml
= (struct MemList
*)sysbase
->KickMemPtr
;
412 ULONG
*p
= (ULONG
*)ml
;
413 for (i
= 0; i
< sizeof(struct MemList
) / sizeof(ULONG
); i
++)
415 DEBUGPUTHEX(("MEM", (ULONG
)p
));
416 DEBUGPUTHEX(("CHK", chksum
));
417 ml
= (struct MemList
*)ml
->ml_Node
.ln_Succ
;
421 if (isdata
&& !chksum
)
427 void doColdCapture(void)
429 APTR ColdCapture
= SysBase
->ColdCapture
;
430 if (ColdCapture
== NULL
)
433 if (((ULONG
*)ColdCapture
)[1] == AROS_MAKE_ID('F','A','K','E')) {
434 /* Fake SysBase installed by AROSBootstrap.
436 * In this case, ColdCapture is the trampoline executed
437 * by the AOS ROM to get into AROS. We need to keep
438 * ColdCapture around in AROS SysBase, but we don't
439 * want to execute it (and cause an infinite loop).
441 DEBUGPUTS(("[ColdCapture] Ignoring AOS->AROS trampoline\n"));
445 SysBase
->ColdCapture
= NULL
;
446 /* ColdCapture calling method is a little
447 * strange. It's in supervisor mode, requires
448 * the return location in A5, and SysBase in A6.
457 : "m" (ColdCapture
), "m" (SysBase
)
458 : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
459 "a0", "a1", "a2", "a3", "a4", "a5", "a6");
462 static void RomInfo(IPTR rom
)
464 APTR ptr
= (APTR
)rom
;
467 if ((*(UWORD
*)(ptr
+ 8) == 0x0000) &&
468 (*(UWORD
*)(ptr
+ 10) == 0xffff) &&
469 (*(UWORD
*)(ptr
+ 12) == *(UWORD
*)(ptr
+ 16)) &&
470 (*(UWORD
*)(ptr
+ 14) == *(UWORD
*)(ptr
+ 18)) &&
471 (*(UWORD
*)(ptr
+ 20) == 0xffff) &&
472 (*(UWORD
*)(ptr
+ 22) == 0xffff)) {
473 DEBUGPUTHEX(("ROM Location", rom
));
474 DEBUGPUTD((" Version", *(UWORD
*)(ptr
+ 12)));
475 DEBUGPUTD((" Revision", *(UWORD
*)(ptr
+ 14)));
477 DEBUGPUTS((" ROM Type: ")); DEBUGPUTS((str
)); DEBUGPUTS(("\n"));
478 str
+= strlen(str
) + 1;
479 DEBUGPUTS((" Copyright: ")); DEBUGPUTS((str
));
480 str
+= strlen(str
) + 1;
482 str
+= strlen(str
) + 1;
485 str
+= strlen(str
) + 1;
486 DEBUGPUTS((" ROM Model: ")); DEBUGPUTS((str
));
491 void exec_boot(ULONG
*membanks
, ULONG
*cpupcr
)
494 struct ExecBase
*oldSysBase
= *(APTR
*)4;
496 DEBUGPUTHEX(("X SysBase->KickCheckSum", (ULONG
)oldSysBase
->KickCheckSum
));
497 SumKickDataX(oldSysBase
);
500 struct TagItem bootmsg
[] = {
501 /* nomonitors - Until we have working m68k PCI support,
502 * attempting to load the monitor drivers
503 * just wastes a lot of time during boot
505 #if AROS_SERIAL_DEBUG
506 { KRN_CmdLine
, (IPTR
)"nomonitors sysdebug=InitCode" },
507 // { KRN_CmdLine, (IPTR)"nomonitors sysdebug=InitCode,debugmmu,mungwall" },
509 { KRN_CmdLine
, (IPTR
)"nomonitors" },
511 { KRN_KernelStackBase
, (IPTR
)&_ss
},
512 { KRN_KernelStackSize
, (IPTR
)(&_ss_end
- &_ss
) },
515 struct TagItem
*bootmsgptr
= bootmsg
;
518 BOOL wasvalid
, arosbootstrapmode
;
520 struct MemHeader
*mh
;
521 LONG oldLastAlert
[4];
524 APTR ColdCapture
= NULL
, CoolCapture
= NULL
, WarmCapture
= NULL
;
525 ULONG KickMemMask
= 0;
526 APTR KickMemPtr
= NULL
, KickTagPtr
= NULL
, KickCheckSum
= NULL
;
527 struct BootStruct
*BootS
= NULL
;
528 /* We can't use the global 'SysBase' symbol, since
529 * the compiler does not know that PrepareExecBase
530 * may change it out from under us.
532 struct ExecBase
*oldSysBase
= *(APTR
*)4;
533 #define SysBase CANNOT_USE_SYSBASE_SYMBOL_HERE
535 #if AROS_SERIAL_DEBUG
539 trap
= (APTR
*)(NULL
);
541 /* Set all the exceptions to the Early_Exception
543 for (i
= 2; i
< 64; i
++) {
545 trap
[i
] = Early_Exception
;
548 /* Let the world know we exist
551 DEBUGPUTS(("[reset]\n"));
556 /* Convert CPU/FPU flags to AttnFlags */
557 attnflags
= cpupcr
[0] & 0xffff;
558 if (attnflags
& (AFF_68030
| AFF_68040
| AFF_68060
))
559 attnflags
|= AFF_ADDR32
;
560 if (cpupcr
[0] & 0xffff0000) {
561 attnflags
|= AFF_FPU
;
562 if (attnflags
& (AFF_68040
| AFF_68060
))
563 attnflags
|= AFF_FPU40
;
564 // AFF_68881 | AFF_68882 set only if 040/060 math emulation running
565 else if (((cpupcr
[0] >> 16) & 0xff) <= 0x1f)
566 attnflags
|= AFF_68881
;
568 attnflags
|= AFF_68881
| AFF_68882
;
571 #if AROS_SERIAL_DEBUG
572 DEBUGPUTS(("CPU: "));
573 if (attnflags
& AFF_68060
)
574 DEBUGPUTS(("68060"));
575 else if (attnflags
& AFF_68040
)
576 DEBUGPUTS(("68040"));
577 else if (attnflags
& AFF_68030
)
578 DEBUGPUTS(("68030"));
579 else if (attnflags
& AFF_68020
) {
580 if (attnflags
& AFF_ADDR32
)
581 DEBUGPUTS(("68020"));
583 DEBUGPUTS(("68EC020"));
584 } else if (attnflags
& AFF_68010
)
585 DEBUGPUTS(("68010"));
587 DEBUGPUTS(("68000"));
588 DEBUGPUTS((" FPU: "));
589 if (attnflags
& AFF_FPU40
) {
590 if (attnflags
& AFF_68060
)
591 DEBUGPUTS(("68060"));
592 else if (attnflags
& AFF_68040
)
593 DEBUGPUTS(("68040"));
596 } else if (attnflags
& AFF_68882
)
597 DEBUGPUTS(("68882"));
598 else if (attnflags
& AFF_68881
)
599 DEBUGPUTS(("68881"));
604 DEBUGPUTHEX(("PCR", cpupcr
[1]));
608 /* Zap out old SysBase if invalid */
609 arosbootstrapmode
= FALSE
;
610 wasvalid
= IsSysBaseValid(oldSysBase
);
612 DEBUGPUTHEX(("[SysBase] was at", (ULONG
)oldSysBase
));
614 wasvalid
= IsSysBaseValidNoVersion(oldSysBase
);
616 arosbootstrapmode
= TRUE
;
617 DEBUGPUTHEX(("[SysBase] fakebase at", (ULONG
)oldSysBase
));
618 BootS
= GetBootStruct(oldSysBase
);
620 bootmsgptr
= BootS
->kerneltags
;
623 DEBUGPUTHEX(("[SysBase] invalid at", (ULONG
)oldSysBase
));
627 if (bootmsgptr
[0].ti_Tag
== KRN_CmdLine
) {
628 DEBUGPUTS(("[SysBase] kernel commandline '"));
629 DEBUGPUTS(((CONST_STRPTR
)bootmsgptr
[0].ti_Data
));
634 /* Save reset proof vectors */
635 ColdCapture
= oldSysBase
->ColdCapture
;
636 CoolCapture
= oldSysBase
->CoolCapture
;
637 WarmCapture
= oldSysBase
->WarmCapture
;
638 KickMemPtr
= oldSysBase
->KickMemPtr
;
639 KickTagPtr
= oldSysBase
->KickTagPtr
;
640 KickCheckSum
= oldSysBase
->KickCheckSum
;
642 /* Mark the oldSysBase as processed */
646 if (BootS
&& BootS
->magicfastmem
) {
647 /* Add early magic fast ram pool
648 * Makes it possible to have execbase and others in fast ram even
649 * if fast ram is non-autocnfig diagrom type.
652 membanks
[0] = (ULONG
)BootS
->magicfastmem
;
653 membanks
[1] = BootS
->magicfastmemsize
;
656 /* Adjust to skip the first 1K/4K bytes of
657 * Chip RAM. It's reserved for the Trap area.
659 for (i
= 0; membanks
[i
+ 2 + 1]; i
+= 2);
660 if (arosbootstrapmode
|| (attnflags
& AFF_68030
))
661 membanks
[i
+ 0] = 0x1000;
663 membanks
[i
+ 0] = 0x400;
664 membanks
[i
+ 1] -= membanks
[i
+ 0];
666 #if AROS_SERIAL_DEBUG
667 for (i
= 0; membanks
[i
+ 1]; i
+= 2) {
668 ULONG addr
= membanks
[i
+ 0];
669 ULONG size
= membanks
[i
+ 1];
670 DEBUGPUTHEX(("RAM lower", addr
));
671 DEBUGPUTHEX(("RAM upper", addr
+ size
- 1));
675 kickrom
[0] = (UWORD
*)&_rom_start
;
676 kickrom
[1] = (UWORD
*)&_rom_end
;
677 kickrom
[2] = (UWORD
*)0x00f00000;
678 kickrom
[3] = (UWORD
*)0x00f80000;
679 kickrom
[4] = (UWORD
*)&_ext_start
;
680 kickrom
[5] = (UWORD
*)&_ext_end
;
681 kickrom
[6] = (UWORD
*)~0;
682 kickrom
[7] = (UWORD
*)~0;
684 /* Look for 'HELP' at address 0 - we're recovering
687 if (trap
[0] == (APTR
)0x48454c50) {
688 for (i
= 0; i
< 4; i
++)
689 oldLastAlert
[i
] = (LONG
)trap
[64 + i
];
691 DEBUGPUTHEX(("LastAlert Alert", oldLastAlert
[0]));
692 DEBUGPUTHEX(("LastAlert Task", oldLastAlert
[1]));
694 oldLastAlert
[0] = (LONG
)-1;
700 /* Clear alert marker */
703 DEBUGPUTHEX(("SS lower", (ULONG
)&_ss
));
704 DEBUGPUTHEX(("SS upper", (ULONG
)&_ss_end
- 1));
706 Early_ScreenCode(CODE_RAM_CHECK
);
708 /* Mark all the kick memory as 'unprotected' */
709 markKick(KickMemPtr
, &KickMemMask
);
711 mh
= addmemoryregion(membanks
[0], membanks
[1], KickMemPtr
, &KickMemMask
, BootS
&& (ULONG
)BootS
->magicfastmem
== membanks
[0]);
713 DEBUGPUTS(("Can't create initial memory header!\n"));
714 Early_Alert(AT_DeadEnd
| AG_NoMemory
);
718 * Call the SysBase initialization.
720 Early_ScreenCode(CODE_EXEC_CHECK
);
721 if (!krnPrepareExecBase(kickrom
, mh
, bootmsgptr
))
722 Early_Alert(AT_DeadEnd
| AG_MakeLib
| AO_ExecLib
);
724 /* From here on, we can reference SysBase */
726 DEBUGPUTHEX(("[SysBase at]", (ULONG
)SysBase
));
728 PrivExecBase(SysBase
)->PlatformData
.BootMsg
= bootmsgptr
;
729 SysBase
->ThisTask
->tc_SPLower
= &_ss
;
730 SysBase
->ThisTask
->tc_SPUpper
= &_ss_end
;
733 SysBase
->ColdCapture
= ColdCapture
;
734 SysBase
->CoolCapture
= CoolCapture
;
735 SysBase
->WarmCapture
= WarmCapture
;
737 SysBase
->ChkSum
= GetSysBaseChkSum(SysBase
) ^ 0xffff;
738 SysBase
->KickMemPtr
= KickMemPtr
;
739 SysBase
->KickTagPtr
= KickTagPtr
;
740 SysBase
->KickCheckSum
= KickCheckSum
;
743 SysBase
->SysStkUpper
= (APTR
)&_ss_end
;
744 SysBase
->SysStkLower
= (APTR
)&_ss
;
746 /* Mark what the last alert was */
747 for (i
= 0; i
< 4; i
++)
748 SysBase
->LastAlert
[i
] = oldLastAlert
[i
];
750 SysBase
->AttnFlags
= attnflags
;
752 /* Inject code for GetCC, depending on CPU model */
753 if (SysBase
->AttnFlags
& AFF_68010
) {
754 /* move.w %ccr,%d0; rts; nop */
755 FAKE_IT(SysBase
, Exec
, GetCC
, 88, 0x42c0, 0x4e75, 0x4e71);
757 /* move.w %sr,%d0; rts; nop */
758 FAKE_IT(SysBase
, Exec
, GetCC
, 88, 0x40c0, 0x4e75, 0x4e71);
761 #ifdef THESE_ARE_KNOWN_SAFE_ASM_ROUTINES
762 PRESERVE_ALL(SysBase
, Exec
, Disable
, 20);
763 PRESERVE_ALL(SysBase
, Exec
, Enable
, 21);
764 PRESERVE_ALL(SysBase
, Exec
, Forbid
, 22);
766 PRESERVE_ALL(SysBase
, Exec
, Permit
, 23);
767 PRESERVE_ALL(SysBase
, Exec
, ObtainSemaphore
, 94);
768 PRESERVE_ALL(SysBase
, Exec
, ReleaseSemaphore
, 95);
769 PRESERVE_ALL(SysBase
, Exec
, ObtainSemaphoreShared
, 113);
771 /* Functions that need sign extension */
772 EXT_BYTE(SysBase
, Exec
, SetTaskPri
, 50);
773 EXT_BYTE(SysBase
, Exec
, AllocSignal
, 55);
775 /* Only add the 2 standard ROM locations, since
776 * we may get memory at 0x00f00000, or when we
777 * are ReKicked, at the rom-in-ram locations.
779 krnCreateROMHeader("Kickstart ROM", (APTR
)0x00f80000, (APTR
)0x00ffffff);
780 krnCreateROMHeader("Kickstart ROM", (APTR
)0x00e00000, (APTR
)0x00e7ffff);
782 /* Add remaining memory regions */
783 for (i
= 2; membanks
[i
+ 1]; i
+= 2) {
784 IPTR addr
= membanks
[i
];
785 ULONG size
= membanks
[i
+ 1];
787 DEBUGPUTHEX(("RAM Addr: ", addr
));
788 DEBUGPUTHEX(("RAM Size: ", size
));
789 mh
= addmemoryregion(addr
, size
, KickMemPtr
, &KickMemMask
, FALSE
);
790 Enqueue(&SysBase
->MemList
, &mh
->mh_Node
);
792 /* Adjust MaxLocMem and MaxExtMem as needed */
793 if (addr
< 0x00200000)
794 SysBase
->MaxLocMem
= (size
+ 0xffff) & 0xffff0000;
795 else if (addr
< 0x00d00000)
796 SysBase
->MaxExtMem
= size
? (APTR
)(((0xc00000 + (size
+ 0xffff)) & 0xffff0000)) : 0;
799 /* Now that we have a valid SysBase,
800 * we can call ColdCapture
805 /* Seal up SysBase's critical variables */
808 /* Set privilege violation trap - we
809 * need this to support the Exec/Supervisor call
811 trap
[8] = Exec_Supervisor_Trap
;
813 oldmem
= AvailMem(MEMF_FAST
);
815 /* SysBase is complete, now we can enable instruction caches safely. */
816 CacheControl(CACRF_EnableI
, CACRF_EnableI
);
819 /* Ok, let's start the system. We have to
820 * do this in Supervisor context, since some
821 * expansions ROMs (Cyperstorm PPC) expect it.
823 DEBUGPUTS(("[start] InitCode(RTF_SINGLETASK, 0)\n"));
824 InitCode(RTF_SINGLETASK
, 0);
826 /* Autoconfig ram expansions are now configured */
828 /* If oldSysBase is not NULL, that means that it
829 * (a) wasn't valid before when we only had MEMF_LOCAL
830 * ram and (b) could possibly be in the MEMF_KICK memory
831 * we just got. Let's check it and find out if we
832 * can use it's capture vectors.
834 if (oldSysBase
&& IsSysBaseValidNoVersion(oldSysBase
)) {
835 /* Save reset proof vectors */
836 SysBase
->ColdCapture
= oldSysBase
->ColdCapture
;
837 SysBase
->CoolCapture
= oldSysBase
->CoolCapture
;
838 SysBase
->WarmCapture
= oldSysBase
->WarmCapture
;
840 SysBase
->KickMemPtr
= oldSysBase
->KickMemPtr
;
841 SysBase
->KickTagPtr
= oldSysBase
->KickTagPtr
;
842 SysBase
->KickCheckSum
= oldSysBase
->KickCheckSum
;
844 /* Re-seal SysBase */
849 /* Before we allocate anything else, we need to
850 * lock down the entries in KickMemPtr
852 * If we get a single failure, try again in diag module
854 if (SysBase
->KickCheckSum
) {
855 if (SysBase
->KickCheckSum
== (APTR
)SumKickData()) {
856 DEBUGPUTS(("KickMem allocation phase 1/2\n"));
857 if (!InitKickMem(&KickMemMask
, SysBase
)) {
858 /* We'll try again after diag rom module */
859 DEBUGPUTS(("KickMem failed an allocation.\n"));
861 DEBUGPUTS(("All KickMem nodes allocated succesfully.\n"));
864 DEBUGPUTS(("[KickMem] Checksum mismatch\n"));
865 SysBase
->KickTagPtr
= NULL
;
867 PrivExecBase(SysBase
)->PlatformData
.ep_KickMemPtr
= SysBase
->KickMemPtr
;
868 SysBase
->KickMemPtr
= NULL
;
869 SysBase
->KickCheckSum
= (APTR
)SumKickData();
872 if ((AvailMem(MEMF_FAST
) > (oldmem
+ 256 * 1024)) &&
873 ((TypeOfMem(SysBase
) & MEMF_CHIP
) ||
874 ((ULONG
)SysBase
>= 0x00a00000ul
&& (ULONG
)SysBase
< 0x01000000ul
))) {
875 /* Move execbase to real fast if available now */
876 SysBase
= PrepareExecBaseMove(SysBase
);
877 AbsExecBase
= SysBase
;
878 DEBUGPUTHEX(("[Sysbase] now at", (ULONG
)SysBase
));
881 /* Initialize IRQ subsystem */
882 AmigaIRQInit(SysBase
);
884 /* Set privilege violation trap again.
885 * AmigaIRQInit may have blown it away.
887 trap
[8] = Exec_Supervisor_Trap
;
889 /* Attempt to allocate a real stack, and switch to it. */
891 const ULONG size
= AROS_STACKSIZE
;
894 usp
= AllocMem(size
* sizeof(IPTR
), MEMF_PUBLIC
);
896 DEBUGPUTS(("Can't allocate a new stack for Exec... Strange.\n"));
897 Early_Alert(CODE_ALLOC_FAIL
);
901 /* Leave supervisor mode, switch power led on */
911 : "a" (&usp
[size
-3]),
917 /* We shouldn't get here */
918 Early_Alert(CODE_EXEC_FAIL
);