| .. | .. |
|---|
| 14 | 14 | |
|---|
| 15 | 15 | #include <linux/linkage.h> |
|---|
| 16 | 16 | #include <asm/asm-offsets.h> |
|---|
| 17 | | -#include <asm/processor.h> |
|---|
| 17 | +#include <asm/asmmacro.h> |
|---|
| 18 | 18 | #include <asm/coprocessor.h> |
|---|
| 19 | | -#include <asm/thread_info.h> |
|---|
| 20 | | -#include <asm/asm-uaccess.h> |
|---|
| 21 | | -#include <asm/unistd.h> |
|---|
| 22 | | -#include <asm/ptrace.h> |
|---|
| 23 | 19 | #include <asm/current.h> |
|---|
| 24 | | -#include <asm/pgtable.h> |
|---|
| 25 | | -#include <asm/page.h> |
|---|
| 26 | | -#include <asm/signal.h> |
|---|
| 27 | | -#include <asm/tlbflush.h> |
|---|
| 20 | +#include <asm/regs.h> |
|---|
| 28 | 21 | |
|---|
| 29 | 22 | #if XTENSA_HAVE_COPROCESSORS |
|---|
| 30 | 23 | |
|---|
| .. | .. |
|---|
| 33 | 26 | */ |
|---|
| 34 | 27 | |
|---|
| 35 | 28 | #define SAVE_CP_REGS(x) \ |
|---|
| 36 | | - .align 4; \ |
|---|
| 37 | | - .Lsave_cp_regs_cp##x: \ |
|---|
| 38 | 29 | .if XTENSA_HAVE_COPROCESSOR(x); \ |
|---|
| 39 | | - xchal_cp##x##_store a2 a4 a5 a6 a7; \ |
|---|
| 40 | | - .endif; \ |
|---|
| 41 | | - jx a0 |
|---|
| 30 | + .align 4; \ |
|---|
| 31 | + .Lsave_cp_regs_cp##x: \ |
|---|
| 32 | + xchal_cp##x##_store a2 a3 a4 a5 a6; \ |
|---|
| 33 | + jx a0; \ |
|---|
| 34 | + .endif |
|---|
| 42 | 35 | |
|---|
| 43 | 36 | #define SAVE_CP_REGS_TAB(x) \ |
|---|
| 44 | 37 | .if XTENSA_HAVE_COPROCESSOR(x); \ |
|---|
| 45 | | - .long .Lsave_cp_regs_cp##x - .Lsave_cp_regs_jump_table; \ |
|---|
| 38 | + .long .Lsave_cp_regs_cp##x; \ |
|---|
| 46 | 39 | .else; \ |
|---|
| 47 | 40 | .long 0; \ |
|---|
| 48 | 41 | .endif; \ |
|---|
| .. | .. |
|---|
| 50 | 43 | |
|---|
| 51 | 44 | |
|---|
| 52 | 45 | #define LOAD_CP_REGS(x) \ |
|---|
| 53 | | - .align 4; \ |
|---|
| 54 | | - .Lload_cp_regs_cp##x: \ |
|---|
| 55 | 46 | .if XTENSA_HAVE_COPROCESSOR(x); \ |
|---|
| 56 | | - xchal_cp##x##_load a2 a4 a5 a6 a7; \ |
|---|
| 57 | | - .endif; \ |
|---|
| 58 | | - jx a0 |
|---|
| 47 | + .align 4; \ |
|---|
| 48 | + .Lload_cp_regs_cp##x: \ |
|---|
| 49 | + xchal_cp##x##_load a2 a3 a4 a5 a6; \ |
|---|
| 50 | + jx a0; \ |
|---|
| 51 | + .endif |
|---|
| 59 | 52 | |
|---|
| 60 | 53 | #define LOAD_CP_REGS_TAB(x) \ |
|---|
| 61 | 54 | .if XTENSA_HAVE_COPROCESSOR(x); \ |
|---|
| 62 | | - .long .Lload_cp_regs_cp##x - .Lload_cp_regs_jump_table; \ |
|---|
| 55 | + .long .Lload_cp_regs_cp##x; \ |
|---|
| 63 | 56 | .else; \ |
|---|
| 64 | 57 | .long 0; \ |
|---|
| 65 | 58 | .endif; \ |
|---|
| 66 | 59 | .long THREAD_XTREGS_CP##x |
|---|
| 60 | + |
|---|
| 61 | + __XTENSA_HANDLER |
|---|
| 67 | 62 | |
|---|
| 68 | 63 | SAVE_CP_REGS(0) |
|---|
| 69 | 64 | SAVE_CP_REGS(1) |
|---|
| .. | .. |
|---|
| 105 | 100 | LOAD_CP_REGS_TAB(7) |
|---|
| 106 | 101 | |
|---|
| 107 | 102 | /* |
|---|
| 108 | | - * coprocessor_save(buffer, index) |
|---|
| 109 | | - * a2 a3 |
|---|
| 110 | | - * coprocessor_load(buffer, index) |
|---|
| 111 | | - * a2 a3 |
|---|
| 112 | | - * |
|---|
| 113 | | - * Save or load coprocessor registers for coprocessor 'index'. |
|---|
| 114 | | - * The register values are saved to or loaded from them 'buffer' address. |
|---|
| 115 | | - * |
|---|
| 116 | | - * Note that these functions don't update the coprocessor_owner information! |
|---|
| 117 | | - * |
|---|
| 118 | | - */ |
|---|
| 119 | | - |
|---|
| 120 | | -ENTRY(coprocessor_save) |
|---|
| 121 | | - |
|---|
| 122 | | - entry a1, 32 |
|---|
| 123 | | - s32i a0, a1, 0 |
|---|
| 124 | | - movi a0, .Lsave_cp_regs_jump_table |
|---|
| 125 | | - addx8 a3, a3, a0 |
|---|
| 126 | | - l32i a3, a3, 0 |
|---|
| 127 | | - beqz a3, 1f |
|---|
| 128 | | - add a0, a0, a3 |
|---|
| 129 | | - callx0 a0 |
|---|
| 130 | | -1: l32i a0, a1, 0 |
|---|
| 131 | | - retw |
|---|
| 132 | | - |
|---|
| 133 | | -ENDPROC(coprocessor_save) |
|---|
| 134 | | - |
|---|
| 135 | | -ENTRY(coprocessor_load) |
|---|
| 136 | | - |
|---|
| 137 | | - entry a1, 32 |
|---|
| 138 | | - s32i a0, a1, 0 |
|---|
| 139 | | - movi a0, .Lload_cp_regs_jump_table |
|---|
| 140 | | - addx4 a3, a3, a0 |
|---|
| 141 | | - l32i a3, a3, 0 |
|---|
| 142 | | - beqz a3, 1f |
|---|
| 143 | | - add a0, a0, a3 |
|---|
| 144 | | - callx0 a0 |
|---|
| 145 | | -1: l32i a0, a1, 0 |
|---|
| 146 | | - retw |
|---|
| 147 | | - |
|---|
| 148 | | -ENDPROC(coprocessor_load) |
|---|
| 149 | | - |
|---|
| 150 | | -/* |
|---|
| 151 | | - * coprocessor_flush(struct task_info*, index) |
|---|
| 152 | | - * a2 a3 |
|---|
| 153 | | - * coprocessor_restore(struct task_info*, index) |
|---|
| 154 | | - * a2 a3 |
|---|
| 155 | | - * |
|---|
| 156 | | - * Save or load coprocessor registers for coprocessor 'index'. |
|---|
| 157 | | - * The register values are saved to or loaded from the coprocessor area |
|---|
| 158 | | - * inside the task_info structure. |
|---|
| 159 | | - * |
|---|
| 160 | | - * Note that these functions don't update the coprocessor_owner information! |
|---|
| 161 | | - * |
|---|
| 162 | | - */ |
|---|
| 163 | | - |
|---|
| 164 | | - |
|---|
| 165 | | -ENTRY(coprocessor_flush) |
|---|
| 166 | | - |
|---|
| 167 | | - entry a1, 32 |
|---|
| 168 | | - s32i a0, a1, 0 |
|---|
| 169 | | - movi a0, .Lsave_cp_regs_jump_table |
|---|
| 170 | | - addx8 a3, a3, a0 |
|---|
| 171 | | - l32i a4, a3, 4 |
|---|
| 172 | | - l32i a3, a3, 0 |
|---|
| 173 | | - add a2, a2, a4 |
|---|
| 174 | | - beqz a3, 1f |
|---|
| 175 | | - add a0, a0, a3 |
|---|
| 176 | | - callx0 a0 |
|---|
| 177 | | -1: l32i a0, a1, 0 |
|---|
| 178 | | - retw |
|---|
| 179 | | - |
|---|
| 180 | | -ENDPROC(coprocessor_flush) |
|---|
| 181 | | - |
|---|
| 182 | | -ENTRY(coprocessor_restore) |
|---|
| 183 | | - entry a1, 32 |
|---|
| 184 | | - s32i a0, a1, 0 |
|---|
| 185 | | - movi a0, .Lload_cp_regs_jump_table |
|---|
| 186 | | - addx4 a3, a3, a0 |
|---|
| 187 | | - l32i a4, a3, 4 |
|---|
| 188 | | - l32i a3, a3, 0 |
|---|
| 189 | | - add a2, a2, a4 |
|---|
| 190 | | - beqz a3, 1f |
|---|
| 191 | | - add a0, a0, a3 |
|---|
| 192 | | - callx0 a0 |
|---|
| 193 | | -1: l32i a0, a1, 0 |
|---|
| 194 | | - retw |
|---|
| 195 | | - |
|---|
| 196 | | -ENDPROC(coprocessor_restore) |
|---|
| 197 | | - |
|---|
| 198 | | -/* |
|---|
| 199 | 103 | * Entry condition: |
|---|
| 200 | 104 | * |
|---|
| 201 | 105 | * a0: trashed, original value saved on stack (PT_AREG0) |
|---|
| .. | .. |
|---|
| 208 | 112 | * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC |
|---|
| 209 | 113 | * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception |
|---|
| 210 | 114 | */ |
|---|
| 211 | | - |
|---|
| 212 | | -ENTRY(fast_coprocessor_double) |
|---|
| 213 | | - |
|---|
| 214 | | - wsr a0, excsave1 |
|---|
| 215 | | - call0 unrecoverable_exception |
|---|
| 216 | | - |
|---|
| 217 | | -ENDPROC(fast_coprocessor_double) |
|---|
| 218 | 115 | |
|---|
| 219 | 116 | ENTRY(fast_coprocessor) |
|---|
| 220 | 117 | |
|---|
| .. | .. |
|---|
| 274 | 171 | movi a0, 2f # a0: 'return' address |
|---|
| 275 | 172 | addx8 a3, a3, a5 # a3: coprocessor number |
|---|
| 276 | 173 | l32i a2, a3, 4 # a2: xtregs offset |
|---|
| 277 | | - l32i a3, a3, 0 # a3: jump offset |
|---|
| 174 | + l32i a3, a3, 0 # a3: jump address |
|---|
| 278 | 175 | add a2, a2, a4 |
|---|
| 279 | | - add a4, a3, a5 # a4: address of save routine |
|---|
| 280 | | - jx a4 |
|---|
| 176 | + jx a3 |
|---|
| 281 | 177 | |
|---|
| 282 | 178 | /* Note that only a0 and a1 were preserved. */ |
|---|
| 283 | 179 | |
|---|
| .. | .. |
|---|
| 297 | 193 | movi a0, 1f |
|---|
| 298 | 194 | addx8 a3, a3, a5 |
|---|
| 299 | 195 | l32i a2, a3, 4 # a2: xtregs offset |
|---|
| 300 | | - l32i a3, a3, 0 # a3: jump offset |
|---|
| 196 | + l32i a3, a3, 0 # a3: jump address |
|---|
| 301 | 197 | add a2, a2, a4 |
|---|
| 302 | | - add a4, a3, a5 |
|---|
| 303 | | - jx a4 |
|---|
| 198 | + jx a3 |
|---|
| 304 | 199 | |
|---|
| 305 | 200 | /* Restore all registers and return from exception handler. */ |
|---|
| 306 | 201 | |
|---|
| .. | .. |
|---|
| 319 | 214 | |
|---|
| 320 | 215 | ENDPROC(fast_coprocessor) |
|---|
| 321 | 216 | |
|---|
| 217 | + .text |
|---|
| 218 | + |
|---|
| 219 | +/* |
|---|
| 220 | + * coprocessor_flush(struct thread_info*, index) |
|---|
| 221 | + * a2 a3 |
|---|
| 222 | + * |
|---|
| 223 | + * Save coprocessor registers for coprocessor 'index'. |
|---|
| 224 | + * The register values are saved to or loaded from the coprocessor area |
|---|
| 225 | + * inside the task_info structure. |
|---|
| 226 | + * |
|---|
| 227 | + * Note that this function doesn't update the coprocessor_owner information! |
|---|
| 228 | + * |
|---|
| 229 | + */ |
|---|
| 230 | + |
|---|
| 231 | +ENTRY(coprocessor_flush) |
|---|
| 232 | + |
|---|
| 233 | + /* reserve 4 bytes on stack to save a0 */ |
|---|
| 234 | + abi_entry(4) |
|---|
| 235 | + |
|---|
| 236 | + s32i a0, a1, 0 |
|---|
| 237 | + movi a0, .Lsave_cp_regs_jump_table |
|---|
| 238 | + addx8 a3, a3, a0 |
|---|
| 239 | + l32i a4, a3, 4 |
|---|
| 240 | + l32i a3, a3, 0 |
|---|
| 241 | + add a2, a2, a4 |
|---|
| 242 | + beqz a3, 1f |
|---|
| 243 | + callx0 a3 |
|---|
| 244 | +1: l32i a0, a1, 0 |
|---|
| 245 | + |
|---|
| 246 | + abi_ret(4) |
|---|
| 247 | + |
|---|
| 248 | +ENDPROC(coprocessor_flush) |
|---|
| 249 | + |
|---|
| 322 | 250 | .data |
|---|
| 323 | 251 | |
|---|
| 324 | 252 | ENTRY(coprocessor_owner) |
|---|