xref: /illumos-gate/usr/src/uts/sun4v/ml/mach_xc.S (revision 55fea89d)
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
5023e71deSHaik Aftandilian * Common Development and Distribution License (the "License").
6023e71deSHaik 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/*
22023e71deSHaik 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#include "assym.h"
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
297c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
307c478bd9Sstevel@tonic-gate#include <sys/x_call.h>
317c478bd9Sstevel@tonic-gate#include <sys/xc_impl.h>
327c478bd9Sstevel@tonic-gate#include <sys/machthread.h>
337c478bd9Sstevel@tonic-gate#include <sys/hypervisor_api.h>
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE
367c478bd9Sstevel@tonic-gate#include <sys/traptrace.h>
377c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate/*
417c478bd9Sstevel@tonic-gate * Entered by the software trap (TT=ST_SELFXCALL, TL>0) thru send_self_xcall().
427c478bd9Sstevel@tonic-gate * Emulate the mondo handler - vec_interrupt().
437c478bd9Sstevel@tonic-gate *
447c478bd9Sstevel@tonic-gate * Global registers are the Alternate Globals.
457c478bd9Sstevel@tonic-gate * Arguments:
467c478bd9Sstevel@tonic-gate * 	%o0 - CPU
477c478bd9Sstevel@tonic-gate * 	ILP32 kernel:
487c478bd9Sstevel@tonic-gate * 		%o5 - function to call
497c478bd9Sstevel@tonic-gate * 		%o1, %o2, %o3, %o4  - arguments
507c478bd9Sstevel@tonic-gate * 	LP64 kernel:
517c478bd9Sstevel@tonic-gate * 		%o3 - function to call
527c478bd9Sstevel@tonic-gate * 		%o1, %o2 - arguments
537c478bd9Sstevel@tonic-gate */
547c478bd9Sstevel@tonic-gate	ENTRY_NP(self_xcall)
557c478bd9Sstevel@tonic-gate	!
567c478bd9Sstevel@tonic-gate	! TL>0 handlers are expected to do "retry"
577c478bd9Sstevel@tonic-gate	! prepare their return PC and nPC now
587c478bd9Sstevel@tonic-gate	!
597c478bd9Sstevel@tonic-gate	rdpr	%tnpc, %g1
607c478bd9Sstevel@tonic-gate	wrpr	%g1, %tpc			!  PC <- TNPC[TL]
617c478bd9Sstevel@tonic-gate 	add	%g1, 4, %g1
627c478bd9Sstevel@tonic-gate	wrpr	%g1, %tnpc			! nPC <- TNPC[TL] + 4
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE
657c478bd9Sstevel@tonic-gate	TRACE_PTR(%g4, %g6)
66023e71deSHaik Aftandilian	GET_TRACE_TICK(%g6, %g3)
677c478bd9Sstevel@tonic-gate	stxa	%g6, [%g4 + TRAP_ENT_TICK]%asi
687c478bd9Sstevel@tonic-gate	rdpr	%tl, %g6
697c478bd9Sstevel@tonic-gate	stha	%g6, [%g4 + TRAP_ENT_TL]%asi
707c478bd9Sstevel@tonic-gate	rdpr	%tt, %g6
717c478bd9Sstevel@tonic-gate	stha	%g6, [%g4 + TRAP_ENT_TT]%asi
727c478bd9Sstevel@tonic-gate	stna	%o3, [%g4 + TRAP_ENT_TR]%asi ! pc of the TL>0 handler
737c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g6
747c478bd9Sstevel@tonic-gate	stna	%g6, [%g4 + TRAP_ENT_TPC]%asi
757c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g6
767c478bd9Sstevel@tonic-gate	stxa	%g6, [%g4 + TRAP_ENT_TSTATE]%asi
777c478bd9Sstevel@tonic-gate	stna	%sp, [%g4 + TRAP_ENT_SP]%asi
787c478bd9Sstevel@tonic-gate	stna	%o1, [%g4 + TRAP_ENT_F1]%asi ! arg 1
797c478bd9Sstevel@tonic-gate	stna	%o2, [%g4 + TRAP_ENT_F2]%asi ! arg 2
807c478bd9Sstevel@tonic-gate	stna	%g0, [%g4 + TRAP_ENT_F3]%asi
817c478bd9Sstevel@tonic-gate	stna	%g0, [%g4 + TRAP_ENT_F4]%asi
827c478bd9Sstevel@tonic-gate	TRACE_NEXT(%g4, %g6, %g3)
837c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */
847c478bd9Sstevel@tonic-gate	!
857c478bd9Sstevel@tonic-gate	! Load the arguments for the fast trap handler.
867c478bd9Sstevel@tonic-gate	!
877c478bd9Sstevel@tonic-gate	mov	%o1, %g1
887c478bd9Sstevel@tonic-gate	jmp	%o3				! call the fast trap handler
897c478bd9Sstevel@tonic-gate	mov	%o2, %g2
907c478bd9Sstevel@tonic-gate	/* Not Reached */
917c478bd9Sstevel@tonic-gate	SET_SIZE(self_xcall)
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate#ifdef  TRAPTRACE
947c478bd9Sstevel@tonic-gate	ENTRY(xc_trace)
957c478bd9Sstevel@tonic-gate	rdpr	%pstate, %g1
967c478bd9Sstevel@tonic-gate	andn	%g1, PSTATE_IE | PSTATE_AM, %g2
977c478bd9Sstevel@tonic-gate	wrpr	%g0, %g2, %pstate			/* disable interrupts */
987c478bd9Sstevel@tonic-gate	TRACE_PTR(%g3, %g4)
99023e71deSHaik Aftandilian	GET_TRACE_TICK(%g6, %g4)
1007c478bd9Sstevel@tonic-gate	stxa	%g6, [%g3 + TRAP_ENT_TICK]%asi
1017c478bd9Sstevel@tonic-gate	stha	%g0, [%g3 + TRAP_ENT_TL]%asi
1027c478bd9Sstevel@tonic-gate	set	TT_XCALL, %g2
1037c478bd9Sstevel@tonic-gate	or	%o0, %g2, %g4
1047c478bd9Sstevel@tonic-gate	stha	%g4, [%g3 + TRAP_ENT_TT]%asi
1057c478bd9Sstevel@tonic-gate	stna	%o7, [%g3 + TRAP_ENT_TPC]%asi
1067c478bd9Sstevel@tonic-gate	ldn	[%o1], %g2
1077c478bd9Sstevel@tonic-gate	stna	%g2, [%g3 + TRAP_ENT_SP]%asi		/* sp = cpuset */
1087c478bd9Sstevel@tonic-gate	stna	%o2, [%g3 + TRAP_ENT_TR]%asi		/* tr = func */
1097c478bd9Sstevel@tonic-gate	stna	%o3, [%g3 + TRAP_ENT_F1]%asi		/* f1 = arg1 */
1107c478bd9Sstevel@tonic-gate	stna	%o4, [%g3 + TRAP_ENT_F2]%asi		/* f2 = arg2 */
1117c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_F3]%asi		/* f3 = 0 */
1127c478bd9Sstevel@tonic-gate	stna	%i7, [%g3 + TRAP_ENT_F4]%asi		/* f4 = xcall caller */
1137c478bd9Sstevel@tonic-gate	stxa	%g1, [%g3 + TRAP_ENT_TSTATE]%asi	/* tstate = pstate */
1147c478bd9Sstevel@tonic-gate	TRACE_NEXT(%g2, %g3, %g4)
1157c478bd9Sstevel@tonic-gate/*
1167c478bd9Sstevel@tonic-gate * In the case of a cpuset of greater size than a long we
1177c478bd9Sstevel@tonic-gate * grab extra trace buffers just to store the cpuset.
118*55fea89dSDan Cross * Seems like a waste but popular opinion opted for this
1197c478bd9Sstevel@tonic-gate * rather than increase the size of the buffer.
1207c478bd9Sstevel@tonic-gate */
1217c478bd9Sstevel@tonic-gate#if CPUSET_SIZE > CLONGSIZE
1227c478bd9Sstevel@tonic-gate	add	%o1, CPUSET_SIZE, %g5			/* end of cpuset */
1237c478bd9Sstevel@tonic-gate	clr	%o2
1247c478bd9Sstevel@tonic-gate1:
1257c478bd9Sstevel@tonic-gate	TRACE_PTR(%g3, %g4)
1267c478bd9Sstevel@tonic-gate	stha	%g0, [%g3 + TRAP_ENT_TL]%asi
1277c478bd9Sstevel@tonic-gate	set	TT_XCALL_CONT, %g2
1287c478bd9Sstevel@tonic-gate	or	%g2, %o2, %g2				/* continuation # */
1297c478bd9Sstevel@tonic-gate	stha	%g2, [%g3 + TRAP_ENT_TT]%asi
1307c478bd9Sstevel@tonic-gate	stxa	%g6, [%g3 + TRAP_ENT_TICK]%asi		/* same tick */
1317c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_TPC]%asi		/* clr unused fields */
1327c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_SP]%asi
1337c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_TR]%asi
1347c478bd9Sstevel@tonic-gate	stxa	%g0, [%g3 + TRAP_ENT_TSTATE]%asi
1357c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_F2]%asi
1367c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_F3]%asi
1377c478bd9Sstevel@tonic-gate	stna	%g0, [%g3 + TRAP_ENT_F4]%asi
1387c478bd9Sstevel@tonic-gate	ldn	[%o1], %g2
1397c478bd9Sstevel@tonic-gate	stna	%g2, [%g3 + TRAP_ENT_F1]%asi
1407c478bd9Sstevel@tonic-gate	add	%o1, CLONGSIZE, %o1
1417c478bd9Sstevel@tonic-gate	cmp	%o1, %g5
1427c478bd9Sstevel@tonic-gate	bge	2f
1437c478bd9Sstevel@tonic-gate	ldn	[%o1], %g2
1447c478bd9Sstevel@tonic-gate	stna	%g2, [%g3 + TRAP_ENT_F2]%asi
1457c478bd9Sstevel@tonic-gate	add	%o1, CLONGSIZE, %o1
1467c478bd9Sstevel@tonic-gate	cmp	%o1, %g5
1477c478bd9Sstevel@tonic-gate	bge	2f
1487c478bd9Sstevel@tonic-gate	ldn	[%o1], %g2
1497c478bd9Sstevel@tonic-gate	stna	%g2, [%g3 + TRAP_ENT_F3]%asi
1507c478bd9Sstevel@tonic-gate	add	%o1, CLONGSIZE, %o1
1517c478bd9Sstevel@tonic-gate	cmp	%o1, %g5
1527c478bd9Sstevel@tonic-gate	bge	2f
1537c478bd9Sstevel@tonic-gate	ldn	[%o1], %g2
1547c478bd9Sstevel@tonic-gate	stna	%g2, [%g3 + TRAP_ENT_F4]%asi
1557c478bd9Sstevel@tonic-gate	add	%o1, CLONGSIZE, %o1
156*55fea89dSDan Cross2:
1577c478bd9Sstevel@tonic-gate	TRACE_NEXT(%g2, %g3, %g4)
1587c478bd9Sstevel@tonic-gate	cmp	%o1, %g5
1597c478bd9Sstevel@tonic-gate	bl	1b
1607c478bd9Sstevel@tonic-gate	inc	%o2
1617c478bd9Sstevel@tonic-gate#endif	/* CPUSET_SIZE */
1627c478bd9Sstevel@tonic-gate	retl
1637c478bd9Sstevel@tonic-gate	wrpr	%g0, %g1, %pstate			/* enable interrupts */
1647c478bd9Sstevel@tonic-gate	SET_SIZE(xc_trace)
1657c478bd9Sstevel@tonic-gate
1667c478bd9Sstevel@tonic-gate#endif	/* TRAPTRACE */
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate/*
1697c478bd9Sstevel@tonic-gate * Setup interrupt dispatch data registers
1707c478bd9Sstevel@tonic-gate * Entry:
1717c478bd9Sstevel@tonic-gate *	%o0 - function or inumber to call
1727c478bd9Sstevel@tonic-gate *	%o1, %o2 - arguments (2 uint64_t's)
1737c478bd9Sstevel@tonic-gate */
1747c478bd9Sstevel@tonic-gate	ENTRY(init_mondo)
1757c478bd9Sstevel@tonic-gate	ALTENTRY(init_mondo_nocheck)
1767c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)			! load CPU struct addr
1777c478bd9Sstevel@tonic-gate	add	%g1, CPU_MCPU, %g1
1787c478bd9Sstevel@tonic-gate	ldx	[%g1 + MCPU_MONDO_DATA], %g1
1797c478bd9Sstevel@tonic-gate	stx	%o0, [%g1]
1807c478bd9Sstevel@tonic-gate	stx	%o1, [%g1+8]
1817c478bd9Sstevel@tonic-gate	stx	%o2, [%g1+0x10]
1827c478bd9Sstevel@tonic-gate	stx	%g0, [%g1+0x18]
1837c478bd9Sstevel@tonic-gate	stx	%g0, [%g1+0x20]
1847c478bd9Sstevel@tonic-gate	stx	%g0, [%g1+0x28]
1857c478bd9Sstevel@tonic-gate	stx	%g0, [%g1+0x30]
1867c478bd9Sstevel@tonic-gate	stx	%g0, [%g1+0x38]
1877c478bd9Sstevel@tonic-gate	retl
1887c478bd9Sstevel@tonic-gate	membar	#Sync			! allowed to be in the delay slot
1897c478bd9Sstevel@tonic-gate	SET_SIZE(init_mondo)
1907c478bd9Sstevel@tonic-gate
1917c478bd9Sstevel@tonic-gate/*
1927c478bd9Sstevel@tonic-gate * Ship mondo to cpuid
1937c478bd9Sstevel@tonic-gate */
1947c478bd9Sstevel@tonic-gate	ENTRY_NP(shipit)
1957c478bd9Sstevel@tonic-gate	/* For now use dummy interface:  cpu# func arg1 arg2 */
1967c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)
1977c478bd9Sstevel@tonic-gate	add	%g1, CPU_MCPU, %g1
1987c478bd9Sstevel@tonic-gate	ldx	[%g1 + MCPU_MONDO_DATA_RA],	%o2
1997c478bd9Sstevel@tonic-gate	mov	HV_INTR_SEND, %o5
2007c478bd9Sstevel@tonic-gate	ta	FAST_TRAP
2017c478bd9Sstevel@tonic-gate	retl
2027c478bd9Sstevel@tonic-gate	membar	#Sync
2037c478bd9Sstevel@tonic-gate	SET_SIZE(shipit)
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate/*
2067c478bd9Sstevel@tonic-gate * Get cpu structure
2077c478bd9Sstevel@tonic-gate * Entry:
2087c478bd9Sstevel@tonic-gate *      %o0 - register for CPU_ADDR macro
2097c478bd9Sstevel@tonic-gate *      %o1 - scratch for CPU_ADDR macro
2107c478bd9Sstevel@tonic-gate */
2117c478bd9Sstevel@tonic-gate	ENTRY(get_cpuaddr)
2127c478bd9Sstevel@tonic-gate	CPU_ADDR(%o0, %o1)	! %o0 == CPU struct addr
2137c478bd9Sstevel@tonic-gate	retl
2147c478bd9Sstevel@tonic-gate	nop
2157c478bd9Sstevel@tonic-gate	SET_SIZE(get_cpuaddr)
2167c478bd9Sstevel@tonic-gate
2177c478bd9Sstevel@tonic-gate/*
2187c478bd9Sstevel@tonic-gate * This is to ensure that previously called xtrap handlers have executed on
2197c478bd9Sstevel@tonic-gate * sun4v. We zero out the byte corresponding to its cpuid in the
2207c478bd9Sstevel@tonic-gate * array passed to us from xt_sync(), so the sender knows the previous
2217c478bd9Sstevel@tonic-gate * mondo has been executed.
2227c478bd9Sstevel@tonic-gate * Register:
2237c478bd9Sstevel@tonic-gate *		%g1 - Addr of the cpu_sync array.
2247c478bd9Sstevel@tonic-gate */
2257c478bd9Sstevel@tonic-gate	ENTRY_NP(xt_sync_tl1)
2267c478bd9Sstevel@tonic-gate	CPU_INDEX(%g3, %g4)		/* %g3 = cpu id */
227*55fea89dSDan Cross	stb	%g0, [%g1 + %g3]
2287c478bd9Sstevel@tonic-gate	retry
2297c478bd9Sstevel@tonic-gate	SET_SIZE(xt_sync_tl1)
2307c478bd9Sstevel@tonic-gate
231