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