a758c58ebee73fbd1dd743a05f07f1e9d86b042c
[rpi-open-firmware.git] / arm_chainloader / start.s
1 /*=============================================================================
2 Copyright (C) 2016-2017 Authors of rpi-open-firmware
3 All rights reserved.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 FILE DESCRIPTION
16 ARM entry point.
17
18 This is where all cores start. For RPi1, only one core starts so we can jump
19 straight to the main bootloader. For later models, the first core jumps to the
20 bootloader. The other cores wait until SMP is enabled by the kernel later in
21 the boot process.
22
23 =============================================================================*/
24
25 #include "memory_map.h"
26
27 .arch_extension sec
28
29 .text
30 .globl _start
31 _start:
32 /* vectors */
33 b _common_start /* reset */
34 b _fleh_undef /* undefined */
35 b _secure_monitor /* swi/smc */
36 b _fleh_prefabt /* prefetch abort */
37 b _fleh_dataabt /* data abort */
38 b _fleh_addrexc /* reserved */
39 b _fleh_irq /* irq */
40 b _fleh_fiq /* fiq */
41
42 .globl g_FirmwareData
43 g_FirmwareData:
44 .long 0 /* SDRAM capacity */
45 .long 0 /* VPU CPUID */
46 .long 0 /* Reserved */
47 .long 0 /* Reserved */
48 .long 0 /* Reserved */
49
50 #define SaveRegisters() \
51 mov sp, #(MEM_STACK_END); \
52 stmea sp, {r0-lr}^; \
53 str lr, [sp, #60]; \
54 mrs r0, spsr
55 str r0, [sp, #64];
56
57 _fleh_undef:
58 SaveRegisters()
59 b sleh_undef
60
61 _fleh_prefabt:
62 SaveRegisters()
63 b sleh_prefabt
64
65 _fleh_dataabt:
66 SaveRegisters()
67 b sleh_dataabt
68
69 _fleh_addrexc:
70 SaveRegisters()
71 b sleh_addrexc
72
73 _fleh_irq:
74 SaveRegisters()
75 b sleh_irq
76
77 _fleh_fiq:
78 SaveRegisters()
79 b sleh_fiq
80
81 _secure_monitor:
82 mrc p15, 0, r0, c1, c1, 0
83 //bic r0, r0, #0x4a /* clear IRQ, EA, nET */
84 orr r0, r0, #1 /* set NS */
85 mcr p15, 0, r0, c1, c1, 0
86
87 //mov r0, #((1 << 7) | (1 << 8) | (1 << 6)) /* mask IRQ, AA and FIQ */
88 //orr r0, r0, #0x1a /* switch to hypervisor mode */
89 //msr spsr_cxfs, r0
90
91 movs pc, lr
92
93 _common_start:
94 /*
95 * read MIDR, see if this is an ARMv6 system, if it is, just
96 * assume single core (BCM2708) and not bother doing SMP stuff.
97 */
98 mrc p15, 0, r0, c0, c0, 0
99 lsr r0, #16
100 and r0, #0xF
101 cmp r0, #0x7
102 mov r12, #0
103 beq L_finish_init
104
105 L_armv7_or_higher:
106 /*
107 * okay, we're an ARMv7 or an ARMv8.
108 */
109 mrc p15, 0, r0, c0, c0, 5 // read MPIDR
110 and r3, r0, #0xc0000000 // multiprocessing extensions and
111 teq r3, #0x80000000 // not part of a uniprocessor system?
112 bne L_setup_monitor // no, assume UP
113 ands r0, r0, #0x03 // CPU 0?
114 bne L_deadloop // if not, spin.
115
116 L_setup_monitor:
117 adr r1, _start
118 //mcr p15, 0, r1, c12, c0, 1 /* MVBAR */
119 //mcr p15, 0, r1, c7, c5, 4 /* ISB (ARMv6 compatible way) */
120
121 mrc p15, 0, r0, c1, c1, 0
122 orr r0, r0, #1 /* set NS */
123 mcr p15, 0, r0, c1, c1, 0
124
125 mov r12, #1
126 //smc 0
127
128 L_finish_init:
129 /* enable instruction cache */
130 //mrc p15, 0, r0, c1, c0, 0
131 //orr r0, r0, #(1<<12)
132 //mcr p15, 0, r0, c1, c0, 0
133
134 mov sp, #(MEM_STACK_END)
135 mov r0, r12
136 b main
137
138 L_deadloop:
139 cpsie if
140 wfi
141 b L_deadloop
This page took 0.070052 seconds and 4 git commands to generate.