diff options
Diffstat (limited to 'arch/arm/lib/copy_template.S')
-rw-r--r-- | arch/arm/lib/copy_template.S | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S index 139cce646055..805e3f8fb007 100644 --- a/arch/arm/lib/copy_template.S +++ b/arch/arm/lib/copy_template.S | |||
@@ -57,6 +57,13 @@ | |||
57 | * | 57 | * |
58 | * Restore registers with the values previously saved with the | 58 | * Restore registers with the values previously saved with the |
59 | * 'preserv' macro. Called upon code termination. | 59 | * 'preserv' macro. Called upon code termination. |
60 | * | ||
61 | * LDR1W_SHIFT | ||
62 | * STR1W_SHIFT | ||
63 | * | ||
64 | * Correction to be applied to the "ip" register when branching into | ||
65 | * the ldr1w or str1w instructions (some of these macros may expand to | ||
66 | * than one 32bit instruction in Thumb-2) | ||
60 | */ | 67 | */ |
61 | 68 | ||
62 | 69 | ||
@@ -99,9 +106,15 @@ | |||
99 | 106 | ||
100 | 5: ands ip, r2, #28 | 107 | 5: ands ip, r2, #28 |
101 | rsb ip, ip, #32 | 108 | rsb ip, ip, #32 |
109 | #if LDR1W_SHIFT > 0 | ||
110 | lsl ip, ip, #LDR1W_SHIFT | ||
111 | #endif | ||
102 | addne pc, pc, ip @ C is always clear here | 112 | addne pc, pc, ip @ C is always clear here |
103 | b 7f | 113 | b 7f |
104 | 6: nop | 114 | 6: |
115 | .rept (1 << LDR1W_SHIFT) | ||
116 | W(nop) | ||
117 | .endr | ||
105 | ldr1w r1, r3, abort=20f | 118 | ldr1w r1, r3, abort=20f |
106 | ldr1w r1, r4, abort=20f | 119 | ldr1w r1, r4, abort=20f |
107 | ldr1w r1, r5, abort=20f | 120 | ldr1w r1, r5, abort=20f |
@@ -110,9 +123,16 @@ | |||
110 | ldr1w r1, r8, abort=20f | 123 | ldr1w r1, r8, abort=20f |
111 | ldr1w r1, lr, abort=20f | 124 | ldr1w r1, lr, abort=20f |
112 | 125 | ||
126 | #if LDR1W_SHIFT < STR1W_SHIFT | ||
127 | lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT | ||
128 | #elif LDR1W_SHIFT > STR1W_SHIFT | ||
129 | lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT | ||
130 | #endif | ||
113 | add pc, pc, ip | 131 | add pc, pc, ip |
114 | nop | 132 | nop |
115 | nop | 133 | .rept (1 << STR1W_SHIFT) |
134 | W(nop) | ||
135 | .endr | ||
116 | str1w r0, r3, abort=20f | 136 | str1w r0, r3, abort=20f |
117 | str1w r0, r4, abort=20f | 137 | str1w r0, r4, abort=20f |
118 | str1w r0, r5, abort=20f | 138 | str1w r0, r5, abort=20f |