1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
;
; Copyright (c) 2011, ARM Limited. All rights reserved.
;
; Redistribution and use in source and binary forms, with
; or without modification, are permitted provided that the
; following conditions are met:
;
; Redistributions of source code must retain the above
; copyright notice, this list of conditions and the
; following disclaimer.
;
; Redistributions in binary form must reproduce the
; above copyright notice, this list of conditions and
; the following disclaimer in the documentation
; and/or other materials provided with the distribution.
;
; Neither the name of ARM nor the names of its
; contributors may be used to endorse or promote products
; derived from this software without specific prior written
; permission.
;
AREA |boot|, CODE, ALIGN=2
PRESERVE8
INCLUDE emubuild.s
IMPORT __use_no_semihosting_swi
IMPORT __use_no_heap_region
IMPORT output_string
IMPORT c_start
IMPORT enable_coherency
IMPORT stack
IMPORT stack_size
IMPORT hexword
IMPORT read_sctlr
IMPORT write_sctlr
IMPORT get_sp
IMPORT inv_icache_all
EXPORT start
EXPORT dabort
EXPORT fiq
EXPORT irq
EXPORT pabort
EXPORT swi
EXPORT undef
EXPORT unused
EXPORT dead
;------------------------------------------------------------------------------
; Boot code starts here - identify the CPU type, set up stacks and call c_start
;------------------------------------------------------------------------------
start
bl inv_icache_all
;------------------------------------------------------------------
; Enable ICache, branch predictor and alignment
;------------------------------------------------------------------
bl read_sctlr
bic r0, r0, #CR_C
orr r0, r0, #CR_Z
orr r0, r0, #CR_I
;------------------------------------------------------------------
; Set U bit - the C compiler produces non-64-bit-aligned LDRD/STRDs
;------------------------------------------------------------------
orr r0, #CR_U
bl write_sctlr
;------------------------------------------------------------------
; Give yourself a stack to make things easier
;------------------------------------------------------------------
ldr r0, =stack
ldr r1, =stack_size
ldr r1, [r1]
bl get_sp
mov sp, r0
;------------------------------------------------------------------
; Caches are inavlidated at reset & MMU is off. So its safe to
; enable coherency
;------------------------------------------------------------------
;; bl enable_coherency
;------------------------------------------------------------------
; TODO: Enable MMU & coherency here
;------------------------------------------------------------------
;------------------------------------------------------------------
; Jump to the C handler
;------------------------------------------------------------------
bl c_start
;------------------------------------------------------------------
; Should never come here
;------------------------------------------------------------------
kernel_returned
b kernel_returned
; ==============================================================================
; End of main code
; ==============================================================================
; ==============================================================================
; Message strings, etc.
; ==============================================================================
LTORG
ALIGN
dabort_string
DCB " Emubuild-DAB!", 0
undef_string
DCB " Emubuild-UND!", 0
pabort_string
DCB " Emubuild-PAB!", 0
swi_string
DCB " Emubuild-SWI!", 0
irq_string
DCB " Emubuild-IRQ!", 0
fiq_string
DCB " Emubuild-FIQ!", 0
unused_string
DCB " Emubuild-UNU!", 0
ALIGN
; ==============================================================================
; Exception handlers - for most exceptions we spin
; ==============================================================================
dabort
mov r12, lr ; save lr, just in case it's interesting
mov r0, r12
bl hexword
mrc p15,0,r0,c5,c0,0 ; DFSR
bl hexword
mrc p15,0,r0,c6,c0,0 ; DFAR
bl hexword
ldr r0, =dabort_string
bl output_string
b dead
undef
push {r0-r1}
ldr r0, [lr,#-4] ; load undeffing instruction
ldr r1, =0xf57ff000 ; ignore unimplemented DSB/DMB/ISB/CLRX
bic r0, r0, #0x000000ff
cmp r0, r1
popeq {r0-r1}
bxeq lr
mov r0, lr ; print lr, just in case it's interesting
bl hexword
ldr r0, =undef_string
bl output_string
b dead
pabort
mov r0, lr ; print lr, just in case it's interesting
bl hexword
ldr r0, =pabort_string
bl output_string
b dead
swi
mov r0, lr ; print lr, just in case it's interesting
bl hexword
ldr r0, =swi_string
bl output_string
b dead
irq
mov r0, lr ; print lr, just in case it's interesting
bl hexword
ldr r0, =irq_string
bl output_string
b dead
fiq
mov r0, lr ; print lr, just in case it's interesting
bl hexword
ldr r0, =fiq_string
bl output_string
b dead
unused
mov r0, lr ; print lr, just in case it's interesting
bl hexword
ldr r0, =unused_string
bl output_string
b dead
dead
B dead
END
|