revert between 56095 -> 55830 in arch
[AROS.git] / arch / arm-native / kernel / kernel_startup.c
blobf5733b945509d13e8245eba9325886c2d89f9ff7
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"
27 #include "tlsf.h"
29 #include "kernel_intern.h"
30 #include "kernel_debug.h"
31 #include "kernel_romtags.h"
33 #include "exec_platform.h"
35 #undef KernelBase
36 #include "tls.h"
38 extern struct TagItem *BootMsg;
40 void __attribute__((used)) kernel_cstart(struct TagItem *msg);
42 uint32_t stack[AROS_STACKSIZE] __attribute__((used,aligned(16)));
43 static uint32_t stack_super[AROS_STACKSIZE] __attribute__((used,aligned(16)));
45 static uint32_t stack_fiq[1024] __attribute__((used,aligned(16)));
47 asm (
48 ".section .aros.init,\"ax\"\n\t"
49 ".globl start\n\t"
50 ".type start,%function\n"
51 "start:\n"
52 " push {r0} \n"
53 " bl __clear_bss \n"
54 " pop {r0} \n"
55 " cps #0x1f \n" /* system mode */
56 " ldr sp, stack_end \n"
57 " cps #0x11 \n" /* fiq mode */
58 " ldr sp, stack_fiq_end \n"
59 " cps #0x13 \n" /* SVC (supervisor) mode */
60 " ldr sp, stack_super_end \n"
61 " b kernel_cstart \n"
63 ".string \"Native/CORE v3 (" __DATE__ ")\"" "\n\t\n\t"
66 static uint32_t * const stack_end __attribute__((used, section(".aros.init"))) = &stack[AROS_STACKSIZE - sizeof(IPTR)];
67 static uint32_t * const stack_super_end __attribute__((used, section(".aros.init"))) = &stack_super[AROS_STACKSIZE - sizeof(IPTR)];
68 static uint32_t * const stack_fiq_end __attribute__((used, section(".aros.init"))) = &stack_fiq[1024 - sizeof(IPTR)];
71 struct ARM_Implementation __arm_arosintern __attribute__((aligned(4), section(".data"))) = {0,0,NULL,0};
72 struct ExecBase *SysBase __attribute__((section(".data"))) = NULL;
74 static void __attribute__((used)) __clear_bss(struct TagItem *msg)
76 struct KernelBSS *bss = (struct KernelBSS *)krnGetTagData(KRN_KernelBss, 0, msg);
77 register unsigned int dest;
78 unsigned int length;
80 if (bss)
82 while (bss->addr && bss->len)
84 dest = (unsigned int)bss->addr;
85 length = bss->len;
87 // If the start address is unaligned, fill in the first 1-3 bytes until it is
88 while((dest & 3) && length)
90 *((unsigned char *)dest) = 0;
91 dest++;
92 length--;
95 // Fill in the remaining 32-bit word-aligned memory locations
96 while(length & 0xfffffffc)
98 *((unsigned int *)dest) = 0;
99 dest += 4;
100 length -= 4;
103 // Deal with the remaining 1-3 bytes, if any
104 while(length)
106 dest++;
107 length--;
108 *((unsigned char *)dest) = 0;
110 bss++;
115 void __attribute__((used)) kernel_cstart(struct TagItem *msg)
117 UWORD *ranges[3];
118 struct MinList memList;
119 struct MemHeader *mh;
120 long unsigned int memlower = 0, memupper = 0, protlower = 0, protupper = 0;
121 char *cmdline = NULL;
122 BootMsg = msg;
123 tls_t *__tls;
125 // First find out if device tree is present
126 while(msg->ti_Tag != TAG_DONE)
128 int found = 0;
130 switch (msg->ti_Tag)
132 case KRN_OpenFirmwareTree:
133 dt_set_root((void *)msg->ti_Data);
134 found = 1;
135 break;
138 if (found)
139 break;
141 msg++;
143 msg = BootMsg;
145 // Probe the ARM core
146 cpu_Probe(&__arm_arosintern);
148 // Probe the ARM Implementation/Platform
149 __arm_arosintern.ARMI_Platform = 0;
150 while(msg->ti_Tag != TAG_DONE)
152 switch (msg->ti_Tag)
154 case KRN_Platform:
155 __arm_arosintern.ARMI_Platform = msg->ti_Data;
156 break;
158 msg++;
160 msg = BootMsg;
162 platform_Init(&__arm_arosintern, msg);
164 if (__arm_arosintern.ARMI_LED_Toggle)
166 if (__arm_arosintern.ARMI_Delay)
167 __arm_arosintern.ARMI_Delay(100000);
168 __arm_arosintern.ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_OFF);
171 cpu_Init(&__arm_arosintern, msg);
173 if (__arm_arosintern.ARMI_LED_Toggle)
175 if (__arm_arosintern.ARMI_Delay)
176 __arm_arosintern.ARMI_Delay(100000);
177 __arm_arosintern.ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_ON);
180 /* NB: the bootstrap has conveniently setup the framebuffer
181 and initialised the serial port and led for us */
183 while(msg->ti_Tag != TAG_DONE)
185 switch (msg->ti_Tag)
187 case KRN_CmdLine:
188 // RelocateStringData(tag);
189 cmdline = (char *)msg->ti_Data;
190 break;
191 case KRN_MEMLower:
192 memlower = msg->ti_Data;
193 break;
194 case KRN_MEMUpper:
195 memupper = msg->ti_Data;
196 break;
197 case KRN_ProtAreaStart:
198 protlower = msg->ti_Data;
199 break;
200 case KRN_ProtAreaEnd:
201 // Page align
202 protupper = (msg->ti_Data + 4095) & ~4095;
203 break;
204 case KRN_KernelBase:
206 * KRN_KernelBase is actually a border between read-only
207 * (code) and read-write (data) sections of the kickstart.
208 * read-write section goes to lower addresses from this one,
209 * so we align it upwards in order not to make part of RW data
210 * read-only.
212 // addr = AROS_ROUNDUP2(msg->ti_Data, PAGE_SIZE);
213 break;
215 msg++;
217 msg = BootMsg;
219 __tls = (void *)protupper;
220 protupper += (sizeof(tls_t) + 4095) & ~4095;
222 __tls->KernelBase = NULL;
223 __tls->SysBase = NULL;
224 __tls->ThisTask = NULL;
226 D(bug("[Kernel] AROS ARM Native Kernel built on %s\n", __DATE__));
227 if (dt_find_node("/")) {
228 D(bug("[Kernel] Device: %s\n", dt_get_prop_value(dt_find_property(dt_find_node("/"), "model"))));
231 D(bug("[Kernel] Entered kernel_cstart @ 0x%p, BootMsg @ 0x%p\n", kernel_cstart, BootMsg));
233 asm volatile("mcr p15, 0, %0, c13, c0, 3" : : "r"(__tls));
236 if (__arm_arosintern.ARMI_PutChar)
238 bug("[Kernel] Using PutChar implementation @ %p\n", __arm_arosintern.ARMI_PutChar);
240 bug("[Kernel] Boot CPU TLS @ 0x%p\n", __tls);
243 core_SetupIntr();
245 if (__arm_arosintern.ARMI_LED_Toggle)
246 __arm_arosintern.ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_OFF);
248 D(bug("[Kernel] Platform initialised\n"));
250 if (__arm_arosintern.ARMI_Delay)
251 __arm_arosintern.ARMI_Delay(1500);
253 if (__arm_arosintern.ARMI_LED_Toggle)
254 __arm_arosintern.ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_ON);
256 D(bug("[Kernel] Preparing memory 0x%p -> 0x%p\n", memlower, memupper));
257 D(bug("[Kernel] - protected area 0x%p -> 0x%p)\n", protlower, protupper));
259 NEWLIST(&memList);
261 if (memlower >= protlower)
262 memlower = protupper;
264 mh = (struct MemHeader *)memlower;
266 if (cmdline && strstr(cmdline, "notlsf"))
268 #if (0)
269 krnCreateMemHeader("System Memory", 0, mh, (memupper - memlower), MEMF_FAST | MEMF_PUBLIC | MEMF_KICK | MEMF_LOCAL);
271 if (memlower < protlower)
273 // AllocAbs(protupper-protlower, (void *)protlower);
275 #endif
277 else
279 /* Initialize TLSF memory allocator */
280 krnCreateTLSFMemHeader("System Memory", 0, mh, (memupper - memlower), MEMF_FAST | MEMF_PUBLIC | MEMF_KICK | MEMF_LOCAL);
281 if (memlower < protlower)
283 /* Protect the bootstrap area from further use. AllocAbs will do the trick */
284 ((struct MemHeaderExt *)mh)->mhe_AllocAbs((struct MemHeaderExt *)mh, protupper-protlower, (void *)protlower);
288 ranges[0] = (UWORD *)krnGetTagData(KRN_KernelLowest, 0, msg);
289 ranges[1] = (UWORD *)krnGetTagData(KRN_KernelHighest, 0, msg);
290 ranges[2] = (UWORD *)-1;
292 D(bug("[Kernel] Preparing ExecBase (memheader @ 0x%p)\n", mh));
293 krnPrepareExecBase(ranges, mh, BootMsg);
295 __tls->SysBase = SysBase;
296 D(bug("[Kernel] SysBase @ 0x%p\n", SysBase));
299 * Make kickstart code area read-only.
300 * We do it only after ExecBase creation because SysBase pointer is put
301 * into .rodata. This way we prevent it from ocassional modification by buggy software.
303 // core_ProtKernelArea(addr, kick_highest - addr, 1, 0, 1);
305 D(bug("[Kernel] InitCode(RTF_SINGLETASK) ... \n"));
306 InitCode(RTF_SINGLETASK, 0);
308 D(bug("[Kernel] Dropping into USER mode ... \n"));
309 asm("cps %[mode_user]\n"
310 #if AROS_BIG_ENDIAN
311 "setend be\n"
312 #endif
313 : : [mode_user] "I" (CPUMODE_USER)); /* switch to user mode */
315 D(bug("[Kernel] InitCode(RTF_COLDSTART) ...\n"));
316 InitCode(RTF_COLDSTART, 0);
318 /* The above should not return */
319 krnPanic(KernelBase, "System Boot Failed!");
322 DEFINESET(ARMPLATFORMS);