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