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