Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
0004  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
0005  */
0006 
0007 #ifndef __ASM_ARC_ENTRY_H
0008 #define __ASM_ARC_ENTRY_H
0009 
0010 #include <asm/unistd.h>     /* For NR_syscalls defination */
0011 #include <asm/arcregs.h>
0012 #include <asm/ptrace.h>
0013 #include <asm/processor.h>  /* For VMALLOC_START */
0014 #include <asm/mmu.h>
0015 
0016 #ifdef CONFIG_ISA_ARCOMPACT
0017 #include <asm/entry-compact.h>  /* ISA specific bits */
0018 #else
0019 #include <asm/entry-arcv2.h>
0020 #endif
0021 
0022 /* Note on the LD/ST addr modes with addr reg wback
0023  *
0024  * LD.a same as LD.aw
0025  *
0026  * LD.a    reg1, [reg2, x]  => Pre Incr
0027  *      Eff Addr for load = [reg2 + x]
0028  *
0029  * LD.ab   reg1, [reg2, x]  => Post Incr
0030  *      Eff Addr for load = [reg2]
0031  */
0032 
0033 .macro PUSH reg
0034     st.a    \reg, [sp, -4]
0035 .endm
0036 
0037 .macro PUSHAX aux
0038     lr  r9, [\aux]
0039     PUSH    r9
0040 .endm
0041 
0042 .macro POP reg
0043     ld.ab   \reg, [sp, 4]
0044 .endm
0045 
0046 .macro POPAX aux
0047     POP r9
0048     sr  r9, [\aux]
0049 .endm
0050 
0051 /*--------------------------------------------------------------
0052  * Helpers to save/restore Scratch Regs:
0053  * used by Interrupt/Exception Prologue/Epilogue
0054  *-------------------------------------------------------------*/
0055 .macro  SAVE_R0_TO_R12
0056     PUSH    r0
0057     PUSH    r1
0058     PUSH    r2
0059     PUSH    r3
0060     PUSH    r4
0061     PUSH    r5
0062     PUSH    r6
0063     PUSH    r7
0064     PUSH    r8
0065     PUSH    r9
0066     PUSH    r10
0067     PUSH    r11
0068     PUSH    r12
0069 .endm
0070 
0071 .macro RESTORE_R12_TO_R0
0072     POP r12
0073     POP r11
0074     POP r10
0075     POP r9
0076     POP r8
0077     POP r7
0078     POP r6
0079     POP r5
0080     POP r4
0081     POP r3
0082     POP r2
0083     POP r1
0084     POP r0
0085 
0086 .endm
0087 
0088 /*--------------------------------------------------------------
0089  * Helpers to save/restore callee-saved regs:
0090  * used by several macros below
0091  *-------------------------------------------------------------*/
0092 .macro SAVE_R13_TO_R24
0093     PUSH    r13
0094     PUSH    r14
0095     PUSH    r15
0096     PUSH    r16
0097     PUSH    r17
0098     PUSH    r18
0099     PUSH    r19
0100     PUSH    r20
0101     PUSH    r21
0102     PUSH    r22
0103     PUSH    r23
0104     PUSH    r24
0105 .endm
0106 
0107 .macro RESTORE_R24_TO_R13
0108     POP r24
0109     POP r23
0110     POP r22
0111     POP r21
0112     POP r20
0113     POP r19
0114     POP r18
0115     POP r17
0116     POP r16
0117     POP r15
0118     POP r14
0119     POP r13
0120 .endm
0121 
0122 /*--------------------------------------------------------------
0123  * Collect User Mode callee regs as struct callee_regs - needed by
0124  * fork/do_signal/unaligned-access-emulation.
0125  * (By default only scratch regs are saved on entry to kernel)
0126  *
0127  * Special handling for r25 if used for caching Task Pointer.
0128  * It would have been saved in task->thread.user_r25 already, but to keep
0129  * the interface same it is copied into regular r25 placeholder in
0130  * struct callee_regs.
0131  *-------------------------------------------------------------*/
0132 .macro SAVE_CALLEE_SAVED_USER
0133 
0134     mov r12, sp     ; save SP as ref to pt_regs
0135     SAVE_R13_TO_R24
0136 
0137 #ifdef CONFIG_ARC_CURR_IN_REG
0138     ; Retrieve orig r25 and save it with rest of callee_regs
0139     ld  r12, [r12, PT_user_r25]
0140     PUSH    r12
0141 #else
0142     PUSH    r25
0143 #endif
0144 
0145 .endm
0146 
0147 /*--------------------------------------------------------------
0148  * Save kernel Mode callee regs at the time of Contect Switch.
0149  *
0150  * Special handling for r25 if used for caching Task Pointer.
0151  * Kernel simply skips saving it since it will be loaded with
0152  * incoming task pointer anyways
0153  *-------------------------------------------------------------*/
0154 .macro SAVE_CALLEE_SAVED_KERNEL
0155 
0156     SAVE_R13_TO_R24
0157 
0158 #ifdef CONFIG_ARC_CURR_IN_REG
0159     sub     sp, sp, 4
0160 #else
0161     PUSH    r25
0162 #endif
0163 .endm
0164 
0165 /*--------------------------------------------------------------
0166  * Opposite of SAVE_CALLEE_SAVED_KERNEL
0167  *-------------------------------------------------------------*/
0168 .macro RESTORE_CALLEE_SAVED_KERNEL
0169 
0170 #ifdef CONFIG_ARC_CURR_IN_REG
0171     add     sp, sp, 4  /* skip usual r25 placeholder */
0172 #else
0173     POP r25
0174 #endif
0175     RESTORE_R24_TO_R13
0176 .endm
0177 
0178 /*--------------------------------------------------------------
0179  * Opposite of SAVE_CALLEE_SAVED_USER
0180  *
0181  * ptrace tracer or unaligned-access fixup might have changed a user mode
0182  * callee reg which is saved back to usual r25 storage location
0183  *-------------------------------------------------------------*/
0184 .macro RESTORE_CALLEE_SAVED_USER
0185 
0186 #ifdef CONFIG_ARC_CURR_IN_REG
0187     POP r12
0188 #else
0189     POP r25
0190 #endif
0191     RESTORE_R24_TO_R13
0192 
0193     ; SP is back to start of pt_regs
0194 #ifdef CONFIG_ARC_CURR_IN_REG
0195     st  r12, [sp, PT_user_r25]
0196 #endif
0197 .endm
0198 
0199 /*--------------------------------------------------------------
0200  * Super FAST Restore callee saved regs by simply re-adjusting SP
0201  *-------------------------------------------------------------*/
0202 .macro DISCARD_CALLEE_SAVED_USER
0203     add     sp, sp, SZ_CALLEE_REGS
0204 .endm
0205 
0206 /*-------------------------------------------------------------
0207  * given a tsk struct, get to the base of it's kernel mode stack
0208  * tsk->thread_info is really a PAGE, whose bottom hoists stack
0209  * which grows upwards towards thread_info
0210  *------------------------------------------------------------*/
0211 
0212 .macro GET_TSK_STACK_BASE tsk, out
0213 
0214     /* Get task->thread_info (this is essentially start of a PAGE) */
0215     ld  \out, [\tsk, TASK_THREAD_INFO]
0216 
0217     /* Go to end of page where stack begins (grows upwards) */
0218     add2 \out, \out, (THREAD_SIZE)/4
0219 
0220 .endm
0221 
0222 /*
0223  * @reg [OUT] thread_info->flags of "current"
0224  */
0225 .macro GET_CURR_THR_INFO_FLAGS  reg
0226     GET_CURR_THR_INFO_FROM_SP  \reg
0227     ld  \reg, [\reg, THREAD_INFO_FLAGS]
0228 .endm
0229 
0230 #ifdef CONFIG_SMP
0231 
0232 /*-------------------------------------------------
0233  * Retrieve the current running task on this CPU
0234  * 1. Determine curr CPU id.
0235  * 2. Use it to index into _current_task[ ]
0236  */
0237 .macro  GET_CURR_TASK_ON_CPU   reg
0238     GET_CPU_ID  \reg
0239     ld.as  \reg, [@_current_task, \reg]
0240 .endm
0241 
0242 /*-------------------------------------------------
0243  * Save a new task as the "current" task on this CPU
0244  * 1. Determine curr CPU id.
0245  * 2. Use it to index into _current_task[ ]
0246  *
0247  * Coded differently than GET_CURR_TASK_ON_CPU (which uses LD.AS)
0248  * because ST r0, [r1, offset] can ONLY have s9 @offset
0249  * while   LD can take s9 (4 byte insn) or LIMM (8 byte insn)
0250  */
0251 
0252 .macro  SET_CURR_TASK_ON_CPU    tsk, tmp
0253     GET_CPU_ID  \tmp
0254     add2 \tmp, @_current_task, \tmp
0255     st   \tsk, [\tmp]
0256 #ifdef CONFIG_ARC_CURR_IN_REG
0257     mov r25, \tsk
0258 #endif
0259 
0260 .endm
0261 
0262 
0263 #else   /* Uniprocessor implementation of macros */
0264 
0265 .macro  GET_CURR_TASK_ON_CPU    reg
0266     ld  \reg, [@_current_task]
0267 .endm
0268 
0269 .macro  SET_CURR_TASK_ON_CPU    tsk, tmp
0270     st  \tsk, [@_current_task]
0271 #ifdef CONFIG_ARC_CURR_IN_REG
0272     mov r25, \tsk
0273 #endif
0274 .endm
0275 
0276 #endif /* SMP / UNI */
0277 
0278 /* ------------------------------------------------------------------
0279  * Get the ptr to some field of Current Task at @off in task struct
0280  *  -Uses r25 for Current task ptr if that is enabled
0281  */
0282 
0283 #ifdef CONFIG_ARC_CURR_IN_REG
0284 
0285 .macro GET_CURR_TASK_FIELD_PTR  off,  reg
0286     add \reg, r25, \off
0287 .endm
0288 
0289 #else
0290 
0291 .macro GET_CURR_TASK_FIELD_PTR  off,  reg
0292     GET_CURR_TASK_ON_CPU  \reg
0293     add \reg, \reg, \off
0294 .endm
0295 
0296 #endif  /* CONFIG_ARC_CURR_IN_REG */
0297 
0298 #endif  /* __ASM_ARC_ENTRY_H */