1*5d9d9091SRichard Lowe/* 2*5d9d9091SRichard Lowe * CDDL HEADER START 3*5d9d9091SRichard Lowe * 4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the 5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License"). 6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License. 7*5d9d9091SRichard Lowe * 8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing. 10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions 11*5d9d9091SRichard Lowe * and limitations under the License. 12*5d9d9091SRichard Lowe * 13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 18*5d9d9091SRichard Lowe * 19*5d9d9091SRichard Lowe * CDDL HEADER END 20*5d9d9091SRichard Lowe */ 21*5d9d9091SRichard Lowe/* 22*5d9d9091SRichard Lowe * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*5d9d9091SRichard Lowe * Use is subject to license terms. 24*5d9d9091SRichard Lowe */ 25*5d9d9091SRichard Lowe 26*5d9d9091SRichard Lowe#include "assym.h" 27*5d9d9091SRichard Lowe 28*5d9d9091SRichard Lowe#include <sys/asm_linkage.h> 29*5d9d9091SRichard Lowe#include <sys/privregs.h> 30*5d9d9091SRichard Lowe#include <sys/x_call.h> 31*5d9d9091SRichard Lowe#include <sys/xc_impl.h> 32*5d9d9091SRichard Lowe 33*5d9d9091SRichard Lowe#ifdef TRAPTRACE 34*5d9d9091SRichard Lowe#include <sys/traptrace.h> 35*5d9d9091SRichard Lowe#endif /* TRAPTRACE */ 36*5d9d9091SRichard Lowe 37*5d9d9091SRichard Lowe 38*5d9d9091SRichard Lowe/* 39*5d9d9091SRichard Lowe * Entered by the software trap (TT=ST_SELFXCALL, TL>0) thru send_self_xcall(). 40*5d9d9091SRichard Lowe * Emulate the mondo handler - vec_interrupt(). 41*5d9d9091SRichard Lowe * 42*5d9d9091SRichard Lowe * Global registers are the Alternate Globals. 43*5d9d9091SRichard Lowe * Arguments: 44*5d9d9091SRichard Lowe * %o0 - CPU 45*5d9d9091SRichard Lowe * ILP32 kernel: 46*5d9d9091SRichard Lowe * %o5 - function to call 47*5d9d9091SRichard Lowe * %o1, %o2, %o3, %o4 - arguments 48*5d9d9091SRichard Lowe * LP64 kernel: 49*5d9d9091SRichard Lowe * %o3 - function to call 50*5d9d9091SRichard Lowe * %o1, %o2 - arguments 51*5d9d9091SRichard Lowe */ 52*5d9d9091SRichard Lowe ENTRY_NP(self_xcall) 53*5d9d9091SRichard Lowe ! 54*5d9d9091SRichard Lowe ! TL>0 handlers are expected to do "retry" 55*5d9d9091SRichard Lowe ! prepare their return PC and nPC now 56*5d9d9091SRichard Lowe ! 57*5d9d9091SRichard Lowe rdpr %tnpc, %g1 58*5d9d9091SRichard Lowe wrpr %g1, %tpc ! PC <- TNPC[TL] 59*5d9d9091SRichard Lowe add %g1, 4, %g1 60*5d9d9091SRichard Lowe wrpr %g1, %tnpc ! nPC <- TNPC[TL] + 4 61*5d9d9091SRichard Lowe 62*5d9d9091SRichard Lowe#ifdef TRAPTRACE 63*5d9d9091SRichard Lowe TRACE_PTR(%g4, %g6) 64*5d9d9091SRichard Lowe GET_TRACE_TICK(%g6, %g3) 65*5d9d9091SRichard Lowe stxa %g6, [%g4 + TRAP_ENT_TICK]%asi 66*5d9d9091SRichard Lowe rdpr %tl, %g6 67*5d9d9091SRichard Lowe stha %g6, [%g4 + TRAP_ENT_TL]%asi 68*5d9d9091SRichard Lowe rdpr %tt, %g6 69*5d9d9091SRichard Lowe stha %g6, [%g4 + TRAP_ENT_TT]%asi 70*5d9d9091SRichard Lowe stna %o3, [%g4 + TRAP_ENT_TR]%asi ! pc of the TL>0 handler 71*5d9d9091SRichard Lowe rdpr %tpc, %g6 72*5d9d9091SRichard Lowe stna %g6, [%g4 + TRAP_ENT_TPC]%asi 73*5d9d9091SRichard Lowe rdpr %tstate, %g6 74*5d9d9091SRichard Lowe stxa %g6, [%g4 + TRAP_ENT_TSTATE]%asi 75*5d9d9091SRichard Lowe stna %sp, [%g4 + TRAP_ENT_SP]%asi 76*5d9d9091SRichard Lowe stna %o1, [%g4 + TRAP_ENT_F1]%asi ! arg 1 77*5d9d9091SRichard Lowe stna %o2, [%g4 + TRAP_ENT_F2]%asi ! arg 2 78*5d9d9091SRichard Lowe stna %g0, [%g4 + TRAP_ENT_F3]%asi 79*5d9d9091SRichard Lowe stna %g0, [%g4 + TRAP_ENT_F4]%asi 80*5d9d9091SRichard Lowe TRACE_NEXT(%g4, %g6, %g3) 81*5d9d9091SRichard Lowe#endif /* TRAPTRACE */ 82*5d9d9091SRichard Lowe ! 83*5d9d9091SRichard Lowe ! Load the arguments for the fast trap handler. 84*5d9d9091SRichard Lowe ! 85*5d9d9091SRichard Lowe mov %o1, %g1 86*5d9d9091SRichard Lowe jmp %o3 ! call the fast trap handler 87*5d9d9091SRichard Lowe mov %o2, %g2 88*5d9d9091SRichard Lowe /* Not Reached */ 89*5d9d9091SRichard Lowe SET_SIZE(self_xcall) 90*5d9d9091SRichard Lowe 91*5d9d9091SRichard Lowe#ifdef TRAPTRACE 92*5d9d9091SRichard Lowe ENTRY(xc_trace) 93*5d9d9091SRichard Lowe rdpr %pstate, %g1 94*5d9d9091SRichard Lowe andn %g1, PSTATE_IE | PSTATE_AM, %g2 95*5d9d9091SRichard Lowe wrpr %g0, %g2, %pstate /* disable interrupts */ 96*5d9d9091SRichard Lowe TRACE_PTR(%g3, %g4) 97*5d9d9091SRichard Lowe GET_TRACE_TICK(%g6, %g4) 98*5d9d9091SRichard Lowe stxa %g6, [%g3 + TRAP_ENT_TICK]%asi 99*5d9d9091SRichard Lowe stha %g0, [%g3 + TRAP_ENT_TL]%asi 100*5d9d9091SRichard Lowe set TT_XCALL, %g2 101*5d9d9091SRichard Lowe or %o0, %g2, %g4 102*5d9d9091SRichard Lowe stha %g4, [%g3 + TRAP_ENT_TT]%asi 103*5d9d9091SRichard Lowe stna %o7, [%g3 + TRAP_ENT_TPC]%asi 104*5d9d9091SRichard Lowe ldn [%o1], %g2 105*5d9d9091SRichard Lowe stna %g2, [%g3 + TRAP_ENT_SP]%asi /* sp = cpuset */ 106*5d9d9091SRichard Lowe stna %o2, [%g3 + TRAP_ENT_TR]%asi /* tr = func */ 107*5d9d9091SRichard Lowe stna %o3, [%g3 + TRAP_ENT_F1]%asi /* f1 = arg1 */ 108*5d9d9091SRichard Lowe stna %o4, [%g3 + TRAP_ENT_F2]%asi /* f2 = arg2 */ 109*5d9d9091SRichard Lowe stna %g0, [%g3 + TRAP_ENT_F3]%asi /* f3 = 0 */ 110*5d9d9091SRichard Lowe stna %i7, [%g3 + TRAP_ENT_F4]%asi /* f4 = xcall caller */ 111*5d9d9091SRichard Lowe stxa %g1, [%g3 + TRAP_ENT_TSTATE]%asi /* tstate = pstate */ 112*5d9d9091SRichard Lowe TRACE_NEXT(%g2, %g3, %g4) 113*5d9d9091SRichard Lowe/* 114*5d9d9091SRichard Lowe * In the case of a cpuset of greater size than a long we 115*5d9d9091SRichard Lowe * grab extra trace buffers just to store the cpuset. 116*5d9d9091SRichard Lowe * Seems like a waste but popular opinion opted for this 117*5d9d9091SRichard Lowe * rather than increase the size of the buffer. 118*5d9d9091SRichard Lowe */ 119*5d9d9091SRichard Lowe#if CPUSET_SIZE > CLONGSIZE 120*5d9d9091SRichard Lowe add %o1, CPUSET_SIZE, %g5 /* end of cpuset */ 121*5d9d9091SRichard Lowe clr %o2 122*5d9d9091SRichard Lowe1: 123*5d9d9091SRichard Lowe TRACE_PTR(%g3, %g4) 124*5d9d9091SRichard Lowe stha %g0, [%g3 + TRAP_ENT_TL]%asi 125*5d9d9091SRichard Lowe set TT_XCALL_CONT, %g2 126*5d9d9091SRichard Lowe or %g2, %o2, %g2 /* continuation # */ 127*5d9d9091SRichard Lowe stha %g2, [%g3 + TRAP_ENT_TT]%asi 128*5d9d9091SRichard Lowe stxa %g6, [%g3 + TRAP_ENT_TICK]%asi /* same tick */ 129*5d9d9091SRichard Lowe stna %g0, [%g3 + TRAP_ENT_TPC]%asi /* clr unused fields */ 130*5d9d9091SRichard Lowe stna %g0, [%g3 + TRAP_ENT_SP]%asi 131*5d9d9091SRichard Lowe stna %g0, [%g3 + TRAP_ENT_TR]%asi 132*5d9d9091SRichard Lowe stxa %g0, [%g3 + TRAP_ENT_TSTATE]%asi 133*5d9d9091SRichard Lowe stna %g0, [%g3 + TRAP_ENT_F2]%asi 134*5d9d9091SRichard Lowe stna %g0, [%g3 + TRAP_ENT_F3]%asi 135*5d9d9091SRichard Lowe stna %g0, [%g3 + TRAP_ENT_F4]%asi 136*5d9d9091SRichard Lowe ldn [%o1], %g2 137*5d9d9091SRichard Lowe stna %g2, [%g3 + TRAP_ENT_F1]%asi 138*5d9d9091SRichard Lowe add %o1, CLONGSIZE, %o1 139*5d9d9091SRichard Lowe cmp %o1, %g5 140*5d9d9091SRichard Lowe bge 2f 141*5d9d9091SRichard Lowe ldn [%o1], %g2 142*5d9d9091SRichard Lowe stna %g2, [%g3 + TRAP_ENT_F2]%asi 143*5d9d9091SRichard Lowe add %o1, CLONGSIZE, %o1 144*5d9d9091SRichard Lowe cmp %o1, %g5 145*5d9d9091SRichard Lowe bge 2f 146*5d9d9091SRichard Lowe ldn [%o1], %g2 147*5d9d9091SRichard Lowe stna %g2, [%g3 + TRAP_ENT_F3]%asi 148*5d9d9091SRichard Lowe add %o1, CLONGSIZE, %o1 149*5d9d9091SRichard Lowe cmp %o1, %g5 150*5d9d9091SRichard Lowe bge 2f 151*5d9d9091SRichard Lowe ldn [%o1], %g2 152*5d9d9091SRichard Lowe stna %g2, [%g3 + TRAP_ENT_F4]%asi 153*5d9d9091SRichard Lowe add %o1, CLONGSIZE, %o1 154*5d9d9091SRichard Lowe2: 155*5d9d9091SRichard Lowe TRACE_NEXT(%g2, %g3, %g4) 156*5d9d9091SRichard Lowe cmp %o1, %g5 157*5d9d9091SRichard Lowe bl 1b 158*5d9d9091SRichard Lowe inc %o2 159*5d9d9091SRichard Lowe#endif /* CPUSET_SIZE */ 160*5d9d9091SRichard Lowe retl 161*5d9d9091SRichard Lowe wrpr %g0, %g1, %pstate /* enable interrupts */ 162*5d9d9091SRichard Lowe SET_SIZE(xc_trace) 163*5d9d9091SRichard Lowe 164*5d9d9091SRichard Lowe#endif /* TRAPTRACE */ 165*5d9d9091SRichard Lowe 166*5d9d9091SRichard Lowe/* 167*5d9d9091SRichard Lowe * This dummy tl1 function is there to ensure that previously called 168*5d9d9091SRichard Lowe * xtrap handlers have exececuted. The hardware (mondo dispatch 169*5d9d9091SRichard Lowe * mechanism) is such that return from xtrap doesn't guarantee execution 170*5d9d9091SRichard Lowe * of xtrap handler. So, callers can call this xtrap-handler to ensure 171*5d9d9091SRichard Lowe * that the previous one is complete. This is because the hardware only 172*5d9d9091SRichard Lowe * can handle 1 mondo at a time - when this mondo is handled, we are sure 173*5d9d9091SRichard Lowe * that the mondo for the previous xtrap must have been handled. 174*5d9d9091SRichard Lowe */ 175*5d9d9091SRichard Lowe ENTRY_NP(xt_sync_tl1) 176*5d9d9091SRichard Lowe retry 177*5d9d9091SRichard Lowe SET_SIZE(xt_sync_tl1) 178*5d9d9091SRichard Lowe 179