Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ebedbb2 authored by Vineet Gupta's avatar Vineet Gupta
Browse files

ARC: Increase readability of entry handlers



* 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: default avatarVineet Gupta <vgupta@synopsys.com>
parent 16f9afe6
Loading
Loading
Loading
Loading
+182 −212
Original line number Diff line number Diff line
@@ -50,150 +50,155 @@
 *      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

@@ -201,21 +206,9 @@
	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

/*--------------------------------------------------------------
@@ -357,7 +350,7 @@
 * @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

/*
@@ -409,21 +402,16 @@
	/* 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

/*--------------------------------------------------------------
@@ -463,22 +451,19 @@
 * 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 */
@@ -490,9 +475,7 @@
 *-------------------------------------------------------------*/
.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
@@ -502,20 +485,17 @@
	/* 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
@@ -530,20 +510,17 @@
	/* 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

/*--------------------------------------------------------------
@@ -557,48 +534,41 @@
 *-------------------------------------------------------------*/

.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


+4 −0
Original line number Diff line number Diff line
@@ -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,