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>
13 #include <exec/memory.h>
14 #include <exec/tasks.h>
15 #include <exec/alerts.h>
16 #include <exec/execbase.h>
18 #include <proto/kernel.h>
19 #include <proto/exec.h>
22 #include "exec_intern.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
);
32 void __attribute__((used
)) kernel_cstart(struct TagItem
*msg
);
34 uint32_t stack
[STACK_SIZE
] __attribute__((used
,aligned(16)));
35 static uint32_t stack_super
[STACK_SIZE
] __attribute__((used
,aligned(16)));
36 static uint32_t stack_abort
[STACK_SIZE
] __attribute__((used
,aligned(16)));
37 static uint32_t stack_irq
[STACK_SIZE
] __attribute__((used
,aligned(16)));
40 ".section .aros.init,\"ax\"\n\t"
42 ".type start,%function\n"
47 " cps #0x1f \n" /* system mode */
48 " ldr sp, stack_end \n"
49 " cps #0x17 \n" /* abort mode */
50 " ldr sp, stack_abort_end \n"
51 " cps #0x12 \n" /* IRQ mode */
52 " ldr sp, stack_irq_end \n"
53 " cps #0x13 \n" /* SVC (supervisor) mode */
54 " ldr sp, stack_super_end \n"
57 ".string \"Native/CORE v3 (" __DATE__
")\"" "\n\t\n\t"
60 static uint32_t * const stack_end
__attribute__((used
, section(".aros.init"))) = &stack
[STACK_SIZE
- sizeof(IPTR
)];
61 static uint32_t * const stack_super_end
__attribute__((used
, section(".aros.init"))) = &stack_super
[STACK_SIZE
- sizeof(IPTR
)];
62 static uint32_t * const stack_abort_end
__attribute__((used
, section(".aros.init"))) = &stack_abort
[STACK_SIZE
- sizeof(IPTR
)];
63 static uint32_t * const stack_irq_end
__attribute__((used
, section(".aros.init"))) = &stack_irq
[STACK_SIZE
- sizeof(IPTR
)];
65 __attribute__((section(".data"))) struct ExecBase
*SysBase
= NULL
;
67 extern struct TagItem
*BootMsg
;
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
;
77 while (bss
->addr
&& 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;
90 // Fill in the remaining 32-bit word-aligned memory locations
91 while(length
& 0xfffffffc)
93 *((unsigned int *)dest
) = 0;
98 // Deal with the remaining 1-3 bytes, if any
103 *((unsigned char *)dest
) = 0;
110 uint32_t __arm_periiobase
= 0;
112 void __attribute__((used
)) kernel_cstart(struct TagItem
*msg
)
115 struct MinList memList
;
116 struct MemHeader
*mh
;
118 long unsigned int memlower
= 0, memupper
= 0, protlower
= 0, protupper
= 0;
121 register unsigned int fpuflags
;
124 /* Guess the cpu type and adjust __arm_periiobase accordingly */
125 asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r" (tmp
));
126 if ((tmp
& 0xfff0) == 0xc070) /* armv7, also RaspberryPi 2 */
128 __arm_periiobase
= BCM2836_PERIPHYSBASE
;
130 /* Power LED back on */
131 *(volatile unsigned int *)GPSET1
= (1 << (35-32)); // Power LED ON
135 __arm_periiobase
= BCM2835_PERIPHYSBASE
;
136 /* Need to detect the plus board here in order to control LEDs properly */
138 *(volatile unsigned int *)GPCLR0
= (1 << 16); // Activity LED ON
141 /* NB: the bootstrap has conveniently setup the framebuffer
142 and initialised the serial port and led for us */
147 for (delay
= 0; delay
< 100000; delay
++) asm volatile ("mov r0, r0\n");
149 *(volatile unsigned int *)GPSET0
= (1 << 16); // LED OFF
151 /* Enable Vector Floating Point Calculations */
152 asm volatile("mrc p15,0,%[fpuflags],c1,c0,2\n" : [fpuflags
] "=r" (fpuflags
)); // Read Access Control Register
153 fpuflags
|= (VFPSingle
| VFPDouble
); // Enable Single & Double Precision
154 asm volatile("mcr p15,0,%[fpuflags],c1,c0,2\n" : : [fpuflags
] "r" (fpuflags
)); // Set Access Control Register
156 " mov %[fpuflags],%[vfpenable] \n" // Enable VFP
157 " fmxr fpexc,%[fpuflags] \n"
158 : [fpuflags
] "=r" (fpuflags
) : [vfpenable
] "I" (VFPEnable
));
160 for (delay
= 0; delay
< 100000; delay
++) asm volatile ("mov r0, r0\n");
162 *(volatile unsigned int *)GPCLR0
= (1 << 16); // LED ON
164 while(msg
->ti_Tag
!= TAG_DONE
)
169 _KrnPutC
= msg
->ti_Data
;
170 _KrnPutC(0xFF); // Clear the display
173 memlower
= msg
->ti_Data
;
176 memupper
= msg
->ti_Data
;
178 case KRN_ProtAreaStart
:
179 protlower
= msg
->ti_Data
;
181 case KRN_ProtAreaEnd
:
182 protupper
= msg
->ti_Data
;
186 * KRN_KernelBase is actually a border between read-only
187 * (code) and read-write (data) sections of the kickstart.
188 * read-write section goes to lower addresses from this one,
189 * so we align it upwards in order not to make part of RW data
192 // addr = AROS_ROUNDUP2(msg->ti_Data, PAGE_SIZE);
199 D(bug("[KRN] AROS Raspberry Pi Kernel built on %s\n", __DATE__
));
201 D(bug("[KRN] Entered kernel_cstart @ 0x%p, BootMsg @ %p\n", kernel_cstart
, BootMsg
));
206 bug("[KRN] Using boostrap PutC implementation @ %p\n", _KrnPutC
);
212 *(volatile unsigned int *)GPSET0
= 1<<16; // LED OFF
213 for (delay
= 0; delay
< 1500; delay
++) asm volatile("mov r0, r0\n");
214 *(volatile unsigned int *)GPCLR0
= 1<<16; // LED ON
218 mh
= (struct MemHeader
*)memlower
;
219 krnCreateMemHeader("System Memory", 0, mh
, protlower
- (long unsigned int)mh
, MEMF_FAST
| MEMF_PUBLIC
| MEMF_KICK
| MEMF_LOCAL
);
221 mc
= (struct MemChunk
*)((protupper
+ MEMCHUNK_TOTAL
-1) & ~(MEMCHUNK_TOTAL
-1));
222 mc
->mc_Bytes
= memupper
- (long unsigned int)mc
;
225 if (mh
->mh_First
->mc_Next
== NULL
)
227 mh
->mh_First
->mc_Next
= mc
;
228 mh
->mh_Upper
= memupper
;
229 mh
->mh_Free
+= mc
->mc_Bytes
;
232 ranges
[0] = (UWORD
*)krnGetTagData(KRN_KernelLowest
, 0, msg
);
233 ranges
[1] = (UWORD
*)krnGetTagData(KRN_KernelHighest
, 0, msg
);
234 ranges
[2] = (UWORD
*)-1;
236 D(bug("[KRN] Preparing ExecBase (memheader @ 0x%p)\n", mh
));
237 krnPrepareExecBase(ranges
, mh
, BootMsg
);
240 * Make kickstart code area read-only.
241 * We do it only after ExecBase creation because SysBase pointer is put
242 * into .rodata. This way we prevent it from ocassional modification by buggy software.
244 // core_ProtKernelArea(addr, kick_highest - addr, 1, 0, 1);
246 D(bug("[KRN] InitCode(RTF_SINGLETASK) ... \n"));
247 InitCode(RTF_SINGLETASK
, 0);
249 D(bug("[KRN] InitCode(RTF_COLDSTART) ...\n"));
251 asm("cps %[mode_user]\n" : : [mode_user
] "I" (CPUMODE_USER
)); /* switch to user mode */
253 InitCode(RTF_COLDSTART
, 0);
255 /* The above should not return */
256 krnPanic(KernelBase
, "System Boot Failed!");