xref: /linux/arch/arc/include/asm/entry.h (revision ad112b3a759cefc245695f7e612f17e6f38d2cc1)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
4  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
5  */
6 
7 #ifndef __ASM_ARC_ENTRY_H
8 #define __ASM_ARC_ENTRY_H
9 
10 #include <asm/unistd.h>		/* For NR_syscalls definition */
11 #include <asm/arcregs.h>
12 #include <asm/ptrace.h>
13 #include <asm/processor.h>	/* For VMALLOC_START */
14 #include <asm/mmu.h>
15 
16 #ifdef __ASSEMBLY__
17 
18 #ifdef CONFIG_ISA_ARCOMPACT
19 #include <asm/entry-compact.h>	/* ISA specific bits */
20 #else
21 #include <asm/entry-arcv2.h>
22 #endif
23 
24 /*
25  * save user mode callee regs as struct callee_regs
26  *  - needed by fork/do_signal/unaligned-access-emulation.
27  */
28 .macro SAVE_CALLEE_SAVED_USER
29 	SAVE_ABI_CALLEE_REGS
30 .endm
31 
32 /*
33  * restore user mode callee regs as struct callee_regs
34  *  - could have been changed by ptrace tracer or unaligned-access fixup
35  */
36 .macro RESTORE_CALLEE_SAVED_USER
37 	RESTORE_ABI_CALLEE_REGS
38 .endm
39 
40 /*
41  * save/restore kernel mode callee regs at the time of context switch
42  */
43 .macro SAVE_CALLEE_SAVED_KERNEL
44 	SAVE_ABI_CALLEE_REGS
45 .endm
46 
47 .macro RESTORE_CALLEE_SAVED_KERNEL
48 	RESTORE_ABI_CALLEE_REGS
49 .endm
50 
51 /*--------------------------------------------------------------
52  * Super FAST Restore callee saved regs by simply re-adjusting SP
53  *-------------------------------------------------------------*/
54 .macro DISCARD_CALLEE_SAVED_USER
55 	add     sp, sp, SZ_CALLEE_REGS
56 .endm
57 
58 /*-------------------------------------------------------------
59  * given a tsk struct, get to the base of its kernel mode stack
60  * tsk->thread_info is really a PAGE, whose bottom hoists stack
61  * which grows upwards towards thread_info
62  *------------------------------------------------------------*/
63 
64 .macro GET_TSK_STACK_BASE tsk, out
65 
66 	/* Get task->thread_info (this is essentially start of a PAGE) */
67 	ld  \out, [\tsk, TASK_THREAD_INFO]
68 
69 	/* Go to end of page where stack begins (grows upwards) */
70 	add2 \out, \out, (THREAD_SIZE)/4
71 
72 .endm
73 
74 /*
75  * @reg [OUT] thread_info->flags of "current"
76  */
77 .macro GET_CURR_THR_INFO_FLAGS  reg
78 	GET_CURR_THR_INFO_FROM_SP  \reg
79 	ld  \reg, [\reg, THREAD_INFO_FLAGS]
80 .endm
81 
82 #ifdef CONFIG_SMP
83 
84 /*
85  * Retrieve the current running task on this CPU
86  *  - loads it from backing _current_task[] (and can't use the
87  *    caching reg for current task
88  */
89 .macro  GET_CURR_TASK_ON_CPU   reg
90 	GET_CPU_ID  \reg
91 	ld.as  \reg, [@_current_task, \reg]
92 .endm
93 
94 /*-------------------------------------------------
95  * Save a new task as the "current" task on this CPU
96  * 1. Determine curr CPU id.
97  * 2. Use it to index into _current_task[ ]
98  *
99  * Coded differently than GET_CURR_TASK_ON_CPU (which uses LD.AS)
100  * because ST r0, [r1, offset] can ONLY have s9 @offset
101  * while   LD can take s9 (4 byte insn) or LIMM (8 byte insn)
102  */
103 
104 .macro  SET_CURR_TASK_ON_CPU    tsk, tmp
105 	GET_CPU_ID  \tmp
106 	add2 \tmp, @_current_task, \tmp
107 	st   \tsk, [\tmp]
108 #ifdef CONFIG_ARC_CURR_IN_REG
109 	mov gp, \tsk
110 #endif
111 
112 .endm
113 
114 
115 #else   /* Uniprocessor implementation of macros */
116 
117 .macro  GET_CURR_TASK_ON_CPU    reg
118 	ld  \reg, [@_current_task]
119 .endm
120 
121 .macro  SET_CURR_TASK_ON_CPU    tsk, tmp
122 	st  \tsk, [@_current_task]
123 #ifdef CONFIG_ARC_CURR_IN_REG
124 	mov gp, \tsk
125 #endif
126 .endm
127 
128 #endif /* SMP / UNI */
129 
130 /*
131  * Get the ptr to some field of Current Task at @off in task struct
132  *  - Uses current task cached in reg if enabled
133  */
134 #ifdef CONFIG_ARC_CURR_IN_REG
135 
136 .macro GET_CURR_TASK_FIELD_PTR  off,  reg
137 	add \reg, gp, \off
138 .endm
139 
140 #else
141 
142 .macro GET_CURR_TASK_FIELD_PTR  off,  reg
143 	GET_CURR_TASK_ON_CPU  \reg
144 	add \reg, \reg, \off
145 .endm
146 
147 #endif	/* CONFIG_ARC_CURR_IN_REG */
148 
149 #else	/* !__ASSEMBLY__ */
150 
151 extern void do_signal(struct pt_regs *);
152 extern void do_notify_resume(struct pt_regs *);
153 extern int do_privilege_fault(unsigned long, struct pt_regs *);
154 extern int do_extension_fault(unsigned long, struct pt_regs *);
155 extern int insterror_is_error(unsigned long, struct pt_regs *);
156 extern int do_memory_error(unsigned long, struct pt_regs *);
157 extern int trap_is_brkpt(unsigned long, struct pt_regs *);
158 extern int do_misaligned_error(unsigned long, struct pt_regs *);
159 extern int do_trap5_error(unsigned long, struct pt_regs *);
160 extern int do_misaligned_access(unsigned long, struct pt_regs *, struct callee_regs *);
161 extern void do_machine_check_fault(unsigned long, struct pt_regs *);
162 extern void do_non_swi_trap(unsigned long, struct pt_regs *);
163 extern void do_insterror_or_kprobe(unsigned long, struct pt_regs *);
164 extern void do_page_fault(unsigned long, struct pt_regs *);
165 
166 #endif
167 
168 #endif  /* __ASM_ARC_ENTRY_H */
169