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 | |
| 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>
| -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 */ |
