summaryrefslogtreecommitdiff
path: root/bootwrapper/boot.S
blob: 6afbf34cf70cdb34e204a56f309b6ecc24e4430d (plain)
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