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 2004 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#include <sys/asm_linkage.h> 30 31#include <mdb/mdb_kreg.h> 32 33/* 34 * Kernel function call invocation 35 */ 36 37#if !defined(__lint) 38 39 .section RODATA 40 .align 8 41 42 /* 43 * A jump table containing the addresses for register argument copy 44 * code. 45 */ 46copyargs: 47 .xword cp0arg 48 .xword cp1arg 49 .xword cp2arg 50 .xword cp3arg 51 .xword cp4arg 52 .xword cp5arg 53copyargsend: 54 .xword cp6arg 55 56#endif /* __lint */ 57 58#if defined(__lint) 59/*ARGSUSED*/ 60uintptr_t 61kaif_invoke(uintptr_t funcva, uint_t argc, const uintptr_t *argv, 62 kreg_t g6, kreg_t g7) 63{ 64 return (0); 65} 66#else 67 68 ENTRY_NP(kaif_invoke) 69 70 save %sp, -SA(MINFRAME), %sp 71 72 /* 73 * Will registers suffice, or do we need to put excess args (>6) on the 74 * stack? 75 */ 76 sub %i1, 6, %i1 ! %i1 is now num regs over 6 (if any) 77 brgz,pn %i1, savestackargs 78 sllx %i1, 3, %i1 ! (argc - 6) * 8 79 80 /* 81 * We have fewer than six arguments. Below, starting at the cp6arg 82 * label, we've got code that'll copy these arguments to the out 83 * registers in descending order (%o5 is copied, then %o4, and so on). 84 * We only want to move valid arguments, so we'll jump into this copy 85 * code just before it copies our highest arg. If we have four args, 86 * for example, we'll jump to cp4arg. 87 * 88 * %i6 is now a negative word-scaled offset, which we can use to 89 * retrieve the appropriate address from the jump table. We start at 90 * bottom of the table, and let the negative offset jump back to the 91 * correct location. If we have four arguments, %i1 will be -16. 92 * Starting from copyargs+48 (the address of the last slot), we get 93 * copyargs+32, which contains the address (cp4arg) to be used to copy 94 * four arguments. 95 */ 96 setx copyargsend, %l1, %l0 97 ldx [%l0 + %i1], %l0 98 jmp %l0 99 nop 100 101savestackargs: 102 /* 103 * We have more than six arguments, and will thus need to allocate space 104 * for the seventh and beyond on the stack. %i1 is the number of bytes 105 * needed to hold the seventh and higher arguments. 106 */ 107 108 /* Allocate swap space - %i1 rounded up to STACK_ALIGN */ 109 add %i1, STACK_ALIGN/2, %g1 110 and %g1, -STACK_ALIGN, %g1 111 sub %sp, %g1, %sp 112 113 add %i2, 6*8, %l0 ! %l0 is &argv[6] 114 add %sp, STACK_BIAS+MINFRAME, %l1 ! %l1 is base of stack reg save 115 116 /* 117 * Copy arguments to the stack. %i1 is the offset from the seventh arg 118 * in argv and the offset from the base of the stack save area. 119 */ 120 sub %i1, 8, %i1 1211: 122 ldx [%l0 + %i1], %l2 123 stx %l2, [%l1 + %i1] 124 brnz,pt %i1, 1b 125 sub %i1, 8, %i1 126 127 /* 128 * Copy the register arguments. The argc <= 6 case will be jumping to 129 * one of these labels. 130 */ 131cp6arg: ldx [%i2 + 5*8], %o5 132cp5arg: ldx [%i2 + 4*8], %o4 133cp4arg: ldx [%i2 + 3*8], %o3 134cp3arg: ldx [%i2 + 2*8], %o2 135cp2arg: ldx [%i2 + 1*8], %o1 136cp1arg: ldx [%i2 + 0*8], %o0 137cp0arg: 138 139 mov %g6, %l0 140 mov %i3, %g6 ! Restore PROC_REG for kernel call 141 142 mov %g7, %l1 143 mov %i4, %g7 ! Restore THREAD_REG for kernel call 144 145 jmpl %i0, %o7 ! Make call 146 nop 147 148 mov %l0, %g6 149 mov %l1, %g7 150 151 ret 152 restore %g0, %o0, %o0 153 154 SET_SIZE(kaif_invoke) 155 156#endif 157