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