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/t_lock.h>
  32 #include <sys/promif.h>
  33 #include <sys/prom_isa.h>
  34 #endif  /* lint */
  35 
  36 #include <sys/asm_linkage.h>
  37 #include <sys/privregs.h>
  38 #include <sys/scb.h>
  39 #include <sys/machparam.h>
  40 #include <sys/machthread.h>
  41 
  42 #if defined(lint)
  43 
  44 #include <sys/thread.h>
  45 #include <sys/time.h>
  46 
  47 #else   /* lint */
  48 
  49 #include "assym.h"
  50 
  51 #endif  /* lint */
  52 
  53 /*
  54  * void
  55  * reestablish_curthread(void)
  56  *    - reestablishes the invariant that THREAD_REG contains
  57  *      the same value as the cpu struct for this cpu (implicit from
  58  *      where we're running). This is needed for OBP callback routines.
  59  *      The CPU_ADDR macro figures out the cpuid by reading hardware registers.
  60  */
  61 
  62 #if defined(lint)
  63 
  64 void
  65 reestablish_curthread(void)
  66 {}
  67 
  68 #else   /* lint */
  69 
  70         ENTRY_NP(reestablish_curthread)
  71 
  72         CPU_ADDR(%o0, %o1)
  73         retl
  74         ldn     [%o0 + CPU_THREAD], THREAD_REG
  75         SET_SIZE(reestablish_curthread)
  76 
  77 
  78 #endif  /* lint */
  79 
  80 /*
  81  * Return the current THREAD pointer.
  82  * This is also available as an inline function.
  83  */
  84 #if defined(lint)
  85 
  86 kthread_id_t
  87 threadp(void)
  88 { return ((kthread_id_t)0); }
  89 
  90 #else   /* lint */
  91 
  92         ENTRY_NP(threadp)
  93         retl
  94         mov     THREAD_REG, %o0
  95         SET_SIZE(threadp)
  96 
  97 #endif  /* lint */
  98 
  99 
 100 /*
 101  * The IEEE 1275-1994 callback handler for a 64-bit SPARC V9 PROM calling
 102  * a 32 bit client program. The PROM calls us with a 64 bit stack and a
 103  * pointer to a client interface argument array in %o0.  The called code
 104  * returns 0 if the call succeeded (i.e. the service name exists) or -1
 105  * if the call failed. NOTE: All addresses are in the range 0..2^^32-1
 106  *
 107  * This code is called as trusted subroutine of the firmware, and is
 108  * called with %tba pointing to the boot firmware's trap table.  All of
 109  * the prom's window handlers are mixed mode handlers.
 110  */
 111 
 112 #if defined(lint)
 113 
 114 int
 115 callback_handler(cell_t *arg_array)
 116 {
 117         extern int vx_handler(cell_t *arg_array);
 118 
 119         return (vx_handler(arg_array));
 120 }
 121 
 122 #else   /* lint */
 123 
 124         ENTRY_NP(callback_handler)
 125         !
 126         ! We assume we are called with a 64 bit stack with PSTATE_AM clear
 127         !
 128         save    %sp, -SA64(MINFRAME64), %sp     ! 64 bit save
 129         rdpr    %wstate, %l5                    ! save %wstate
 130         andn    %l5, WSTATE_MASK, %l6
 131         wrpr    %l6, WSTATE_KMIX, %wstate
 132         rdpr    %pstate, %l0                    ! save %pstate
 133 
 134         !
 135         ! If anybody tries to trace the call stack of this callback
 136         ! then the traceback should stop here.  This matters
 137         ! particularly for sync callbacks on Serengeti, but it's a
 138         ! good idea generally.
 139         !
 140         flushw
 141         mov     %fp, %l1
 142         clr     %fp                             ! terminate stack traces
 143 
 144         call    vx_handler                      ! vx_handler(void **arg_array)
 145           mov   %i0, %o0                        ! delay; argument array
 146         sra     %o0, 0, %i0                     ! sign extend result
 147 
 148         mov     %l1, %fp                        ! restore %fp for return
 149 
 150 1:      wrpr    %g0, %l0, %pstate               ! restore %pstate
 151         wrpr    %g0, %l5, %wstate               ! restore %wstate
 152 
 153         ret                                     ! return result in %o0
 154         restore                                 ! back to a 64 bit stack
 155         SET_SIZE(callback_handler)
 156 
 157 #endif  /* lint */
 158