Merge tag 'for-linus' of git://github.com/openrisc/linux
[sfrench/cifs-2.6.git] / arch / arc / include / asm / entry.h
1 /*
2  * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
3  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  */
9
10 #ifndef __ASM_ARC_ENTRY_H
11 #define __ASM_ARC_ENTRY_H
12
13 #include <asm/unistd.h>         /* For NR_syscalls defination */
14 #include <asm/arcregs.h>
15 #include <asm/ptrace.h>
16 #include <asm/processor.h>      /* For VMALLOC_START */
17 #include <asm/mmu.h>
18
19 #ifdef CONFIG_ISA_ARCOMPACT
20 #include <asm/entry-compact.h>  /* ISA specific bits */
21 #else
22 #include <asm/entry-arcv2.h>
23 #endif
24
25 /* Note on the LD/ST addr modes with addr reg wback
26  *
27  * LD.a same as LD.aw
28  *
29  * LD.a    reg1, [reg2, x]  => Pre Incr
30  *      Eff Addr for load = [reg2 + x]
31  *
32  * LD.ab   reg1, [reg2, x]  => Post Incr
33  *      Eff Addr for load = [reg2]
34  */
35
36 .macro PUSH reg
37         st.a    \reg, [sp, -4]
38 .endm
39
40 .macro PUSHAX aux
41         lr      r9, [\aux]
42         PUSH    r9
43 .endm
44
45 .macro POP reg
46         ld.ab   \reg, [sp, 4]
47 .endm
48
49 .macro POPAX aux
50         POP     r9
51         sr      r9, [\aux]
52 .endm
53
54 /*--------------------------------------------------------------
55  * Helpers to save/restore Scratch Regs:
56  * used by Interrupt/Exception Prologue/Epilogue
57  *-------------------------------------------------------------*/
58 .macro  SAVE_R0_TO_R12
59         PUSH    r0
60         PUSH    r1
61         PUSH    r2
62         PUSH    r3
63         PUSH    r4
64         PUSH    r5
65         PUSH    r6
66         PUSH    r7
67         PUSH    r8
68         PUSH    r9
69         PUSH    r10
70         PUSH    r11
71         PUSH    r12
72 .endm
73
74 .macro RESTORE_R12_TO_R0
75         POP     r12
76         POP     r11
77         POP     r10
78         POP     r9
79         POP     r8
80         POP     r7
81         POP     r6
82         POP     r5
83         POP     r4
84         POP     r3
85         POP     r2
86         POP     r1
87         POP     r0
88
89 .endm
90
91 /*--------------------------------------------------------------
92  * Helpers to save/restore callee-saved regs:
93  * used by several macros below
94  *-------------------------------------------------------------*/
95 .macro SAVE_R13_TO_R24
96         PUSH    r13
97         PUSH    r14
98         PUSH    r15
99         PUSH    r16
100         PUSH    r17
101         PUSH    r18
102         PUSH    r19
103         PUSH    r20
104         PUSH    r21
105         PUSH    r22
106         PUSH    r23
107         PUSH    r24
108 .endm
109
110 .macro RESTORE_R24_TO_R13
111         POP     r24
112         POP     r23
113         POP     r22
114         POP     r21
115         POP     r20
116         POP     r19
117         POP     r18
118         POP     r17
119         POP     r16
120         POP     r15
121         POP     r14
122         POP     r13
123 .endm
124
125 /*--------------------------------------------------------------
126  * Collect User Mode callee regs as struct callee_regs - needed by
127  * fork/do_signal/unaligned-access-emulation.
128  * (By default only scratch regs are saved on entry to kernel)
129  *
130  * Special handling for r25 if used for caching Task Pointer.
131  * It would have been saved in task->thread.user_r25 already, but to keep
132  * the interface same it is copied into regular r25 placeholder in
133  * struct callee_regs.
134  *-------------------------------------------------------------*/
135 .macro SAVE_CALLEE_SAVED_USER
136
137         mov     r12, sp         ; save SP as ref to pt_regs
138         SAVE_R13_TO_R24
139
140 #ifdef CONFIG_ARC_CURR_IN_REG
141         ; Retrieve orig r25 and save it with rest of callee_regs
142         ld      r12, [r12, PT_user_r25]
143         PUSH    r12
144 #else
145         PUSH    r25
146 #endif
147
148 .endm
149
150 /*--------------------------------------------------------------
151  * Save kernel Mode callee regs at the time of Contect Switch.
152  *
153  * Special handling for r25 if used for caching Task Pointer.
154  * Kernel simply skips saving it since it will be loaded with
155  * incoming task pointer anyways
156  *-------------------------------------------------------------*/
157 .macro SAVE_CALLEE_SAVED_KERNEL
158
159         SAVE_R13_TO_R24
160
161 #ifdef CONFIG_ARC_CURR_IN_REG
162         sub     sp, sp, 4
163 #else
164         PUSH    r25
165 #endif
166 .endm
167
168 /*--------------------------------------------------------------
169  * Opposite of SAVE_CALLEE_SAVED_KERNEL
170  *-------------------------------------------------------------*/
171 .macro RESTORE_CALLEE_SAVED_KERNEL
172
173 #ifdef CONFIG_ARC_CURR_IN_REG
174         add     sp, sp, 4  /* skip usual r25 placeholder */
175 #else
176         POP     r25
177 #endif
178         RESTORE_R24_TO_R13
179 .endm
180
181 /*--------------------------------------------------------------
182  * Opposite of SAVE_CALLEE_SAVED_USER
183  *
184  * ptrace tracer or unaligned-access fixup might have changed a user mode
185  * callee reg which is saved back to usual r25 storage location
186  *-------------------------------------------------------------*/
187 .macro RESTORE_CALLEE_SAVED_USER
188
189 #ifdef CONFIG_ARC_CURR_IN_REG
190         POP     r12
191 #else
192         POP     r25
193 #endif
194         RESTORE_R24_TO_R13
195
196         ; SP is back to start of pt_regs
197 #ifdef CONFIG_ARC_CURR_IN_REG
198         st      r12, [sp, PT_user_r25]
199 #endif
200 .endm
201
202 /*--------------------------------------------------------------
203  * Super FAST Restore callee saved regs by simply re-adjusting SP
204  *-------------------------------------------------------------*/
205 .macro DISCARD_CALLEE_SAVED_USER
206         add     sp, sp, SZ_CALLEE_REGS
207 .endm
208
209 /*-------------------------------------------------------------
210  * given a tsk struct, get to the base of it's kernel mode stack
211  * tsk->thread_info is really a PAGE, whose bottom hoists stack
212  * which grows upwards towards thread_info
213  *------------------------------------------------------------*/
214
215 .macro GET_TSK_STACK_BASE tsk, out
216
217         /* Get task->thread_info (this is essentially start of a PAGE) */
218         ld  \out, [\tsk, TASK_THREAD_INFO]
219
220         /* Go to end of page where stack begins (grows upwards) */
221         add2 \out, \out, (THREAD_SIZE)/4
222
223 .endm
224
225 /*
226  * @reg [OUT] thread_info->flags of "current"
227  */
228 .macro GET_CURR_THR_INFO_FLAGS  reg
229         GET_CURR_THR_INFO_FROM_SP  \reg
230         ld  \reg, [\reg, THREAD_INFO_FLAGS]
231 .endm
232
233 #ifdef CONFIG_SMP
234
235 /*-------------------------------------------------
236  * Retrieve the current running task on this CPU
237  * 1. Determine curr CPU id.
238  * 2. Use it to index into _current_task[ ]
239  */
240 .macro  GET_CURR_TASK_ON_CPU   reg
241         GET_CPU_ID  \reg
242         ld.as  \reg, [@_current_task, \reg]
243 .endm
244
245 /*-------------------------------------------------
246  * Save a new task as the "current" task on this CPU
247  * 1. Determine curr CPU id.
248  * 2. Use it to index into _current_task[ ]
249  *
250  * Coded differently than GET_CURR_TASK_ON_CPU (which uses LD.AS)
251  * because ST r0, [r1, offset] can ONLY have s9 @offset
252  * while   LD can take s9 (4 byte insn) or LIMM (8 byte insn)
253  */
254
255 .macro  SET_CURR_TASK_ON_CPU    tsk, tmp
256         GET_CPU_ID  \tmp
257         add2 \tmp, @_current_task, \tmp
258         st   \tsk, [\tmp]
259 #ifdef CONFIG_ARC_CURR_IN_REG
260         mov r25, \tsk
261 #endif
262
263 .endm
264
265
266 #else   /* Uniprocessor implementation of macros */
267
268 .macro  GET_CURR_TASK_ON_CPU    reg
269         ld  \reg, [@_current_task]
270 .endm
271
272 .macro  SET_CURR_TASK_ON_CPU    tsk, tmp
273         st  \tsk, [@_current_task]
274 #ifdef CONFIG_ARC_CURR_IN_REG
275         mov r25, \tsk
276 #endif
277 .endm
278
279 #endif /* SMP / UNI */
280
281 /* ------------------------------------------------------------------
282  * Get the ptr to some field of Current Task at @off in task struct
283  *  -Uses r25 for Current task ptr if that is enabled
284  */
285
286 #ifdef CONFIG_ARC_CURR_IN_REG
287
288 .macro GET_CURR_TASK_FIELD_PTR  off,  reg
289         add \reg, r25, \off
290 .endm
291
292 #else
293
294 .macro GET_CURR_TASK_FIELD_PTR  off,  reg
295         GET_CURR_TASK_ON_CPU  \reg
296         add \reg, \reg, \off
297 .endm
298
299 #endif  /* CONFIG_ARC_CURR_IN_REG */
300
301 #endif  /* __ASM_ARC_ENTRY_H */