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");