18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef __M68K_ENTRY_H
38c2ecf20Sopenharmony_ci#define __M68K_ENTRY_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <asm/setup.h>
68c2ecf20Sopenharmony_ci#include <asm/page.h>
78c2ecf20Sopenharmony_ci#ifdef __ASSEMBLY__
88c2ecf20Sopenharmony_ci#include <asm/thread_info.h>
98c2ecf20Sopenharmony_ci#endif
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci/*
128c2ecf20Sopenharmony_ci * Stack layout in 'ret_from_exception':
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci *	This allows access to the syscall arguments in registers d1-d5
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci *	 0(sp) - d1
178c2ecf20Sopenharmony_ci *	 4(sp) - d2
188c2ecf20Sopenharmony_ci *	 8(sp) - d3
198c2ecf20Sopenharmony_ci *	 C(sp) - d4
208c2ecf20Sopenharmony_ci *	10(sp) - d5
218c2ecf20Sopenharmony_ci *	14(sp) - a0
228c2ecf20Sopenharmony_ci *	18(sp) - a1
238c2ecf20Sopenharmony_ci *	1C(sp) - a2
248c2ecf20Sopenharmony_ci *	20(sp) - d0
258c2ecf20Sopenharmony_ci *	24(sp) - orig_d0
268c2ecf20Sopenharmony_ci *	28(sp) - stack adjustment
278c2ecf20Sopenharmony_ci *	2C(sp) - [ sr              ] [ format & vector ]
288c2ecf20Sopenharmony_ci *	2E(sp) - [ pc-hiword       ] [ sr              ]
298c2ecf20Sopenharmony_ci *	30(sp) - [ pc-loword       ] [ pc-hiword       ]
308c2ecf20Sopenharmony_ci *	32(sp) - [ format & vector ] [ pc-loword       ]
318c2ecf20Sopenharmony_ci *		  ^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^
328c2ecf20Sopenharmony_ci *			M68K		  COLDFIRE
338c2ecf20Sopenharmony_ci */
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci/* the following macro is used when enabling interrupts */
368c2ecf20Sopenharmony_ci#if defined(MACH_ATARI_ONLY)
378c2ecf20Sopenharmony_ci	/* block out HSYNC = ipl 2 on the atari */
388c2ecf20Sopenharmony_ci#define ALLOWINT	(~0x500)
398c2ecf20Sopenharmony_ci#else
408c2ecf20Sopenharmony_ci	/* portable version */
418c2ecf20Sopenharmony_ci#define ALLOWINT	(~0x700)
428c2ecf20Sopenharmony_ci#endif /* machine compilation types */
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#ifdef __ASSEMBLY__
458c2ecf20Sopenharmony_ci/*
468c2ecf20Sopenharmony_ci * This defines the normal kernel pt-regs layout.
478c2ecf20Sopenharmony_ci *
488c2ecf20Sopenharmony_ci * regs a3-a6 and d6-d7 are preserved by C code
498c2ecf20Sopenharmony_ci * the kernel doesn't mess with usp unless it needs to
508c2ecf20Sopenharmony_ci */
518c2ecf20Sopenharmony_ci#define SWITCH_STACK_SIZE	(6*4+4)	/* includes return address */
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci#ifdef CONFIG_COLDFIRE
548c2ecf20Sopenharmony_ci#ifdef CONFIG_COLDFIRE_SW_A7
558c2ecf20Sopenharmony_ci/*
568c2ecf20Sopenharmony_ci * This is made a little more tricky on older ColdFires. There is no
578c2ecf20Sopenharmony_ci * separate supervisor and user stack pointers. Need to artificially
588c2ecf20Sopenharmony_ci * construct a usp in software... When doing this we need to disable
598c2ecf20Sopenharmony_ci * interrupts, otherwise bad things will happen.
608c2ecf20Sopenharmony_ci */
618c2ecf20Sopenharmony_ci.globl sw_usp
628c2ecf20Sopenharmony_ci.globl sw_ksp
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci.macro SAVE_ALL_SYS
658c2ecf20Sopenharmony_ci	move	#0x2700,%sr		/* disable intrs */
668c2ecf20Sopenharmony_ci	btst	#5,%sp@(2)		/* from user? */
678c2ecf20Sopenharmony_ci	bnes	6f			/* no, skip */
688c2ecf20Sopenharmony_ci	movel	%sp,sw_usp		/* save user sp */
698c2ecf20Sopenharmony_ci	addql	#8,sw_usp		/* remove exception */
708c2ecf20Sopenharmony_ci	movel	sw_ksp,%sp		/* kernel sp */
718c2ecf20Sopenharmony_ci	subql	#8,%sp			/* room for exception */
728c2ecf20Sopenharmony_ci	clrl	%sp@-			/* stkadj */
738c2ecf20Sopenharmony_ci	movel	%d0,%sp@-		/* orig d0 */
748c2ecf20Sopenharmony_ci	movel	%d0,%sp@-		/* d0 */
758c2ecf20Sopenharmony_ci	lea	%sp@(-32),%sp		/* space for 8 regs */
768c2ecf20Sopenharmony_ci	moveml	%d1-%d5/%a0-%a2,%sp@
778c2ecf20Sopenharmony_ci	movel	sw_usp,%a0		/* get usp */
788c2ecf20Sopenharmony_ci	movel	%a0@-,%sp@(PT_OFF_PC)	/* copy exception program counter */
798c2ecf20Sopenharmony_ci	movel	%a0@-,%sp@(PT_OFF_FORMATVEC)/*copy exception format/vector/sr */
808c2ecf20Sopenharmony_ci	bra	7f
818c2ecf20Sopenharmony_ci	6:
828c2ecf20Sopenharmony_ci	clrl	%sp@-			/* stkadj */
838c2ecf20Sopenharmony_ci	movel	%d0,%sp@-		/* orig d0 */
848c2ecf20Sopenharmony_ci	movel	%d0,%sp@-		/* d0 */
858c2ecf20Sopenharmony_ci	lea	%sp@(-32),%sp		/* space for 8 regs */
868c2ecf20Sopenharmony_ci	moveml	%d1-%d5/%a0-%a2,%sp@
878c2ecf20Sopenharmony_ci	7:
888c2ecf20Sopenharmony_ci.endm
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci.macro SAVE_ALL_INT
918c2ecf20Sopenharmony_ci	SAVE_ALL_SYS
928c2ecf20Sopenharmony_ci	moveq	#-1,%d0			/* not system call entry */
938c2ecf20Sopenharmony_ci	movel	%d0,%sp@(PT_OFF_ORIG_D0)
948c2ecf20Sopenharmony_ci.endm
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci.macro RESTORE_USER
978c2ecf20Sopenharmony_ci	move	#0x2700,%sr		/* disable intrs */
988c2ecf20Sopenharmony_ci	movel	sw_usp,%a0		/* get usp */
998c2ecf20Sopenharmony_ci	movel	%sp@(PT_OFF_PC),%a0@-	/* copy exception program counter */
1008c2ecf20Sopenharmony_ci	movel	%sp@(PT_OFF_FORMATVEC),%a0@-/*copy exception format/vector/sr */
1018c2ecf20Sopenharmony_ci	moveml	%sp@,%d1-%d5/%a0-%a2
1028c2ecf20Sopenharmony_ci	lea	%sp@(32),%sp		/* space for 8 regs */
1038c2ecf20Sopenharmony_ci	movel	%sp@+,%d0
1048c2ecf20Sopenharmony_ci	addql	#4,%sp			/* orig d0 */
1058c2ecf20Sopenharmony_ci	addl	%sp@+,%sp		/* stkadj */
1068c2ecf20Sopenharmony_ci	addql	#8,%sp			/* remove exception */
1078c2ecf20Sopenharmony_ci	movel	%sp,sw_ksp		/* save ksp */
1088c2ecf20Sopenharmony_ci	subql	#8,sw_usp		/* set exception */
1098c2ecf20Sopenharmony_ci	movel	sw_usp,%sp		/* restore usp */
1108c2ecf20Sopenharmony_ci	rte
1118c2ecf20Sopenharmony_ci.endm
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci.macro RDUSP
1148c2ecf20Sopenharmony_ci	movel	sw_usp,%a3
1158c2ecf20Sopenharmony_ci.endm
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci.macro WRUSP
1188c2ecf20Sopenharmony_ci	movel	%a3,sw_usp
1198c2ecf20Sopenharmony_ci.endm
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci#else /* !CONFIG_COLDFIRE_SW_A7 */
1228c2ecf20Sopenharmony_ci/*
1238c2ecf20Sopenharmony_ci * Modern ColdFire parts have separate supervisor and user stack
1248c2ecf20Sopenharmony_ci * pointers. Simple load and restore macros for this case.
1258c2ecf20Sopenharmony_ci */
1268c2ecf20Sopenharmony_ci.macro SAVE_ALL_SYS
1278c2ecf20Sopenharmony_ci	move	#0x2700,%sr		/* disable intrs */
1288c2ecf20Sopenharmony_ci	clrl	%sp@-			/* stkadj */
1298c2ecf20Sopenharmony_ci	movel	%d0,%sp@-		/* orig d0 */
1308c2ecf20Sopenharmony_ci	movel	%d0,%sp@-		/* d0 */
1318c2ecf20Sopenharmony_ci	lea	%sp@(-32),%sp		/* space for 8 regs */
1328c2ecf20Sopenharmony_ci	moveml	%d1-%d5/%a0-%a2,%sp@
1338c2ecf20Sopenharmony_ci.endm
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci.macro SAVE_ALL_INT
1368c2ecf20Sopenharmony_ci	move	#0x2700,%sr		/* disable intrs */
1378c2ecf20Sopenharmony_ci	clrl	%sp@-			/* stkadj */
1388c2ecf20Sopenharmony_ci	pea	-1:w			/* orig d0 */
1398c2ecf20Sopenharmony_ci	movel	%d0,%sp@-		/* d0 */
1408c2ecf20Sopenharmony_ci	lea	%sp@(-32),%sp		/* space for 8 regs */
1418c2ecf20Sopenharmony_ci	moveml	%d1-%d5/%a0-%a2,%sp@
1428c2ecf20Sopenharmony_ci.endm
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci.macro RESTORE_USER
1458c2ecf20Sopenharmony_ci	moveml	%sp@,%d1-%d5/%a0-%a2
1468c2ecf20Sopenharmony_ci	lea	%sp@(32),%sp		/* space for 8 regs */
1478c2ecf20Sopenharmony_ci	movel	%sp@+,%d0
1488c2ecf20Sopenharmony_ci	addql	#4,%sp			/* orig d0 */
1498c2ecf20Sopenharmony_ci	addl	%sp@+,%sp		/* stkadj */
1508c2ecf20Sopenharmony_ci	rte
1518c2ecf20Sopenharmony_ci.endm
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci.macro RDUSP
1548c2ecf20Sopenharmony_ci	/*move	%usp,%a3*/
1558c2ecf20Sopenharmony_ci	.word	0x4e6b
1568c2ecf20Sopenharmony_ci.endm
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci.macro WRUSP
1598c2ecf20Sopenharmony_ci	/*move	%a3,%usp*/
1608c2ecf20Sopenharmony_ci	.word	0x4e63
1618c2ecf20Sopenharmony_ci.endm
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci#endif /* !CONFIG_COLDFIRE_SW_A7 */
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci.macro SAVE_SWITCH_STACK
1668c2ecf20Sopenharmony_ci	lea	%sp@(-24),%sp		/* 6 regs */
1678c2ecf20Sopenharmony_ci	moveml	%a3-%a6/%d6-%d7,%sp@
1688c2ecf20Sopenharmony_ci.endm
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci.macro RESTORE_SWITCH_STACK
1718c2ecf20Sopenharmony_ci	moveml	%sp@,%a3-%a6/%d6-%d7
1728c2ecf20Sopenharmony_ci	lea	%sp@(24),%sp		/* 6 regs */
1738c2ecf20Sopenharmony_ci.endm
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci#else /* !CONFIG_COLDFIRE */
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci/*
1788c2ecf20Sopenharmony_ci * All other types of m68k parts (68000, 680x0, CPU32) have the same
1798c2ecf20Sopenharmony_ci * entry and exit code.
1808c2ecf20Sopenharmony_ci */
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci/*
1838c2ecf20Sopenharmony_ci * a -1 in the orig_d0 field signifies
1848c2ecf20Sopenharmony_ci * that the stack frame is NOT for syscall
1858c2ecf20Sopenharmony_ci */
1868c2ecf20Sopenharmony_ci.macro SAVE_ALL_INT
1878c2ecf20Sopenharmony_ci	clrl	%sp@-			/* stk_adj */
1888c2ecf20Sopenharmony_ci	pea	-1:w			/* orig d0 */
1898c2ecf20Sopenharmony_ci	movel	%d0,%sp@-		/* d0 */
1908c2ecf20Sopenharmony_ci	moveml	%d1-%d5/%a0-%a2,%sp@-
1918c2ecf20Sopenharmony_ci.endm
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci.macro SAVE_ALL_SYS
1948c2ecf20Sopenharmony_ci	clrl	%sp@-			/* stk_adj */
1958c2ecf20Sopenharmony_ci	movel	%d0,%sp@-		/* orig d0 */
1968c2ecf20Sopenharmony_ci	movel	%d0,%sp@-		/* d0 */
1978c2ecf20Sopenharmony_ci	moveml	%d1-%d5/%a0-%a2,%sp@-
1988c2ecf20Sopenharmony_ci.endm
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci.macro RESTORE_ALL
2018c2ecf20Sopenharmony_ci	moveml	%sp@+,%a0-%a2/%d1-%d5
2028c2ecf20Sopenharmony_ci	movel	%sp@+,%d0
2038c2ecf20Sopenharmony_ci	addql	#4,%sp			/* orig d0 */
2048c2ecf20Sopenharmony_ci	addl	%sp@+,%sp		/* stk adj */
2058c2ecf20Sopenharmony_ci	rte
2068c2ecf20Sopenharmony_ci.endm
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci.macro SAVE_SWITCH_STACK
2108c2ecf20Sopenharmony_ci	moveml	%a3-%a6/%d6-%d7,%sp@-
2118c2ecf20Sopenharmony_ci.endm
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci.macro RESTORE_SWITCH_STACK
2148c2ecf20Sopenharmony_ci	moveml	%sp@+,%a3-%a6/%d6-%d7
2158c2ecf20Sopenharmony_ci.endm
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci#endif /* !CONFIG_COLDFIRE */
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci/*
2208c2ecf20Sopenharmony_ci * Register %a2 is reserved and set to current task on MMU enabled systems.
2218c2ecf20Sopenharmony_ci * Non-MMU systems do not reserve %a2 in this way, and this definition is
2228c2ecf20Sopenharmony_ci * not used for them.
2238c2ecf20Sopenharmony_ci */
2248c2ecf20Sopenharmony_ci#ifdef CONFIG_MMU
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci#define curptr a2
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci#define GET_CURRENT(tmp) get_current tmp
2298c2ecf20Sopenharmony_ci.macro get_current reg=%d0
2308c2ecf20Sopenharmony_ci	movel	%sp,\reg
2318c2ecf20Sopenharmony_ci	andl	#-THREAD_SIZE,\reg
2328c2ecf20Sopenharmony_ci	movel	\reg,%curptr
2338c2ecf20Sopenharmony_ci	movel	%curptr@,%curptr
2348c2ecf20Sopenharmony_ci.endm
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci#else
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci#define GET_CURRENT(tmp)
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci#endif /* CONFIG_MMU */
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci#else /* C source */
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci#define STR(X) STR1(X)
2458c2ecf20Sopenharmony_ci#define STR1(X) #X
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci#define SAVE_ALL_INT				\
2488c2ecf20Sopenharmony_ci	"clrl	%%sp@-;"    /* stk_adj */	\
2498c2ecf20Sopenharmony_ci	"pea	-1:w;"	    /* orig d0 = -1 */	\
2508c2ecf20Sopenharmony_ci	"movel	%%d0,%%sp@-;" /* d0 */		\
2518c2ecf20Sopenharmony_ci	"moveml	%%d1-%%d5/%%a0-%%a2,%%sp@-"
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci#define GET_CURRENT(tmp) \
2548c2ecf20Sopenharmony_ci	"movel	%%sp,"#tmp"\n\t" \
2558c2ecf20Sopenharmony_ci	"andw	#-"STR(THREAD_SIZE)","#tmp"\n\t" \
2568c2ecf20Sopenharmony_ci	"movel	"#tmp",%%a2\n\t" \
2578c2ecf20Sopenharmony_ci	"movel	%%a2@,%%a2"
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci#endif
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci#endif /* __M68K_ENTRY_H */
262