18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci *  linux/arch/h8300/kernel/entry.S
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci *  Yoshinori Sato <ysato@users.sourceforge.jp>
78c2ecf20Sopenharmony_ci *  David McCullough <davidm@snapgear.com>
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci/*
128c2ecf20Sopenharmony_ci *  entry.S
138c2ecf20Sopenharmony_ci *  include exception/interrupt gateway
148c2ecf20Sopenharmony_ci *          system call entry
158c2ecf20Sopenharmony_ci */
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <linux/sys.h>
188c2ecf20Sopenharmony_ci#include <asm/unistd.h>
198c2ecf20Sopenharmony_ci#include <asm/setup.h>
208c2ecf20Sopenharmony_ci#include <asm/segment.h>
218c2ecf20Sopenharmony_ci#include <asm/linkage.h>
228c2ecf20Sopenharmony_ci#include <asm/asm-offsets.h>
238c2ecf20Sopenharmony_ci#include <asm/thread_info.h>
248c2ecf20Sopenharmony_ci#include <asm/errno.h>
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_H8300H)
278c2ecf20Sopenharmony_ci#define USERRET 8
288c2ecf20Sopenharmony_ciINTERRUPTS = 64
298c2ecf20Sopenharmony_ci	.h8300h
308c2ecf20Sopenharmony_ci	.macro	SHLL2 reg
318c2ecf20Sopenharmony_ci	shll.l	\reg
328c2ecf20Sopenharmony_ci	shll.l	\reg
338c2ecf20Sopenharmony_ci	.endm
348c2ecf20Sopenharmony_ci	.macro	SHLR2 reg
358c2ecf20Sopenharmony_ci	shlr.l	\reg
368c2ecf20Sopenharmony_ci	shlr.l	\reg
378c2ecf20Sopenharmony_ci	.endm
388c2ecf20Sopenharmony_ci	.macro	SAVEREGS
398c2ecf20Sopenharmony_ci	mov.l	er0,@-sp
408c2ecf20Sopenharmony_ci	mov.l	er1,@-sp
418c2ecf20Sopenharmony_ci	mov.l	er2,@-sp
428c2ecf20Sopenharmony_ci	mov.l	er3,@-sp
438c2ecf20Sopenharmony_ci	.endm
448c2ecf20Sopenharmony_ci	.macro	RESTOREREGS
458c2ecf20Sopenharmony_ci	mov.l	@sp+,er3
468c2ecf20Sopenharmony_ci	mov.l	@sp+,er2
478c2ecf20Sopenharmony_ci	.endm
488c2ecf20Sopenharmony_ci	.macro	SAVEEXR
498c2ecf20Sopenharmony_ci	.endm
508c2ecf20Sopenharmony_ci	.macro	RESTOREEXR
518c2ecf20Sopenharmony_ci	.endm
528c2ecf20Sopenharmony_ci#endif
538c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_H8S)
548c2ecf20Sopenharmony_ci#define USERRET 10
558c2ecf20Sopenharmony_ci#define USEREXR 8
568c2ecf20Sopenharmony_ciINTERRUPTS = 128
578c2ecf20Sopenharmony_ci	.h8300s
588c2ecf20Sopenharmony_ci	.macro	SHLL2 reg
598c2ecf20Sopenharmony_ci	shll.l	#2,\reg
608c2ecf20Sopenharmony_ci	.endm
618c2ecf20Sopenharmony_ci	.macro	SHLR2 reg
628c2ecf20Sopenharmony_ci	shlr.l	#2,\reg
638c2ecf20Sopenharmony_ci	.endm
648c2ecf20Sopenharmony_ci	.macro	SAVEREGS
658c2ecf20Sopenharmony_ci	stm.l	er0-er3,@-sp
668c2ecf20Sopenharmony_ci	.endm
678c2ecf20Sopenharmony_ci	.macro	RESTOREREGS
688c2ecf20Sopenharmony_ci	ldm.l	@sp+,er2-er3
698c2ecf20Sopenharmony_ci	.endm
708c2ecf20Sopenharmony_ci	.macro	SAVEEXR
718c2ecf20Sopenharmony_ci	mov.w	@(USEREXR:16,er0),r1
728c2ecf20Sopenharmony_ci	mov.w	r1,@(LEXR-LER3:16,sp)		/* copy EXR */
738c2ecf20Sopenharmony_ci	.endm
748c2ecf20Sopenharmony_ci	.macro	RESTOREEXR
758c2ecf20Sopenharmony_ci	mov.w	@(LEXR-LER1:16,sp),r1		/* restore EXR */
768c2ecf20Sopenharmony_ci	mov.b	r1l,r1h
778c2ecf20Sopenharmony_ci	mov.w	r1,@(USEREXR:16,er0)
788c2ecf20Sopenharmony_ci	.endm
798c2ecf20Sopenharmony_ci#endif
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci/* CPU context save/restore macros. */
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	.macro	SAVE_ALL
858c2ecf20Sopenharmony_ci	mov.l	er0,@-sp
868c2ecf20Sopenharmony_ci	stc	ccr,r0l				/* check kernel mode */
878c2ecf20Sopenharmony_ci	btst	#4,r0l
888c2ecf20Sopenharmony_ci	bne	5f
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	/* user mode */
918c2ecf20Sopenharmony_ci	mov.l	sp,@_sw_usp
928c2ecf20Sopenharmony_ci	mov.l	@sp,er0				/* restore saved er0 */
938c2ecf20Sopenharmony_ci	orc	#0x10,ccr			/* switch kernel stack */
948c2ecf20Sopenharmony_ci	mov.l	@_sw_ksp,sp
958c2ecf20Sopenharmony_ci	sub.l	#(LRET-LORIG),sp		/* allocate LORIG - LRET */
968c2ecf20Sopenharmony_ci	SAVEREGS
978c2ecf20Sopenharmony_ci	mov.l   @_sw_usp,er0
988c2ecf20Sopenharmony_ci	mov.l   @(USERRET:16,er0),er1           /* copy the RET addr */
998c2ecf20Sopenharmony_ci	mov.l   er1,@(LRET-LER3:16,sp)
1008c2ecf20Sopenharmony_ci	SAVEEXR
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	mov.l	@(LORIG-LER3:16,sp),er0
1038c2ecf20Sopenharmony_ci	mov.l	er0,@(LER0-LER3:16,sp)		/* copy ER0 */
1048c2ecf20Sopenharmony_ci	mov.w	e1,r1				/* e1 highbyte = ccr */
1058c2ecf20Sopenharmony_ci	and	#0xef,r1h			/* mask mode? flag */
1068c2ecf20Sopenharmony_ci	bra	6f
1078c2ecf20Sopenharmony_ci5:
1088c2ecf20Sopenharmony_ci	/* kernel mode */
1098c2ecf20Sopenharmony_ci	mov.l	@sp,er0				/* restore saved er0 */
1108c2ecf20Sopenharmony_ci	subs	#2,sp				/* set dummy ccr */
1118c2ecf20Sopenharmony_ci	subs	#4,sp				/* set dummp sp */
1128c2ecf20Sopenharmony_ci	SAVEREGS
1138c2ecf20Sopenharmony_ci	mov.w	@(LRET-LER3:16,sp),r1		/* copy old ccr */
1148c2ecf20Sopenharmony_ci6:
1158c2ecf20Sopenharmony_ci	mov.b	r1h,r1l
1168c2ecf20Sopenharmony_ci	mov.b	#0,r1h
1178c2ecf20Sopenharmony_ci	mov.w	r1,@(LCCR-LER3:16,sp)		/* set ccr */
1188c2ecf20Sopenharmony_ci	mov.l	@_sw_usp,er2
1198c2ecf20Sopenharmony_ci	mov.l	er2,@(LSP-LER3:16,sp)		/* set usp */
1208c2ecf20Sopenharmony_ci	mov.l	er6,@-sp			/* syscall arg #6 */
1218c2ecf20Sopenharmony_ci	mov.l	er5,@-sp			/* syscall arg #5 */
1228c2ecf20Sopenharmony_ci	mov.l	er4,@-sp			/* syscall arg #4 */
1238c2ecf20Sopenharmony_ci	.endm					/* r1 = ccr */
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	.macro	RESTORE_ALL
1268c2ecf20Sopenharmony_ci	mov.l	@sp+,er4
1278c2ecf20Sopenharmony_ci	mov.l	@sp+,er5
1288c2ecf20Sopenharmony_ci	mov.l	@sp+,er6
1298c2ecf20Sopenharmony_ci	RESTOREREGS
1308c2ecf20Sopenharmony_ci	mov.w	@(LCCR-LER1:16,sp),r0		/* check kernel mode */
1318c2ecf20Sopenharmony_ci	btst	#4,r0l
1328c2ecf20Sopenharmony_ci	bne	7f
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	orc	#0xc0,ccr
1358c2ecf20Sopenharmony_ci	mov.l	@(LSP-LER1:16,sp),er0
1368c2ecf20Sopenharmony_ci	mov.l	@(LER0-LER1:16,sp),er1		/* restore ER0 */
1378c2ecf20Sopenharmony_ci	mov.l	er1,@er0
1388c2ecf20Sopenharmony_ci	RESTOREEXR
1398c2ecf20Sopenharmony_ci	mov.w	@(LCCR-LER1:16,sp),r1		/* restore the RET addr */
1408c2ecf20Sopenharmony_ci	mov.b	r1l,r1h
1418c2ecf20Sopenharmony_ci	mov.b	@(LRET+1-LER1:16,sp),r1l
1428c2ecf20Sopenharmony_ci	mov.w	r1,e1
1438c2ecf20Sopenharmony_ci	mov.w	@(LRET+2-LER1:16,sp),r1
1448c2ecf20Sopenharmony_ci	mov.l	er1,@(USERRET:16,er0)
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	mov.l	@sp+,er1
1478c2ecf20Sopenharmony_ci	add.l	#(LRET-LER1),sp			/* remove LORIG - LRET */
1488c2ecf20Sopenharmony_ci	mov.l	sp,@_sw_ksp
1498c2ecf20Sopenharmony_ci	andc	#0xef,ccr			/* switch to user mode */
1508c2ecf20Sopenharmony_ci	mov.l	er0,sp
1518c2ecf20Sopenharmony_ci	bra	8f
1528c2ecf20Sopenharmony_ci7:
1538c2ecf20Sopenharmony_ci	mov.l	@sp+,er1
1548c2ecf20Sopenharmony_ci	add.l	#10,sp
1558c2ecf20Sopenharmony_ci8:
1568c2ecf20Sopenharmony_ci	mov.l	@sp+,er0
1578c2ecf20Sopenharmony_ci	adds	#4,sp				/* remove the sw created LVEC */
1588c2ecf20Sopenharmony_ci	rte
1598c2ecf20Sopenharmony_ci	.endm
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci.globl _system_call
1628c2ecf20Sopenharmony_ci.globl ret_from_exception
1638c2ecf20Sopenharmony_ci.globl ret_from_fork
1648c2ecf20Sopenharmony_ci.globl ret_from_kernel_thread
1658c2ecf20Sopenharmony_ci.globl ret_from_interrupt
1668c2ecf20Sopenharmony_ci.globl _interrupt_redirect_table
1678c2ecf20Sopenharmony_ci.globl _sw_ksp,_sw_usp
1688c2ecf20Sopenharmony_ci.globl _resume
1698c2ecf20Sopenharmony_ci.globl _interrupt_entry
1708c2ecf20Sopenharmony_ci.globl _trace_break
1718c2ecf20Sopenharmony_ci.globl _nmi
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci#if defined(CONFIG_ROMKERNEL)
1748c2ecf20Sopenharmony_ci	.section .int_redirect,"ax"
1758c2ecf20Sopenharmony_ci_interrupt_redirect_table:
1768c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_H8300H)
1778c2ecf20Sopenharmony_ci	.rept	7
1788c2ecf20Sopenharmony_ci	.long	0
1798c2ecf20Sopenharmony_ci	.endr
1808c2ecf20Sopenharmony_ci#endif
1818c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_H8S)
1828c2ecf20Sopenharmony_ci	.rept	5
1838c2ecf20Sopenharmony_ci	.long	0
1848c2ecf20Sopenharmony_ci	.endr
1858c2ecf20Sopenharmony_ci	jmp	@_trace_break
1868c2ecf20Sopenharmony_ci	.long	0
1878c2ecf20Sopenharmony_ci#endif
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	jsr	@_interrupt_entry		/* NMI */
1908c2ecf20Sopenharmony_ci	jmp	@_system_call			/* TRAPA #0 (System call) */
1918c2ecf20Sopenharmony_ci	.long	0
1928c2ecf20Sopenharmony_ci#if defined(CONFIG_KGDB)
1938c2ecf20Sopenharmony_ci	jmp	@_kgdb_trap
1948c2ecf20Sopenharmony_ci#else
1958c2ecf20Sopenharmony_ci	.long	0
1968c2ecf20Sopenharmony_ci#endif
1978c2ecf20Sopenharmony_ci	jmp	@_trace_break			/* TRAPA #3 (breakpoint) */
1988c2ecf20Sopenharmony_ci	.rept	INTERRUPTS-12
1998c2ecf20Sopenharmony_ci	jsr	@_interrupt_entry
2008c2ecf20Sopenharmony_ci	.endr
2018c2ecf20Sopenharmony_ci#endif
2028c2ecf20Sopenharmony_ci#if defined(CONFIG_RAMKERNEL)
2038c2ecf20Sopenharmony_ci.globl _interrupt_redirect_table
2048c2ecf20Sopenharmony_ci	.section .bss
2058c2ecf20Sopenharmony_ci_interrupt_redirect_table:
2068c2ecf20Sopenharmony_ci	.space	4
2078c2ecf20Sopenharmony_ci#endif
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci	.section .text
2108c2ecf20Sopenharmony_ci	.align	2
2118c2ecf20Sopenharmony_ci_interrupt_entry:
2128c2ecf20Sopenharmony_ci	SAVE_ALL
2138c2ecf20Sopenharmony_ci/* r1l is saved ccr */
2148c2ecf20Sopenharmony_ci	mov.l	sp,er0
2158c2ecf20Sopenharmony_ci	add.l	#LVEC,er0
2168c2ecf20Sopenharmony_ci	btst	#4,r1l
2178c2ecf20Sopenharmony_ci	bne	1f
2188c2ecf20Sopenharmony_ci	/* user LVEC */
2198c2ecf20Sopenharmony_ci	mov.l	@_sw_usp,er0
2208c2ecf20Sopenharmony_ci	adds	#4,er0
2218c2ecf20Sopenharmony_ci1:
2228c2ecf20Sopenharmony_ci	mov.l	@er0,er0			/* LVEC address */
2238c2ecf20Sopenharmony_ci#if defined(CONFIG_ROMKERNEL)
2248c2ecf20Sopenharmony_ci	sub.l	#_interrupt_redirect_table,er0
2258c2ecf20Sopenharmony_ci#endif
2268c2ecf20Sopenharmony_ci#if defined(CONFIG_RAMKERNEL)
2278c2ecf20Sopenharmony_ci	mov.l	@_interrupt_redirect_table,er1
2288c2ecf20Sopenharmony_ci	sub.l	er1,er0
2298c2ecf20Sopenharmony_ci#endif
2308c2ecf20Sopenharmony_ci	SHLR2	er0
2318c2ecf20Sopenharmony_ci	dec.l	#1,er0
2328c2ecf20Sopenharmony_ci	mov.l	sp,er1
2338c2ecf20Sopenharmony_ci	subs	#4,er1				/* adjust ret_pc */
2348c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_H8S)
2358c2ecf20Sopenharmony_ci	orc	#7,exr
2368c2ecf20Sopenharmony_ci#endif
2378c2ecf20Sopenharmony_ci	jsr	@do_IRQ
2388c2ecf20Sopenharmony_ci	jmp	@ret_from_interrupt
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci_system_call:
2418c2ecf20Sopenharmony_ci	subs	#4,sp				/* dummy LVEC */
2428c2ecf20Sopenharmony_ci	SAVE_ALL
2438c2ecf20Sopenharmony_ci	/* er0: syscall nr */
2448c2ecf20Sopenharmony_ci	andc	#0xbf,ccr
2458c2ecf20Sopenharmony_ci	mov.l	er0,er4
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci	/* save top of frame */
2488c2ecf20Sopenharmony_ci	mov.l	sp,er0
2498c2ecf20Sopenharmony_ci	jsr	@set_esp0
2508c2ecf20Sopenharmony_ci	andc	#0x3f,ccr
2518c2ecf20Sopenharmony_ci	mov.l	sp,er2
2528c2ecf20Sopenharmony_ci	and.w	#0xe000,r2
2538c2ecf20Sopenharmony_ci	mov.l	@(TI_FLAGS:16,er2),er2
2548c2ecf20Sopenharmony_ci	and.w	#_TIF_WORK_SYSCALL_MASK,r2
2558c2ecf20Sopenharmony_ci	beq	1f
2568c2ecf20Sopenharmony_ci	mov.l	sp,er0
2578c2ecf20Sopenharmony_ci	jsr	@do_syscall_trace_enter
2588c2ecf20Sopenharmony_ci1:
2598c2ecf20Sopenharmony_ci	cmp.l	#__NR_syscalls,er4
2608c2ecf20Sopenharmony_ci	bcc	badsys
2618c2ecf20Sopenharmony_ci	SHLL2	er4
2628c2ecf20Sopenharmony_ci	mov.l	#_sys_call_table,er0
2638c2ecf20Sopenharmony_ci	add.l	er4,er0
2648c2ecf20Sopenharmony_ci	mov.l	@er0,er4
2658c2ecf20Sopenharmony_ci	beq	ret_from_exception:16
2668c2ecf20Sopenharmony_ci	mov.l	@(LER1:16,sp),er0
2678c2ecf20Sopenharmony_ci	mov.l	@(LER2:16,sp),er1
2688c2ecf20Sopenharmony_ci	mov.l	@(LER3:16,sp),er2
2698c2ecf20Sopenharmony_ci	jsr	@er4
2708c2ecf20Sopenharmony_ci	mov.l	er0,@(LER0:16,sp)		/* save the return value */
2718c2ecf20Sopenharmony_ci	mov.l	sp,er2
2728c2ecf20Sopenharmony_ci	and.w	#0xe000,r2
2738c2ecf20Sopenharmony_ci	mov.l	@(TI_FLAGS:16,er2),er2
2748c2ecf20Sopenharmony_ci	and.w	#_TIF_WORK_SYSCALL_MASK,r2
2758c2ecf20Sopenharmony_ci	beq	2f
2768c2ecf20Sopenharmony_ci	mov.l	sp,er0
2778c2ecf20Sopenharmony_ci	jsr	@do_syscall_trace_leave
2788c2ecf20Sopenharmony_ci2:
2798c2ecf20Sopenharmony_ci	orc	#0xc0,ccr
2808c2ecf20Sopenharmony_ci	bra	resume_userspace
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_cibadsys:
2838c2ecf20Sopenharmony_ci	mov.l	#-ENOSYS,er0
2848c2ecf20Sopenharmony_ci	mov.l	er0,@(LER0:16,sp)
2858c2ecf20Sopenharmony_ci	bra	resume_userspace
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci#if !defined(CONFIG_PREEMPTION)
2888c2ecf20Sopenharmony_ci#define resume_kernel restore_all
2898c2ecf20Sopenharmony_ci#endif
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ciret_from_exception:
2928c2ecf20Sopenharmony_ci#if defined(CONFIG_PREEMPTION)
2938c2ecf20Sopenharmony_ci	orc	#0xc0,ccr
2948c2ecf20Sopenharmony_ci#endif
2958c2ecf20Sopenharmony_ciret_from_interrupt:
2968c2ecf20Sopenharmony_ci	mov.b	@(LCCR+1:16,sp),r0l
2978c2ecf20Sopenharmony_ci	btst	#4,r0l
2988c2ecf20Sopenharmony_ci	bne	resume_kernel:16	/* return from kernel */
2998c2ecf20Sopenharmony_ciresume_userspace:
3008c2ecf20Sopenharmony_ci	andc	#0xbf,ccr
3018c2ecf20Sopenharmony_ci	mov.l	sp,er4
3028c2ecf20Sopenharmony_ci	and.w	#0xe000,r4		/* er4 <- current thread info */
3038c2ecf20Sopenharmony_ci	mov.l	@(TI_FLAGS:16,er4),er1
3048c2ecf20Sopenharmony_ci	and.l	#_TIF_WORK_MASK,er1
3058c2ecf20Sopenharmony_ci	beq	restore_all:8
3068c2ecf20Sopenharmony_ciwork_pending:
3078c2ecf20Sopenharmony_ci	btst	#TIF_NEED_RESCHED,r1l
3088c2ecf20Sopenharmony_ci	bne	work_resched:8
3098c2ecf20Sopenharmony_ci	/* work notifysig */
3108c2ecf20Sopenharmony_ci	mov.l	sp,er0
3118c2ecf20Sopenharmony_ci	subs	#4,er0			/* er0: pt_regs */
3128c2ecf20Sopenharmony_ci	jsr	@do_notify_resume
3138c2ecf20Sopenharmony_ci	bra	resume_userspace:8
3148c2ecf20Sopenharmony_ciwork_resched:
3158c2ecf20Sopenharmony_ci	mov.l	sp,er0
3168c2ecf20Sopenharmony_ci	jsr	@set_esp0
3178c2ecf20Sopenharmony_ci	jsr	@schedule
3188c2ecf20Sopenharmony_ci	bra	resume_userspace:8
3198c2ecf20Sopenharmony_cirestore_all:
3208c2ecf20Sopenharmony_ci	RESTORE_ALL			/* Does RTE */
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci#if defined(CONFIG_PREEMPTION)
3238c2ecf20Sopenharmony_ciresume_kernel:
3248c2ecf20Sopenharmony_ci	mov.l	@(TI_PRE_COUNT:16,er4),er0
3258c2ecf20Sopenharmony_ci	bne	restore_all:8
3268c2ecf20Sopenharmony_cineed_resched:
3278c2ecf20Sopenharmony_ci	mov.l	@(TI_FLAGS:16,er4),er0
3288c2ecf20Sopenharmony_ci	btst	#TIF_NEED_RESCHED,r0l
3298c2ecf20Sopenharmony_ci	beq	restore_all:8
3308c2ecf20Sopenharmony_ci	mov.b	@(LCCR+1:16,sp),r0l	/* Interrupt Enabled? */
3318c2ecf20Sopenharmony_ci	bmi	restore_all:8
3328c2ecf20Sopenharmony_ci	mov.l	sp,er0
3338c2ecf20Sopenharmony_ci	jsr	@set_esp0
3348c2ecf20Sopenharmony_ci	jsr	@preempt_schedule_irq
3358c2ecf20Sopenharmony_ci	bra	need_resched:8
3368c2ecf20Sopenharmony_ci#endif
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ciret_from_fork:
3398c2ecf20Sopenharmony_ci	mov.l	er2,er0
3408c2ecf20Sopenharmony_ci	jsr	@schedule_tail
3418c2ecf20Sopenharmony_ci	jmp	@ret_from_exception
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ciret_from_kernel_thread:
3448c2ecf20Sopenharmony_ci	mov.l	er2,er0
3458c2ecf20Sopenharmony_ci	jsr	@schedule_tail
3468c2ecf20Sopenharmony_ci	mov.l	@(LER4:16,sp),er0
3478c2ecf20Sopenharmony_ci	mov.l	@(LER5:16,sp),er1
3488c2ecf20Sopenharmony_ci	jsr	@er1
3498c2ecf20Sopenharmony_ci	jmp	@ret_from_exception
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci_resume:
3528c2ecf20Sopenharmony_ci	/*
3538c2ecf20Sopenharmony_ci	 * Beware - when entering resume, offset of tss is in d1,
3548c2ecf20Sopenharmony_ci	 * prev (the current task) is in a0, next (the new task)
3558c2ecf20Sopenharmony_ci	 * is in a1 and d2.b is non-zero if the mm structure is
3568c2ecf20Sopenharmony_ci	 * shared between the tasks, so don't change these
3578c2ecf20Sopenharmony_ci	 * registers until their contents are no longer needed.
3588c2ecf20Sopenharmony_ci	 */
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci	/* save sr */
3618c2ecf20Sopenharmony_ci	sub.w	r3,r3
3628c2ecf20Sopenharmony_ci	stc	ccr,r3l
3638c2ecf20Sopenharmony_ci	mov.w	r3,@(THREAD_CCR+2:16,er0)
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci	/* disable interrupts */
3668c2ecf20Sopenharmony_ci	orc	#0xc0,ccr
3678c2ecf20Sopenharmony_ci	mov.l	@_sw_usp,er3
3688c2ecf20Sopenharmony_ci	mov.l	er3,@(THREAD_USP:16,er0)
3698c2ecf20Sopenharmony_ci	mov.l	sp,@(THREAD_KSP:16,er0)
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ci	/* Skip address space switching if they are the same. */
3728c2ecf20Sopenharmony_ci	/* FIXME: what did we hack out of here, this does nothing! */
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci	mov.l	@(THREAD_USP:16,er1),er0
3758c2ecf20Sopenharmony_ci	mov.l	er0,@_sw_usp
3768c2ecf20Sopenharmony_ci	mov.l	@(THREAD_KSP:16,er1),sp
3778c2ecf20Sopenharmony_ci
3788c2ecf20Sopenharmony_ci	/* restore status register */
3798c2ecf20Sopenharmony_ci	mov.w	@(THREAD_CCR+2:16,er1),r3
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci	ldc	r3l,ccr
3828c2ecf20Sopenharmony_ci	rts
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci_trace_break:
3858c2ecf20Sopenharmony_ci	subs	#4,sp
3868c2ecf20Sopenharmony_ci	SAVE_ALL
3878c2ecf20Sopenharmony_ci	sub.l	er1,er1
3888c2ecf20Sopenharmony_ci	dec.l	#1,er1
3898c2ecf20Sopenharmony_ci	mov.l	er1,@(LORIG,sp)
3908c2ecf20Sopenharmony_ci	mov.l	sp,er0
3918c2ecf20Sopenharmony_ci	jsr	@set_esp0
3928c2ecf20Sopenharmony_ci	mov.l	@_sw_usp,er0
3938c2ecf20Sopenharmony_ci	mov.l	@er0,er1
3948c2ecf20Sopenharmony_ci	mov.w	@(-2:16,er1),r2
3958c2ecf20Sopenharmony_ci	cmp.w	#0x5730,r2
3968c2ecf20Sopenharmony_ci	beq	1f
3978c2ecf20Sopenharmony_ci	subs	#2,er1
3988c2ecf20Sopenharmony_ci	mov.l	er1,@er0
3998c2ecf20Sopenharmony_ci1:
4008c2ecf20Sopenharmony_ci	and.w	#0xff,e1
4018c2ecf20Sopenharmony_ci	mov.l	er1,er0
4028c2ecf20Sopenharmony_ci	jsr	@trace_trap
4038c2ecf20Sopenharmony_ci	jmp	@ret_from_exception
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci_nmi:
4068c2ecf20Sopenharmony_ci	subs	#4, sp
4078c2ecf20Sopenharmony_ci	mov.l	er0, @-sp
4088c2ecf20Sopenharmony_ci	mov.l	@_interrupt_redirect_table, er0
4098c2ecf20Sopenharmony_ci	add.l	#8*4, er0
4108c2ecf20Sopenharmony_ci	mov.l	er0, @(4,sp)
4118c2ecf20Sopenharmony_ci	mov.l	@sp+, er0
4128c2ecf20Sopenharmony_ci	jmp	@_interrupt_entry
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_ci#if defined(CONFIG_KGDB)
4158c2ecf20Sopenharmony_ci_kgdb_trap:
4168c2ecf20Sopenharmony_ci	subs	#4,sp
4178c2ecf20Sopenharmony_ci	SAVE_ALL
4188c2ecf20Sopenharmony_ci	mov.l	sp,er0
4198c2ecf20Sopenharmony_ci	add.l	#LRET,er0
4208c2ecf20Sopenharmony_ci	mov.l	er0,@(LSP,sp)
4218c2ecf20Sopenharmony_ci	jsr	@set_esp0
4228c2ecf20Sopenharmony_ci	mov.l	sp,er0
4238c2ecf20Sopenharmony_ci	subs	#4,er0
4248c2ecf20Sopenharmony_ci	jsr	@h8300_kgdb_trap
4258c2ecf20Sopenharmony_ci	jmp	@ret_from_exception
4268c2ecf20Sopenharmony_ci#endif
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci	.section	.bss
4298c2ecf20Sopenharmony_ci_sw_ksp:
4308c2ecf20Sopenharmony_ci	.space	4
4318c2ecf20Sopenharmony_ci_sw_usp:
4328c2ecf20Sopenharmony_ci	.space	4
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_ci	.end
435