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 /* 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 * This file is through cpp before being used as 31 * an inline. It contains support routines used 32 * only by DR for the copy-rename sequence. 33 */ 34 35 #if defined(lint) 36 #include <sys/types.h> 37 #include <sys/sbd_ioctl.h> 38 #include <sys/sbdp_priv.h> 39 #else 40 #include "assym.h" 41 #endif /* lint */ 42 43 #include <sys/asm_linkage.h> 44 #include <sys/param.h> 45 #include <sys/privregs.h> 46 #include <sys/machasi.h> 47 #include <sys/mmu.h> 48 #include <sys/machthread.h> 49 #include <sys/pte.h> 50 #include <sys/stack.h> 51 #include <sys/vis.h> 52 #include <sys/param.h> 53 #include <sys/errno.h> 54 #include <sys/vtrace.h> 55 #include <sys/clock.h> 56 #include <sys/asi.h> 57 #include <sys/fsr.h> 58 #include <sys/cheetahregs.h> 59 #include <sys/cheetahasm.h> 60 61 #ifndef lint 62 63 /* 64 * Invalidating the E$ tags is only needed on Cheetah following 65 * the manual displacement flush. The internal flush ASI used by 66 * Cheetahplus, Jaguar, and Panther will invalidate the cache lines. 67 * 68 * arg1 = ecache_size 69 * arg2 = ecache_linesize 70 */ 71 #define ECACHE_FLUSHTAGS(arg1, arg2, tmp1) \ 72 GET_CPU_IMPL(tmp1) ;\ 73 srlx arg1, 1, arg1 ;\ 74 cmp tmp1, CHEETAH_IMPL ;\ 75 bne 1f ;\ 76 nop ;\ 77 sub arg1, arg2, tmp1 ;\ 78 0: ;\ 79 stxa %g0, [tmp1]ASI_EC_DIAG ;\ 80 membar #Sync ;\ 81 cmp %g0, tmp1 ;\ 82 bne,pt %icc, 0b ;\ 83 sub tmp1, arg2, tmp1 ;\ 84 1: 85 86 87 #define SWITCH_STACK(estk) \ 88 flushw ;\ 89 sub estk, SA(KFPUSIZE+GSR_SIZE), estk ;\ 90 andn estk, 0x3f, estk ;\ 91 sub estk, SA(MINFRAME) + STACK_BIAS, %sp ;\ 92 mov estk, %fp 93 94 /* 95 * Returns icache size and linesize in reg1 and reg2, respectively. 96 * Panther has a larger icache compared to Cheetahplus and Jaguar. 97 */ 98 #define GET_ICACHE_PARAMS(reg1, reg2) \ 99 GET_CPU_IMPL(reg1) ;\ 100 cmp reg1, PANTHER_IMPL ;\ 101 bne %xcc, 1f ;\ 102 nop ;\ 103 set PN_ICACHE_SIZE, reg1 ;\ 104 set PN_ICACHE_LSIZE, reg2 ;\ 105 ba 2f ;\ 106 nop ;\ 107 1: ;\ 108 set CH_ICACHE_SIZE, reg1 ;\ 109 set CH_ICACHE_LSIZE, reg2 ;\ 110 2: 111 112 #endif /* !lint */ 113 114 #if defined(lint) 115 116 /*ARGSUSED*/ 117 void 118 sbdp_shutdown_asm(sbdp_shutdown_t *shutshown) 119 {} 120 121 #else /* lint */ 122 123 ENTRY_NP(sbdp_shutdown_asm) 124 ! %o0 = address of sbdp_shutdown_t structure passed in 125 ! 126 ! struct sbdp_shutdown { 127 ! uint64_t estack; -> %o0 128 ! uint64_t flushaddr; -> %o1 129 ! uint32_t size; -> %o2 130 ! uint32_t linesize; -> %g1 131 ! uint64_t physaddr; -> %o0 132 ! } sbdp_shutdown_t; 133 ! 134 membar #LoadStore 135 mov %o0, %o4 136 ldx [%o4], %o0 137 ldx [%o4 + 8], %o1 138 ld [%o4 + 16], %o2 139 ld [%o4 + 20], %g1 140 141 ! 142 ! Switch stack pointer to bbsram 143 ! 144 SWITCH_STACK(%o0) 145 146 ldx [%o4 + 24], %o0 !save physaddr in %o0 147 ! 148 ! Get some globals 149 ! 150 ! ecache_linesize already in %g1 151 152 sethi %hi(dcache_linesize), %g2 153 ld [%g2 + %lo(dcache_linesize)], %g2 154 155 sethi %hi(dcache_size), %g3 156 ld [%g3 + %lo(dcache_size)], %g3 157 158 ! 159 ! Save the E$ size 160 ! 161 mov %o2, %o5 162 ! 163 ! Flush E$ 164 ! 165 rdpr %pstate, %o3 166 andn %o3, PSTATE_IE | PSTATE_AM, %o4 167 wrpr %g0, %o4, %pstate 168 169 ! Panther needs to flush L2 before L3 cache. 170 PN_L2_FLUSHALL(%o4, %g4, %g5) 171 172 ECACHE_FLUSHALL(%o2, %g1, %o1, %o4) 173 174 wrpr %g0, %o3, %pstate 175 176 ! 177 ! Invalidate the E$ tags (Cheetah only). 178 ! 179 ECACHE_FLUSHTAGS(%o5, %g1, %o3) 180 181 ! 182 ! %o2 & %o3 now available 183 ! 184 185 membar #Sync 186 187 ! 188 ! Flush D$ 189 ! 190 CH_DCACHE_FLUSHALL(%g3, %g2, %o3) 191 192 ! 193 ! Flush I$ 194 ! 195 GET_ICACHE_PARAMS(%g5, %g4) 196 CH_ICACHE_FLUSHALL(%g5, %g4, %o3, %o4) 197 198 membar #Sync 199 200 ! 201 ! Flush all unlocked dtlb's & itlb's 202 ! 203 sethi %hi(FLUSH_ADDR), %g3 204 set DEMAP_ALL_TYPE, %g1 205 stxa %g0, [%g1]ASI_DTLB_DEMAP 206 stxa %g0, [%g1]ASI_ITLB_DEMAP 207 flush %g3 208 209 sir 0 210 SET_SIZE(sbdp_shutdown_asm) 211 212 .global sbdp_shutdown_asm_end 213 214 .skip 2048 215 216 sbdp_shutdown_asm_end: 217 218 #endif /* lint */ 219 220 221 #if defined(lint) 222 223 #else /* lint */ 224 #include "assym.h" 225 #endif /* lint */ 226 227 #define TT_HSM 0x99 228 229 #if defined(lint) 230 /* ARGSUSED */ 231 void 232 sgdr_mem_blkcopy(caddr_t src, caddr_t dst, u_int linecount, u_int linesize) 233 {} 234 235 void 236 stdmcdecode(uint64_t physaddr, uint64_t value) 237 { 238 physaddr = physaddr; 239 value = value; 240 } 241 242 #else /* !lint */ 243 ! 244 ! Move a single cache line of data. Survive UE and CE on the read 245 ! 246 ! i0 = src va 247 ! i1 = dst va 248 ! i2 = line count 249 ! i3 = line size 250 ! i4 = cache of fpu state 251 ! 252 ENTRY(sgdr_mem_blkcopy) 253 254 ! TODO: can we safely SAVE here 255 save %sp, -SA(MINFRAME + 2*64), %sp 256 257 ! XXX do we need to save the state of the fpu? 258 rd %fprs, %i4 259 btst (FPRS_DU|FPRS_DL|FPRS_FEF), %i4 260 261 ! always enable FPU 262 wr %g0, FPRS_FEF, %fprs 263 264 bz,a 1f 265 nop 266 267 ! save in-use fpregs on stack 268 membar #Sync 269 add %fp, STACK_BIAS - 81, %o2 270 and %o2, -64, %o2 271 stda %d0, [%o2]ASI_BLK_P 272 membar #Sync 273 274 1: 275 brz,pn %i2, 2f ! while (linecount) { 276 nop 277 ldda [%i0]ASI_BLK_P, %d0 ! *dst = *src; 278 membar #Sync 279 stda %d0, [%i1]ASI_BLK_COMMIT_P 280 membar #Sync 281 282 add %i0, %i3, %i0 ! dst++, src++; 283 add %i1, %i3, %i1 284 285 ba 1b ! linecount-- } 286 dec %i2 287 288 2: 289 membar #Sync 290 291 ! restore fp to the way we got it 292 btst (FPRS_DU|FPRS_DL|FPRS_FEF), %i4 293 bz,a 3f 294 nop 295 296 ! restore fpregs from stack 297 add %fp, STACK_BIAS - 81, %o2 298 and %o2, -64, %o2 299 ldda [%o2]ASI_BLK_P, %d0 300 membar #Sync 301 302 3: 303 wr %g0, %i4, %fprs ! fpu back to the way it was 304 ret 305 restore 306 SET_SIZE(sgdr_mem_blkcopy) 307 308 ! Store long word value at mc regs 309 ! 310 ! void stdmcdecode(uint64_t physaddr, uint64_t value) 311 ! 312 ENTRY(stdmcdecode) 313 /* 314 * disable interrupts, clear Address Mask to access 64 bit physaddr 315 */ 316 rdpr %pstate, %o4 317 andn %o4, PSTATE_IE | PSTATE_AM, %o5 318 wrpr %o5, 0, %pstate ! clear IE, AM bits 319 stxa %o1, [%o0]ASI_MC_DECODE 320 membar #Sync 321 retl 322 wrpr %g0, %o4, %pstate ! restore earlier pstate register value 323 SET_SIZE(stdmcdecode) 324 325 #endif /* lint */