-
Notifications
You must be signed in to change notification settings - Fork 42
/
entry.S
226 lines (194 loc) · 4.29 KB
/
entry.S
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/**
* GreenPois0n Cynanide - entry.S
* Copyright (C) 2010 Chronic-Dev Team
* Copyright (C) 2010 Joshua Hill
* Copyright (C) 2010 Cyril Cattiaux
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
#include "offsets.h"
.arm
.ltorg
.code 32
.global _start
_start:
b reset
ldr pc, undefined_vector
ldr pc, syscall_vector
ldr pc, prefetch_abort_vector
ldr pc, data_abort_vector
ldr pc, reserved_vector
ldr pc, irq_vector
ldr pc, fiq_vector
reset_vector: .word reset
undefined_vector: .word halt
syscall_vector: .word halt
prefetch_abort_vector: .word halt
data_abort_vector: .word halt
reserved_vector: .word halt
irq_vector: .word halt
fiq_vector: .word halt
.pool
.set FP_CMD_1, 0x47184b00 @ search: LDR R3, =0x41000000 @ BR R3
.set FP_CMD_2, 0x41000000 @ search: 0x41000000
.set PATCH_CMD_1, 0x47184b00 @ _patch: LDR R3, =0x42000000 @ BX R3
.set PATCH_CMD_2, 0x42000000 @ _patch: 0x42000000
.set FP_CMD2_1, 0x47184b00 @ search: LDR R3, =0x09000000 @ BR R3
.set FP_CMD2_2, 0x09000000 @ search: 0x09000000
.set PATCH_CMD2_1, 0x47184b00 @ _patch: LDR R3, =0x0A000000 @ BX R3
.set PATCH_CMD2_2, 0x0A000000 @ _patch: 0x0A000000
.set new_loadaddr, 0x41000000
.set new_payload_dest, 0x42000000
.set old_loadaddr, 0x09000000
.set old_payload_dest, 0x0A000000
.code 32
@---------------------------------------------
reset:
push {r0-r12, lr}
mov r5, pc
lsr r5, #24
cmp r5, #0x42
beq relocated
cmp r5, #0x0A
beq relocated
cmp r5, #0x41
beq relocate_new
cmp r5, #0x09
beq relocate_old
b halt
relocate_new:
ldr r0, =new_loadaddr
ldr r1, =new_payload_dest
b relocate
relocate_old:
ldr r0, =old_loadaddr
ldr r1, =old_payload_dest
b relocate
relocate:
mov r4, r1
bl copy
bl patch
cmp r5, #0x09
bne flush_new
@bl clear_dcache
bl clear_icache
b jump_main
flush_new:
bl clear_icache
bl flush_dcache
jump_main:
blx r4
b done
relocated:
ldr r0, [sp, #0x0]
ldr r1, [sp, #0x4]
ldr r2, [sp, #0x8]
ldr r3, [sp, #0xc]
bl main
str r0, [sp, #0x0] @ push r0 return onto the stack to be returned
done:
pop {r0-r12, pc}
halt:
b halt
@---------------------------------------------
.code 32
copy:
mov r2, #0x00100000
copy_loop:
ldr r3, [r0], #4
str r3, [r1], #4
subs r2, r2, #4
bne copy_loop
bx lr
@---------------------------------------------
.code 32
patch:
push {lr}
mov r0, pc
lsr r0, #24
patch1:
ldr r0, =FP_CMD_1
ldr r1, =TARGET_BASEADDR
mov r2, #0x2c000 @ search area
ldr r3, =FP_CMD_2
blx find_64
cmp r0, #0
beq patch2
ldr r1, =PATCH_CMD_1
str r1, [r0]
ldr r1, =PATCH_CMD_2
str r1, [r0, #4]
b patch_done
patch2:
ldr r0, =FP_CMD2_1
ldr r1, =TARGET_BASEADDR
mov r2, #0x24000 @ search area
ldr r3, =FP_CMD2_2
blx find_64
cmp r0, #0
beq patch3
ldr r1, =PATCH_CMD2_1
str r1, [r0]
ldr r1, =PATCH_CMD2_2
str r1, [r0, #4]
b patch_done
patch3:
patch_done:
pop {pc}
@---------------------------------------------
.code 16
.thumb_func
find_64:
push {r4, lr}
find_loop:
ldr r4, [r1]
cmp r4, r0
bne find_loop_continue
ldr r4, [r1,#4]
cmp r4, r3
beq find_return
find_loop_continue:
add r1, #2
sub r2, #2
cmp r2, #0
bne find_loop
mov r1, #0
find_return:
mov r0, r1
pop {r4, pc}
@---------------------------------------------
.code 32
clear_icache:
mov r0, #0
mcr p15, 0, r0, c7, c5
mcr p15, 0, r0, c7, c5, 4 @ Flush Prefetch Buffer
nop
nop
nop
nop
bx lr
@---------------------------------------------
.code 32
flush_dcache:
mrc p15, 0, r0, c1, c0, 1
bx lr
@---------------------------------------------
.code 32
clear_dcache:
mov r0, #0
mcr p15, 0, r0, c7, c10, 0 @ Clean Entire Data Cache
mcr p15, 0, r0, c7, c10, 4 @ Data Synchronization Barrier
bx lr
@---------------------------------------------
.end