xref: /titanic_41/usr/src/uts/sun4v/ml/mach_xc.s (revision 023e71de9e5670cebc23dd51162833661d3d2d3b)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*023e71deSHaik Aftandilian * Common Development and Distribution License (the "License").
6*023e71deSHaik Aftandilian * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate/*
22*023e71deSHaik Aftandilian * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate#if defined(lint)
277c478bd9Sstevel@tonic-gate#include <sys/types.h>
287c478bd9Sstevel@tonic-gate#include <sys/cpuvar.h>
297c478bd9Sstevel@tonic-gate#else	/*lint */
307c478bd9Sstevel@tonic-gate#include "assym.h"
317c478bd9Sstevel@tonic-gate#endif	/* lint */
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
347c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
357c478bd9Sstevel@tonic-gate#include <sys/x_call.h>
367c478bd9Sstevel@tonic-gate#include <sys/xc_impl.h>
377c478bd9Sstevel@tonic-gate#include <sys/machthread.h>
387c478bd9Sstevel@tonic-gate#include <sys/hypervisor_api.h>
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE
417c478bd9Sstevel@tonic-gate#include <sys/traptrace.h>
427c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gate
457c478bd9Sstevel@tonic-gate#if defined(lint)
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate/* ARGSUSED */
487c478bd9Sstevel@tonic-gatevoid
497c478bd9Sstevel@tonic-gateself_xcall(struct cpu *cpu, uint64_t arg1, uint64_t arg2, xcfunc_t *func)
507c478bd9Sstevel@tonic-gate{}
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate#else
537c478bd9Sstevel@tonic-gate
547c478bd9Sstevel@tonic-gate/*
557c478bd9Sstevel@tonic-gate * Entered by the software trap (TT=ST_SELFXCALL, TL>0) thru send_self_xcall().
567c478bd9Sstevel@tonic-gate * Emulate the mondo handler - vec_interrupt().
577c478bd9Sstevel@tonic-gate *
587c478bd9Sstevel@tonic-gate * Global registers are the Alternate Globals.
597c478bd9Sstevel@tonic-gate * Arguments:
607c478bd9Sstevel@tonic-gate * 	%o0 - CPU
617c478bd9Sstevel@tonic-gate * 	ILP32 kernel:
627c478bd9Sstevel@tonic-gate * 		%o5 - function to call
637c478bd9Sstevel@tonic-gate * 		%o1, %o2, %o3, %o4  - arguments
647c478bd9Sstevel@tonic-gate * 	LP64 kernel:
657c478bd9Sstevel@tonic-gate * 		%o3 - function to call
667c478bd9Sstevel@tonic-gate * 		%o1, %o2 - arguments
677c478bd9Sstevel@tonic-gate */
687c478bd9Sstevel@tonic-gate	ENTRY_NP(self_xcall)
697c478bd9Sstevel@tonic-gate	!
707c478bd9Sstevel@tonic-gate	! TL>0 handlers are expected to do "retry"
717c478bd9Sstevel@tonic-gate	! prepare their return PC and nPC now
727c478bd9Sstevel@tonic-gate	!
737c478bd9Sstevel@tonic-gate	rdpr	%tnpc, %g1
747c478bd9Sstevel@tonic-gate	wrpr	%g1, %tpc			!  PC <- TNPC[TL]
757c478bd9Sstevel@tonic-gate 	add	%g1, 4, %g1
767c478bd9Sstevel@tonic-gate	wrpr	%g1, %tnpc			! nPC <- TNPC[TL] + 4
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE
797c478bd9Sstevel@tonic-gate	TRACE_PTR(%g4, %g6)
80*023e71deSHaik Aftandilian	GET_TRACE_TICK(%g6, %g3)
817c478bd9Sstevel@tonic-gate	stxa	%g6, [%g4 + TRAP_ENT_TICK]%asi
827c478bd9Sstevel@tonic-gate	rdpr	%tl, %g6
837c478bd9Sstevel@tonic-gate	stha	%g6, [%g4 + TRAP_ENT_TL]%asi
847c478bd9Sstevel@tonic-gate	rdpr	%tt, %g6
857c478bd9Sstevel@tonic-gate	stha	%g6, [%g4 + TRAP_ENT_TT]%asi
867c478bd9Sstevel@tonic-gate	stna	%o3, [%g4 + TRAP_ENT_TR]%asi ! pc of the TL>0 handler
877c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g6
887c478bd9Sstevel@tonic-gate	stna	%g6, [%g4 + TRAP_ENT_TPC]%asi
897c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g6
907c478bd9Sstevel@tonic-gate	stxa	%g6, [%g4 + TRAP_ENT_TSTATE]%asi
917c478bd9Sstevel@tonic-gate	stna	%sp, [%g4 + TRAP_ENT_SP]%asi
927c478bd9Sstevel@tonic-gate	stna	%o1, [%g4 + TRAP_ENT_F1]%asi ! arg 1
937c478bd9Sstevel@tonic-gate	stna	%o2, [%g4 + TRAP_ENT_F2]%asi ! arg 2
947c478bd9Sstevel@tonic-gate	stna	%g0, [%g4 + TRAP_ENT_F3]%asi
957c478bd9Sstevel@tonic-gate	stna	%g0, [%g4 + TRAP_ENT_F4]%asi
967c478bd9Sstevel@tonic-gate	TRACE_NEXT(%g4, %g6, %g3)
977c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */
987c478bd9Sstevel@tonic-gate	!
997c478bd9Sstevel@tonic-gate	! Load the arguments for the fast trap handler.
1007c478bd9Sstevel@tonic-gate	!
1017c478bd9Sstevel@tonic-gate	mov	%o1, %g1
1027c478bd9Sstevel@tonic-gate	jmp	%o3				! call the fast trap handler
1037c478bd9Sstevel@tonic-gate	mov	%o2, %g2
1047c478bd9Sstevel@tonic-gate	/* Not Reached */
1057c478bd9Sstevel@tonic-gate	SET_SIZE(self_xcall)
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate#endif	/* lint */
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate#ifdef  TRAPTRACE
1107c478bd9Sstevel@tonic-gate#if defined(lint)
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate/* ARGSUSED */
1137c478bd9Sstevel@tonic-gatevoid
1147c478bd9Sstevel@tonic-gatexc_trace(u_int traptype, cpuset_t *cpu_set, xcfunc_t *func,
1157c478bd9Sstevel@tonic-gate	uint64_t arg1, uint64_t arg2)
1167c478bd9Sstevel@tonic-gate{}
1177c478bd9Sstevel@tonic-gate
1187c478bd9Sstevel@tonic-gate#else	/* lint */
1197c478bd9Sstevel@tonic-gate	ENTRY(xc_trace)
1207c478bd9Sstevel@tonic-gate	rdpr	%pstate, %g1
1217c478bd9Sstevel@tonic-gate	andn	%g1, PSTATE_IE | PSTATE_AM, %g2
1227c478bd9Sstevel@tonic-gate	wrpr	%g0, %g2, %pstate			/* disable interrupts */
1237c478bd9Sstevel@tonic-gate	TRACE_PTR(%g3, %g4)
124*023e71deSHaik Aftandilian	GET_TRACE_TICK(%g6, %g4)
1257c478bd9Sstevel@tonic-gate	stxa	%g6, [%g3 + TRAP_ENT_TICK]%asi
1267c478bd9Sstevel@tonic-gate	stha	%g0, [%g3 + TRAP_ENT_TL]%asi
1277c478bd9Sstevel@tonic-gate	set	TT_XCALL, %g2
1287c478bd9Sstevel@tonic-gate	or	%o0, %g2, %g4
1297c478bd9Sstevel@tonic-gate	stha	%g4, [%g3 + TRAP_ENT_TT]%asi
1307c478bd9Sstevel@tonic-gate	stna	%o7, [%g3 + TRAP_ENT_TPC]%asi
1317c478bd9Sstevel@tonic-gate	ldn	[%o1], %g2
1327c478bd9Sstevel@tonic-gate	stna	%g2, [%g3 + TRAP_ENT_SP]%asi		/* sp = cpuset */
1337c478bd9Sstevel@tonic-gate	stna	%o2, [%g3 + TRAP_ENT_TR]%asi		/* tr = func */
1347c478bd9Sstevel@tonic-gate	stna	%o3, [%g3 + TRAP_ENT_F1]%asi		/* f1 = arg1 */
1357c478bd9Sstevel@tonic-gate	stna	%o4, [%g3 + TRAP_ENT_F2]%asi		/* f2 = arg2 */
1367c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_F3]%asi		/* f3 = 0 */
1377c478bd9Sstevel@tonic-gate	stna	%i7, [%g3 + TRAP_ENT_F4]%asi		/* f4 = xcall caller */
1387c478bd9Sstevel@tonic-gate	stxa	%g1, [%g3 + TRAP_ENT_TSTATE]%asi	/* tstate = pstate */
1397c478bd9Sstevel@tonic-gate	TRACE_NEXT(%g2, %g3, %g4)
1407c478bd9Sstevel@tonic-gate/*
1417c478bd9Sstevel@tonic-gate * In the case of a cpuset of greater size than a long we
1427c478bd9Sstevel@tonic-gate * grab extra trace buffers just to store the cpuset.
1437c478bd9Sstevel@tonic-gate * Seems like a waste but popular opinion opted for this
1447c478bd9Sstevel@tonic-gate * rather than increase the size of the buffer.
1457c478bd9Sstevel@tonic-gate */
1467c478bd9Sstevel@tonic-gate#if CPUSET_SIZE > CLONGSIZE
1477c478bd9Sstevel@tonic-gate	add	%o1, CPUSET_SIZE, %g5			/* end of cpuset */
1487c478bd9Sstevel@tonic-gate	clr	%o2
1497c478bd9Sstevel@tonic-gate1:
1507c478bd9Sstevel@tonic-gate	TRACE_PTR(%g3, %g4)
1517c478bd9Sstevel@tonic-gate	stha	%g0, [%g3 + TRAP_ENT_TL]%asi
1527c478bd9Sstevel@tonic-gate	set	TT_XCALL_CONT, %g2
1537c478bd9Sstevel@tonic-gate	or	%g2, %o2, %g2				/* continuation # */
1547c478bd9Sstevel@tonic-gate	stha	%g2, [%g3 + TRAP_ENT_TT]%asi
1557c478bd9Sstevel@tonic-gate	stxa	%g6, [%g3 + TRAP_ENT_TICK]%asi		/* same tick */
1567c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_TPC]%asi		/* clr unused fields */
1577c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_SP]%asi
1587c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_TR]%asi
1597c478bd9Sstevel@tonic-gate	stxa	%g0, [%g3 + TRAP_ENT_TSTATE]%asi
1607c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_F2]%asi
1617c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_F3]%asi
1627c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_F4]%asi
1637c478bd9Sstevel@tonic-gate	ldn	[%o1], %g2
1647c478bd9Sstevel@tonic-gate	stna	%g2, [%g3 + TRAP_ENT_F1]%asi
1657c478bd9Sstevel@tonic-gate	add	%o1, CLONGSIZE, %o1
1667c478bd9Sstevel@tonic-gate	cmp	%o1, %g5
1677c478bd9Sstevel@tonic-gate	bge	2f
1687c478bd9Sstevel@tonic-gate	ldn	[%o1], %g2
1697c478bd9Sstevel@tonic-gate	stna	%g2, [%g3 + TRAP_ENT_F2]%asi
1707c478bd9Sstevel@tonic-gate	add	%o1, CLONGSIZE, %o1
1717c478bd9Sstevel@tonic-gate	cmp	%o1, %g5
1727c478bd9Sstevel@tonic-gate	bge	2f
1737c478bd9Sstevel@tonic-gate	ldn	[%o1], %g2
1747c478bd9Sstevel@tonic-gate	stna	%g2, [%g3 + TRAP_ENT_F3]%asi
1757c478bd9Sstevel@tonic-gate	add	%o1, CLONGSIZE, %o1
1767c478bd9Sstevel@tonic-gate	cmp	%o1, %g5
1777c478bd9Sstevel@tonic-gate	bge	2f
1787c478bd9Sstevel@tonic-gate	ldn	[%o1], %g2
1797c478bd9Sstevel@tonic-gate	stna	%g2, [%g3 + TRAP_ENT_F4]%asi
1807c478bd9Sstevel@tonic-gate	add	%o1, CLONGSIZE, %o1
1817c478bd9Sstevel@tonic-gate2:
1827c478bd9Sstevel@tonic-gate	TRACE_NEXT(%g2, %g3, %g4)
1837c478bd9Sstevel@tonic-gate	cmp	%o1, %g5
1847c478bd9Sstevel@tonic-gate	bl	1b
1857c478bd9Sstevel@tonic-gate	inc	%o2
1867c478bd9Sstevel@tonic-gate#endif	/* CPUSET_SIZE */
1877c478bd9Sstevel@tonic-gate	retl
1887c478bd9Sstevel@tonic-gate	wrpr	%g0, %g1, %pstate			/* enable interrupts */
1897c478bd9Sstevel@tonic-gate	SET_SIZE(xc_trace)
1907c478bd9Sstevel@tonic-gate
1917c478bd9Sstevel@tonic-gate#endif	/* lint */
1927c478bd9Sstevel@tonic-gate#endif	/* TRAPTRACE */
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate#if defined(lint)
1957c478bd9Sstevel@tonic-gate
1967c478bd9Sstevel@tonic-gate/*ARGSUSED*/
1977c478bd9Sstevel@tonic-gatevoid
1987c478bd9Sstevel@tonic-gateinit_mondo(xcfunc_t *func, uint64_t arg1, uint64_t arg2)
1997c478bd9Sstevel@tonic-gate{}
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate/*ARGSUSED*/
2027c478bd9Sstevel@tonic-gateint
2037c478bd9Sstevel@tonic-gateshipit(int n, uint64_t cpuid)
2047c478bd9Sstevel@tonic-gate{ return(0); }
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate#else	/* lint */
2077c478bd9Sstevel@tonic-gate/*
2087c478bd9Sstevel@tonic-gate * Setup interrupt dispatch data registers
2097c478bd9Sstevel@tonic-gate * Entry:
2107c478bd9Sstevel@tonic-gate *	%o0 - function or inumber to call
2117c478bd9Sstevel@tonic-gate *	%o1, %o2 - arguments (2 uint64_t's)
2127c478bd9Sstevel@tonic-gate */
2137c478bd9Sstevel@tonic-gate	ENTRY(init_mondo)
2147c478bd9Sstevel@tonic-gate	ALTENTRY(init_mondo_nocheck)
2157c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)			! load CPU struct addr
2167c478bd9Sstevel@tonic-gate	add	%g1, CPU_MCPU, %g1
2177c478bd9Sstevel@tonic-gate	ldx	[%g1 + MCPU_MONDO_DATA], %g1
2187c478bd9Sstevel@tonic-gate	stx	%o0, [%g1]
2197c478bd9Sstevel@tonic-gate	stx	%o1, [%g1+8]
2207c478bd9Sstevel@tonic-gate	stx	%o2, [%g1+0x10]
2217c478bd9Sstevel@tonic-gate	stx	%g0, [%g1+0x18]
2227c478bd9Sstevel@tonic-gate	stx	%g0, [%g1+0x20]
2237c478bd9Sstevel@tonic-gate	stx	%g0, [%g1+0x28]
2247c478bd9Sstevel@tonic-gate	stx	%g0, [%g1+0x30]
2257c478bd9Sstevel@tonic-gate	stx	%g0, [%g1+0x38]
2267c478bd9Sstevel@tonic-gate	retl
2277c478bd9Sstevel@tonic-gate	membar	#Sync			! allowed to be in the delay slot
2287c478bd9Sstevel@tonic-gate	SET_SIZE(init_mondo)
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate/*
2317c478bd9Sstevel@tonic-gate * Ship mondo to cpuid
2327c478bd9Sstevel@tonic-gate */
2337c478bd9Sstevel@tonic-gate	ENTRY_NP(shipit)
2347c478bd9Sstevel@tonic-gate	/* For now use dummy interface:  cpu# func arg1 arg2 */
2357c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)
2367c478bd9Sstevel@tonic-gate	add	%g1, CPU_MCPU, %g1
2377c478bd9Sstevel@tonic-gate	ldx	[%g1 + MCPU_MONDO_DATA_RA],	%o2
2387c478bd9Sstevel@tonic-gate	mov	HV_INTR_SEND, %o5
2397c478bd9Sstevel@tonic-gate	ta	FAST_TRAP
2407c478bd9Sstevel@tonic-gate	retl
2417c478bd9Sstevel@tonic-gate	membar	#Sync
2427c478bd9Sstevel@tonic-gate	SET_SIZE(shipit)
2437c478bd9Sstevel@tonic-gate
2447c478bd9Sstevel@tonic-gate#endif	/* lint */
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate#if defined(lint)
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate/*ARGSUSED*/
2497c478bd9Sstevel@tonic-gateuint64_t
2507c478bd9Sstevel@tonic-gateget_cpuaddr(uint64_t reg, uint64_t scr)
2517c478bd9Sstevel@tonic-gate{ return (0);}
2527c478bd9Sstevel@tonic-gate
2537c478bd9Sstevel@tonic-gate#else	/* lint */
2547c478bd9Sstevel@tonic-gate/*
2557c478bd9Sstevel@tonic-gate * Get cpu structure
2567c478bd9Sstevel@tonic-gate * Entry:
2577c478bd9Sstevel@tonic-gate *      %o0 - register for CPU_ADDR macro
2587c478bd9Sstevel@tonic-gate *      %o1 - scratch for CPU_ADDR macro
2597c478bd9Sstevel@tonic-gate */
2607c478bd9Sstevel@tonic-gate	ENTRY(get_cpuaddr)
2617c478bd9Sstevel@tonic-gate	CPU_ADDR(%o0, %o1)	! %o0 == CPU struct addr
2627c478bd9Sstevel@tonic-gate	retl
2637c478bd9Sstevel@tonic-gate	nop
2647c478bd9Sstevel@tonic-gate	SET_SIZE(get_cpuaddr)
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate#endif	/* lint */
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate#if defined(lint)
2697c478bd9Sstevel@tonic-gate/* ARGSUSED */
2707c478bd9Sstevel@tonic-gatevoid
2717c478bd9Sstevel@tonic-gatext_sync_tl1(uint64_t *cpu_sync_addr)
2727c478bd9Sstevel@tonic-gate{}
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate#else /* lint */
2757c478bd9Sstevel@tonic-gate/*
2767c478bd9Sstevel@tonic-gate * This is to ensure that previously called xtrap handlers have executed on
2777c478bd9Sstevel@tonic-gate * sun4v. We zero out the byte corresponding to its cpuid in the
2787c478bd9Sstevel@tonic-gate * array passed to us from xt_sync(), so the sender knows the previous
2797c478bd9Sstevel@tonic-gate * mondo has been executed.
2807c478bd9Sstevel@tonic-gate * Register:
2817c478bd9Sstevel@tonic-gate *		%g1 - Addr of the cpu_sync array.
2827c478bd9Sstevel@tonic-gate */
2837c478bd9Sstevel@tonic-gate	ENTRY_NP(xt_sync_tl1)
2847c478bd9Sstevel@tonic-gate	CPU_INDEX(%g3, %g4)		/* %g3 = cpu id */
2857c478bd9Sstevel@tonic-gate	stb	%g0, [%g1 + %g3]
2867c478bd9Sstevel@tonic-gate	retry
2877c478bd9Sstevel@tonic-gate	SET_SIZE(xt_sync_tl1)
2887c478bd9Sstevel@tonic-gate
2897c478bd9Sstevel@tonic-gate#endif  /* lint */
290