diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arc/include/asm/entry-compact.h | 71 |
1 files changed, 35 insertions, 36 deletions
diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h index 8b65eb36655a..1174ddd4cac8 100644 --- a/arch/arc/include/asm/entry-compact.h +++ b/arch/arc/include/asm/entry-compact.h @@ -39,8 +39,8 @@ * Switch to Kernel Mode stack if SP points to User Mode stack * * Entry : r9 contains pre-IRQ/exception/trap status32 - * Exit : SP is set to kernel mode stack pointer - * If CURR_IN_REG, r25 set to "current" task pointer + * Exit : SP set to K mode stack + * SP at the time of entry (K/U) saved @ pt_regs->sp * Clobbers: r9 *-------------------------------------------------------------*/ @@ -80,12 +80,11 @@ #endif - /* Save Pre Intr/Exception KERNEL MODE SP on kernel stack - * safe-keeping not really needed, but it keeps the epilogue code - * (SP restore) simpler/uniform. - */ + /*------Intr/Ecxp happened in kernel mode, SP already setup ------ */ + /* save it nevertheless @ pt_regs->sp for uniformity */ + b.d 66f - mov r9, sp + st sp, [sp, PT_sp - SZ_PT_REGS] 88: /*------Intr/Ecxp happened in user mode, "switch" stack ------ */ @@ -94,30 +93,12 @@ /* With current tsk in r9, get it's kernel mode stack base */ GET_TSK_STACK_BASE r9, r9 -66: -#ifdef CONFIG_ARC_CURR_IN_REG - /* - * Treat r25 as scratch reg, save it on stack first - * Load it with current task pointer - */ - st r25, [r9, -4] - GET_CURR_TASK_ON_CPU r25 -#endif - - /* Save Pre Intr/Exception User SP on kernel stack */ - st.a sp, [r9, -16] ; Make room for orig_r0, ECR, user_r25 - - /* CAUTION: - * SP should be set at the very end when we are done with everything - * In case of 2 levels of interrupt we depend on value of SP to assume - * that everything else is done (loading r25 etc) - */ - - /* set SP to point to kernel mode stack */ - mov sp, r9 - - /* ----- Stack Switched to kernel Mode, Now save REG FILE ----- */ + /* save U mode SP @ pt_regs->sp */ + st sp, [r9, PT_sp - SZ_PT_REGS] + /* final SP switch */ + mov sp, r9 +66: .endm /*------------------------------------------------------------ @@ -181,11 +162,21 @@ /* ARC700 doesn't provide auto-stack switching */ SWITCH_TO_KERNEL_STK - st r0, [sp, 4] /* orig_r0, needed only for sys calls */ +#ifdef CONFIG_ARC_CURR_IN_REG + /* Treat r25 as scratch reg (save on stack) and load with "current" */ + PUSH r25 + GET_CURR_TASK_ON_CPU r25 +#else + sub sp, sp, 4 +#endif + + st.a r0, [sp, -8] /* orig_r0 needed for syscall (skip ECR slot) */ + sub sp, sp, 4 /* skip pt_regs->sp, already saved above */ /* Restore r9 used to code the early prologue */ PROLOG_RESTORE_REG r9, @ex_saved_reg1 + /* now we are ready to save the regfile */ SAVE_R0_TO_R12 PUSH gp PUSH fp @@ -245,12 +236,20 @@ SWITCH_TO_KERNEL_STK - /* restore original r9 */ - PROLOG_RESTORE_REG r9, @int\LVL\()_saved_reg +#ifdef CONFIG_ARC_CURR_IN_REG + /* Treat r25 as scratch reg (save on stack) and load with "current" */ + PUSH r25 + GET_CURR_TASK_ON_CPU r25 +#else + sub sp, sp, 4 +#endif - /* now we are ready to save the remaining context */ - st 0x003\LVL\()abcd, [sp, 8] /* Dummy ECR */ - st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ + PUSH 0x003\LVL\()abcd /* Dummy ECR */ + sub sp, sp, 8 /* skip orig_r0 (not needed) + skip pt_regs->sp, already saved above */ + + /* Restore r9 used to code the early prologue */ + PROLOG_RESTORE_REG r9, @int\LVL\()_saved_reg SAVE_R0_TO_R12 PUSH gp |