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"