diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-01-18 04:42:18 -0500 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-02-11 09:30:36 -0500 |
commit | 9d42c84f9182da615e7ec0964ce585f23c822349 (patch) | |
tree | ffc926232c9453c7bedb0590ef17ad6a0ed09d55 /arch/arc/include/asm | |
parent | 5210d1e6889c8183ecad269e86e2d9c524015b5f (diff) |
ARC: Low level IRQ/Trap/Exception Handling
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Diffstat (limited to 'arch/arc/include/asm')
-rw-r--r-- | arch/arc/include/asm/entry.h | 495 |
1 files changed, 495 insertions, 0 deletions
diff --git a/arch/arc/include/asm/entry.h b/arch/arc/include/asm/entry.h new file mode 100644 index 000000000000..63705b12d911 --- /dev/null +++ b/arch/arc/include/asm/entry.h | |||
@@ -0,0 +1,495 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * Vineetg: Aug 28th 2008: Bug #94984 | ||
9 | * -Zero Overhead Loop Context shd be cleared when entering IRQ/EXcp/Trap | ||
10 | * Normally CPU does this automatically, however when doing FAKE rtie, | ||
11 | * we also need to explicitly do this. The problem in macros | ||
12 | * FAKE_RET_FROM_EXCPN and FAKE_RET_FROM_EXCPN_LOCK_IRQ was that this bit | ||
13 | * was being "CLEARED" rather then "SET". Actually "SET" clears ZOL context | ||
14 | * | ||
15 | * Vineetg: May 5th 2008 | ||
16 | * - Defined Stack Switching Macro to be reused in all intr/excp hdlrs | ||
17 | * - Shaved off 11 instructions from RESTORE_ALL_INT1 by using the | ||
18 | * address Write back load ld.ab instead of seperate ld/add instn | ||
19 | * | ||
20 | * Amit Bhor, Sameer Dhavale: Codito Technologies 2004 | ||
21 | */ | ||
22 | |||
23 | #ifndef __ASM_ARC_ENTRY_H | ||
24 | #define __ASM_ARC_ENTRY_H | ||
25 | |||
26 | #ifdef __ASSEMBLY__ | ||
27 | #include <asm/unistd.h> /* For NR_syscalls defination */ | ||
28 | #include <asm/asm-offsets.h> | ||
29 | #include <asm/arcregs.h> | ||
30 | #include <asm/ptrace.h> | ||
31 | #include <asm/thread_info.h> /* For THREAD_SIZE */ | ||
32 | |||
33 | /* Note on the LD/ST addr modes with addr reg wback | ||
34 | * | ||
35 | * LD.a same as LD.aw | ||
36 | * | ||
37 | * LD.a reg1, [reg2, x] => Pre Incr | ||
38 | * Eff Addr for load = [reg2 + x] | ||
39 | * | ||
40 | * LD.ab reg1, [reg2, x] => Post Incr | ||
41 | * Eff Addr for load = [reg2] | ||
42 | */ | ||
43 | |||
44 | /*-------------------------------------------------------------- | ||
45 | * Save caller saved registers (scratch registers) ( r0 - r12 ) | ||
46 | * Registers are pushed / popped in the order defined in struct ptregs | ||
47 | * in asm/ptrace.h | ||
48 | *-------------------------------------------------------------*/ | ||
49 | .macro SAVE_CALLER_SAVED | ||
50 | st.a r0, [sp, -4] | ||
51 | st.a r1, [sp, -4] | ||
52 | st.a r2, [sp, -4] | ||
53 | st.a r3, [sp, -4] | ||
54 | st.a r4, [sp, -4] | ||
55 | st.a r5, [sp, -4] | ||
56 | st.a r6, [sp, -4] | ||
57 | st.a r7, [sp, -4] | ||
58 | st.a r8, [sp, -4] | ||
59 | st.a r9, [sp, -4] | ||
60 | st.a r10, [sp, -4] | ||
61 | st.a r11, [sp, -4] | ||
62 | st.a r12, [sp, -4] | ||
63 | .endm | ||
64 | |||
65 | /*-------------------------------------------------------------- | ||
66 | * Restore caller saved registers (scratch registers) | ||
67 | *-------------------------------------------------------------*/ | ||
68 | .macro RESTORE_CALLER_SAVED | ||
69 | ld.ab r12, [sp, 4] | ||
70 | ld.ab r11, [sp, 4] | ||
71 | ld.ab r10, [sp, 4] | ||
72 | ld.ab r9, [sp, 4] | ||
73 | ld.ab r8, [sp, 4] | ||
74 | ld.ab r7, [sp, 4] | ||
75 | ld.ab r6, [sp, 4] | ||
76 | ld.ab r5, [sp, 4] | ||
77 | ld.ab r4, [sp, 4] | ||
78 | ld.ab r3, [sp, 4] | ||
79 | ld.ab r2, [sp, 4] | ||
80 | ld.ab r1, [sp, 4] | ||
81 | ld.ab r0, [sp, 4] | ||
82 | .endm | ||
83 | |||
84 | |||
85 | /*-------------------------------------------------------------- | ||
86 | * Save callee saved registers (non scratch registers) ( r13 - r25 ) | ||
87 | * on kernel stack. | ||
88 | * User mode callee regs need to be saved in case of | ||
89 | * -fork and friends for replicating from parent to child | ||
90 | * -before going into do_signal( ) for ptrace/core-dump | ||
91 | * Special case handling is required for r25 in case it is used by kernel | ||
92 | * for caching task ptr. Low level exception/ISR save user mode r25 | ||
93 | * into task->thread.user_r25. So it needs to be retrieved from there and | ||
94 | * saved into kernel stack with rest of callee reg-file | ||
95 | *-------------------------------------------------------------*/ | ||
96 | .macro SAVE_CALLEE_SAVED_USER | ||
97 | st.a r13, [sp, -4] | ||
98 | st.a r14, [sp, -4] | ||
99 | st.a r15, [sp, -4] | ||
100 | st.a r16, [sp, -4] | ||
101 | st.a r17, [sp, -4] | ||
102 | st.a r18, [sp, -4] | ||
103 | st.a r19, [sp, -4] | ||
104 | st.a r20, [sp, -4] | ||
105 | st.a r21, [sp, -4] | ||
106 | st.a r22, [sp, -4] | ||
107 | st.a r23, [sp, -4] | ||
108 | st.a r24, [sp, -4] | ||
109 | st.a r25, [sp, -4] | ||
110 | |||
111 | /* move up by 1 word to "create" callee_regs->"stack_place_holder" */ | ||
112 | sub sp, sp, 4 | ||
113 | .endm | ||
114 | |||
115 | /*-------------------------------------------------------------- | ||
116 | * Save callee saved registers (non scratch registers) ( r13 - r25 ) | ||
117 | * kernel mode callee regs needed to be saved in case of context switch | ||
118 | * If r25 is used for caching task pointer then that need not be saved | ||
119 | * as it can be re-created from current task global | ||
120 | *-------------------------------------------------------------*/ | ||
121 | .macro SAVE_CALLEE_SAVED_KERNEL | ||
122 | st.a r13, [sp, -4] | ||
123 | st.a r14, [sp, -4] | ||
124 | st.a r15, [sp, -4] | ||
125 | st.a r16, [sp, -4] | ||
126 | st.a r17, [sp, -4] | ||
127 | st.a r18, [sp, -4] | ||
128 | st.a r19, [sp, -4] | ||
129 | st.a r20, [sp, -4] | ||
130 | st.a r21, [sp, -4] | ||
131 | st.a r22, [sp, -4] | ||
132 | st.a r23, [sp, -4] | ||
133 | st.a r24, [sp, -4] | ||
134 | st.a r25, [sp, -4] | ||
135 | sub sp, sp, 4 | ||
136 | .endm | ||
137 | |||
138 | /*-------------------------------------------------------------- | ||
139 | * RESTORE_CALLEE_SAVED_KERNEL: | ||
140 | * Loads callee (non scratch) Reg File by popping from Kernel mode stack. | ||
141 | * This is reverse of SAVE_CALLEE_SAVED, | ||
142 | * | ||
143 | * NOTE: | ||
144 | * Ideally this shd only be called in switch_to for loading | ||
145 | * switched-IN task's CALLEE Reg File. | ||
146 | * For all other cases RESTORE_CALLEE_SAVED_FAST must be used | ||
147 | * which simply pops the stack w/o touching regs. | ||
148 | *-------------------------------------------------------------*/ | ||
149 | .macro RESTORE_CALLEE_SAVED_KERNEL | ||
150 | |||
151 | add sp, sp, 4 /* skip "callee_regs->stack_place_holder" */ | ||
152 | ld.ab r25, [sp, 4] | ||
153 | ld.ab r24, [sp, 4] | ||
154 | ld.ab r23, [sp, 4] | ||
155 | ld.ab r22, [sp, 4] | ||
156 | ld.ab r21, [sp, 4] | ||
157 | ld.ab r20, [sp, 4] | ||
158 | ld.ab r19, [sp, 4] | ||
159 | ld.ab r18, [sp, 4] | ||
160 | ld.ab r17, [sp, 4] | ||
161 | ld.ab r16, [sp, 4] | ||
162 | ld.ab r15, [sp, 4] | ||
163 | ld.ab r14, [sp, 4] | ||
164 | ld.ab r13, [sp, 4] | ||
165 | |||
166 | .endm | ||
167 | |||
168 | /*-------------------------------------------------------------- | ||
169 | * Super FAST Restore callee saved regs by simply re-adjusting SP | ||
170 | *-------------------------------------------------------------*/ | ||
171 | .macro DISCARD_CALLEE_SAVED_USER | ||
172 | add sp, sp, 14 * 4 | ||
173 | .endm | ||
174 | |||
175 | /*-------------------------------------------------------------- | ||
176 | * Restore User mode r25 saved in task_struct->thread.user_r25 | ||
177 | *-------------------------------------------------------------*/ | ||
178 | .macro RESTORE_USER_R25 | ||
179 | ld r25, [r25, TASK_THREAD + THREAD_USER_R25] | ||
180 | .endm | ||
181 | |||
182 | /*------------------------------------------------------------- | ||
183 | * given a tsk struct, get to the base of it's kernel mode stack | ||
184 | * tsk->thread_info is really a PAGE, whose bottom hoists stack | ||
185 | * which grows upwards towards thread_info | ||
186 | *------------------------------------------------------------*/ | ||
187 | |||
188 | .macro GET_TSK_STACK_BASE tsk, out | ||
189 | |||
190 | /* Get task->thread_info (this is essentially start of a PAGE) */ | ||
191 | ld \out, [\tsk, TASK_THREAD_INFO] | ||
192 | |||
193 | /* Go to end of page where stack begins (grows upwards) */ | ||
194 | add2 \out, \out, (THREAD_SIZE - 4)/4 /* one word GUTTER */ | ||
195 | |||
196 | .endm | ||
197 | |||
198 | /*-------------------------------------------------------------- | ||
199 | * Switch to Kernel Mode stack if SP points to User Mode stack | ||
200 | * | ||
201 | * Entry : r9 contains pre-IRQ/exception/trap status32 | ||
202 | * Exit : SP is set to kernel mode stack pointer | ||
203 | * Clobbers: r9 | ||
204 | *-------------------------------------------------------------*/ | ||
205 | |||
206 | .macro SWITCH_TO_KERNEL_STK | ||
207 | |||
208 | /* User Mode when this happened ? Yes: Proceed to switch stack */ | ||
209 | bbit1 r9, STATUS_U_BIT, 88f | ||
210 | |||
211 | /* OK we were already in kernel mode when this event happened, thus can | ||
212 | * assume SP is kernel mode SP. _NO_ need to do any stack switching | ||
213 | */ | ||
214 | |||
215 | /* Save Pre Intr/Exception KERNEL MODE SP on kernel stack | ||
216 | * safe-keeping not really needed, but it keeps the epilogue code | ||
217 | * (SP restore) simpler/uniform. | ||
218 | */ | ||
219 | b.d 77f | ||
220 | |||
221 | st.a sp, [sp, -12] ; Make room for orig_r0 and orig_r8 | ||
222 | |||
223 | 88: /*------Intr/Ecxp happened in user mode, "switch" stack ------ */ | ||
224 | |||
225 | GET_CURR_TASK_ON_CPU r9 | ||
226 | |||
227 | /* With current tsk in r9, get it's kernel mode stack base */ | ||
228 | GET_TSK_STACK_BASE r9, r9 | ||
229 | |||
230 | #ifdef PT_REGS_CANARY | ||
231 | st 0xabcdabcd, [r9, 0] | ||
232 | #endif | ||
233 | |||
234 | /* Save Pre Intr/Exception User SP on kernel stack */ | ||
235 | st.a sp, [r9, -12] ; Make room for orig_r0 and orig_r8 | ||
236 | |||
237 | /* CAUTION: | ||
238 | * SP should be set at the very end when we are done with everything | ||
239 | * In case of 2 levels of interrupt we depend on value of SP to assume | ||
240 | * that everything else is done (loading r25 etc) | ||
241 | */ | ||
242 | |||
243 | /* set SP to point to kernel mode stack */ | ||
244 | mov sp, r9 | ||
245 | |||
246 | 77: /* ----- Stack Switched to kernel Mode, Now save REG FILE ----- */ | ||
247 | |||
248 | .endm | ||
249 | |||
250 | /*------------------------------------------------------------ | ||
251 | * "FAKE" a rtie to return from CPU Exception context | ||
252 | * This is to re-enable Exceptions within exception | ||
253 | * Look at EV_ProtV to see how this is actually used | ||
254 | *-------------------------------------------------------------*/ | ||
255 | |||
256 | .macro FAKE_RET_FROM_EXCPN reg | ||
257 | |||
258 | ld \reg, [sp, PT_status32] | ||
259 | bic \reg, \reg, (STATUS_U_MASK|STATUS_DE_MASK) | ||
260 | bset \reg, \reg, STATUS_L_BIT | ||
261 | sr \reg, [erstatus] | ||
262 | mov \reg, 55f | ||
263 | sr \reg, [eret] | ||
264 | |||
265 | rtie | ||
266 | 55: | ||
267 | .endm | ||
268 | |||
269 | /* | ||
270 | * @reg [OUT] &thread_info of "current" | ||
271 | */ | ||
272 | .macro GET_CURR_THR_INFO_FROM_SP reg | ||
273 | and \reg, sp, ~(THREAD_SIZE - 1) | ||
274 | .endm | ||
275 | |||
276 | /* | ||
277 | * @reg [OUT] thread_info->flags of "current" | ||
278 | */ | ||
279 | .macro GET_CURR_THR_INFO_FLAGS reg | ||
280 | GET_CURR_THR_INFO_FROM_SP \reg | ||
281 | ld \reg, [\reg, THREAD_INFO_FLAGS] | ||
282 | .endm | ||
283 | |||
284 | /*-------------------------------------------------------------- | ||
285 | * For early Exception Prologue, a core reg is temporarily needed to | ||
286 | * code the rest of prolog (stack switching). This is done by stashing | ||
287 | * it to memory (non-SMP case) or SCRATCH0 Aux Reg (SMP). | ||
288 | * | ||
289 | * Before saving the full regfile - this reg is restored back, only | ||
290 | * to be saved again on kernel mode stack, as part of ptregs. | ||
291 | *-------------------------------------------------------------*/ | ||
292 | .macro EXCPN_PROLOG_FREEUP_REG reg | ||
293 | st \reg, [@ex_saved_reg1] | ||
294 | .endm | ||
295 | |||
296 | .macro EXCPN_PROLOG_RESTORE_REG reg | ||
297 | ld \reg, [@ex_saved_reg1] | ||
298 | .endm | ||
299 | |||
300 | /*-------------------------------------------------------------- | ||
301 | * Save all registers used by Exceptions (TLB Miss, Prot-V, Mem err etc) | ||
302 | * Requires SP to be already switched to kernel mode Stack | ||
303 | * sp points to the next free element on the stack at exit of this macro. | ||
304 | * Registers are pushed / popped in the order defined in struct ptregs | ||
305 | * in asm/ptrace.h | ||
306 | * Note that syscalls are implemented via TRAP which is also a exception | ||
307 | * from CPU's point of view | ||
308 | *-------------------------------------------------------------*/ | ||
309 | .macro SAVE_ALL_EXCEPTION marker | ||
310 | |||
311 | /* Restore r9 used to code the early prologue */ | ||
312 | EXCPN_PROLOG_RESTORE_REG r9 | ||
313 | |||
314 | /* Save the complete regfile now */ | ||
315 | |||
316 | /* orig_r8 marker: | ||
317 | * syscalls -> 1 to NR_SYSCALLS | ||
318 | * Exceptions -> NR_SYSCALLS + 1 | ||
319 | * Break-point-> NR_SYSCALLS + 2 | ||
320 | */ | ||
321 | st \marker, [sp, 8] | ||
322 | st r0, [sp, 4] /* orig_r0, needed only for sys calls */ | ||
323 | SAVE_CALLER_SAVED | ||
324 | st.a r26, [sp, -4] /* gp */ | ||
325 | st.a fp, [sp, -4] | ||
326 | st.a blink, [sp, -4] | ||
327 | lr r9, [eret] | ||
328 | st.a r9, [sp, -4] | ||
329 | lr r9, [erstatus] | ||
330 | st.a r9, [sp, -4] | ||
331 | st.a lp_count, [sp, -4] | ||
332 | lr r9, [lp_end] | ||
333 | st.a r9, [sp, -4] | ||
334 | lr r9, [lp_start] | ||
335 | st.a r9, [sp, -4] | ||
336 | lr r9, [erbta] | ||
337 | st.a r9, [sp, -4] | ||
338 | |||
339 | #ifdef PT_REGS_CANARY | ||
340 | mov r9, 0xdeadbeef | ||
341 | st r9, [sp, -4] | ||
342 | #endif | ||
343 | |||
344 | /* move up by 1 word to "create" pt_regs->"stack_place_holder" */ | ||
345 | sub sp, sp, 4 | ||
346 | .endm | ||
347 | |||
348 | /*-------------------------------------------------------------- | ||
349 | * Save scratch regs for exceptions | ||
350 | *-------------------------------------------------------------*/ | ||
351 | .macro SAVE_ALL_SYS | ||
352 | SAVE_ALL_EXCEPTION (NR_syscalls + 1) | ||
353 | .endm | ||
354 | |||
355 | /*-------------------------------------------------------------- | ||
356 | * Save scratch regs for sys calls | ||
357 | *-------------------------------------------------------------*/ | ||
358 | .macro SAVE_ALL_TRAP | ||
359 | SAVE_ALL_EXCEPTION r8 | ||
360 | .endm | ||
361 | |||
362 | /*-------------------------------------------------------------- | ||
363 | * Restore all registers used by system call or Exceptions | ||
364 | * SP should always be pointing to the next free stack element | ||
365 | * when entering this macro. | ||
366 | * | ||
367 | * NOTE: | ||
368 | * | ||
369 | * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg | ||
370 | * for memory load operations. If used in that way interrupts are deffered | ||
371 | * by hardware and that is not good. | ||
372 | *-------------------------------------------------------------*/ | ||
373 | .macro RESTORE_ALL_SYS | ||
374 | |||
375 | add sp, sp, 4 /* hop over unused "pt_regs->stack_place_holder" */ | ||
376 | |||
377 | ld.ab r9, [sp, 4] | ||
378 | sr r9, [erbta] | ||
379 | ld.ab r9, [sp, 4] | ||
380 | sr r9, [lp_start] | ||
381 | ld.ab r9, [sp, 4] | ||
382 | sr r9, [lp_end] | ||
383 | ld.ab r9, [sp, 4] | ||
384 | mov lp_count, r9 | ||
385 | ld.ab r9, [sp, 4] | ||
386 | sr r9, [erstatus] | ||
387 | ld.ab r9, [sp, 4] | ||
388 | sr r9, [eret] | ||
389 | ld.ab blink, [sp, 4] | ||
390 | ld.ab fp, [sp, 4] | ||
391 | ld.ab r26, [sp, 4] /* gp */ | ||
392 | RESTORE_CALLER_SAVED | ||
393 | |||
394 | ld sp, [sp] /* restore original sp */ | ||
395 | /* orig_r0 and orig_r8 skipped automatically */ | ||
396 | .endm | ||
397 | |||
398 | |||
399 | /*-------------------------------------------------------------- | ||
400 | * Save all registers used by interrupt handlers. | ||
401 | *-------------------------------------------------------------*/ | ||
402 | .macro SAVE_ALL_INT1 | ||
403 | |||
404 | /* restore original r9 , saved in int1_saved_reg | ||
405 | * It will be saved on stack in macro: SAVE_CALLER_SAVED | ||
406 | */ | ||
407 | ld r9, [@int1_saved_reg] | ||
408 | |||
409 | /* now we are ready to save the remaining context :) */ | ||
410 | st -1, [sp, 8] /* orig_r8, -1 for interuppt level one */ | ||
411 | st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ | ||
412 | SAVE_CALLER_SAVED | ||
413 | st.a r26, [sp, -4] /* gp */ | ||
414 | st.a fp, [sp, -4] | ||
415 | st.a blink, [sp, -4] | ||
416 | st.a ilink1, [sp, -4] | ||
417 | lr r9, [status32_l1] | ||
418 | st.a r9, [sp, -4] | ||
419 | st.a lp_count, [sp, -4] | ||
420 | lr r9, [lp_end] | ||
421 | st.a r9, [sp, -4] | ||
422 | lr r9, [lp_start] | ||
423 | st.a r9, [sp, -4] | ||
424 | lr r9, [bta_l1] | ||
425 | st.a r9, [sp, -4] | ||
426 | |||
427 | #ifdef PT_REGS_CANARY | ||
428 | mov r9, 0xdeadbee1 | ||
429 | st r9, [sp, -4] | ||
430 | #endif | ||
431 | /* move up by 1 word to "create" pt_regs->"stack_place_holder" */ | ||
432 | sub sp, sp, 4 | ||
433 | .endm | ||
434 | |||
435 | /*-------------------------------------------------------------- | ||
436 | * Restore all registers used by interrupt handlers. | ||
437 | * | ||
438 | * NOTE: | ||
439 | * | ||
440 | * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg | ||
441 | * for memory load operations. If used in that way interrupts are deffered | ||
442 | * by hardware and that is not good. | ||
443 | *-------------------------------------------------------------*/ | ||
444 | |||
445 | .macro RESTORE_ALL_INT1 | ||
446 | add sp, sp, 4 /* hop over unused "pt_regs->stack_place_holder" */ | ||
447 | |||
448 | ld.ab r9, [sp, 4] /* Actual reg file */ | ||
449 | sr r9, [bta_l1] | ||
450 | ld.ab r9, [sp, 4] | ||
451 | sr r9, [lp_start] | ||
452 | ld.ab r9, [sp, 4] | ||
453 | sr r9, [lp_end] | ||
454 | ld.ab r9, [sp, 4] | ||
455 | mov lp_count, r9 | ||
456 | ld.ab r9, [sp, 4] | ||
457 | sr r9, [status32_l1] | ||
458 | ld.ab r9, [sp, 4] | ||
459 | mov ilink1, r9 | ||
460 | ld.ab blink, [sp, 4] | ||
461 | ld.ab fp, [sp, 4] | ||
462 | ld.ab r26, [sp, 4] /* gp */ | ||
463 | RESTORE_CALLER_SAVED | ||
464 | |||
465 | ld sp, [sp] /* restore original sp */ | ||
466 | /* orig_r0 and orig_r8 skipped automatically */ | ||
467 | .endm | ||
468 | |||
469 | /* Get CPU-ID of this core */ | ||
470 | .macro GET_CPU_ID reg | ||
471 | lr \reg, [identity] | ||
472 | lsr \reg, \reg, 8 | ||
473 | bmsk \reg, \reg, 7 | ||
474 | .endm | ||
475 | |||
476 | .macro GET_CURR_TASK_ON_CPU reg | ||
477 | ld \reg, [@_current_task] | ||
478 | .endm | ||
479 | |||
480 | .macro SET_CURR_TASK_ON_CPU tsk, tmp | ||
481 | st \tsk, [@_current_task] | ||
482 | .endm | ||
483 | |||
484 | /* ------------------------------------------------------------------ | ||
485 | * Get the ptr to some field of Current Task at @off in task struct | ||
486 | */ | ||
487 | |||
488 | .macro GET_CURR_TASK_FIELD_PTR off, reg | ||
489 | GET_CURR_TASK_ON_CPU \reg | ||
490 | add \reg, \reg, \off | ||
491 | .endm | ||
492 | |||
493 | #endif /* __ASSEMBLY__ */ | ||
494 | |||
495 | #endif /* __ASM_ARC_ENTRY_H */ | ||