18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * rtrap.S: Preparing for return from trap on Sparc V9.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
68c2ecf20Sopenharmony_ci * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <asm/asi.h>
118c2ecf20Sopenharmony_ci#include <asm/pstate.h>
128c2ecf20Sopenharmony_ci#include <asm/ptrace.h>
138c2ecf20Sopenharmony_ci#include <asm/spitfire.h>
148c2ecf20Sopenharmony_ci#include <asm/head.h>
158c2ecf20Sopenharmony_ci#include <asm/visasm.h>
168c2ecf20Sopenharmony_ci#include <asm/processor.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#ifdef CONFIG_CONTEXT_TRACKING
198c2ecf20Sopenharmony_ci# define SCHEDULE_USER schedule_user
208c2ecf20Sopenharmony_ci#else
218c2ecf20Sopenharmony_ci# define SCHEDULE_USER schedule
228c2ecf20Sopenharmony_ci#endif
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci		.text
258c2ecf20Sopenharmony_ci		.align			32
268c2ecf20Sopenharmony_ci__handle_preemption:
278c2ecf20Sopenharmony_ci		call			SCHEDULE_USER
288c2ecf20Sopenharmony_ci661:		 wrpr			%g0, RTRAP_PSTATE, %pstate
298c2ecf20Sopenharmony_ci		/* If userspace is using ADI, it could potentially pass
308c2ecf20Sopenharmony_ci		 * a pointer with version tag embedded in it. To maintain
318c2ecf20Sopenharmony_ci		 * the ADI security, we must re-enable PSTATE.mcde before
328c2ecf20Sopenharmony_ci		 * we continue execution in the kernel for another thread.
338c2ecf20Sopenharmony_ci		 */
348c2ecf20Sopenharmony_ci		.section .sun_m7_1insn_patch, "ax"
358c2ecf20Sopenharmony_ci		.word	661b
368c2ecf20Sopenharmony_ci		 wrpr			%g0, RTRAP_PSTATE|PSTATE_MCDE, %pstate
378c2ecf20Sopenharmony_ci		.previous
388c2ecf20Sopenharmony_ci		ba,pt			%xcc, __handle_preemption_continue
398c2ecf20Sopenharmony_ci		 wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci__handle_user_windows:
428c2ecf20Sopenharmony_ci		add			%sp, PTREGS_OFF, %o0
438c2ecf20Sopenharmony_ci		call			fault_in_user_windows
448c2ecf20Sopenharmony_ci661:		 wrpr			%g0, RTRAP_PSTATE, %pstate
458c2ecf20Sopenharmony_ci		/* If userspace is using ADI, it could potentially pass
468c2ecf20Sopenharmony_ci		 * a pointer with version tag embedded in it. To maintain
478c2ecf20Sopenharmony_ci		 * the ADI security, we must re-enable PSTATE.mcde before
488c2ecf20Sopenharmony_ci		 * we continue execution in the kernel for another thread.
498c2ecf20Sopenharmony_ci		 */
508c2ecf20Sopenharmony_ci		.section .sun_m7_1insn_patch, "ax"
518c2ecf20Sopenharmony_ci		.word	661b
528c2ecf20Sopenharmony_ci		 wrpr			%g0, RTRAP_PSTATE|PSTATE_MCDE, %pstate
538c2ecf20Sopenharmony_ci		.previous
548c2ecf20Sopenharmony_ci		ba,pt			%xcc, __handle_preemption_continue
558c2ecf20Sopenharmony_ci		 wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci__handle_userfpu:
588c2ecf20Sopenharmony_ci		rd			%fprs, %l5
598c2ecf20Sopenharmony_ci		andcc			%l5, FPRS_FEF, %g0
608c2ecf20Sopenharmony_ci		sethi			%hi(TSTATE_PEF), %o0
618c2ecf20Sopenharmony_ci		be,a,pn			%icc, __handle_userfpu_continue
628c2ecf20Sopenharmony_ci		 andn			%l1, %o0, %l1
638c2ecf20Sopenharmony_ci		ba,a,pt			%xcc, __handle_userfpu_continue
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci__handle_signal:
668c2ecf20Sopenharmony_ci		mov			%l5, %o1
678c2ecf20Sopenharmony_ci		add			%sp, PTREGS_OFF, %o0
688c2ecf20Sopenharmony_ci		mov			%l0, %o2
698c2ecf20Sopenharmony_ci		call			do_notify_resume
708c2ecf20Sopenharmony_ci661:		 wrpr			%g0, RTRAP_PSTATE, %pstate
718c2ecf20Sopenharmony_ci		/* If userspace is using ADI, it could potentially pass
728c2ecf20Sopenharmony_ci		 * a pointer with version tag embedded in it. To maintain
738c2ecf20Sopenharmony_ci		 * the ADI security, we must re-enable PSTATE.mcde before
748c2ecf20Sopenharmony_ci		 * we continue execution in the kernel for another thread.
758c2ecf20Sopenharmony_ci		 */
768c2ecf20Sopenharmony_ci		.section .sun_m7_1insn_patch, "ax"
778c2ecf20Sopenharmony_ci		.word	661b
788c2ecf20Sopenharmony_ci		 wrpr			%g0, RTRAP_PSTATE|PSTATE_MCDE, %pstate
798c2ecf20Sopenharmony_ci		.previous
808c2ecf20Sopenharmony_ci		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci		/* Signal delivery can modify pt_regs tstate, so we must
838c2ecf20Sopenharmony_ci		 * reload it.
848c2ecf20Sopenharmony_ci		 */
858c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
868c2ecf20Sopenharmony_ci		sethi			%hi(0xf << 20), %l4
878c2ecf20Sopenharmony_ci		and			%l1, %l4, %l4
888c2ecf20Sopenharmony_ci		andn			%l1, %l4, %l1
898c2ecf20Sopenharmony_ci		ba,pt			%xcc, __handle_preemption_continue
908c2ecf20Sopenharmony_ci		 srl			%l4, 20, %l4
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci		/* When returning from a NMI (%pil==15) interrupt we want to
938c2ecf20Sopenharmony_ci		 * avoid running softirqs, doing IRQ tracing, preempting, etc.
948c2ecf20Sopenharmony_ci		 */
958c2ecf20Sopenharmony_ci		.globl			rtrap_nmi
968c2ecf20Sopenharmony_cirtrap_nmi:	ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
978c2ecf20Sopenharmony_ci		sethi			%hi(0xf << 20), %l4
988c2ecf20Sopenharmony_ci		and			%l1, %l4, %l4
998c2ecf20Sopenharmony_ci		andn			%l1, %l4, %l1
1008c2ecf20Sopenharmony_ci		srl			%l4, 20, %l4
1018c2ecf20Sopenharmony_ci		ba,pt			%xcc, rtrap_no_irq_enable
1028c2ecf20Sopenharmony_ci		nop
1038c2ecf20Sopenharmony_ci		/* Do not actually set the %pil here.  We will do that
1048c2ecf20Sopenharmony_ci		 * below after we clear PSTATE_IE in the %pstate register.
1058c2ecf20Sopenharmony_ci		 * If we re-enable interrupts here, we can recurse down
1068c2ecf20Sopenharmony_ci		 * the hardirq stack potentially endlessly, causing a
1078c2ecf20Sopenharmony_ci		 * stack overflow.
1088c2ecf20Sopenharmony_ci		 */
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci		.align			64
1118c2ecf20Sopenharmony_ci		.globl			rtrap_irq, rtrap, irqsz_patchme, rtrap_xcall
1128c2ecf20Sopenharmony_cirtrap_irq:
1138c2ecf20Sopenharmony_cirtrap:
1148c2ecf20Sopenharmony_ci		/* mm/ultra.S:xcall_report_regs KNOWS about this load. */
1158c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
1168c2ecf20Sopenharmony_cirtrap_xcall:
1178c2ecf20Sopenharmony_ci		sethi			%hi(0xf << 20), %l4
1188c2ecf20Sopenharmony_ci		and			%l1, %l4, %l4
1198c2ecf20Sopenharmony_ci		andn			%l1, %l4, %l1
1208c2ecf20Sopenharmony_ci		srl			%l4, 20, %l4
1218c2ecf20Sopenharmony_ci#ifdef CONFIG_TRACE_IRQFLAGS
1228c2ecf20Sopenharmony_ci		brnz,pn			%l4, rtrap_no_irq_enable
1238c2ecf20Sopenharmony_ci		 nop
1248c2ecf20Sopenharmony_ci		call			trace_hardirqs_on
1258c2ecf20Sopenharmony_ci		 nop
1268c2ecf20Sopenharmony_ci		/* Do not actually set the %pil here.  We will do that
1278c2ecf20Sopenharmony_ci		 * below after we clear PSTATE_IE in the %pstate register.
1288c2ecf20Sopenharmony_ci		 * If we re-enable interrupts here, we can recurse down
1298c2ecf20Sopenharmony_ci		 * the hardirq stack potentially endlessly, causing a
1308c2ecf20Sopenharmony_ci		 * stack overflow.
1318c2ecf20Sopenharmony_ci		 *
1328c2ecf20Sopenharmony_ci		 * It is tempting to put this test and trace_hardirqs_on
1338c2ecf20Sopenharmony_ci		 * call at the 'rt_continue' label, but that will not work
1348c2ecf20Sopenharmony_ci		 * as that path hits unconditionally and we do not want to
1358c2ecf20Sopenharmony_ci		 * execute this in NMI return paths, for example.
1368c2ecf20Sopenharmony_ci		 */
1378c2ecf20Sopenharmony_ci#endif
1388c2ecf20Sopenharmony_cirtrap_no_irq_enable:
1398c2ecf20Sopenharmony_ci		andcc			%l1, TSTATE_PRIV, %l3
1408c2ecf20Sopenharmony_ci		bne,pn			%icc, to_kernel
1418c2ecf20Sopenharmony_ci		 nop
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci		/* We must hold IRQs off and atomically test schedule+signal
1448c2ecf20Sopenharmony_ci		 * state, then hold them off all the way back to userspace.
1458c2ecf20Sopenharmony_ci		 * If we are returning to kernel, none of this matters.  Note
1468c2ecf20Sopenharmony_ci		 * that we are disabling interrupts via PSTATE_IE, not using
1478c2ecf20Sopenharmony_ci		 * %pil.
1488c2ecf20Sopenharmony_ci		 *
1498c2ecf20Sopenharmony_ci		 * If we do not do this, there is a window where we would do
1508c2ecf20Sopenharmony_ci		 * the tests, later the signal/resched event arrives but we do
1518c2ecf20Sopenharmony_ci		 * not process it since we are still in kernel mode.  It would
1528c2ecf20Sopenharmony_ci		 * take until the next local IRQ before the signal/resched
1538c2ecf20Sopenharmony_ci		 * event would be handled.
1548c2ecf20Sopenharmony_ci		 *
1558c2ecf20Sopenharmony_ci		 * This also means that if we have to deal with user
1568c2ecf20Sopenharmony_ci		 * windows, we have to redo all of these sched+signal checks
1578c2ecf20Sopenharmony_ci		 * with IRQs disabled.
1588c2ecf20Sopenharmony_ci		 */
1598c2ecf20Sopenharmony_cito_user:	wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
1608c2ecf20Sopenharmony_ci		wrpr			0, %pil
1618c2ecf20Sopenharmony_ci__handle_preemption_continue:
1628c2ecf20Sopenharmony_ci		ldx			[%g6 + TI_FLAGS], %l0
1638c2ecf20Sopenharmony_ci		sethi			%hi(_TIF_USER_WORK_MASK), %o0
1648c2ecf20Sopenharmony_ci		or			%o0, %lo(_TIF_USER_WORK_MASK), %o0
1658c2ecf20Sopenharmony_ci		andcc			%l0, %o0, %g0
1668c2ecf20Sopenharmony_ci		sethi			%hi(TSTATE_PEF), %o0
1678c2ecf20Sopenharmony_ci		be,pt			%xcc, user_nowork
1688c2ecf20Sopenharmony_ci		 andcc			%l1, %o0, %g0
1698c2ecf20Sopenharmony_ci		andcc			%l0, _TIF_NEED_RESCHED, %g0
1708c2ecf20Sopenharmony_ci		bne,pn			%xcc, __handle_preemption
1718c2ecf20Sopenharmony_ci		 andcc			%l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
1728c2ecf20Sopenharmony_ci		bne,pn			%xcc, __handle_signal
1738c2ecf20Sopenharmony_ci		 ldub			[%g6 + TI_WSAVED], %o2
1748c2ecf20Sopenharmony_ci		brnz,pn			%o2, __handle_user_windows
1758c2ecf20Sopenharmony_ci		 nop
1768c2ecf20Sopenharmony_ci		sethi			%hi(TSTATE_PEF), %o0
1778c2ecf20Sopenharmony_ci		andcc			%l1, %o0, %g0
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci		/* This fpdepth clear is necessary for non-syscall rtraps only */
1808c2ecf20Sopenharmony_ciuser_nowork:
1818c2ecf20Sopenharmony_ci		bne,pn			%xcc, __handle_userfpu
1828c2ecf20Sopenharmony_ci		 stb			%g0, [%g6 + TI_FPDEPTH]
1838c2ecf20Sopenharmony_ci__handle_userfpu_continue:
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_cirt_continue:	ldx			[%sp + PTREGS_OFF + PT_V9_G1], %g1
1868c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_G2], %g2
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_G3], %g3
1898c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_G4], %g4
1908c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_G5], %g5
1918c2ecf20Sopenharmony_ci		brz,pt			%l3, 1f
1928c2ecf20Sopenharmony_ci		mov			%g6, %l2
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci		/* Must do this before thread reg is clobbered below.  */
1958c2ecf20Sopenharmony_ci		LOAD_PER_CPU_BASE(%g5, %g6, %i0, %i1, %i2)
1968c2ecf20Sopenharmony_ci1:
1978c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_G6], %g6
1988c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_G7], %g7
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci		/* Normal globals are restored, go to trap globals.  */
2018c2ecf20Sopenharmony_ci661:		wrpr			%g0, RTRAP_PSTATE_AG_IRQOFF, %pstate
2028c2ecf20Sopenharmony_ci		nop
2038c2ecf20Sopenharmony_ci		.section		.sun4v_2insn_patch, "ax"
2048c2ecf20Sopenharmony_ci		.word			661b
2058c2ecf20Sopenharmony_ci		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
2068c2ecf20Sopenharmony_ci		SET_GL(1)
2078c2ecf20Sopenharmony_ci		.previous
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci		mov			%l2, %g6
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_I0], %i0
2128c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_I1], %i1
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_I2], %i2
2158c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_I3], %i3
2168c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_I4], %i4
2178c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_I5], %i5
2188c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_I6], %i6
2198c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_I7], %i7
2208c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_TPC], %l2
2218c2ecf20Sopenharmony_ci		ldx			[%sp + PTREGS_OFF + PT_V9_TNPC], %o2
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci		ld			[%sp + PTREGS_OFF + PT_V9_Y], %o3
2248c2ecf20Sopenharmony_ci		wr			%o3, %g0, %y
2258c2ecf20Sopenharmony_ci		wrpr			%l4, 0x0, %pil
2268c2ecf20Sopenharmony_ci		wrpr			%g0, 0x1, %tl
2278c2ecf20Sopenharmony_ci		andn			%l1, TSTATE_SYSCALL, %l1
2288c2ecf20Sopenharmony_ci		wrpr			%l1, %g0, %tstate
2298c2ecf20Sopenharmony_ci		wrpr			%l2, %g0, %tpc
2308c2ecf20Sopenharmony_ci		wrpr			%o2, %g0, %tnpc
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci		brnz,pn			%l3, kern_rtt
2338c2ecf20Sopenharmony_ci		 mov			PRIMARY_CONTEXT, %l7
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci661:		ldxa			[%l7 + %l7] ASI_DMMU, %l0
2368c2ecf20Sopenharmony_ci		.section		.sun4v_1insn_patch, "ax"
2378c2ecf20Sopenharmony_ci		.word			661b
2388c2ecf20Sopenharmony_ci		ldxa			[%l7 + %l7] ASI_MMU, %l0
2398c2ecf20Sopenharmony_ci		.previous
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci		sethi			%hi(sparc64_kern_pri_nuc_bits), %l1
2428c2ecf20Sopenharmony_ci		ldx			[%l1 + %lo(sparc64_kern_pri_nuc_bits)], %l1
2438c2ecf20Sopenharmony_ci		or			%l0, %l1, %l0
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci661:		stxa			%l0, [%l7] ASI_DMMU
2468c2ecf20Sopenharmony_ci		.section		.sun4v_1insn_patch, "ax"
2478c2ecf20Sopenharmony_ci		.word			661b
2488c2ecf20Sopenharmony_ci		stxa			%l0, [%l7] ASI_MMU
2498c2ecf20Sopenharmony_ci		.previous
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci		sethi			%hi(KERNBASE), %l7
2528c2ecf20Sopenharmony_ci		flush			%l7
2538c2ecf20Sopenharmony_ci		rdpr			%wstate, %l1
2548c2ecf20Sopenharmony_ci		rdpr			%otherwin, %l2
2558c2ecf20Sopenharmony_ci		srl			%l1, 3, %l1
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ci661:		wrpr			%l2, %g0, %canrestore
2588c2ecf20Sopenharmony_ci		.section		.fast_win_ctrl_1insn_patch, "ax"
2598c2ecf20Sopenharmony_ci		.word			661b
2608c2ecf20Sopenharmony_ci		.word			0x89880000	! normalw
2618c2ecf20Sopenharmony_ci		.previous
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci		wrpr			%l1, %g0, %wstate
2648c2ecf20Sopenharmony_ci		brnz,pt			%l2, user_rtt_restore
2658c2ecf20Sopenharmony_ci661:		 wrpr			%g0, %g0, %otherwin
2668c2ecf20Sopenharmony_ci		.section		.fast_win_ctrl_1insn_patch, "ax"
2678c2ecf20Sopenharmony_ci		.word			661b
2688c2ecf20Sopenharmony_ci		 nop
2698c2ecf20Sopenharmony_ci		.previous
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci		ldx			[%g6 + TI_FLAGS], %g3
2728c2ecf20Sopenharmony_ci		wr			%g0, ASI_AIUP, %asi
2738c2ecf20Sopenharmony_ci		rdpr			%cwp, %g1
2748c2ecf20Sopenharmony_ci		andcc			%g3, _TIF_32BIT, %g0
2758c2ecf20Sopenharmony_ci		sub			%g1, 1, %g1
2768c2ecf20Sopenharmony_ci		bne,pt			%xcc, user_rtt_fill_32bit
2778c2ecf20Sopenharmony_ci		 wrpr			%g1, %cwp
2788c2ecf20Sopenharmony_ci		ba,a,pt			%xcc, user_rtt_fill_64bit
2798c2ecf20Sopenharmony_ci		 nop
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ciuser_rtt_fill_fixup_dax:
2828c2ecf20Sopenharmony_ci		ba,pt	%xcc, user_rtt_fill_fixup_common
2838c2ecf20Sopenharmony_ci		 mov	1, %g3
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ciuser_rtt_fill_fixup_mna:
2868c2ecf20Sopenharmony_ci		ba,pt	%xcc, user_rtt_fill_fixup_common
2878c2ecf20Sopenharmony_ci		 mov	2, %g3
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ciuser_rtt_fill_fixup:
2908c2ecf20Sopenharmony_ci		ba,pt	%xcc, user_rtt_fill_fixup_common
2918c2ecf20Sopenharmony_ci		 clr	%g3
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ciuser_rtt_pre_restore:
2948c2ecf20Sopenharmony_ci		add			%g1, 1, %g1
2958c2ecf20Sopenharmony_ci		wrpr			%g1, 0x0, %cwp
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ciuser_rtt_restore:
2988c2ecf20Sopenharmony_ci		restore
2998c2ecf20Sopenharmony_ci		rdpr			%canrestore, %g1
3008c2ecf20Sopenharmony_ci		wrpr			%g1, 0x0, %cleanwin
3018c2ecf20Sopenharmony_ci		retry
3028c2ecf20Sopenharmony_ci		nop
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_cikern_rtt:	rdpr			%canrestore, %g1
3058c2ecf20Sopenharmony_ci		brz,pn			%g1, kern_rtt_fill
3068c2ecf20Sopenharmony_ci		 nop
3078c2ecf20Sopenharmony_cikern_rtt_restore:
3088c2ecf20Sopenharmony_ci		stw			%g0, [%sp + PTREGS_OFF + PT_V9_MAGIC]
3098c2ecf20Sopenharmony_ci		restore
3108c2ecf20Sopenharmony_ci		retry
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_cito_kernel:
3138c2ecf20Sopenharmony_ci#ifdef CONFIG_PREEMPTION
3148c2ecf20Sopenharmony_ci		ldsw			[%g6 + TI_PRE_COUNT], %l5
3158c2ecf20Sopenharmony_ci		brnz			%l5, kern_fpucheck
3168c2ecf20Sopenharmony_ci		 ldx			[%g6 + TI_FLAGS], %l5
3178c2ecf20Sopenharmony_ci		andcc			%l5, _TIF_NEED_RESCHED, %g0
3188c2ecf20Sopenharmony_ci		be,pt			%xcc, kern_fpucheck
3198c2ecf20Sopenharmony_ci		 nop
3208c2ecf20Sopenharmony_ci		cmp			%l4, 0
3218c2ecf20Sopenharmony_ci		bne,pn			%xcc, kern_fpucheck
3228c2ecf20Sopenharmony_ci		 nop
3238c2ecf20Sopenharmony_ci		call			preempt_schedule_irq
3248c2ecf20Sopenharmony_ci		 nop
3258c2ecf20Sopenharmony_ci		ba,pt			%xcc, rtrap
3268c2ecf20Sopenharmony_ci#endif
3278c2ecf20Sopenharmony_cikern_fpucheck:	ldub			[%g6 + TI_FPDEPTH], %l5
3288c2ecf20Sopenharmony_ci		brz,pt			%l5, rt_continue
3298c2ecf20Sopenharmony_ci		 srl			%l5, 1, %o0
3308c2ecf20Sopenharmony_ci		add			%g6, TI_FPSAVED, %l6
3318c2ecf20Sopenharmony_ci		ldub			[%l6 + %o0], %l2
3328c2ecf20Sopenharmony_ci		sub			%l5, 2, %l5
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci		add			%g6, TI_GSR, %o1
3358c2ecf20Sopenharmony_ci		andcc			%l2, (FPRS_FEF|FPRS_DU), %g0
3368c2ecf20Sopenharmony_ci		be,pt			%icc, 2f
3378c2ecf20Sopenharmony_ci		 and			%l2, FPRS_DL, %l6
3388c2ecf20Sopenharmony_ci		andcc			%l2, FPRS_FEF, %g0
3398c2ecf20Sopenharmony_ci		be,pn			%icc, 5f
3408c2ecf20Sopenharmony_ci		 sll			%o0, 3, %o5
3418c2ecf20Sopenharmony_ci		rd			%fprs, %g1
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ci		wr			%g1, FPRS_FEF, %fprs
3448c2ecf20Sopenharmony_ci		ldx			[%o1 + %o5], %g1
3458c2ecf20Sopenharmony_ci		add			%g6, TI_XFSR, %o1
3468c2ecf20Sopenharmony_ci		sll			%o0, 8, %o2
3478c2ecf20Sopenharmony_ci		add			%g6, TI_FPREGS, %o3
3488c2ecf20Sopenharmony_ci		brz,pn			%l6, 1f
3498c2ecf20Sopenharmony_ci		 add			%g6, TI_FPREGS+0x40, %o4
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci		membar			#Sync
3528c2ecf20Sopenharmony_ci		ldda			[%o3 + %o2] ASI_BLK_P, %f0
3538c2ecf20Sopenharmony_ci		ldda			[%o4 + %o2] ASI_BLK_P, %f16
3548c2ecf20Sopenharmony_ci		membar			#Sync
3558c2ecf20Sopenharmony_ci1:		andcc			%l2, FPRS_DU, %g0
3568c2ecf20Sopenharmony_ci		be,pn			%icc, 1f
3578c2ecf20Sopenharmony_ci		 wr			%g1, 0, %gsr
3588c2ecf20Sopenharmony_ci		add			%o2, 0x80, %o2
3598c2ecf20Sopenharmony_ci		membar			#Sync
3608c2ecf20Sopenharmony_ci		ldda			[%o3 + %o2] ASI_BLK_P, %f32
3618c2ecf20Sopenharmony_ci		ldda			[%o4 + %o2] ASI_BLK_P, %f48
3628c2ecf20Sopenharmony_ci1:		membar			#Sync
3638c2ecf20Sopenharmony_ci		ldx			[%o1 + %o5], %fsr
3648c2ecf20Sopenharmony_ci2:		stb			%l5, [%g6 + TI_FPDEPTH]
3658c2ecf20Sopenharmony_ci		ba,pt			%xcc, rt_continue
3668c2ecf20Sopenharmony_ci		 nop
3678c2ecf20Sopenharmony_ci5:		wr			%g0, FPRS_FEF, %fprs
3688c2ecf20Sopenharmony_ci		sll			%o0, 8, %o2
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci		add			%g6, TI_FPREGS+0x80, %o3
3718c2ecf20Sopenharmony_ci		add			%g6, TI_FPREGS+0xc0, %o4
3728c2ecf20Sopenharmony_ci		membar			#Sync
3738c2ecf20Sopenharmony_ci		ldda			[%o3 + %o2] ASI_BLK_P, %f32
3748c2ecf20Sopenharmony_ci		ldda			[%o4 + %o2] ASI_BLK_P, %f48
3758c2ecf20Sopenharmony_ci		membar			#Sync
3768c2ecf20Sopenharmony_ci		wr			%g0, FPRS_DU, %fprs
3778c2ecf20Sopenharmony_ci		ba,pt			%xcc, rt_continue
3788c2ecf20Sopenharmony_ci		 stb			%l5, [%g6 + TI_FPDEPTH]
379