move the generic arm kernel & exec to arm-native
[AROS.git] / arch / arm-native / kernel / kernel_startup.c
blob3b520a16bd56458d645d2a29267908396be0c53e
1 /*
2 Copyright � 2013-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
8 #include <aros/kernel.h>
9 #include <aros/symbolsets.h>
11 #include <aros/arm/cpucontext.h>
13 #include <exec/memory.h>
14 #include <exec/tasks.h>
15 #include <exec/alerts.h>
16 #include <exec/execbase.h>
17 #include <asm/io.h>
18 #include <proto/kernel.h>
19 #include <proto/exec.h>
20 #include <strings.h>
22 #include "exec_intern.h"
23 #include "etask.h"
25 #include "kernel_intern.h"
26 #include "kernel_debug.h"
27 #include "kernel_fb.h"
28 #include "kernel_romtags.h"
30 extern void krnCreateMemHeader(CONST_STRPTR name, BYTE pri, APTR start, IPTR size, ULONG flags);
31 extern struct TagItem *BootMsg;
33 void __attribute__((used)) kernel_cstart(struct TagItem *msg);
35 uint32_t stack[STACK_SIZE] __attribute__((used,aligned(16)));
36 static uint32_t stack_super[STACK_SIZE] __attribute__((used,aligned(16)));
37 static uint32_t stack_abort[STACK_SIZE] __attribute__((used,aligned(16)));
38 static uint32_t stack_irq[STACK_SIZE] __attribute__((used,aligned(16)));
40 asm (
41 ".section .aros.init,\"ax\"\n\t"
42 ".globl start\n\t"
43 ".type start,%function\n"
44 "start:\n"
45 " push {r0} \n"
46 " bl __clear_bss \n"
47 " pop {r0} \n"
48 " cps #0x1f \n" /* system mode */
49 " ldr sp, stack_end \n"
50 " cps #0x17 \n" /* abort mode */
51 " ldr sp, stack_abort_end \n"
52 " cps #0x12 \n" /* IRQ mode */
53 " ldr sp, stack_irq_end \n"
54 " cps #0x13 \n" /* SVC (supervisor) mode */
55 " ldr sp, stack_super_end \n"
56 " b kernel_cstart \n"
58 ".string \"Native/CORE v3 (" __DATE__ ")\"" "\n\t\n\t"
61 static uint32_t * const stack_end __attribute__((used, section(".aros.init"))) = &stack[STACK_SIZE - sizeof(IPTR)];
62 static uint32_t * const stack_super_end __attribute__((used, section(".aros.init"))) = &stack_super[STACK_SIZE - sizeof(IPTR)];
63 static uint32_t * const stack_abort_end __attribute__((used, section(".aros.init"))) = &stack_abort[STACK_SIZE - sizeof(IPTR)];
64 static uint32_t * const stack_irq_end __attribute__((used, section(".aros.init"))) = &stack_irq[STACK_SIZE - sizeof(IPTR)];
66 struct ARM_Implementation krnARMImpl __attribute__((aligned(4), section(".data"))) = {0,0,NULL,NULL};
67 struct ExecBase *SysBase __attribute__((section(".data"))) = NULL;
69 static void __attribute__((used)) __clear_bss(struct TagItem *msg)
71 struct KernelBSS *bss = (struct KernelBSS *)krnGetTagData(KRN_KernelBss, 0, msg);
72 register unsigned int dest;
73 unsigned int length;
75 if (bss)
77 while (bss->addr && bss->len)
79 dest = (unsigned int)bss->addr;
80 length = bss->len;
82 // If the start address is unaligned, fill in the first 1-3 bytes until it is
83 while((dest & 3) && length)
85 *((unsigned char *)dest) = 0;
86 dest++;
87 length--;
90 // Fill in the remaining 32-bit word-aligned memory locations
91 while(length & 0xfffffffc)
93 *((unsigned int *)dest) = 0;
94 dest += 4;
95 length -= 4;
98 // Deal with the remaining 1-3 bytes, if any
99 while(length)
101 dest++;
102 length--;
103 *((unsigned char *)dest) = 0;
105 bss++;
110 uint32_t __arm_periiobase __attribute__((section(".data"))) = 0;
112 void __attribute__((used)) kernel_cstart(struct TagItem *msg)
114 UWORD *ranges[3];
115 struct MinList memList;
116 struct MemHeader *mh;
117 struct MemChunk *mc;
118 long unsigned int memlower = 0, memupper = 0, protlower = 0, protupper = 0;
119 BootMsg = msg;
121 cpu_Probe(&krnARMImpl);
122 platform_Init(&krnARMImpl, msg);
123 cpu_Init(&krnARMImpl, msg);
125 /* NB: the bootstrap has conveniently setup the framebuffer
126 and initialised the serial port and led for us */
128 while(msg->ti_Tag != TAG_DONE)
130 switch (msg->ti_Tag)
132 case KRN_FuncPutC:
133 _KrnPutC = (void *)msg->ti_Data;
134 _KrnPutC(0xFF); // Clear the display
135 break;
136 case KRN_MEMLower:
137 memlower = msg->ti_Data;
138 break;
139 case KRN_MEMUpper:
140 memupper = msg->ti_Data;
141 break;
142 case KRN_ProtAreaStart:
143 protlower = msg->ti_Data;
144 break;
145 case KRN_ProtAreaEnd:
146 protupper = msg->ti_Data;
147 break;
148 case KRN_KernelBase:
150 * KRN_KernelBase is actually a border between read-only
151 * (code) and read-write (data) sections of the kickstart.
152 * read-write section goes to lower addresses from this one,
153 * so we align it upwards in order not to make part of RW data
154 * read-only.
156 // addr = AROS_ROUNDUP2(msg->ti_Data, PAGE_SIZE);
157 break;
159 msg++;
161 msg = BootMsg;
163 D(bug("[KRN] AROS Raspberry Pi Kernel built on %s\n", __DATE__));
165 D(bug("[KRN] Entered kernel_cstart @ 0x%p, BootMsg @ %p\n", kernel_cstart, BootMsg));
168 if (_KrnPutC)
170 bug("[KRN] Using boostrap PutC implementation @ %p\n", _KrnPutC);
174 core_SetupIntr();
176 if (krnARMImpl.ARMI_LED_Toggle)
178 krnARMImpl.ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_OFF);
179 if (krnARMImpl.ARMI_Delay)
180 krnARMImpl.ARMI_Delay(1500);
181 krnARMImpl.ARMI_LED_Toggle(ARM_LED_POWER, ARM_LED_ON);
184 NEWLIST(&memList);
186 mh = (struct MemHeader *)memlower;
187 krnCreateMemHeader("System Memory", 0, mh, protlower - (long unsigned int)mh, MEMF_FAST | MEMF_PUBLIC | MEMF_KICK | MEMF_LOCAL);
189 mc = (struct MemChunk *)((protupper + MEMCHUNK_TOTAL-1) & ~(MEMCHUNK_TOTAL-1));
190 mc->mc_Bytes = memupper - (long unsigned int)mc;
191 mc->mc_Next = NULL;
193 if (mh->mh_First->mc_Next == NULL)
195 mh->mh_First->mc_Next = mc;
196 mh->mh_Upper = (void *)memupper;
197 mh->mh_Free += mc->mc_Bytes;
200 ranges[0] = (UWORD *)krnGetTagData(KRN_KernelLowest, 0, msg);
201 ranges[1] = (UWORD *)krnGetTagData(KRN_KernelHighest, 0, msg);
202 ranges[2] = (UWORD *)-1;
204 D(bug("[KRN] Preparing ExecBase (memheader @ 0x%p)\n", mh));
205 krnPrepareExecBase(ranges, mh, BootMsg);
208 * Make kickstart code area read-only.
209 * We do it only after ExecBase creation because SysBase pointer is put
210 * into .rodata. This way we prevent it from ocassional modification by buggy software.
212 // core_ProtKernelArea(addr, kick_highest - addr, 1, 0, 1);
214 D(bug("[KRN] InitCode(RTF_SINGLETASK) ... \n"));
215 InitCode(RTF_SINGLETASK, 0);
217 D(bug("[KRN] InitCode(RTF_COLDSTART) ...\n"));
219 asm("cps %[mode_user]\n" : : [mode_user] "I" (CPUMODE_USER)); /* switch to user mode */
221 InitCode(RTF_COLDSTART, 0);
223 /* The above should not return */
224 krnPanic(KernelBase, "System Boot Failed!");
227 DEFINESET(ARMPLATFORMS);