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