1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __M68K_ENTRY_H
3 #define __M68K_ENTRY_H
4 
5 #include <asm/setup.h>
6 #include <asm/page.h>
7 #ifdef __ASSEMBLY__
8 #include <asm/thread_info.h>
9 #endif
10 
11 /*
12  * Stack layout in 'ret_from_exception':
13  *
14  *	This allows access to the syscall arguments in registers d1-d5
15  *
16  *	 0(sp) - d1
17  *	 4(sp) - d2
18  *	 8(sp) - d3
19  *	 C(sp) - d4
20  *	10(sp) - d5
21  *	14(sp) - a0
22  *	18(sp) - a1
23  *	1C(sp) - a2
24  *	20(sp) - d0
25  *	24(sp) - orig_d0
26  *	28(sp) - stack adjustment
27  *	2C(sp) - [ sr              ] [ format & vector ]
28  *	2E(sp) - [ pc-hiword       ] [ sr              ]
29  *	30(sp) - [ pc-loword       ] [ pc-hiword       ]
30  *	32(sp) - [ format & vector ] [ pc-loword       ]
31  *		  ^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^
32  *			M68K		  COLDFIRE
33  */
34 
35 /* the following macro is used when enabling interrupts */
36 #if defined(MACH_ATARI_ONLY)
37 	/* block out HSYNC = ipl 2 on the atari */
38 #define ALLOWINT	(~0x500)
39 #else
40 	/* portable version */
41 #define ALLOWINT	(~0x700)
42 #endif /* machine compilation types */
43 
44 #ifdef __ASSEMBLY__
45 /*
46  * This defines the normal kernel pt-regs layout.
47  *
48  * regs a3-a6 and d6-d7 are preserved by C code
49  * the kernel doesn't mess with usp unless it needs to
50  */
51 #define SWITCH_STACK_SIZE	(6*4+4)	/* includes return address */
52 
53 #ifdef CONFIG_COLDFIRE
54 #ifdef CONFIG_COLDFIRE_SW_A7
55 /*
56  * This is made a little more tricky on older ColdFires. There is no
57  * separate supervisor and user stack pointers. Need to artificially
58  * construct a usp in software... When doing this we need to disable
59  * interrupts, otherwise bad things will happen.
60  */
61 .globl sw_usp
62 .globl sw_ksp
63 
64 .macro SAVE_ALL_SYS
65 	move	#0x2700,%sr		/* disable intrs */
66 	btst	#5,%sp@(2)		/* from user? */
67 	bnes	6f			/* no, skip */
68 	movel	%sp,sw_usp		/* save user sp */
69 	addql	#8,sw_usp		/* remove exception */
70 	movel	sw_ksp,%sp		/* kernel sp */
71 	subql	#8,%sp			/* room for exception */
72 	clrl	%sp@-			/* stkadj */
73 	movel	%d0,%sp@-		/* orig d0 */
74 	movel	%d0,%sp@-		/* d0 */
75 	lea	%sp@(-32),%sp		/* space for 8 regs */
76 	moveml	%d1-%d5/%a0-%a2,%sp@
77 	movel	sw_usp,%a0		/* get usp */
78 	movel	%a0@-,%sp@(PT_OFF_PC)	/* copy exception program counter */
79 	movel	%a0@-,%sp@(PT_OFF_FORMATVEC)/*copy exception format/vector/sr */
80 	bra	7f
81 	6:
82 	clrl	%sp@-			/* stkadj */
83 	movel	%d0,%sp@-		/* orig d0 */
84 	movel	%d0,%sp@-		/* d0 */
85 	lea	%sp@(-32),%sp		/* space for 8 regs */
86 	moveml	%d1-%d5/%a0-%a2,%sp@
87 	7:
88 .endm
89 
90 .macro SAVE_ALL_INT
91 	SAVE_ALL_SYS
92 	moveq	#-1,%d0			/* not system call entry */
93 	movel	%d0,%sp@(PT_OFF_ORIG_D0)
94 .endm
95 
96 .macro RESTORE_USER
97 	move	#0x2700,%sr		/* disable intrs */
98 	movel	sw_usp,%a0		/* get usp */
99 	movel	%sp@(PT_OFF_PC),%a0@-	/* copy exception program counter */
100 	movel	%sp@(PT_OFF_FORMATVEC),%a0@-/*copy exception format/vector/sr */
101 	moveml	%sp@,%d1-%d5/%a0-%a2
102 	lea	%sp@(32),%sp		/* space for 8 regs */
103 	movel	%sp@+,%d0
104 	addql	#4,%sp			/* orig d0 */
105 	addl	%sp@+,%sp		/* stkadj */
106 	addql	#8,%sp			/* remove exception */
107 	movel	%sp,sw_ksp		/* save ksp */
108 	subql	#8,sw_usp		/* set exception */
109 	movel	sw_usp,%sp		/* restore usp */
110 	rte
111 .endm
112 
113 .macro RDUSP
114 	movel	sw_usp,%a3
115 .endm
116 
117 .macro WRUSP
118 	movel	%a3,sw_usp
119 .endm
120 
121 #else /* !CONFIG_COLDFIRE_SW_A7 */
122 /*
123  * Modern ColdFire parts have separate supervisor and user stack
124  * pointers. Simple load and restore macros for this case.
125  */
126 .macro SAVE_ALL_SYS
127 	move	#0x2700,%sr		/* disable intrs */
128 	clrl	%sp@-			/* stkadj */
129 	movel	%d0,%sp@-		/* orig d0 */
130 	movel	%d0,%sp@-		/* d0 */
131 	lea	%sp@(-32),%sp		/* space for 8 regs */
132 	moveml	%d1-%d5/%a0-%a2,%sp@
133 .endm
134 
135 .macro SAVE_ALL_INT
136 	move	#0x2700,%sr		/* disable intrs */
137 	clrl	%sp@-			/* stkadj */
138 	pea	-1:w			/* orig d0 */
139 	movel	%d0,%sp@-		/* d0 */
140 	lea	%sp@(-32),%sp		/* space for 8 regs */
141 	moveml	%d1-%d5/%a0-%a2,%sp@
142 .endm
143 
144 .macro RESTORE_USER
145 	moveml	%sp@,%d1-%d5/%a0-%a2
146 	lea	%sp@(32),%sp		/* space for 8 regs */
147 	movel	%sp@+,%d0
148 	addql	#4,%sp			/* orig d0 */
149 	addl	%sp@+,%sp		/* stkadj */
150 	rte
151 .endm
152 
153 .macro RDUSP
154 	/*move	%usp,%a3*/
155 	.word	0x4e6b
156 .endm
157 
158 .macro WRUSP
159 	/*move	%a3,%usp*/
160 	.word	0x4e63
161 .endm
162 
163 #endif /* !CONFIG_COLDFIRE_SW_A7 */
164 
165 .macro SAVE_SWITCH_STACK
166 	lea	%sp@(-24),%sp		/* 6 regs */
167 	moveml	%a3-%a6/%d6-%d7,%sp@
168 .endm
169 
170 .macro RESTORE_SWITCH_STACK
171 	moveml	%sp@,%a3-%a6/%d6-%d7
172 	lea	%sp@(24),%sp		/* 6 regs */
173 .endm
174 
175 #else /* !CONFIG_COLDFIRE */
176 
177 /*
178  * All other types of m68k parts (68000, 680x0, CPU32) have the same
179  * entry and exit code.
180  */
181 
182 /*
183  * a -1 in the orig_d0 field signifies
184  * that the stack frame is NOT for syscall
185  */
186 .macro SAVE_ALL_INT
187 	clrl	%sp@-			/* stk_adj */
188 	pea	-1:w			/* orig d0 */
189 	movel	%d0,%sp@-		/* d0 */
190 	moveml	%d1-%d5/%a0-%a2,%sp@-
191 .endm
192 
193 .macro SAVE_ALL_SYS
194 	clrl	%sp@-			/* stk_adj */
195 	movel	%d0,%sp@-		/* orig d0 */
196 	movel	%d0,%sp@-		/* d0 */
197 	moveml	%d1-%d5/%a0-%a2,%sp@-
198 .endm
199 
200 .macro RESTORE_ALL
201 	moveml	%sp@+,%a0-%a2/%d1-%d5
202 	movel	%sp@+,%d0
203 	addql	#4,%sp			/* orig d0 */
204 	addl	%sp@+,%sp		/* stk adj */
205 	rte
206 .endm
207 
208 
209 .macro SAVE_SWITCH_STACK
210 	moveml	%a3-%a6/%d6-%d7,%sp@-
211 .endm
212 
213 .macro RESTORE_SWITCH_STACK
214 	moveml	%sp@+,%a3-%a6/%d6-%d7
215 .endm
216 
217 #endif /* !CONFIG_COLDFIRE */
218 
219 /*
220  * Register %a2 is reserved and set to current task on MMU enabled systems.
221  * Non-MMU systems do not reserve %a2 in this way, and this definition is
222  * not used for them.
223  */
224 #ifdef CONFIG_MMU
225 
226 #define curptr a2
227 
228 #define GET_CURRENT(tmp) get_current tmp
229 .macro get_current reg=%d0
230 	movel	%sp,\reg
231 	andl	#-THREAD_SIZE,\reg
232 	movel	\reg,%curptr
233 	movel	%curptr@,%curptr
234 .endm
235 
236 #else
237 
238 #define GET_CURRENT(tmp)
239 
240 #endif /* CONFIG_MMU */
241 
242 #else /* C source */
243 
244 #define STR(X) STR1(X)
245 #define STR1(X) #X
246 
247 #define SAVE_ALL_INT				\
248 	"clrl	%%sp@-;"    /* stk_adj */	\
249 	"pea	-1:w;"	    /* orig d0 = -1 */	\
250 	"movel	%%d0,%%sp@-;" /* d0 */		\
251 	"moveml	%%d1-%%d5/%%a0-%%a2,%%sp@-"
252 
253 #define GET_CURRENT(tmp) \
254 	"movel	%%sp,"#tmp"\n\t" \
255 	"andw	#-"STR(THREAD_SIZE)","#tmp"\n\t" \
256 	"movel	"#tmp",%%a2\n\t" \
257 	"movel	%%a2@,%%a2"
258 
259 #endif
260 
261 #endif /* __M68K_ENTRY_H */
262