2 Copyright © 2013-2015, The AROS Development Team. All rights reserved.
8 #include <aros/kernel.h>
9 #include <aros/symbolsets.h>
11 #include <aros/arm/cpucontext.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>
21 #include <proto/kernel.h>
22 #include <proto/exec.h>
25 #include "exec_intern.h"
30 #include "kernel_intern.h"
31 #include "kernel_debug.h"
32 #include "kernel_romtags.h"
34 #include "exec_platform.h"
36 extern struct TagItem
*BootMsg
;
38 void __attribute__((used
)) kernel_cstart(struct TagItem
*msg
);
40 uint32_t stack
[AROS_STACKSIZE
] __attribute__((used
,aligned(16)));
41 static uint32_t stack_super
[AROS_STACKSIZE
] __attribute__((used
,aligned(16)));
43 static uint32_t stack_fiq
[1024] __attribute__((used
,aligned(16)));
46 ".section .aros.init,\"ax\"\n\t"
48 ".type start,%function\n"
53 " cps #0x1f \n" /* system mode */
54 " ldr sp, stack_end \n"
55 " cps #0x11 \n" /* fiq mode */
56 " ldr sp, stack_fiq_end \n"
57 " cps #0x13 \n" /* SVC (supervisor) mode */
58 " ldr sp, stack_super_end \n"
61 ".string \"Native/CORE v3 (" __DATE__
")\"" "\n\t\n\t"
64 static uint32_t * const stack_end
__attribute__((used
, section(".aros.init"))) = &stack
[AROS_STACKSIZE
- sizeof(IPTR
)];
65 static uint32_t * const stack_super_end
__attribute__((used
, section(".aros.init"))) = &stack_super
[AROS_STACKSIZE
- sizeof(IPTR
)];
66 static uint32_t * const stack_fiq_end
__attribute__((used
, section(".aros.init"))) = &stack_fiq
[1024 - sizeof(IPTR
)];
69 struct ARM_Implementation __arm_arosintern
__attribute__((aligned(4), section(".data"))) = {0,0,NULL
,NULL
};
70 struct ExecBase
*SysBase
__attribute__((section(".data"))) = NULL
;
72 static void __attribute__((used
)) __clear_bss(struct TagItem
*msg
)
74 struct KernelBSS
*bss
= (struct KernelBSS
*)krnGetTagData(KRN_KernelBss
, 0, msg
);
75 register unsigned int dest
;
80 while (bss
->addr
&& bss
->len
)
82 dest
= (unsigned int)bss
->addr
;
85 // If the start address is unaligned, fill in the first 1-3 bytes until it is
86 while((dest
& 3) && length
)
88 *((unsigned char *)dest
) = 0;
93 // Fill in the remaining 32-bit word-aligned memory locations
94 while(length
& 0xfffffffc)
96 *((unsigned int *)dest
) = 0;
101 // Deal with the remaining 1-3 bytes, if any
106 *((unsigned char *)dest
) = 0;
113 extern uint32_t __arm_affinitymask
;
115 void __attribute__((used
)) kernel_cstart(struct TagItem
*msg
)
118 struct MinList memList
;
119 struct MemHeader
*mh
;
121 long unsigned int memlower
= 0, memupper
= 0, protlower
= 0, protupper
= 0;
122 char *cmdline
= NULL
;
126 // Probe the ARM core
127 cpu_Probe(&__arm_arosintern
);
129 // Probe the ARM Implementation/Platform
130 __arm_arosintern
.ARMI_Platform
= 0;
131 while(msg
->ti_Tag
!= TAG_DONE
)
136 __arm_arosintern
.ARMI_Platform
= msg
->ti_Data
;
143 platform_Init(&__arm_arosintern
, msg
);
145 if (__arm_arosintern
.ARMI_LED_Toggle
)
147 if (__arm_arosintern
.ARMI_Delay
)
148 __arm_arosintern
.ARMI_Delay(100000);
149 __arm_arosintern
.ARMI_LED_Toggle(ARM_LED_POWER
, ARM_LED_OFF
);
152 cpu_Init(&__arm_arosintern
, msg
);
154 if (__arm_arosintern
.ARMI_LED_Toggle
)
156 if (__arm_arosintern
.ARMI_Delay
)
157 __arm_arosintern
.ARMI_Delay(100000);
158 __arm_arosintern
.ARMI_LED_Toggle(ARM_LED_POWER
, ARM_LED_ON
);
161 /* NB: the bootstrap has conveniently setup the framebuffer
162 and initialised the serial port and led for us */
164 while(msg
->ti_Tag
!= TAG_DONE
)
169 // RelocateStringData(tag);
170 cmdline
= (char *)msg
->ti_Data
;
173 memlower
= msg
->ti_Data
;
176 memupper
= msg
->ti_Data
;
178 case KRN_ProtAreaStart
:
179 protlower
= msg
->ti_Data
;
181 case KRN_ProtAreaEnd
:
183 protupper
= (msg
->ti_Data
+ 4095) & ~4095;
187 * KRN_KernelBase is actually a border between read-only
188 * (code) and read-write (data) sections of the kickstart.
189 * read-write section goes to lower addresses from this one,
190 * so we align it upwards in order not to make part of RW data
193 // addr = AROS_ROUNDUP2(msg->ti_Data, PAGE_SIZE);
200 __tls
= (void *)protupper
;
201 protupper
+= (sizeof(tls_t
) + 4095) & ~4095;
203 __tls
->KernelBase
= NULL
;
204 __tls
->SysBase
= NULL
;
205 __tls
->ThisTask
= NULL
;
207 D(bug("[KRN] AROS ARM Native Kernel built on %s\n", __DATE__
));
209 D(bug("[KRN] Entered kernel_cstart @ 0x%p, BootMsg @ 0x%p\n", kernel_cstart
, BootMsg
));
211 asm volatile("mcr p15, 0, %0, c13, c0, 3" : : "r"(__tls
));
214 if (__arm_arosintern
.ARMI_PutChar
)
216 bug("[KRN] Using PutChar implementation @ %p\n", __arm_arosintern
.ARMI_PutChar
);
218 bug("[KRN] Boot CPU TLS @ 0x%p\n", __tls
);
223 if (__arm_arosintern
.ARMI_LED_Toggle
)
224 __arm_arosintern
.ARMI_LED_Toggle(ARM_LED_POWER
, ARM_LED_OFF
);
226 D(bug("[KRN] Platform initialised\n"));
227 D(bug("[KRN] Affinity mask %08x\n", __arm_affinitymask
));
229 if (__arm_arosintern
.ARMI_Delay
)
230 __arm_arosintern
.ARMI_Delay(1500);
232 if (__arm_arosintern
.ARMI_LED_Toggle
)
233 __arm_arosintern
.ARMI_LED_Toggle(ARM_LED_POWER
, ARM_LED_ON
);
235 D(bug("[KRN] Preparing memory 0x%p -> 0x%p\n", memlower
, memupper
));
236 D(bug("[KRN] (protected area 0x%p -> 0x%p)\n", protlower
, protupper
));
240 if (memlower
>= protlower
)
241 memlower
= protupper
;
243 mh
= (struct MemHeader
*)memlower
;
245 if (cmdline
&& strstr(cmdline
, "notlsf"))
248 krnCreateMemHeader("System Memory", 0, mh
, (memupper
- memlower
), MEMF_FAST
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
);
250 if (memlower
< protlower
)
252 // AllocAbs(protupper-protlower, (void *)protlower);
258 /* Initialize TLSF memory allocator */
259 krnCreateTLSFMemHeader("System Memory", 0, mh
, (memupper
- memlower
), MEMF_FAST
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
);
260 if (memlower
< protlower
)
262 /* Protect the bootstrap area from further use. AllocAbs will do the trick */
263 ((struct MemHeaderExt
*)mh
)->mhe_AllocAbs((struct MemHeaderExt
*)mh
, protupper
-protlower
, (void *)protlower
);
267 ranges
[0] = (UWORD
*)krnGetTagData(KRN_KernelLowest
, 0, msg
);
268 ranges
[1] = (UWORD
*)krnGetTagData(KRN_KernelHighest
, 0, msg
);
269 ranges
[2] = (UWORD
*)-1;
271 D(bug("[KRN] Preparing ExecBase (memheader @ 0x%p)\n", mh
));
272 krnPrepareExecBase(ranges
, mh
, BootMsg
);
274 __tls
->SysBase
= SysBase
;
275 D(bug("[KRN] SysBase @ 0x%p\n", SysBase
));
278 * Make kickstart code area read-only.
279 * We do it only after ExecBase creation because SysBase pointer is put
280 * into .rodata. This way we prevent it from ocassional modification by buggy software.
282 // core_ProtKernelArea(addr, kick_highest - addr, 1, 0, 1);
284 D(bug("[KRN] InitCode(RTF_SINGLETASK) ... \n"));
285 InitCode(RTF_SINGLETASK
, 0);
287 D(bug("[KRN] Dropping into USER mode ... \n"));
288 asm("cps %[mode_user]\n" : : [mode_user
] "I" (CPUMODE_USER
)); /* switch to user mode */
290 D(bug("[KRN] InitCode(RTF_COLDSTART) ...\n"));
291 InitCode(RTF_COLDSTART
, 0);
293 /* The above should not return */
294 krnPanic(KernelBase
, "System Boot Failed!");
297 DEFINESET(ARMPLATFORMS
);