18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2020-2021 Loongson Technology Corporation Limited
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci#include <asm/asm.h>
68c2ecf20Sopenharmony_ci#include <asm/asmmacro.h>
78c2ecf20Sopenharmony_ci#include <asm/regdef.h>
88c2ecf20Sopenharmony_ci#include <asm/fpregdef.h>
98c2ecf20Sopenharmony_ci#include <asm/loongarchregs.h>
108c2ecf20Sopenharmony_ci#include <asm/stackframe.h>
118c2ecf20Sopenharmony_ci#include <asm/thread_info.h>
128c2ecf20Sopenharmony_ci#include <asm/unwind_hints.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci	.align	5
158c2ecf20Sopenharmony_ciSYM_FUNC_START(__arch_cpu_idle)
168c2ecf20Sopenharmony_ci	/* start of rollback region */
178c2ecf20Sopenharmony_ci	LONG_L	t0, tp, TI_FLAGS
188c2ecf20Sopenharmony_ci	nop
198c2ecf20Sopenharmony_ci	andi	t0, t0, _TIF_NEED_RESCHED
208c2ecf20Sopenharmony_ci	bnez	t0, 1f
218c2ecf20Sopenharmony_ci	nop
228c2ecf20Sopenharmony_ci	nop
238c2ecf20Sopenharmony_ci	nop
248c2ecf20Sopenharmony_ci	idle	0
258c2ecf20Sopenharmony_ci	/* end of rollback region */
268c2ecf20Sopenharmony_ci1:	jirl	zero, ra, 0
278c2ecf20Sopenharmony_ciSYM_FUNC_END(__arch_cpu_idle)
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ciSYM_CODE_START(handle_vint)
308c2ecf20Sopenharmony_ci	BACKUP_T0T1
318c2ecf20Sopenharmony_ci	SAVE_ALL
328c2ecf20Sopenharmony_ci	UNWIND_HINT_REGS
338c2ecf20Sopenharmony_ci	la.abs	t1, __arch_cpu_idle
348c2ecf20Sopenharmony_ci	LONG_L  t0, sp, PT_ERA
358c2ecf20Sopenharmony_ci	/* 32 byte rollback region */
368c2ecf20Sopenharmony_ci	ori	t0, t0, 0x1f
378c2ecf20Sopenharmony_ci	xori	t0, t0, 0x1f
388c2ecf20Sopenharmony_ci	bne	t0, t1, 1f
398c2ecf20Sopenharmony_ci	LONG_S  t0, sp, PT_ERA
408c2ecf20Sopenharmony_ci1:	move	a0, sp
418c2ecf20Sopenharmony_ci	move	a1, sp
428c2ecf20Sopenharmony_ci	la.abs	t0, do_vint
438c2ecf20Sopenharmony_ci	jirl    ra, t0, 0
448c2ecf20Sopenharmony_ci	UNWIND_HINT_REGS
458c2ecf20Sopenharmony_ci	RESTORE_ALL_AND_RET
468c2ecf20Sopenharmony_ciSYM_CODE_END(handle_vint)
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ciSYM_CODE_START(except_vec_cex)
498c2ecf20Sopenharmony_ci	b	cache_parity_error
508c2ecf20Sopenharmony_ciSYM_CODE_END(except_vec_cex)
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	.macro	build_prep_badv
538c2ecf20Sopenharmony_ci	csrrd	t0, LOONGARCH_CSR_BADV
548c2ecf20Sopenharmony_ci	PTR_S	t0, sp, PT_BVADDR
558c2ecf20Sopenharmony_ci	.endm
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci	.macro	build_prep_fcsr
588c2ecf20Sopenharmony_ci	movfcsr2gr	a1, fcsr0
598c2ecf20Sopenharmony_ci	.endm
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	.macro	build_prep_none
628c2ecf20Sopenharmony_ci	.endm
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	.macro	BUILD_HANDLER exception handler prep
658c2ecf20Sopenharmony_ci	.align	5
668c2ecf20Sopenharmony_ci	SYM_CODE_START(handle_\exception)
678c2ecf20Sopenharmony_ci	BACKUP_T0T1
688c2ecf20Sopenharmony_ci	SAVE_ALL
698c2ecf20Sopenharmony_ci	build_prep_\prep
708c2ecf20Sopenharmony_ci	move	a0, sp
718c2ecf20Sopenharmony_ci	la.abs	t0, do_\handler
728c2ecf20Sopenharmony_ci	jirl    ra, t0, 0
738c2ecf20Sopenharmony_ci	UNWIND_HINT_REGS
748c2ecf20Sopenharmony_ci	RESTORE_ALL_AND_RET
758c2ecf20Sopenharmony_ci	SYM_CODE_END(handle_\exception)
768c2ecf20Sopenharmony_ci	.endm
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	BUILD_HANDLER ade ade badv
798c2ecf20Sopenharmony_ci	BUILD_HANDLER ale ale badv
808c2ecf20Sopenharmony_ci	BUILD_HANDLER bce bce none
818c2ecf20Sopenharmony_ci	BUILD_HANDLER bp bp none
828c2ecf20Sopenharmony_ci	BUILD_HANDLER fpe fpe fcsr
838c2ecf20Sopenharmony_ci	BUILD_HANDLER fpu fpu none
848c2ecf20Sopenharmony_ci	BUILD_HANDLER lsx lsx none
858c2ecf20Sopenharmony_ci	BUILD_HANDLER lasx lasx none
868c2ecf20Sopenharmony_ci	BUILD_HANDLER lbt lbt none
878c2ecf20Sopenharmony_ci	BUILD_HANDLER ri ri none
888c2ecf20Sopenharmony_ci	BUILD_HANDLER watch watch none
898c2ecf20Sopenharmony_ci	BUILD_HANDLER reserved reserved none	/* others */
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ciSYM_CODE_START(handle_sys)
928c2ecf20Sopenharmony_ci	la.abs	t0, handle_syscall
938c2ecf20Sopenharmony_ci	jirl    zero, t0, 0
948c2ecf20Sopenharmony_ciSYM_CODE_END(handle_sys)
95