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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26#pragma ident "%Z%%M% %I% %E% SMI" 27 28/* 29 * General machine architecture & implementation specific 30 * assembly language routines. 31 */ 32#if defined(lint) 33#include <sys/types.h> 34#include <sys/t_lock.h> 35#else /* lint */ 36#include "assym.h" 37#endif /* lint */ 38 39#include <sys/asm_linkage.h> 40#include <sys/machsystm.h> 41#include <sys/machthread.h> 42#include <sys/privregs.h> 43#include <sys/cmpregs.h> 44#include <sys/clock.h> 45#include <sys/fpras.h> 46#include <sys/soft_state.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 78 79#if defined(lint) 80/* ARGSUSED */ 81void 82cpu_intrq_unregister_powerdown(uint64_t doneflag_va) 83{} 84 85#else /* lint */ 86 87/* 88 * Called from a x-trap at tl1 must use %g1 as arg 89 * and save/restore %o0-%o5 after hypervisor calls 90 */ 91 92 ENTRY(cpu_intrq_unregister_powerdown) 93 94 CPU_ADDR(%g2, %g3) 95 add %g2, CPU_MCPU, %g2 96 /* 97 * Save %o regs 98 */ 99 mov %o0, %g3 100 mov %o1, %g4 101 mov %o2, %g5 102 mov %o5, %g6 103 104 ldx [%g2 + MCPU_CPU_Q_BASE], %o1 105 mov INTR_CPU_Q, %o0 106 call hv_cpu_qconf 107 mov %g0, %o2 108 109 ldx [%g2 + MCPU_DEV_Q_BASE], %o1 110 mov INTR_DEV_Q, %o0 111 call hv_cpu_qconf 112 mov %g0, %o2 113 114 ldx [%g2 + MCPU_RQ_BASE], %o1 115 mov CPU_RQ, %o0 116 call hv_cpu_qconf 117 mov %g0, %o2 118 119 ldx [%g2 + MCPU_NRQ_BASE], %o1 120 mov CPU_NRQ, %o0 121 call hv_cpu_qconf 122 mov %g0, %o2 123 124 /* 125 * set done flag to 0 126 */ 127 stub %g0, [%g1] 128 129 /* 130 * Restore %o regs 131 */ 132 mov %g3, %o0 133 mov %g4, %o1 134 mov %g5, %o2 135 mov %g6, %o5 136 137 /* 138 * This CPU is on its way out. Spin here 139 * until the DR unconfigure code stops it. 140 * Returning would put it back in the OS 141 * where it might grab resources like locks, 142 * causing some nastiness to occur. 143 */ 1440: 145 ba,a 0b 146 147 SET_SIZE(cpu_intrq_unregister_powerdown) 148#endif /* lint */ 149 150 151#if defined(lint) 152/* ARGSUSED */ 153int 154getprocessorid(void) 155{ return (0); } 156 157#else /* lint */ 158 159/* 160 * Get the processor ID. 161 * === MID reg as specified in 15dec89 sun4u spec, sec 5.4.3 162 */ 163 164 ENTRY(getprocessorid) 165 CPU_INDEX(%o0, %o1) 166 retl 167 nop 168 SET_SIZE(getprocessorid) 169 170#endif /* lint */ 171 172#if defined(lint) || defined(__lint) 173 174/* ARGSUSED */ 175hrtime_t 176tick2ns(hrtime_t tick, uint_t cpuid) 177{ return 0; } 178 179#else /* lint */ 180 181 ENTRY_NP(tick2ns) 182 sethi %hi(cpunodes), %o4 183 or %o4, %lo(cpunodes), %o4 ! %o4 = &cpunodes 184 ! Register usage: 185 ! 186 ! o0 = timestamp 187 ! o2 = byte offset into cpunodes for tick_nsec_scale of this CPU 188 ! o4 = &cpunodes 189 ! 190 mulx %o1, CPU_NODE_SIZE, %o2 ! %o2 = byte offset into cpunodes 191 add %o2, TICK_NSEC_SCALE, %o2 192 ld [%o4 + %o2], %o2 ! %o2 = cpunodes[cpuid].tick_nsec_scale 193 NATIVE_TIME_TO_NSEC_SCALE(%o0, %o2, %o3, TICK_NSEC_SHIFT) 194 retl 195 nop 196 SET_SIZE(tick2ns) 197 198#endif /* lint */ 199 200#if defined(lint) 201 202/* ARGSUSED */ 203void 204set_cmp_error_steering(void) 205{} 206 207#else /* lint */ 208 209 ENTRY(set_cmp_error_steering) 210 retl 211 nop 212 SET_SIZE(set_cmp_error_steering) 213 214#endif /* lint */ 215 216#if defined(lint) 217 218/* ARGSUSED */ 219uint64_t 220ultra_getver(void) 221{ 222 return (0); 223} 224 225#else /* lint */ 226 227 ENTRY(ultra_getver) 228 retl 229 mov -1, %o0 ! XXXQ no version available 230 SET_SIZE(ultra_getver) 231 232#endif /* lint */ 233 234#if defined(lint) 235 236int 237fpras_chkfn_type1(void) 238{ return 0; } 239 240#else /* lint */ 241 242 /* 243 * Check instructions using just the AX pipelines, designed by 244 * C.B. Liaw of PNP. 245 * 246 * This function must match a struct fpras_chkfn and must be 247 * block aligned. A zero return means all was well. These 248 * instructions are chosen to be sensitive to bit corruptions 249 * on the fpras rewrite, so if a bit corruption still produces 250 * a valid instruction we should still get an incorrect result 251 * here. This function is never called directly - it is copied 252 * into per-cpu and per-operation buffers; it must therefore 253 * be absolutely position independent. If an illegal instruction 254 * is encountered then the trap handler trampolines to the final 255 * three instructions of this function. 256 * 257 * We want two instructions that are complements of one another, 258 * and which can perform a calculation with a known result. 259 * 260 * SETHI: 261 * 262 * | 0 0 | rd | 1 0 0 | imm22 | 263 * 31 30 29 25 24 22 21 0 264 * 265 * ADDCCC with two source registers: 266 * 267 * | 1 0 | rd | 0 1 1 0 0 0 | rs1 | 0 | - | rs2 | 268 * 31 30 29 25 24 19 18 14 13 12 5 4 0 269 * 270 * We can choose rd and imm2 of the SETHI and rd, rs1 and rs2 of 271 * the ADDCCC to obtain instructions that are complements in all but 272 * bit 30. 273 * 274 * Registers are numbered as follows: 275 * 276 * r[31] %i7 277 * r[30] %i6 278 * r[29] %i5 279 * r[28] %i4 280 * r[27] %i3 281 * r[26] %i2 282 * r[25] %i1 283 * r[24] %i0 284 * r[23] %l7 285 * r[22] %l6 286 * r[21] %l5 287 * r[20] %l4 288 * r[19] %l3 289 * r[18] %l2 290 * r[17] %l1 291 * r[16] %l0 292 * r[15] %o7 293 * r[14] %o6 294 * r[13] %o5 295 * r[12] %o4 296 * r[11] %o3 297 * r[10] %o2 298 * r[9] %o1 299 * r[8] %o0 300 * r[7] %g7 301 * r[6] %g6 302 * r[5] %g5 303 * r[4] %g4 304 * r[3] %g3 305 * r[2] %g2 306 * r[1] %g1 307 * r[0] %g0 308 * 309 * For register r[n], register r[31-n] is the complement. We must 310 * avoid use of %i6/%i7 and %o6/%o7 as well as %g7. Clearly we need 311 * to use a local or input register as one half of the pair, which 312 * requires us to obtain our own register window or take steps 313 * to preserve any local or input we choose to use. We choose 314 * %o1 as rd for the SETHI, so rd of the ADDCCC must be %l6. 315 * We'll use %o1 as rs1 and %l6 as rs2 of the ADDCCC, which then 316 * requires that imm22 be 0b111 10110 1 11111111 01001 or 0x3dbfe9, 317 * or %hi(0xf6ffa400). This determines the value of the constant 318 * CBV2 below. 319 * 320 * The constant CBV1 is chosen such that an initial subcc %g0, CBV1 321 * will set the carry bit and every addccc thereafter will continue 322 * to generate a carry. Other values are possible for CBV1 - this 323 * is just one that works this way. 324 * 325 * Finally CBV3 is the expected answer when we perform our repeated 326 * calculations on CBV1 and CBV2 - it is not otherwise specially 327 * derived. If this result is not obtained then a corruption has 328 * occured during the FPRAS_REWRITE of one of the two blocks of 329 * 16 instructions. A corruption could also result in an illegal 330 * instruction or other unexpected trap - we catch illegal 331 * instruction traps in the PC range and trampoline to the 332 * last instructions of the function to return a failure indication. 333 * 334 */ 335 336#define CBV1 0xc11 337#define CBV2 0xf6ffa400 338#define CBV3 0x66f9d800 339#define CBR1 %o1 340#define CBR2 %l6 341#define CBO2 %o2 342#define SETHI_CBV2_CBR1 sethi %hi(CBV2), CBR1 343#define ADDCCC_CBR1_CBR2_CBR2 addccc CBR1, CBR2, CBR2 344 345 .align 64 346 ENTRY_NP(fpras_chkfn_type1) 347 mov CBR2, CBO2 ! 1, preserve CBR2 of (callers) window 348 mov FPRAS_OK, %o0 ! 2, default return value 349 ba,pt %icc, 1f ! 3 350 subcc %g0, CBV1, CBR2 ! 4 351 ! 5 - 16 352 .align 64 3531: SETHI_CBV2_CBR1 ! 1 354 ADDCCC_CBR1_CBR2_CBR2 ! 2 355 SETHI_CBV2_CBR1 ! 3 356 ADDCCC_CBR1_CBR2_CBR2 ! 4 357 SETHI_CBV2_CBR1 ! 5 358 ADDCCC_CBR1_CBR2_CBR2 ! 6 359 SETHI_CBV2_CBR1 ! 7 360 ADDCCC_CBR1_CBR2_CBR2 ! 8 361 SETHI_CBV2_CBR1 ! 9 362 ADDCCC_CBR1_CBR2_CBR2 ! 10 363 SETHI_CBV2_CBR1 ! 11 364 ADDCCC_CBR1_CBR2_CBR2 ! 12 365 SETHI_CBV2_CBR1 ! 13 366 ADDCCC_CBR1_CBR2_CBR2 ! 14 367 SETHI_CBV2_CBR1 ! 15 368 ADDCCC_CBR1_CBR2_CBR2 ! 16 369 370 ADDCCC_CBR1_CBR2_CBR2 ! 1 371 SETHI_CBV2_CBR1 ! 2 372 ADDCCC_CBR1_CBR2_CBR2 ! 3 373 SETHI_CBV2_CBR1 ! 4 374 ADDCCC_CBR1_CBR2_CBR2 ! 5 375 SETHI_CBV2_CBR1 ! 6 376 ADDCCC_CBR1_CBR2_CBR2 ! 7 377 SETHI_CBV2_CBR1 ! 8 378 ADDCCC_CBR1_CBR2_CBR2 ! 9 379 SETHI_CBV2_CBR1 ! 10 380 ADDCCC_CBR1_CBR2_CBR2 ! 11 381 SETHI_CBV2_CBR1 ! 12 382 ADDCCC_CBR1_CBR2_CBR2 ! 13 383 SETHI_CBV2_CBR1 ! 14 384 ADDCCC_CBR1_CBR2_CBR2 ! 15 385 SETHI_CBV2_CBR1 ! 16 386 387 addc CBR1, CBR2, CBR2 ! 1 388 sethi %hi(CBV3), CBR1 ! 2 389 cmp CBR1, CBR2 ! 3 390 movnz %icc, FPRAS_BADCALC, %o0! 4, how detected 391 retl ! 5 392 mov CBO2, CBR2 ! 6, restore borrowed register 393 .skip 4*(13-7+1) ! 7 - 13 394 ! 395 ! illegal instr'n trap comes here 396 ! 397 mov CBO2, CBR2 ! 14, restore borrowed register 398 retl ! 15 399 mov FPRAS_BADTRAP, %o0 ! 16, how detected 400 SET_SIZE(fpras_chkfn_type1) 401#endif /* lint */ 402 403#if defined(lint) 404char soft_state_message_strings[SOLARIS_SOFT_STATE_MSG_CNT][SSM_SIZE]; 405#else /* lint */ 406 .seg ".data" 407 .global soft_state_message_strings 408 409 .align SSM_SIZE 410soft_state_message_strings: 411 .asciz SOLARIS_SOFT_STATE_BOOT_MSG_STR 412 .align SSM_SIZE 413 .asciz SOLARIS_SOFT_STATE_RUN_MSG_STR 414 .align SSM_SIZE 415 .asciz SOLARIS_SOFT_STATE_HALT_MSG_STR 416 .align SSM_SIZE 417 .asciz SOLARIS_SOFT_STATE_POWER_MSG_STR 418 .align SSM_SIZE 419 .asciz SOLARIS_SOFT_STATE_PANIC_MSG_STR 420 .align SSM_SIZE 421 .asciz SOLARIS_SOFT_STATE_REBOOT_MSG_STR 422 .align SSM_SIZE 423 .asciz SOLARIS_SOFT_STATE_DEBUG_MSG_STR 424 .align SSM_SIZE 425 .skip SSM_SIZE /* saved message */ 426 .nword 0 427 428 .seg ".text" 429#endif /* lint */ 430