2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
5 Desc: m68k-amiga bootstrap to exec.
9 #include <aros/kernel.h>
10 #include <exec/resident.h>
11 #include <exec/execbase.h>
12 #include <exec/memory.h>
13 #include <proto/exec.h>
15 #include "exec_intern.h"
16 #include "kernel_romtags.h"
18 #include "amiga_hwreg.h"
19 #include "amiga_irq.h"
21 extern const struct Resident Exec_resident
;
23 extern void __clear_bss(const struct KernelBSS
*bss
);
25 #define RGB(r,g,b) ((((r) & 0xf) << 8) | (((g) & 0xf) << 4) | (((b) & 0xf) << 0))
27 #define CODE_ROM_CHECK RGB( 4, 4, 4)
28 #define CODE_RAM_CHECK RGB( 9, 9, 9)
29 #define CODE_EXEC_CHECK RGB( 9, 0, 9)
30 #define CODE_TRAP_FAIL RGB(12, 12, 0)
32 static void Exec_ScreenCode(UWORD code
)
34 reg_w(BPLCON0
, 0x0200);
35 reg_w(BPL1DAT
, 0x0000);
41 /* Set the debug UART to 9600 */
42 reg_w(SERPER
, SERPER_BAUD(SERPER_BASE_PAL
, 9600));
45 int DebugPutChar(register int chr
)
47 while ((reg_r(SERDATR
) & SERDATR_TBE
) == 0);
49 /* Output a char to the debug UART */
50 reg_w(SERDAT
, SERDAT_STP8
| SERDAT_DB8(chr
));
55 int DebugGetChar(void)
57 while ((reg_r(SERDATR
) & SERDATR_RBF
) == 0);
59 return SERDATR_DB8_of(reg_r(SERDATR
));
64 #include "m68k-gdbstub.c"
67 static __attribute__((interrupt
)) void Exec_FatalException(void)
71 Exec_ScreenCode(CODE_TRAP_FAIL
);
73 /* FIXME: Idle loop delay
74 * We should really wait for a number of
75 * verical retrace intervals
77 for (i
= 0; i
< 150000; i
++);
79 /* Reset everything but the CPU, then restart
80 * at the ROM exception vector
87 static void DebugPuts(register const char *buff
)
89 for (; *buff
!= 0; buff
++)
93 extern void *_ram_start
;
94 #define MEM_START ((ULONG)(&_ram_start))
95 #define MEM_SIZE (0x00200000-MEM_START)
97 void DebugPutHex(const char *what
, ULONG val
)
102 for (i
= 0; i
< 8; i
++) {
103 DebugPutChar("0123456789abcdef"[(val
>> (28 - (i
* 4))) & 0xf]);
108 extern void __attribute__((interrupt
)) Exec_Supervisor_Trap (void);
110 void __attribute__((interrupt
)) cpu_detect_trap(void);
113 " .globl cpu_detect_trap\n"
115 " addq.l #2,%sp@(2)\n"
120 /* Detect 68000 vs 68010/68020 */
121 ULONG
cpu_detect(void)
123 volatile APTR
*trap
= (NULL
+ 8);
128 trap
[6] = cpu_detect_trap
;
132 : "=m" (ret
) : : "%d0" );
141 #if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
143 * Create a call stub like so:
145 * movem.l %d0-%d1/%a0-%a1,%sp@-
147 * jsr AROS_SLIB_ENTRY(funcname, libname)
149 * movem.l %sp@+,%d0-%d1/%d0-%a1
154 #define PRESERVE_ALL(lib, libname, funcname, funcid) \
157 IPTR func = (IPTR)__AROS_GETVECADDR(lib, funcid); \
158 asmcall = AllocMem(8 * sizeof(UWORD), MEMF_PUBLIC); \
159 /* NOTE: 'asmcall' will intentionally never be freed */ \
160 asmcall[0] = 0x48e7; \
161 asmcall[1] = 0xc0c0; \
162 asmcall[2] = 0x4eb9; \
163 asmcall[3] = (func >> 16) & 0xffff; \
164 asmcall[4] = (func >> 0) & 0xffff; \
165 asmcall[5] = 0x4cdf; \
166 asmcall[6] = 0x0303; \
167 asmcall[7] = 0x4e75; \
168 /* Insert into the library's jumptable */ \
169 __AROS_SETVECADDR(lib, funcid, asmcall); \
172 /* Not needed on EABI */
173 #define PRESERVE_ALL(lib, libname, funcname, funcid) do { } while (0)
179 extern void *_bss_end
;
180 extern void *_ss_stack_upper
;
181 extern void *_ss_stack_lower
;
194 const struct KernelBSS kbss
[2] = {
197 .len
= &_bss_end
- &_bss
,
204 struct ExecBase
*sysBase
;
206 struct MemHeader ChipRAM
;
207 struct MemHeader
*mh
= &ChipRAM
;
209 *((APTR
*)(NULL
+ 0x4)) = NULL
;
211 /* Let the world know we exist
214 DebugPuts("[reset]\n");
216 /* Fill exception table with a stub that will
219 tmp
= (APTR
*)(NULL
+ 0x8);
220 for (i
= 0; i
< 46; i
++)
221 tmp
[i
] = Exec_FatalException
;
224 __clear_bss(&kbss
[0]);
225 DebugPuts("[bss clear]\n");
228 /* Must be after the BSS clear! */
232 /* Set privilige violation trap - we
233 * need this to support the Exec/Supervisor call
235 tmp
[6] = Exec_Supervisor_Trap
;
237 Exec_ScreenCode(CODE_RAM_CHECK
);
239 DebugPuts("[prep SysBase]\n");
240 Exec_ScreenCode(CODE_EXEC_CHECK
);
241 mc
= (struct MemChunk
*)(NULL
+ MEM_START
);
243 mc
->mc_Bytes
= MEM_SIZE
;
245 mh
->mh_Node
.ln_Succ
= NULL
;
246 mh
->mh_Node
.ln_Pred
= NULL
;
247 mh
->mh_Node
.ln_Type
= NT_MEMORY
;
248 mh
->mh_Node
.ln_Name
= "chip memory";
249 mh
->mh_Node
.ln_Pri
= -5;
250 mh
->mh_Attributes
= MEMF_CHIP
| MEMF_PUBLIC
| MEMF_LOCAL
| MEMF_24BITDMA
| MEMF_KICK
;
252 mh
->mh_Lower
= (APTR
)mc
;
253 mh
->mh_Upper
= ((APTR
)mc
) + mc
->mc_Bytes
;
254 mh
->mh_Free
= mc
->mc_Bytes
;
255 sysBase
= PrepareExecBase(mh
, NULL
, NULL
);
256 DebugPutHex("PrepareExecBase [ret]",(ULONG
)sysBase
);
257 *((APTR
*)(NULL
+ 0x4)) = sysBase
;
258 DebugPuts("[init SysBase]\n");
260 /* Fix up functions that need 'preserves all registers'
261 * semantics. This AllocMem()s a little wrapper routine
262 * that pushes the %d0-%d1/%a0-%a1 registers before
263 * calling the routine.
265 #ifdef THESE_ARE_KNOWN_SAFE_ASM_ROUTINES
266 PERSERVE_ALL(SysBase
, Exec
, Disable
, 20);
267 PERSERVE_ALL(SysBase
, Exec
, Enable
, 21);
268 PRESERVE_ALL(SysBase
, Exec
, Forbid
, 22);
270 PRESERVE_ALL(SysBase
, Exec
, Permit
, 23);
271 PRESERVE_ALL(SysBase
, Exec
, ObtainSemaphore
, 94);
272 PRESERVE_ALL(SysBase
, Exec
, ReleaseSemaphore
, 95);
273 PRESERVE_ALL(SysBase
, Exec
, ObtainSemaphoreShared
, 113);
276 sysBase
->SysStkUpper
= (APTR
)(&_ss_stack_upper
)-1;
277 sysBase
->SysStkLower
= (APTR
)&_ss_stack_lower
;
279 /* Determine CPU model */
280 sysBase
->AttnFlags
|= cpu_detect();
282 /* Initialize IRQ subsystem */
283 AmigaIRQInit(sysBase
);
285 /* Scan for all other ROM Tags */
286 sysBase
->ResModules
= krnRomTagScanner(sysBase
, kickrom
);
287 DebugPuts("[start] InitCode(RTF_SINGLETASK, 0)\n");
288 InitCode(RTF_SINGLETASK
, 0);
290 /* We shouldn't get here */
291 DebugPuts("[DOS Task failed to start]\n");