Skip to content

Commit 36d12b9

Browse files
committed
Attempt to fix TZ0 patch for A7 10.3.3 and possibly some others
1 parent 760647f commit 36d12b9

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

src/boot/stage3.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,24 +167,41 @@ void patch_bootloader(void* boot_image)
167167
// str wN, [xM]
168168
// ldr wS, [xM]
169169
// tbz wS, 0, ...
170+
// And just because clang hates us, at least A7 on 10.3.3 has a completely unnecessary mov in between:
171+
// str wN, [xM]
172+
// ldr wT, [xM]
173+
// tbz wT, 0, ...
174+
// mov wZ, 1
175+
// str wZ, [xM, 4]
176+
// ldr wS, [xM, 4]
177+
// tbz wS, 0, ...
170178
// We require that T and S are <16, and that the two tbz have positive offset.
171179
// /x 000000b9000040b900000036000400b9000440b900000036:00fcffff10fcffff0000fcff00fcffff10fcffff0000fcff
172180
// /x 000000b9000040b9000000364000c0d2802281f2000000b9000040b900000036:00fcffff10fcffff0000fcffe0ffffffe0ffffff00fcffff10fcffff0000fcff
181+
// /x 000000b9000040b900000036e0030032000400b9000440b900000036:00fcffff10fcffff0000fcffe0ffffff00fcffff10fcffff0000fcff
173182
if((op1 & 0xfffffc00) == 0xb9000000 && (op2 & 0xfffffff0) == ((op1 & 0x000003e0) | 0xb9400000) && (op3 & 0xfffc001f) == ((op2 & 0x0000001f) | 0x36000000))
174183
{
175184
volatile uint32_t *one = p,
176185
*two = p + 3;
177186
uint32_t op4 = two[0],
178187
op5 = two[1];
179188
uint32_t imm = 1; // 1 << 2
189+
uint32_t regs = op1 & 0x3ff;
180190
if(op4 == (((op1 & 0x000003e0) >> 5) | 0xd2c00040) && op5 == (((op1 & 0x000003e0) >> 5) | 0xf2812280))
181191
{
182192
two += 2;
193+
imm = 0;
194+
op4 = two[0];
195+
op5 = two[1];
196+
}
197+
else if((op4 & 0xffffffe0) == 0x320003e0) // orr wZ, wzr, 1
198+
{
199+
two += 1;
200+
regs = (regs & ~0x1f) | (op4 & 0x1f);
183201
op4 = two[0];
184202
op5 = two[1];
185-
imm = 0;
186203
}
187-
if(op4 == ((op1 & 0x000003ff) | (imm << 10) | 0xb9000000) && (op5 & 0xfffffff0) == ((op1 & 0x000003e0) | (imm << 10) | 0xb9400000) && (two[2] & 0xfffc001f) == ((op5 & 0x0000001f) | 0x36000000))
204+
if(op4 == (regs | (imm << 10) | 0xb9000000) && (op5 & 0xfffffff0) == ((op1 & 0x000003e0) | (imm << 10) | 0xb9400000) && (two[2] & 0xfffc001f) == ((op5 & 0x0000001f) | 0x36000000))
188205
{
189206
// Nop them all out.
190207
one[0] = 0xd503201f;

0 commit comments

Comments
 (0)