diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2014-01-22 00:16:37 -0500 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2014-08-14 03:59:27 -0400 |
commit | c3ef1f4d379cbc79daf80ffb8d43c611da090b82 (patch) | |
tree | 69e296cac620848d60c94867597d551e8872dbd5 /arch/xtensa/kernel | |
parent | a450dc69dc57e2bd9de5a970f5015502e6950c73 (diff) |
xtensa: add double exception fixup handler for fast_unaligned
fast_unaligned_fixup restores user registers and runs normal exception
handler in the current stack frame. Unaligned load/store is retried
after that.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'arch/xtensa/kernel')
-rw-r--r-- | arch/xtensa/kernel/align.S | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S index 25a65938dda8..904f32f05c09 100644 --- a/arch/xtensa/kernel/align.S +++ b/arch/xtensa/kernel/align.S | |||
@@ -8,6 +8,7 @@ | |||
8 | * this archive for more details. | 8 | * this archive for more details. |
9 | * | 9 | * |
10 | * Copyright (C) 2001 - 2005 Tensilica, Inc. | 10 | * Copyright (C) 2001 - 2005 Tensilica, Inc. |
11 | * Copyright (C) 2014 Cadence Design Systems Inc. | ||
11 | * | 12 | * |
12 | * Rewritten by Chris Zankel <chris@zankel.net> | 13 | * Rewritten by Chris Zankel <chris@zankel.net> |
13 | * | 14 | * |
@@ -174,6 +175,10 @@ ENTRY(fast_unaligned) | |||
174 | s32i a0, a2, PT_AREG2 | 175 | s32i a0, a2, PT_AREG2 |
175 | s32i a3, a2, PT_AREG3 | 176 | s32i a3, a2, PT_AREG3 |
176 | 177 | ||
178 | rsr a3, excsave1 | ||
179 | movi a4, fast_unaligned_fixup | ||
180 | s32i a4, a3, EXC_TABLE_FIXUP | ||
181 | |||
177 | /* Keep value of SAR in a0 */ | 182 | /* Keep value of SAR in a0 */ |
178 | 183 | ||
179 | rsr a0, sar | 184 | rsr a0, sar |
@@ -430,6 +435,10 @@ ENTRY(fast_unaligned) | |||
430 | .Linvalid_instruction_store: | 435 | .Linvalid_instruction_store: |
431 | .Linvalid_instruction: | 436 | .Linvalid_instruction: |
432 | 437 | ||
438 | movi a4, 0 | ||
439 | rsr a3, excsave1 | ||
440 | s32i a4, a3, EXC_TABLE_FIXUP | ||
441 | |||
433 | /* Restore a4...a8 and SAR, set SP, and jump to default exception. */ | 442 | /* Restore a4...a8 and SAR, set SP, and jump to default exception. */ |
434 | 443 | ||
435 | l32i a8, a2, PT_AREG8 | 444 | l32i a8, a2, PT_AREG8 |
@@ -451,4 +460,38 @@ ENTRY(fast_unaligned) | |||
451 | 460 | ||
452 | ENDPROC(fast_unaligned) | 461 | ENDPROC(fast_unaligned) |
453 | 462 | ||
463 | ENTRY(fast_unaligned_fixup) | ||
464 | |||
465 | l32i a2, a3, EXC_TABLE_DOUBLE_SAVE | ||
466 | wsr a3, excsave1 | ||
467 | |||
468 | l32i a8, a2, PT_AREG8 | ||
469 | l32i a7, a2, PT_AREG7 | ||
470 | l32i a6, a2, PT_AREG6 | ||
471 | l32i a5, a2, PT_AREG5 | ||
472 | l32i a4, a2, PT_AREG4 | ||
473 | l32i a0, a2, PT_AREG2 | ||
474 | xsr a0, depc # restore depc and a0 | ||
475 | wsr a0, sar | ||
476 | |||
477 | rsr a0, exccause | ||
478 | s32i a0, a2, PT_DEPC # mark as a regular exception | ||
479 | |||
480 | rsr a0, ps | ||
481 | bbsi.l a0, PS_UM_BIT, 1f # jump if user mode | ||
482 | |||
483 | rsr a0, exccause | ||
484 | addx4 a0, a0, a3 # find entry in table | ||
485 | l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler | ||
486 | l32i a3, a2, PT_AREG3 | ||
487 | jx a0 | ||
488 | 1: | ||
489 | rsr a0, exccause | ||
490 | addx4 a0, a0, a3 # find entry in table | ||
491 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler | ||
492 | l32i a3, a2, PT_AREG3 | ||
493 | jx a0 | ||
494 | |||
495 | ENDPROC(fast_unaligned_fixup) | ||
496 | |||
454 | #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ | 497 | #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ |