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