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