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