added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / arch / .unmaintained / arm-all / exec / init.c
blob1cc8510d31816c4b897a25f71c7861b0f8eb18aa
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
4 */
7 #define AROS_USE_OOP
9 #include <aros/config.h>
10 #include <exec/io.h>
11 #include <exec/types.h>
12 #include <exec/nodes.h>
13 #include <exec/memory.h>
14 #include <exec/resident.h>
15 #include <exec/libraries.h>
16 #include <exec/execbase.h>
17 #include <proto/oop.h>
18 #include <proto/exec.h>
20 #include <devices/keyboard.h>
22 #define DEBUG 1
23 #include <aros/debug.h>
24 #include <aros/core.h>
25 #include <asm/registers.h>
26 #include <asm/cpu.h>
28 #include "memory.h"
29 //#include "traps.h"
30 #include <memory.h>
32 #include "exec_intern.h"
33 #include "etask.h"
35 #include "arm_exec_internal.h"
39 * local static functions.
41 static void main_init_cont(void);
45 * Just to be sure all of these modules get linked into the
46 * final module, this structure should stay here, because
47 * otherwise the linker might not take it if there is no
48 * reference to a certain module at all.
50 extern const struct Resident
51 Expansion_resident,
52 Exec_resident,
53 Utility_resident,
54 Aros_resident,
55 OOP_resident,
56 HIDD_resident,
57 Mathieeesingbas_resident,
58 irqHidd_resident,
59 Graphics_resident,
60 Layers_resident,
61 Timer_resident,
62 Misc_resident,
63 Battclock_resident,
64 Keyboard_resident,
65 Gameport_resident,
66 Keymap_resident,
67 Input_resident,
68 Intuition_resident,
69 hiddgraphics_resident,
70 displayHidd_resident,
71 hiddserial_resident,
72 mouseHidd_resident,
73 kbdHidd_resident,
74 Console_resident,
75 TrackDisk_resident,
76 ide_resident,
77 Workbench_resident,
78 Mathffp_resident,
79 boot_resident,
80 Dos_resident,
81 LDDemon_resident,
82 con_handler_resident,
83 ram_handler_resident,
84 cram_handler_resident,
85 nil_handler_resident,
86 AFS_resident;
89 /* This list MUST be in the correct order (priority). */
90 static const struct Resident *romtagList[] =
92 &Expansion_resident,
93 &Exec_resident,
94 &Utility_resident,
95 &Aros_resident,
96 &Mathieeesingbas_resident,
97 &OOP_resident,
98 &HIDD_resident,
99 &irqHidd_resident,
100 &Graphics_resident,
101 &Layers_resident,
102 &Timer_resident, // CRASHES
103 &Misc_resident,
104 &Battclock_resident,
105 &Keyboard_resident,
106 &Gameport_resident,
107 &Keymap_resident,
108 &Input_resident, // CRASHES
109 &Intuition_resident, // CRASHES
110 // &hiddgraphics_resident,
111 // &displayHidd_resident,
112 &hiddserial_resident,
113 // &Console_resident, // CRASHES
114 &Workbench_resident,
115 &Mathffp_resident,
116 &boot_resident,
117 &Dos_resident,
118 &LDDemon_resident,
119 &con_handler_resident,
120 &ram_handler_resident,
121 &nil_handler_resident,
122 // &cram_handler_resident
125 /************************************************************************************/
127 void processor_init(void)
129 /************ CPU setup *******************/
131 /*** Turn MMU off *************************/
132 #if 0
133 /* cannot do that... */
134 __asm__ __volatile__ ("mov %%r0,#(0x2|0x10|0x20)\n\t
135 mrc p15,0,%%r1,c1,c0,0\n\t
136 and %r1,%r1,%r0\n\t
137 mcr p15,0,%%r1,c1,c0,0\n\t" \
140 : "%r0", "%r1" );
141 #endif
142 /*** Turn caching off (for now) ***********/
143 __asm__ __volatile__ ("nop \n\t
144 mrc p15,0,r0,c1,c0,0\n\t
145 bic r0,r0,#12\n\t
146 mcr p15,0,r0,c1,c0,0\n\t" \
149 : "%r0", "%r1" );
150 /*** Do not allow interrupts */
152 /************ LCD Controller **************/
154 * Turn the LCD controller on
157 /************* Interrupt Controller **********/
158 WREG_L(ICMR) = 0;
159 WREG_L(ICLR) = 0;
160 WREG_L(ICCR) = 0x1;
162 /************** OS Timer *********************/
163 WREG_L(OSCR) = 0;
164 WREG_L(OSMR0) = 3686400 / 2 ;
165 WREG_L(OSMR1) = 0;
166 WREG_L(OSMR2) = 0;
167 WREG_L(OSMR3) = ~0;
168 WREG_L(OSSR) = 0xf;
169 WREG_L(OIER) = 0x0; // disable timers
170 WREG_L(OWER) = 0x0;
172 /************* Memory Controller *************/
175 /************************************************************************************/
177 #define DO_SERIAL_DEBUG
179 #ifdef DO_SERIAL_DEBUG
180 static void init_serial(void)
183 * Set the UART3 to 115200 baud
185 WREG_L(UTCR0) = 0x8;
186 WREG_L(UTCR1) = 0x0;
187 WREG_L(UTCR2) = 0x1;
188 WREG_L(UTCR3) = 0x3;
189 WREG_L(UTDR) = 0xD;
190 WREG_L(UTSR0) = 0x0;
191 WREG_L(UTSR1) = 0x1;
195 /*static*/ void print_ser(char * string)
197 int i = 0;
198 while (0 != string[i]) {
199 ULONG j = 0;
200 volatile ULONG utsr1;
201 do {
202 utsr1 = RREG_L(UTSR1);
203 j++;
204 } while ((0 == (utsr1 & 0x04)) && (j < 1000000));
205 WREG_L(UTDR) = (ULONG)string[i];
206 i++;
210 void print_serial(char * string)
212 print_ser(string);
213 print_ser("\r\n");
215 #endif
217 /************************************************************************************/
219 void mmu_lookup(ULONG addr, struct ExecBase * SysBase)
221 ULONG * ttb = (ULONG *)(get_cp15_r2() & 0xffffc000);
222 ULONG * fld;
223 D(bug("translation table base at %p\n",ttb));
224 ttb = (ULONG *)((ULONG)ttb | ((addr & 0xfff00000) >> 18));
225 D(bug("first level descriptor for address %p at %p (%p)\n",addr,*ttb,ttb));
226 fld = *ttb;
227 D(bug("Content of first level descriptor: %x\n",*fld));
228 if (0x2 == ((*fld) & 0x2)) {
229 D(bug("This is a section entry!\n"));
230 D(bug("B : %x\n",(*fld >> 2) & 1 ));
231 D(bug("C : %x\n",(*fld >> 3) & 1 ));
232 D(bug("AP: %x\n",(*fld >> 10) & 3 ));
233 D(bug("Section base address: %x\n",(*fld) & 0xfff00000 ));
234 } else if (0x1 == ((*fld) & 0x2)) {
235 D(bug("This is a page entry\n"));
236 } else {
237 D(bug("Wrong entry!?\n"));
241 /************************************************************************************/
242 extern ULONG initial_ssp;
244 extern ULONG _binary_rom_disk_start;
247 void main_init(void)
249 struct ExecBase *SysBase = NULL;
250 ULONG * arm_SP_User = 0xbad0c0de;
251 ULONG * arm_SP_IRQ = 0xbad0c0de;
252 ULONG * arm_SP_FIQ = 0xbad0c0de;
253 ULONG * arm_SP_Abort = 0xbad0c0de;
254 ULONG * arm_SP_Undef = 0xbad0c0de;
255 #if 0
256 UWORD * rom_ranges[] = {(UWORD *)0xc0000000 , (UWORD *)0xc0000000 + (2 * 1024 * 1024),
257 (UWORD *)~0};
258 #else
259 UWORD * rom_ranges[] = {(UWORD *)0x90000 , (UWORD *)0xfff00,
260 (UWORD *)~0};
261 #endif
262 #define MAX_MEM_HEADERS 10
263 struct MemHeader * mh = NULL;
265 processor_init();
266 #ifdef DO_SERIAL_DEBUG
267 init_serial();
268 print_serial("Serial Port initialized!\n");
269 #endif
272 * detect memory of the system
274 print_serial("Detecting memory now\n");
275 mh = detect_memory();
278 We have to put somewhere in this function checking for ColdStart,
279 CoolStart and many other Exec vectors!
283 It is OK to place ExecBase here. Remember that interrupt table starts
284 at 0x0100UL address, so 4UL is quite safe.
285 Even with MP this addr is OK for ExecBase. We may write an int handler
286 which detects "read from 4UL" commands.
288 print_serial("preparing execbase now\n");
289 SysBase = (struct ExecBase*)PrepareExecBase(mh);
290 *(APTR *)0x4 = SysBase;
292 * Detect the rest of the memory...
294 print_serial("detecting rest of memory now\n");
295 detect_memory_rest(SysBase);
298 Setup ChkBase (checksum for base ptr), ChkSum (for library)
299 SysBase+ChkBase should be -1 otherwise somebody has destroyed ExecBase!
301 SysBase->ChkBase=~(ULONG)SysBase;
302 #warning TODO: SysBase->ChkSum=.....
304 if (NULL == (arm_SP_User =(ULONG *)AllocMem(AROS_STACKSIZE,MEMF_PUBLIC))) {
305 do {} while(1);
307 arm_SP_User = (ULONG *)(((ULONG)arm_SP_User) + AROS_STACKSIZE);
310 * Allocate memory for the SSP. The SSP is already set
311 * but I need to AllocAbs() it so nobody else will step on this
312 * memory.
314 #if 0
315 if (NULL == AllocAbs(AROS_STACKSIZE,
316 (APTR)(initial_ssp+sizeof(ULONG)-AROS_STACKSIZE))) {
317 D(bug("Alloc for SSP failed!\n"));
319 D(bug("SSP: %x\n",initial_ssp));
320 #endif
321 D(bug("Now running the romtagscanner!\n"));
322 SysBase->ResModules=Exec_RomTagScanner(SysBase, rom_ranges);
325 * Init the core
327 D(bug("init core now\n"));
328 init_core(SysBase);
330 // D(bug("init traps now\n"));
331 // Init_Traps();
333 if (NULL == (arm_SP_IRQ =(ULONG *)AllocMem(AROS_STACKSIZE,MEMF_PUBLIC))) {
334 do {} while(1);
336 arm_SP_IRQ = (ULONG *)(((ULONG)arm_SP_IRQ) + AROS_STACKSIZE - sizeof(ULONG));
337 D(bug("Now setting IRQ Stackpointer! %x\n",arm_SP_IRQ));
338 set_sp_mode(arm_SP_IRQ, MODE_IRQ);
340 if (NULL == (arm_SP_FIQ =(ULONG *)AllocMem(AROS_STACKSIZE,MEMF_PUBLIC))) {
341 do {} while(1);
343 arm_SP_FIQ = (ULONG *)(((ULONG)arm_SP_FIQ) + AROS_STACKSIZE - sizeof(ULONG));
344 D(bug("Now setting FIQ Stackpointer! %x\n",arm_SP_FIQ));
345 set_sp_mode(arm_SP_FIQ, MODE_FIQ);
347 if (NULL == (arm_SP_Abort =(ULONG *)AllocMem(AROS_STACKSIZE,MEMF_PUBLIC))) {
348 do {} while(1);
350 arm_SP_Abort = (ULONG *)(((ULONG)arm_SP_Abort) + AROS_STACKSIZE - sizeof(ULONG));
351 D(bug("Now setting Abort Stackpointer! %x\n",arm_SP_Abort));
352 set_sp_mode(arm_SP_Abort, MODE_ABORT);
354 if (NULL == (arm_SP_Undef =(ULONG *)AllocMem(AROS_STACKSIZE,MEMF_PUBLIC))) {
355 do {} while(1);
357 arm_SP_Undef = (ULONG *)(((ULONG)arm_SP_Undef) + AROS_STACKSIZE - sizeof(ULONG));
358 D(bug("Now setting Undef Stackpointer! %x\n",arm_SP_Undef));
359 set_sp_mode(arm_SP_Undef, MODE_UNDEF);
362 D(bug("cp15 register 0: 0x%x\n",get_cp15_r0()));
363 D(bug("cp15 register 1: 0x%x\n",get_cp15_r1()));
364 D(bug("cp15 register 2: 0x%x\n",get_cp15_r2()));
365 mmu_lookup(0x0,SysBase);
366 mmu_lookup(0xc0000000,SysBase);
368 * This is the last place where I am in supervisor mode.
369 * so let me switch into user mode and continue there.
370 * The user mode function will then call main_init_cont.
372 D(bug("switching to user mode now\n"));
373 switch_to_user_mode(main_init_cont, arm_SP_User);
377 * The following function will be executed whan AROS is in user mode
379 static void main_init_cont(void)
381 D(bug("!!!!! in user mode now !!!!\n"));
382 InitCode(RTF_SINGLETASK, 0);
383 D(bug("Ooops, should never get here!\n"));
384 while (1) {
387 All done. In normal cases CPU should never reach this point