aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2012-11-14 21:25:48 -0500
committerChris Zankel <chris@zankel.net>2012-12-19 00:10:22 -0500
commit733536b865441d9bad02c4711a4372d48ce21e54 (patch)
treee54c74b6f27dab1175701128e1c0ac2a18cccdc3 /arch/xtensa
parent2f6ea6a767e9e26d23e4de4b03fdebe41f3b88f8 (diff)
xtensa: save and restore scompare1 SR on kernel entry
Although scompare1 may be saved/restored by xchal_ncp_{load,store} macros, explicit save/restore of registers manipulated by the kernel itself is considered more correct. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'arch/xtensa')
-rw-r--r--arch/xtensa/include/asm/ptrace.h2
-rw-r--r--arch/xtensa/kernel/asm-offsets.c1
-rw-r--r--arch/xtensa/kernel/entry.S13
3 files changed, 15 insertions, 1 deletions
diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h
index da21c17f23aa..9fe249c8f90e 100644
--- a/arch/xtensa/include/asm/ptrace.h
+++ b/arch/xtensa/include/asm/ptrace.h
@@ -37,7 +37,7 @@ struct pt_regs {
37 unsigned long windowstart; /* 52 */ 37 unsigned long windowstart; /* 52 */
38 unsigned long syscall; /* 56 */ 38 unsigned long syscall; /* 56 */
39 unsigned long icountlevel; /* 60 */ 39 unsigned long icountlevel; /* 60 */
40 int reserved[1]; /* 64 */ 40 unsigned long scompare1; /* 64 */
41 41
42 /* Additional configurable registers that are used by the compiler. */ 42 /* Additional configurable registers that are used by the compiler. */
43 xtregs_opt_t xtregs_opt; 43 xtregs_opt_t xtregs_opt;
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c
index 7dc3f9157185..845475afc683 100644
--- a/arch/xtensa/kernel/asm-offsets.c
+++ b/arch/xtensa/kernel/asm-offsets.c
@@ -41,6 +41,7 @@ int main(void)
41 DEFINE(PT_SAR, offsetof (struct pt_regs, sar)); 41 DEFINE(PT_SAR, offsetof (struct pt_regs, sar));
42 DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel)); 42 DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel));
43 DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); 43 DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall));
44 DEFINE(PT_SCOMPARE1, offsetof(struct pt_regs, scompare1));
44 DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); 45 DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0]));
45 DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); 46 DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0]));
46 DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1])); 47 DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1]));
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 41ad9cfe9a2a..4c2f2706ad5b 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -372,6 +372,13 @@ common_exception:
372 s32i a2, a1, PT_LBEG 372 s32i a2, a1, PT_LBEG
373 s32i a3, a1, PT_LEND 373 s32i a3, a1, PT_LEND
374 374
375 /* Save SCOMPARE1 */
376
377#if XCHAL_HAVE_S32C1I
378 rsr a2, scompare1
379 s32i a2, a1, PT_SCOMPARE1
380#endif
381
375 /* Save optional registers. */ 382 /* Save optional registers. */
376 383
377 save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT 384 save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
@@ -433,6 +440,12 @@ common_exception_return:
433 440
434 load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT 441 load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
435 442
443 /* Restore SCOMPARE1 */
444
445#if XCHAL_HAVE_S32C1I
446 l32i a2, a1, PT_SCOMPARE1
447 wsr a2, scompare1
448#endif
436 wsr a3, ps /* disable interrupts */ 449 wsr a3, ps /* disable interrupts */
437 450
438 _bbci.l a3, PS_UM_BIT, kernel_exception_exit 451 _bbci.l a3, PS_UM_BIT, kernel_exception_exit