Blame view

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