arch/m68k-amiga: Native Amiga support
[AROS.git] / arch / m68k-amiga / boot / start.c
blobc1510bd852cb282a17e549ec3d9be3462455aa2a
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: m68k-amiga bootstrap to exec.
6 Lang: english
7 */
9 #include <aros/kernel.h>
10 #include <exec/resident.h>
11 #include <exec/execbase.h>
12 #include <exec/memory.h>
14 #include "exec_intern.h"
15 #include "kernel_romtags.h"
17 #define USE_GDBSTUB
19 extern const struct Resident Exec_resident;
21 extern void __clear_bss(const struct KernelBSS *bss);
23 /** Screen/Serial Debug **/
25 #define SERPER_BASE_PAL 3546895
26 #define SERPER_BASE_NTSC 3579545
27 #define SERPER 0x32
28 #define SERPER_BAUD(base, x) (((base)/(x)-1) & 0x7fff) /* Baud rate */
29 #define SERDATR 0x18
30 #define SERDATR_OVRUN (1 << 15) /* Overrun */
31 #define SERDATR_RBF (1 << 14) /* Rx Buffer Full */
32 #define SERDATR_TBE (1 << 13) /* Tx Buffer Empty */
33 #define SERDATR_TSRE (1 << 12) /* Tx Shift Empty */
34 #define SERDATR_RXD (1 << 11) /* Rx Pin */
35 #define SERDATR_STP9 (1 << 9) /* Stop bit (if 9 data) */
36 #define SERDATR_STP8 (1 << 8) /* Stop bit (if 8 data) */
37 #define SERDATR_DB9_of(x) ((x) & 0x1ff) /* 9-bit data */
38 #define SERDATR_DB8_of(x) ((x) & 0xff) /* 8-bit data */
39 #define ADKCON 0x9e
40 #define ADKCON_SETCLR (1 << 15)
41 #define ADKCON_UARTBRK (1 << 11) /* Force break */
42 #define SERDAT 0x30
43 #define SERDAT_STP9 (1 << 9)
44 #define SERDAT_STP8 (1 << 8)
45 #define SERDAT_DB9(x) ((x) & 0x1ff)
46 #define SERDAT_DB8(x) ((x) & 0xff)
48 #define BPLCON0 0x100
49 #define BPL1DAT 0x110
50 #define COLOR00 0x180
52 static inline void reg_w(ULONG reg, UWORD val)
54 volatile UWORD *r = (void *)(0xdff000 + reg);
56 *r = val;
59 static inline UWORD reg_r(ULONG reg)
61 volatile UWORD *r = (void *)(0xdff000 + reg);
63 return *r;
66 #define RGB(r,g,b) ((((r) & 0xf) << 8) | (((g) & 0xf) << 4) | (((b) & 0xf) << 0))
68 #define CODE_ROM_CHECK RGB( 4, 4, 4)
69 #define CODE_RAM_CHECK RGB( 9, 9, 9)
70 #define CODE_EXEC_CHECK RGB( 9, 0, 9)
71 #define CODE_TRAP_FAIL RGB(12, 12, 0)
73 static void Exec_ScreenCode(UWORD code)
75 reg_w(BPLCON0, 0x0200);
76 reg_w(BPL1DAT, 0x0000);
77 reg_w(COLOR00, code);
80 void DebugInit()
82 /* Set the debug UART to 9600 */
83 reg_w(SERPER, SERPER_BAUD(SERPER_BASE_PAL, 9600));
86 int DebugPutChar(register int chr)
88 while ((reg_r(SERDATR) & SERDATR_TBE) == 0);
90 /* Output a char to the debug UART */
91 reg_w(SERDAT, SERDAT_STP8 | SERDAT_DB8(chr));
93 return 1;
96 int DebugGetChar(void)
98 while ((reg_r(SERDATR) & SERDATR_RBF) == 0);
100 return SERDATR_DB8_of(reg_r(SERDATR));
103 #ifdef USE_GDBSTUB
104 #define mc68020
105 #include "m68k-gdbstub.c"
106 #endif
108 static __attribute__((interrupt)) void Exec_FatalException(void)
110 volatile int i;
112 Exec_ScreenCode(CODE_TRAP_FAIL);
114 /* FIXME: Idle loop delay
115 * We should really wait for a number of
116 * verical retrace intervals
118 for (i = 0; i < 150000; i++);
120 /* Reset everything but the CPU, then restart
121 * at the ROM exception vector
123 asm("reset\n"
124 "move.l #4,%a0\n"
125 "jmp (%a0)\n");
128 static void DebugPuts(register const char *buff)
130 for (; *buff != 0; buff++)
131 DebugPutChar(*buff);
134 #define MEM_START 0x00040000
135 #define MEM_SIZE 0x001c0000
137 struct MemHeader ChipRAM;
139 void DebugPutHex(const char *what, ULONG val)
141 int i;
142 DebugPuts(what);
143 DebugPuts(": ");
144 for (i = 0; i < 8; i ++) {
145 DebugPutChar("0123456789abcdef"[(val >> (28 - (i * 4))) & 0xf]);
147 DebugPutChar('\n');
150 void start(void)
152 extern void *_bss;
153 extern void *_bss_end;
154 extern void *_stack;
155 extern void *_stack_end;
156 APTR *tmp;
157 int i;
158 UWORD *kickrom[4] = {
159 (UWORD *)0x00f80000,
160 (UWORD *)0x01000000,
161 (UWORD *)~0,
162 (UWORD *)~0,
164 const struct KernelBSS kbss[2] = {
166 .addr = &_bss,
167 .len = &_bss_end - &_bss,
168 }, {
169 .addr = 0,
170 .len = 0,
174 struct ExecBase *sysBase;
175 struct MemChunk *mc;
176 struct MemHeader *mh = &ChipRAM;
178 *((APTR *)(NULL + 0x4)) = NULL;
180 /* Set the world know we exist
182 DebugInit();
183 DebugPuts("[reset]\n");
185 /* Fill exception table with a stub that will
186 * reset the ROM
188 tmp = (APTR *)(NULL + 0x8);
189 for (i = 0; i < 46; i++)
190 tmp[i] = Exec_FatalException;
192 /* Clear the BSS */
193 __clear_bss(&kbss[0]);
194 DebugPuts("[bss clear]\n");
196 #ifdef USE_GDBSTUB
197 /* Must be after the BSS clear! */
198 gdbstub();
199 #endif
201 Exec_ScreenCode(CODE_RAM_CHECK);
203 DebugPuts("[prep SysBase]\n");
204 Exec_ScreenCode(CODE_EXEC_CHECK);
205 mc = (struct MemChunk *)(NULL + MEM_START);
206 mc->mc_Next = NULL;
207 mc->mc_Bytes = MEM_SIZE;
209 mh->mh_Node.ln_Succ = NULL;
210 mh->mh_Node.ln_Pred = NULL;
211 mh->mh_Node.ln_Type = NT_MEMORY;
212 mh->mh_Node.ln_Name = "chip memory";
213 mh->mh_Node.ln_Pri = -5;
214 mh->mh_Attributes = MEMF_CHIP | MEMF_PUBLIC | MEMF_LOCAL | MEMF_24BITDMA | MEMF_KICK;
215 mh->mh_First = mc;
216 mh->mh_Lower = (APTR)mc;
217 mh->mh_Upper = ((APTR)mc) + mc->mc_Bytes;
218 mh->mh_Free = mc->mc_Bytes;
219 sysBase = PrepareExecBase(mh, NULL, NULL);
220 DebugPutHex("PrepareExecBase [ret]",(ULONG)sysBase);
221 *((APTR *)(NULL + 0x4)) = sysBase;
222 DebugPuts("[init SysBase]\n");
224 sysBase->SysStkUpper = (APTR)&_stack_end-1;
225 sysBase->SysStkLower = (APTR)&_stack;
226 sysBase->ChkBase=~(ULONG)sysBase;
228 /* Scan for all other ROM Tags */
229 sysBase->ResModules = krnRomTagScanner(sysBase, kickrom);
230 DebugPuts("[start] InitCode(RTF_SINGLETASK, 0)\n");
231 InitCode(RTF_SINGLETASK, 0);
233 /* We shouldn't get here */
234 DebugPuts("[DOS Task failed to start]\n");
235 for (;;)
236 breakpoint();