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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 /*
  26  * General machine architecture & implementation specific
  27  * assembly language routines.
  28  */
  29 #include "assym.h"
  30 
  31 #define CPU_MODULE /* need it for NSEC_SHIFT used by NATIVE_TIME_TO_NSEC() */
  32 
  33 #include <sys/asm_linkage.h>
  34 #include <sys/machsystm.h>
  35 #include <sys/machthread.h>
  36 #include <sys/machclock.h>
  37 #include <sys/privregs.h>
  38 #include <sys/cmpregs.h>
  39 #include <sys/clock.h>
  40 #include <sys/fpras.h>
  41 #include <sys/soft_state.h>
  42 
  43 /*
  44  * This isn't the routine you're looking for.
  45  *
  46  * The routine simply returns the value of %tick on the *current* processor.
  47  * Most of the time, gettick() [which in turn maps to %stick on platforms
  48  * that have different CPU %tick rates] is what you want.
  49  */
  50 
  51         ENTRY(ultra_gettick)
  52         RD_TICK(%o0,%o1,%o2,__LINE__)
  53         retl
  54         nop
  55         SET_SIZE(ultra_gettick)
  56 
  57         ENTRY(set_mmfsa_scratchpad)
  58         stxa    %o0, [%g0]ASI_SCRATCHPAD 
  59         retl
  60         nop
  61         SET_SIZE(set_mmfsa_scratchpad)
  62 
  63         ENTRY(get_mmfsa_scratchpad)
  64         ldxa    [%g0]ASI_SCRATCHPAD, %o0 
  65         retl
  66         nop
  67         SET_SIZE(get_mmfsa_scratchpad)
  68 
  69 
  70 
  71 /*
  72  * Called from a x-trap at tl1 must use %g1 as arg
  73  * and save/restore %o0-%o5 after hypervisor calls
  74  */
  75 
  76         ENTRY(cpu_intrq_unregister_powerdown)
  77 
  78         CPU_ADDR(%g2, %g3)
  79         add %g2, CPU_MCPU, %g2 
  80         /*
  81          * Save %o regs
  82          */
  83         mov %o0, %g3
  84         mov %o1, %g4
  85         mov %o2, %g5
  86         mov %o5, %g6
  87 
  88         ldx [%g2 + MCPU_CPU_Q_BASE], %o1
  89         mov INTR_CPU_Q, %o0
  90         call hv_cpu_qconf
  91         mov %g0, %o2
  92 
  93         ldx [%g2 + MCPU_DEV_Q_BASE], %o1
  94         mov INTR_DEV_Q, %o0
  95         call hv_cpu_qconf
  96         mov %g0, %o2
  97 
  98         ldx [%g2 + MCPU_RQ_BASE], %o1
  99         mov CPU_RQ, %o0
 100         call hv_cpu_qconf
 101         mov %g0, %o2
 102 
 103         ldx [%g2 + MCPU_NRQ_BASE], %o1
 104         mov CPU_NRQ, %o0
 105         call hv_cpu_qconf
 106         mov %g0, %o2
 107 
 108         /*
 109          * set done flag to 0
 110          */
 111         stub %g0, [%g1]
 112 
 113         /*
 114          * Restore %o regs
 115          */
 116         mov %g3, %o0
 117         mov %g4, %o1
 118         mov %g5, %o2
 119         mov %g6, %o5
 120 
 121         /*
 122          * This CPU is on its way out. Spin here
 123          * until the DR unconfigure code stops it.
 124          * Returning would put it back in the OS
 125          * where it might grab resources like locks,
 126          * causing some nastiness to occur.
 127          */
 128 0:
 129         ba,a    0b
 130 
 131         SET_SIZE(cpu_intrq_unregister_powerdown)
 132 
 133 
 134 /*
 135  * Get the processor ID.
 136  * === MID reg as specified in 15dec89 sun4u spec, sec 5.4.3
 137  */
 138 
 139         ENTRY(getprocessorid)
 140         CPU_INDEX(%o0, %o1)
 141         retl
 142         nop
 143         SET_SIZE(getprocessorid)
 144 
 145         ENTRY_NP(tick2ns)
 146         !
 147         ! Use nsec_scale for sun4v which is based on %stick
 148         !
 149         NATIVE_TIME_TO_NSEC(%o0, %o2, %o3)
 150         retl
 151         nop
 152         SET_SIZE(tick2ns)
 153 
 154         ENTRY(set_cmp_error_steering)
 155         retl
 156         nop
 157         SET_SIZE(set_cmp_error_steering)
 158 
 159         ENTRY(ultra_getver)
 160         retl
 161         mov     -1, %o0         ! XXXQ no version available
 162         SET_SIZE(ultra_getver)
 163 
 164         /*
 165          * Check instructions using just the AX pipelines, designed by
 166          * C.B. Liaw of PNP.
 167          *
 168          * This function must match a struct fpras_chkfn and must be
 169          * block aligned.  A zero return means all was well.  These
 170          * instructions are chosen to be sensitive to bit corruptions
 171          * on the fpras rewrite, so if a bit corruption still produces
 172          * a valid instruction we should still get an incorrect result
 173          * here.  This function is never called directly - it is copied
 174          * into per-cpu and per-operation buffers;  it must therefore
 175          * be absolutely position independent.  If an illegal instruction
 176          * is encountered then the trap handler trampolines to the final
 177          * three instructions of this function.
 178          *
 179          * We want two instructions that are complements of one another,
 180          * and which can perform a calculation with a known result.
 181          *
 182          * SETHI:
 183          *
 184          * | 0 0 |  rd   | 1 0 0 |      imm22                           |
 185          *  31 30 29   25 24   22 21                                   0
 186          *
 187          * ADDCCC with two source registers:
 188          *
 189          * | 1 0 |  rd   | 0 1 1   0 0 0 |  rs1  | 0 |     -    |  rs2  |
 190          *  31 30 29   25 24           19 18   14 13  12       5 4     0
 191          *
 192          * We can choose rd and imm2 of the SETHI and rd, rs1 and rs2 of
 193          * the ADDCCC to obtain instructions that are complements in all but
 194          * bit 30.
 195          *
 196          * Registers are numbered as follows:
 197          *
 198          * r[31]        %i7
 199          * r[30]        %i6
 200          * r[29]        %i5
 201          * r[28]        %i4
 202          * r[27]        %i3
 203          * r[26]        %i2
 204          * r[25]        %i1
 205          * r[24]        %i0
 206          * r[23]        %l7
 207          * r[22]        %l6
 208          * r[21]        %l5
 209          * r[20]        %l4
 210          * r[19]        %l3
 211          * r[18]        %l2
 212          * r[17]        %l1
 213          * r[16]        %l0
 214          * r[15]        %o7
 215          * r[14]        %o6
 216          * r[13]        %o5
 217          * r[12]        %o4
 218          * r[11]        %o3
 219          * r[10]        %o2
 220          * r[9]         %o1
 221          * r[8]         %o0     
 222          * r[7]         %g7
 223          * r[6]         %g6
 224          * r[5]         %g5
 225          * r[4]         %g4
 226          * r[3]         %g3
 227          * r[2]         %g2
 228          * r[1]         %g1
 229          * r[0]         %g0
 230          *
 231          * For register r[n], register r[31-n] is the complement.  We must
 232          * avoid use of %i6/%i7 and %o6/%o7 as well as %g7.  Clearly we need
 233          * to use a local or input register as one half of the pair, which
 234          * requires us to obtain our own register window or take steps
 235          * to preserve any local or input we choose to use.  We choose
 236          * %o1 as rd for the SETHI, so rd of the ADDCCC must be %l6.
 237          * We'll use %o1 as rs1 and %l6 as rs2 of the ADDCCC, which then
 238          * requires that imm22 be 0b111 10110 1 11111111 01001 or 0x3dbfe9,
 239          * or %hi(0xf6ffa400).  This determines the value of the constant
 240          * CBV2 below.
 241          *
 242          * The constant CBV1 is chosen such that an initial subcc %g0, CBV1
 243          * will set the carry bit and every addccc thereafter will continue
 244          * to generate a carry.  Other values are possible for CBV1 - this
 245          * is just one that works this way.
 246          *
 247          * Finally CBV3 is the expected answer when we perform our repeated
 248          * calculations on CBV1 and CBV2 - it is not otherwise specially
 249          * derived.  If this result is not obtained then a corruption has
 250          * occured during the FPRAS_REWRITE of one of the two blocks of
 251          * 16 instructions.  A corruption could also result in an illegal
 252          * instruction or other unexpected trap - we catch illegal
 253          * instruction traps in the PC range and trampoline to the
 254          * last instructions of the function to return a failure indication.
 255          *
 256          */
 257 
 258 #define CBV1            0xc11
 259 #define CBV2            0xf6ffa400
 260 #define CBV3            0x66f9d800
 261 #define CBR1            %o1
 262 #define CBR2            %l6
 263 #define CBO2            %o2
 264 #define SETHI_CBV2_CBR1         sethi %hi(CBV2), CBR1
 265 #define ADDCCC_CBR1_CBR2_CBR2   addccc CBR1, CBR2, CBR2
 266 
 267         .align  64
 268         ENTRY_NP(fpras_chkfn_type1)
 269         mov     CBR2, CBO2              ! 1, preserve CBR2 of (callers) window
 270         mov     FPRAS_OK, %o0           ! 2, default return value
 271         ba,pt   %icc, 1f                ! 3
 272           subcc %g0, CBV1, CBR2         ! 4
 273                                         ! 5 - 16
 274         .align  64
 275 1:      SETHI_CBV2_CBR1                 ! 1
 276         ADDCCC_CBR1_CBR2_CBR2           ! 2
 277         SETHI_CBV2_CBR1                 ! 3
 278         ADDCCC_CBR1_CBR2_CBR2           ! 4
 279         SETHI_CBV2_CBR1                 ! 5
 280         ADDCCC_CBR1_CBR2_CBR2           ! 6
 281         SETHI_CBV2_CBR1                 ! 7
 282         ADDCCC_CBR1_CBR2_CBR2           ! 8
 283         SETHI_CBV2_CBR1                 ! 9
 284         ADDCCC_CBR1_CBR2_CBR2           ! 10
 285         SETHI_CBV2_CBR1                 ! 11
 286         ADDCCC_CBR1_CBR2_CBR2           ! 12
 287         SETHI_CBV2_CBR1                 ! 13
 288         ADDCCC_CBR1_CBR2_CBR2           ! 14
 289         SETHI_CBV2_CBR1                 ! 15
 290         ADDCCC_CBR1_CBR2_CBR2           ! 16
 291 
 292         ADDCCC_CBR1_CBR2_CBR2           ! 1
 293         SETHI_CBV2_CBR1                 ! 2
 294         ADDCCC_CBR1_CBR2_CBR2           ! 3
 295         SETHI_CBV2_CBR1                 ! 4
 296         ADDCCC_CBR1_CBR2_CBR2           ! 5
 297         SETHI_CBV2_CBR1                 ! 6
 298         ADDCCC_CBR1_CBR2_CBR2           ! 7
 299         SETHI_CBV2_CBR1                 ! 8
 300         ADDCCC_CBR1_CBR2_CBR2           ! 9
 301         SETHI_CBV2_CBR1                 ! 10
 302         ADDCCC_CBR1_CBR2_CBR2           ! 11
 303         SETHI_CBV2_CBR1                 ! 12
 304         ADDCCC_CBR1_CBR2_CBR2           ! 13
 305         SETHI_CBV2_CBR1                 ! 14
 306         ADDCCC_CBR1_CBR2_CBR2           ! 15
 307         SETHI_CBV2_CBR1                 ! 16
 308 
 309         addc    CBR1, CBR2, CBR2        ! 1
 310         sethi   %hi(CBV3), CBR1         ! 2
 311         cmp     CBR1, CBR2              ! 3
 312         movnz   %icc, FPRAS_BADCALC, %o0! 4, how detected
 313         retl                            ! 5
 314           mov   CBO2, CBR2              ! 6, restore borrowed register
 315         .skip 4*(13-7+1)                ! 7 - 13
 316                                         !
 317                                         ! illegal instr'n trap comes here
 318                                         !
 319         mov     CBO2, CBR2              ! 14, restore borrowed register
 320         retl                            ! 15
 321           mov   FPRAS_BADTRAP, %o0      ! 16, how detected
 322         SET_SIZE(fpras_chkfn_type1)
 323 
 324         .seg    ".data"
 325         .global soft_state_message_strings
 326 
 327         .align  SSM_SIZE
 328 soft_state_message_strings:
 329         .asciz  SOLARIS_SOFT_STATE_BOOT_MSG_STR
 330         .align  SSM_SIZE
 331         .asciz  SOLARIS_SOFT_STATE_RUN_MSG_STR
 332         .align  SSM_SIZE
 333         .asciz  SOLARIS_SOFT_STATE_HALT_MSG_STR
 334         .align  SSM_SIZE
 335         .asciz  SOLARIS_SOFT_STATE_POWER_MSG_STR
 336         .align  SSM_SIZE
 337         .asciz  SOLARIS_SOFT_STATE_PANIC_MSG_STR
 338         .align  SSM_SIZE
 339         .asciz  SOLARIS_SOFT_STATE_REBOOT_MSG_STR
 340         .align  SSM_SIZE
 341         .asciz  SOLARIS_SOFT_STATE_DEBUG_MSG_STR
 342         .align  SSM_SIZE
 343         .skip   SSM_SIZE                        /* saved message */
 344         .nword  0
 345 
 346         .seg    ".text"