]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ARC: Increase readability of low level handlers
authorVineet Gupta <vgupta@synopsys.com>
Tue, 28 May 2013 07:54:43 +0000 (13:24 +0530)
committerVineet Gupta <vgupta@synopsys.com>
Mon, 17 Jun 2013 13:02:20 +0000 (18:32 +0530)
* use artificial PUSH/POP contructs for CORE Reg save/restore to stack
* use artificial PUSHAX/POPAX contructs for Auxiliary Space regs
* macro'ize multiple copies of callee-reg-save/restore (SAVE_R13_TO_R24)
* use BIC insn for inverse-and operation

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/include/asm/entry.h
arch/arc/kernel/process.c

index 820202af21a5f3512d5417f3d88b77ce581d5056..5191945f3d39bbe54e70cb36c7c191b45befed76 100644 (file)
  *      Eff Addr for load = [reg2]
  */
 
+.macro PUSH reg
+       st.a    \reg, [sp, -4]
+.endm
+
+.macro PUSHAX aux
+       lr      r9, [\aux]
+       PUSH    r9
+.endm
+
+.macro POP reg
+       ld.ab   \reg, [sp, 4]
+.endm
+
+.macro POPAX aux
+       POP     r9
+       sr      r9, [\aux]
+.endm
+
 /*--------------------------------------------------------------
- * Save caller saved registers (scratch registers) ( r0 - r12 )
- * Registers are pushed / popped in the order defined in struct ptregs
- * in asm/ptrace.h
+ * Helpers to save/restore Scratch Regs:
+ * used by Interrupt/Exception Prologue/Epilogue
  *-------------------------------------------------------------*/
-.macro  SAVE_CALLER_SAVED
-       st.a    r0, [sp, -4]
-       st.a    r1, [sp, -4]
-       st.a    r2, [sp, -4]
-       st.a    r3, [sp, -4]
-       st.a    r4, [sp, -4]
-       st.a    r5, [sp, -4]
-       st.a    r6, [sp, -4]
-       st.a    r7, [sp, -4]
-       st.a    r8, [sp, -4]
-       st.a    r9, [sp, -4]
-       st.a    r10, [sp, -4]
-       st.a    r11, [sp, -4]
-       st.a    r12, [sp, -4]
+.macro  SAVE_R0_TO_R12
+       PUSH    r0
+       PUSH    r1
+       PUSH    r2
+       PUSH    r3
+       PUSH    r4
+       PUSH    r5
+       PUSH    r6
+       PUSH    r7
+       PUSH    r8
+       PUSH    r9
+       PUSH    r10
+       PUSH    r11
+       PUSH    r12
+.endm
+
+.macro RESTORE_R12_TO_R0
+       POP     r12
+       POP     r11
+       POP     r10
+       POP     r9
+       POP     r8
+       POP     r7
+       POP     r6
+       POP     r5
+       POP     r4
+       POP     r3
+       POP     r2
+       POP     r1
+       POP     r0
 .endm
 
 /*--------------------------------------------------------------
- * Restore caller saved registers (scratch registers)
+ * Helpers to save/restore callee-saved regs:
+ * used by several macros below
  *-------------------------------------------------------------*/
-.macro RESTORE_CALLER_SAVED
-       ld.ab   r12, [sp, 4]
-       ld.ab   r11, [sp, 4]
-       ld.ab   r10, [sp, 4]
-       ld.ab   r9, [sp, 4]
-       ld.ab   r8, [sp, 4]
-       ld.ab   r7, [sp, 4]
-       ld.ab   r6, [sp, 4]
-       ld.ab   r5, [sp, 4]
-       ld.ab   r4, [sp, 4]
-       ld.ab   r3, [sp, 4]
-       ld.ab   r2, [sp, 4]
-       ld.ab   r1, [sp, 4]
-       ld.ab   r0, [sp, 4]
+.macro SAVE_R13_TO_R24
+       PUSH    r13
+       PUSH    r14
+       PUSH    r15
+       PUSH    r16
+       PUSH    r17
+       PUSH    r18
+       PUSH    r19
+       PUSH    r20
+       PUSH    r21
+       PUSH    r22
+       PUSH    r23
+       PUSH    r24
+.endm
+
+.macro RESTORE_R24_TO_R13
+       POP     r24
+       POP     r23
+       POP     r22
+       POP     r21
+       POP     r20
+       POP     r19
+       POP     r18
+       POP     r17
+       POP     r16
+       POP     r15
+       POP     r14
+       POP     r13
 .endm
 
 
 /*--------------------------------------------------------------
- * Save callee saved registers (non scratch registers) ( r13 - r25 )
- *  on kernel stack.
- * User mode callee regs need to be saved in case of
- *    -fork and friends for replicating from parent to child
- *    -before going into do_signal( ) for ptrace/core-dump
- * Special case handling is required for r25 in case it is used by kernel
- *  for caching task ptr. Low level exception/ISR save user mode r25
- *  into task->thread.user_r25. So it needs to be retrieved from there and
- *  saved into kernel stack with rest of callee reg-file
+ * Collect User Mode callee regs as struct callee_regs - needed by
+ * fork/do_signal/unaligned-access-emulation.
+ * (By default only scratch regs are saved on entry to kernel)
+ *
+ * Special handling for r25 if used for caching Task Pointer.
+ * It would have been saved in task->thread.user_r25 already, but to keep
+ * the interface same it is copied into regular r25 placeholder in
+ * struct callee_regs.
  *-------------------------------------------------------------*/
 .macro SAVE_CALLEE_SAVED_USER
-       st.a    r13, [sp, -4]
-       st.a    r14, [sp, -4]
-       st.a    r15, [sp, -4]
-       st.a    r16, [sp, -4]
-       st.a    r17, [sp, -4]
-       st.a    r18, [sp, -4]
-       st.a    r19, [sp, -4]
-       st.a    r20, [sp, -4]
-       st.a    r21, [sp, -4]
-       st.a    r22, [sp, -4]
-       st.a    r23, [sp, -4]
-       st.a    r24, [sp, -4]
+
+       SAVE_R13_TO_R24
 
 #ifdef CONFIG_ARC_CURR_IN_REG
        ; Retrieve orig r25 and save it on stack
        ld      r12, [r25, TASK_THREAD + THREAD_USER_R25]
        st.a    r12, [sp, -4]
 #else
-       st.a    r25, [sp, -4]
+       PUSH    r25
 #endif
 
 .endm
 
 /*--------------------------------------------------------------
- * Save callee saved registers (non scratch registers) ( r13 - r25 )
- * kernel mode callee regs needed to be saved in case of context switch
- * If r25 is used for caching task pointer then that need not be saved
- * as it can be re-created from current task global
+ * Save kernel Mode callee regs at the time of Contect Switch.
+ *
+ * Special handling for r25 if used for caching Task Pointer.
+ * Kernel simply skips saving it since it will be loaded with
+ * incoming task pointer anyways
  *-------------------------------------------------------------*/
 .macro SAVE_CALLEE_SAVED_KERNEL
-       st.a    r13, [sp, -4]
-       st.a    r14, [sp, -4]
-       st.a    r15, [sp, -4]
-       st.a    r16, [sp, -4]
-       st.a    r17, [sp, -4]
-       st.a    r18, [sp, -4]
-       st.a    r19, [sp, -4]
-       st.a    r20, [sp, -4]
-       st.a    r21, [sp, -4]
-       st.a    r22, [sp, -4]
-       st.a    r23, [sp, -4]
-       st.a    r24, [sp, -4]
+
+       SAVE_R13_TO_R24
+
 #ifdef CONFIG_ARC_CURR_IN_REG
        sub     sp, sp, 4
 #else
-       st.a    r25, [sp, -4]
+       PUSH    r25
 #endif
 .endm
 
 /*--------------------------------------------------------------
- * RESTORE_CALLEE_SAVED_KERNEL:
- * Loads callee (non scratch) Reg File by popping from Kernel mode stack.
- *  This is reverse of SAVE_CALLEE_SAVED,
- *
- * NOTE:
- * Ideally this shd only be called in switch_to for loading
- *  switched-IN task's CALLEE Reg File.
- *  For all other cases RESTORE_CALLEE_SAVED_FAST must be used
- *  which simply pops the stack w/o touching regs.
+ * Opposite of SAVE_CALLEE_SAVED_KERNEL
  *-------------------------------------------------------------*/
 .macro RESTORE_CALLEE_SAVED_KERNEL
 
 #ifdef CONFIG_ARC_CURR_IN_REG
        add     sp, sp, 4  /* skip usual r25 placeholder */
 #else
-       ld.ab   r25, [sp, 4]
+       POP     r25
 #endif
-       ld.ab   r24, [sp, 4]
-       ld.ab   r23, [sp, 4]
-       ld.ab   r22, [sp, 4]
-       ld.ab   r21, [sp, 4]
-       ld.ab   r20, [sp, 4]
-       ld.ab   r19, [sp, 4]
-       ld.ab   r18, [sp, 4]
-       ld.ab   r17, [sp, 4]
-       ld.ab   r16, [sp, 4]
-       ld.ab   r15, [sp, 4]
-       ld.ab   r14, [sp, 4]
-       ld.ab   r13, [sp, 4]
-
+       RESTORE_R24_TO_R13
 .endm
 
 /*--------------------------------------------------------------
- * RESTORE_CALLEE_SAVED_USER:
- * This is called after do_signal where tracer might have changed callee regs
- * thus we need to restore the reg file.
- * Special case handling is required for r25 in case it is used by kernel
- *  for caching task ptr. Ptrace would have modified on-kernel-stack value of
- *  r25, which needs to be shoved back into task->thread.user_r25 where from
- *  Low level exception/ISR return code will retrieve to populate with rest of
- *  callee reg-file.
+ * Opposite of SAVE_CALLEE_SAVED_USER
+ *
+ * ptrace tracer or unaligned-access fixup might have changed a user mode
+ * callee reg which is saved back to usual r25 storage location
  *-------------------------------------------------------------*/
 .macro RESTORE_CALLEE_SAVED_USER
 
        ld.ab   r12, [sp, 4]
        st      r12, [r25, TASK_THREAD + THREAD_USER_R25]
 #else
-       ld.ab   r25, [sp, 4]
+       POP     r25
 #endif
-
-       ld.ab   r24, [sp, 4]
-       ld.ab   r23, [sp, 4]
-       ld.ab   r22, [sp, 4]
-       ld.ab   r21, [sp, 4]
-       ld.ab   r20, [sp, 4]
-       ld.ab   r19, [sp, 4]
-       ld.ab   r18, [sp, 4]
-       ld.ab   r17, [sp, 4]
-       ld.ab   r16, [sp, 4]
-       ld.ab   r15, [sp, 4]
-       ld.ab   r14, [sp, 4]
-       ld.ab   r13, [sp, 4]
+       RESTORE_R24_TO_R13
 .endm
 
 /*--------------------------------------------------------------
  * @reg [OUT] &thread_info of "current"
  */
 .macro GET_CURR_THR_INFO_FROM_SP  reg
-       and \reg, sp, ~(THREAD_SIZE - 1)
+       bic \reg, sp, (THREAD_SIZE - 1)
 .endm
 
 /*
        /* Restore r9 used to code the early prologue */
        EXCPN_PROLOG_RESTORE_REG  r9
 
-       SAVE_CALLER_SAVED
-       st.a    r26, [sp, -4]   /* gp */
-       st.a    fp, [sp, -4]
-       st.a    blink, [sp, -4]
-       lr      r9, [eret]
-       st.a    r9, [sp, -4]
-       lr      r9, [erstatus]
-       st.a    r9, [sp, -4]
-       st.a    lp_count, [sp, -4]
-       lr      r9, [lp_end]
-       st.a    r9, [sp, -4]
-       lr      r9, [lp_start]
-       st.a    r9, [sp, -4]
-       lr      r9, [erbta]
-       st.a    r9, [sp, -4]
+       SAVE_R0_TO_R12
+       PUSH    gp
+       PUSH    fp
+       PUSH    blink
+       PUSHAX  eret
+       PUSHAX  erstatus
+       PUSH    lp_count
+       PUSHAX  lp_end
+       PUSHAX  lp_start
+       PUSHAX  erbta
 .endm
 
 /*--------------------------------------------------------------
  * by hardware and that is not good.
  *-------------------------------------------------------------*/
 .macro RESTORE_ALL_SYS
-       ld.ab   r9, [sp, 4]
-       sr      r9, [erbta]
-       ld.ab   r9, [sp, 4]
-       sr      r9, [lp_start]
-       ld.ab   r9, [sp, 4]
-       sr      r9, [lp_end]
-       ld.ab   r9, [sp, 4]
-       mov     lp_count, r9
-       ld.ab   r9, [sp, 4]
-       sr      r9, [erstatus]
-       ld.ab   r9, [sp, 4]
-       sr      r9, [eret]
-       ld.ab   blink, [sp, 4]
-       ld.ab   fp, [sp, 4]
-       ld.ab   r26, [sp, 4]    /* gp */
-       RESTORE_CALLER_SAVED
+       POPAX   erbta
+       POPAX   lp_start
+       POPAX   lp_end
+
+       POP     r9
+       mov     lp_count, r9    ;LD to lp_count is not allowed
+
+       POPAX   erstatus
+       POPAX   eret
+       POP     blink
+       POP     fp
+       POP     gp
+       RESTORE_R12_TO_R0
 
        ld  sp, [sp] /* restore original sp */
        /* orig_r0 and orig_r8 skipped automatically */
  *-------------------------------------------------------------*/
 .macro SAVE_ALL_INT1
 
-       /* restore original r9 , saved in int1_saved_reg
-       * It will be saved on stack in macro: SAVE_CALLER_SAVED
-       */
+       /* restore original r9 to be saved as part of reg-file */
 #ifdef CONFIG_SMP
        lr  r9, [ARC_REG_SCRATCH_DATA0]
 #else
        /* now we are ready to save the remaining context :) */
        st      orig_r8_IS_IRQ1, [sp, 8]    /* Event Type */
        st      0, [sp, 4]    /* orig_r0 , N/A for IRQ */
-       SAVE_CALLER_SAVED
-       st.a    r26, [sp, -4]   /* gp */
-       st.a    fp, [sp, -4]
-       st.a    blink, [sp, -4]
-       st.a    ilink1, [sp, -4]
-       lr      r9, [status32_l1]
-       st.a    r9, [sp, -4]
-       st.a    lp_count, [sp, -4]
-       lr      r9, [lp_end]
-       st.a    r9, [sp, -4]
-       lr      r9, [lp_start]
-       st.a    r9, [sp, -4]
-       lr      r9, [bta_l1]
-       st.a    r9, [sp, -4]
+
+       SAVE_R0_TO_R12
+       PUSH    gp
+       PUSH    fp
+       PUSH    blink
+       PUSH    ilink1
+       PUSHAX  status32_l1
+       PUSH    lp_count
+       PUSHAX  lp_end
+       PUSHAX  lp_start
+       PUSHAX  bta_l1
 .endm
 
 .macro SAVE_ALL_INT2
        /* now we are ready to save the remaining context :) */
        st      orig_r8_IS_IRQ2, [sp, 8]    /* Event Type */
        st      0, [sp, 4]    /* orig_r0 , N/A for IRQ */
-       SAVE_CALLER_SAVED
-       st.a    r26, [sp, -4]   /* gp */
-       st.a    fp, [sp, -4]
-       st.a    blink, [sp, -4]
-       st.a    ilink2, [sp, -4]
-       lr      r9, [status32_l2]
-       st.a    r9, [sp, -4]
-       st.a    lp_count, [sp, -4]
-       lr      r9, [lp_end]
-       st.a    r9, [sp, -4]
-       lr      r9, [lp_start]
-       st.a    r9, [sp, -4]
-       lr      r9, [bta_l2]
-       st.a    r9, [sp, -4]
+
+       SAVE_R0_TO_R12
+       PUSH    gp
+       PUSH    fp
+       PUSH    blink
+       PUSH    ilink2
+       PUSHAX  status32_l2
+       PUSH    lp_count
+       PUSHAX  lp_end
+       PUSHAX  lp_start
+       PUSHAX  bta_l2
 .endm
 
 /*--------------------------------------------------------------
  *-------------------------------------------------------------*/
 
 .macro RESTORE_ALL_INT1
-       ld.ab   r9, [sp, 4] /* Actual reg file */
-       sr      r9, [bta_l1]
-       ld.ab   r9, [sp, 4]
-       sr      r9, [lp_start]
-       ld.ab   r9, [sp, 4]
-       sr      r9, [lp_end]
-       ld.ab   r9, [sp, 4]
-       mov     lp_count, r9
-       ld.ab   r9, [sp, 4]
-       sr      r9, [status32_l1]
-       ld.ab   r9, [sp, 4]
-       mov     ilink1, r9
-       ld.ab   blink, [sp, 4]
-       ld.ab   fp, [sp, 4]
-       ld.ab   r26, [sp, 4]    /* gp */
-       RESTORE_CALLER_SAVED
+       POPAX   bta_l1
+       POPAX   lp_start
+       POPAX   lp_end
+
+       POP     r9
+       mov     lp_count, r9    ;LD to lp_count is not allowed
+
+       POPAX   status32_l1
+       POP     ilink1
+       POP     blink
+       POP     fp
+       POP     gp
+       RESTORE_R12_TO_R0
 
        ld  sp, [sp] /* restore original sp */
        /* orig_r0 and orig_r8 skipped automatically */
 .endm
 
 .macro RESTORE_ALL_INT2
-       ld.ab   r9, [sp, 4]
-       sr      r9, [bta_l2]
-       ld.ab   r9, [sp, 4]
-       sr      r9, [lp_start]
-       ld.ab   r9, [sp, 4]
-       sr      r9, [lp_end]
-       ld.ab   r9, [sp, 4]
-       mov     lp_count, r9
-       ld.ab   r9, [sp, 4]
-       sr      r9, [status32_l2]
-       ld.ab   r9, [sp, 4]
-       mov     ilink2, r9
-       ld.ab   blink, [sp, 4]
-       ld.ab   fp, [sp, 4]
-       ld.ab   r26, [sp, 4]    /* gp */
-       RESTORE_CALLER_SAVED
+       POPAX   bta_l2
+       POPAX   lp_start
+       POPAX   lp_end
+
+       POP     r9
+       mov     lp_count, r9    ;LD to lp_count is not allowed
+
+       POPAX   status32_l2
+       POP     ilink2
+       POP     blink
+       POP     fp
+       POP     gp
+       RESTORE_R12_TO_R0
 
        ld  sp, [sp] /* restore original sp */
        /* orig_r0 and orig_r8 skipped automatically */
-
 .endm
 
 
index db868db82944d5e6bf74fc59d4453836866b38c7..c6e22e060578e3f5c21d6a04d4b488dc54a06a33 100644 (file)
@@ -73,6 +73,10 @@ asmlinkage void ret_from_fork(void);
  * ~                ~
  * |    --to--      |   (scratch Regs of user mode)
  * |     r0         |
+ * ------------------
+ * |      SP        |
+ * |    orig_r0     |
+ * |    orig_r8     |
  * ------------------  <===== END of PAGE
  */
 int copy_thread(unsigned long clone_flags,