Use new ARM instructions for interrupts, exceptions and system calls.
[AROS.git] / arch / arm-native / kernel / kernel_startup.c
blobbc342ffc56a4092ed10e43a1dcc4a4a10420b1db
1 /*
2 Copyright � 2013-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 1
8 #include <aros/kernel.h>
9 #include <aros/symbolsets.h>
11 #include <aros/arm/cpucontext.h>
13 #include <aros/cpu.h>
15 #include <exec/memory.h>
16 #include <exec/memheaderext.h>
17 #include <exec/tasks.h>
18 #include <exec/alerts.h>
19 #include <exec/execbase.h>
20 #include <asm/io.h>
21 #include <proto/kernel.h>
22 #include <proto/exec.h>
23 #include <strings.h>
25 #include "exec_intern.h"
26 #include "etask.h"
28 #include "tlsf.h"
30 #include "kernel_intern.h"
31 #include "kernel_debug.h"
32 #include "kernel_romtags.h"
34 extern struct TagItem *BootMsg;
36 void __attribute__((used)) kernel_cstart(struct TagItem *msg);
38 uint32_t stack[AROS_STACKSIZE] __attribute__((used,aligned(16)));
39 static uint32_t stack_super[AROS_STACKSIZE] __attribute__((used,aligned(16)));
41 asm (
42 ".section .aros.init,\"ax\"\n\t"
43 ".globl start\n\t"
44 ".type start,%function\n"
45 "start:\n"
46 " push {r0} \n"
47 " bl __clear_bss \n"
48 " pop {r0} \n"
49 " cps #0x1f \n" /* system mode */
50 " ldr sp, stack_end \n"
51 " cps #0x13 \n" /* SVC (supervisor) mode */
52 " ldr sp, stack_super_end \n"
53 " b kernel_cstart \n"
55 ".string \"Native/CORE v3 (" __DATE__ ")\"" "\n\t\n\t"
58 static uint32_t * const stack_end __attribute__((used, section(".aros.init"))) = &stack[AROS_STACKSIZE - sizeof(IPTR)];
59 static uint32_t * const stack_super_end __attribute__((used, section(".aros.init"))) = &stack_super[AROS_STACKSIZE - sizeof(IPTR)];
61 struct ARM_Implementation __arm_arosintern __attribute__((aligned(4), section(".data"))) = {0,0,NULL,NULL};
62 struct ExecBase *SysBase __attribute__((section(".data"))) = NULL;
64 static void __attribute__((used)) __clear_bss(struct TagItem *msg)
66 struct KernelBSS *bss = (struct KernelBSS *)krnGetTagData(KRN_KernelBss, 0, msg);
67 register unsigned int dest;
68 unsigned int length;
70 if (bss)
72 while (bss->addr && bss->len)
74 dest = (unsigned int)bss->addr;
75 length = bss->len;
77 // If the start address is unaligned, fill in the first 1-3 bytes until it is
78 while((dest & 3) && length)
80 *((unsigned char *)dest) = 0;
81 dest++;
82 length--;
85 // Fill in the remaining 32-bit word-aligned memory locations
86 while(length & 0xfffffffc)
88 *((unsigned int *)dest) = 0;
89 dest += 4;
90 length -= 4;
93 // Deal with the remaining 1-3 bytes, if any
94 while(length)
96 dest++;
97 length--;
98 *((unsigned char *)dest) = 0;
100 bss++;
105 uint32_t __arm_periiobase __attribute__((section(".data"))) = 0;
107 void __attribute__((used)) kernel_cstart(struct TagItem *msg)
109 UWORD *ranges[3];
110 struct MinList memList;
111 struct MemHeader *mh;
112 struct MemChunk *mc;
113 long unsigned int memlower = 0, memupper = 0, protlower = 0, protupper = 0;
114 BootMsg = msg;
116 cpu_Probe(&__arm_arosintern);
117 platform_Init(&__arm_arosintern, msg);
119 if (__arm_arosintern.ARMI_LED_Toggle)
121 if (__arm_arosintern.ARMI_Delay)
122 __arm_arosintern.ARMI_Delay(100000);
123 __arm_arosintern.ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_OFF);
126 cpu_Init(&__arm_arosintern, msg);
128 if (__arm_arosintern.ARMI_LED_Toggle)
130 if (__arm_arosintern.ARMI_Delay)
131 __arm_arosintern.ARMI_Delay(100000);
132 __arm_arosintern.ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_ON);
135 /* NB: the bootstrap has conveniently setup the framebuffer
136 and initialised the serial port and led for us */
138 while(msg->ti_Tag != TAG_DONE)
140 switch (msg->ti_Tag)
142 case KRN_MEMLower:
143 memlower = msg->ti_Data;
144 break;
145 case KRN_MEMUpper:
146 memupper = msg->ti_Data;
147 break;
148 case KRN_ProtAreaStart:
149 protlower = msg->ti_Data;
150 break;
151 case KRN_ProtAreaEnd:
152 protupper = msg->ti_Data;
153 break;
154 case KRN_KernelBase:
156 * KRN_KernelBase is actually a border between read-only
157 * (code) and read-write (data) sections of the kickstart.
158 * read-write section goes to lower addresses from this one,
159 * so we align it upwards in order not to make part of RW data
160 * read-only.
162 // addr = AROS_ROUNDUP2(msg->ti_Data, PAGE_SIZE);
163 break;
165 msg++;
167 msg = BootMsg;
169 D(bug("[KRN] AROS ARM Native Kernel built on %s\n", __DATE__));
171 D(bug("[KRN] Entered kernel_cstart @ 0x%p, BootMsg @ %p\n", kernel_cstart, BootMsg));
174 if (__arm_arosintern.ARMI_PutChar)
176 bug("[KRN] Using PutChar implementation @ %p\n", __arm_arosintern.ARMI_PutChar);
180 core_SetupIntr();
182 if (__arm_arosintern.ARMI_LED_Toggle)
183 __arm_arosintern.ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_OFF);
185 D(bug("[KRN] Platform initialised\n"));
187 if (__arm_arosintern.ARMI_Delay)
188 __arm_arosintern.ARMI_Delay(1500);
190 if (__arm_arosintern.ARMI_LED_Toggle)
191 __arm_arosintern.ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_ON);
193 D(bug("[KRN] Preparing memory 0x%p -> 0x%p\n", memlower, memupper));
194 D(bug("[KRN] (protected area 0x%p -> 0x%p)\n", protlower, protupper));
196 NEWLIST(&memList);
198 if (memlower >= protlower)
199 memlower = protupper;
201 mh = (struct MemHeader *)memlower;
203 /* Initialize TLSF memory allocator */
204 krnCreateTLSFMemHeader("System Memory", 0, mh, (memupper - memlower), MEMF_FAST | MEMF_PUBLIC | MEMF_KICK | MEMF_LOCAL);
206 if (memlower < protlower)
208 /* Protect the bootstrap area from further use. AllocAbs will do the trick */
209 ((struct MemHeaderExt *)mh)->mhe_AllocAbs((struct MemHeaderExt *)mh, protupper-protlower, (void *)protlower);
212 ranges[0] = (UWORD *)krnGetTagData(KRN_KernelLowest, 0, msg);
213 ranges[1] = (UWORD *)krnGetTagData(KRN_KernelHighest, 0, msg);
214 ranges[2] = (UWORD *)-1;
216 D(bug("[KRN] Preparing ExecBase (memheader @ 0x%p)\n", mh));
217 krnPrepareExecBase(ranges, mh, BootMsg);
220 * Make kickstart code area read-only.
221 * We do it only after ExecBase creation because SysBase pointer is put
222 * into .rodata. This way we prevent it from ocassional modification by buggy software.
224 // core_ProtKernelArea(addr, kick_highest - addr, 1, 0, 1);
226 D(bug("[KRN] InitCode(RTF_SINGLETASK) ... \n"));
227 InitCode(RTF_SINGLETASK, 0);
229 D(bug("[KRN] InitCode(RTF_COLDSTART) ...\n"));
231 asm("cps %[mode_user]\n" : : [mode_user] "I" (CPUMODE_USER)); /* switch to user mode */
233 InitCode(RTF_COLDSTART, 0);
235 /* The above should not return */
236 krnPanic(KernelBase, "System Boot Failed!");
239 DEFINESET(ARMPLATFORMS);