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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 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#if defined(lint) 30#include <sys/types.h> 31#include <sys/thread.h> 32#else /* lint */ 33#include "assym.h" 34#endif /* lint */ 35 36#include <sys/asi.h> 37#include <sys/sun4asi.h> 38#include <sys/machasi.h> 39#include <sys/asm_linkage.h> 40#include <sys/pte.h> 41#include <sys/mmu.h> 42#include <sys/intreg.h> 43#include <sys/zulumod.h> 44#include <vm/hat_sfmmu.h> 45#include <sys/zulu_hat.h> 46#include <zuluvm_offsets.h> 47 48#ifdef lint 49void 50zuluvm_dmv_tlbmiss_tl1() 51{} 52 53#else /* lint */ 54 55 DGDEF(zuluvm_base_pgsize) 56 .word 0 57 58 ENTRY_NP(zuluvm_dmv_tlbmiss_tl1) 59 60 ! g1 - zuluvm_state_t pointer 61 ! g2 - IRDR_0 62 mov UIII_IRDR_1, %g3 63 ldxa [%g3]ASI_INTR_RECEIVE, %g5 64 stx %g5, [%g1 + ZULUVM_ASM_TLB_ADDR] 65 mov UIII_IRDR_6, %g3 66 ldxa [%g3]ASI_INTR_RECEIVE, %g5 67 stx %g5, [%g1 + ZULUVM_ASM_TLB_TYPE] 68 69 stxa %g0, [%g0]ASI_INTR_RECEIVE_STATUS ! clear the BUSY bit 70 membar #Sync 71 72 mov %g1, %g7 73 74 ! check the fast tlb miss flag 75 sethi %hi(zuluvm_fast_tlb), %g6 76 lduw [%g6 + %lo(zuluvm_fast_tlb)], %g6 77 brz,pn %g6, send_intr1 78 mov ZULUVM_TTE_DELAY, %g1 79#if 1 80 add %g7, ZULUVM_STATE, %g4 81 mov ZULUVM_STATE_IDLE, %g1 82 mov ZULUVM_STATE_TLB_PENDING, %g6 83 casa [%g4]ASI_N, %g1, %g6 84 cmp %g6, %g1 85 be,pt %icc, 2f 86 nop 87 88 mov ZULUVM_STATE_CANCELED, %g1 89 cmp %g6, %g1 90 be,pt %icc, 1f 91 mov ZULUVM_STATE_STOPPED, %g1 92 retry 931: 94 st %g1, [%g4] 95#ifdef ZULUVM_STATS 96 lduw [%g7 + ZULUVM_ST_TLBCANCEL], %g3 97 add %g3, 1, %g3 98 stuw %g3, [%g7 + ZULUVM_ST_TLBCANCEL] 99#endif 100 retry 101 1022: 103 ldx [%g7 + ZULUVM_ASM_TLB_TYPE], %g4 104 and %g4, ZULUVM_DMA_MASK, %g4 105#ifdef ZULUVM_STATS 106 cmp %g4, ZULUVM_DMA2 107 be,a,pn %icc, 1f 108 add %g7, ZULUVM_ST_DTLB2MISS, %g1 109 cmp %g4, ZULUVM_ITLB1 110 be,a,pn %icc, 1f 111 add %g7, ZULUVM_ST_ITLB1MISS, %g1 112 cmp %g4, ZULUVM_ITLB2 113 be,a,pn %icc, 1f 114 add %g7, ZULUVM_ST_ITLB2MISS, %g1 115 add %g7, ZULUVM_ST_DTLB1MISS, %g1 1161: 117 lduw [%g1], %g3 118 add %g3, 1, %g3 119 stuw %g3, [%g1] 120#endif 121 /* 122 * lookup the tte in the tsb 123 * %g1 - vaddr[63:13], ctx[12:0] 124 * %g2 - our trap level 125 * %g3 - return address 126 * %g7 - zulu data pointer (needs to be preserved) 127 * return: 128 * %g1 - flags [63..58] and pfn [31..0] 129 * %g2 - status code if %g1 is null 130 * %g7 - zulu data pointer 131 */ 132 mov 1, %g2 133 set zulu_hat_tsb_lookup_tl1, %g3 134 jmpl %g3, %g3 135 ldx [%g7 + ZULUVM_ASM_TLB_ADDR], %g1 ! vaddr(tag) 136 137 /* 138 * did we find a tte ?? 139 * If not, %g2 has the error code 140 */ 141 brgez,a,pt %g1, send_intr 142 mov %g2, %g1 143 144 set zulu_tsb_hit, %g6 145 ldx [%g6], %g3 146 add %g3, 1, %g3 147 stx %g3, [%g6] 148 149 /* 150 * get flags and pfn 151 */ 152 sllx %g1, 32, %g6 153 srlx %g6, 32, %g6 ! %g6 pfn 154 srlx %g1, 59, %g3 155 and %g3, 0x7, %g2 ! %g2 page size 156 srlx %g3, 3, %g4 157 and %g4, 1, %g4 ! %g4 write perm 158 mov %g6, %g1 159 160 /* 161 * check if this is a dtlb2 miss(no itlb, pgsz != 8k) 162 * and if the current dtlb2 pgsz != tte pgsz 163 */ 164 ldx [%g7 + ZULUVM_ASM_TLB_TYPE], %g3 165 and %g3, 0x1, %g3 166 brnz,pt %g3, 3f ! not 0 => itlb => handles 167 nop 168 169 ! check page size, base page size is always handled by dtlb1, so we 170 ! only need to check against dtlb2 171 sethi %hi(zuluvm_base_pgsize), %g3 172 lduw [%g3 + %lo(zuluvm_base_pgsize)], %g3 173 cmp %g2, %g3 174 be,pt %icc, 2f 175 cmp %g2, ZULU_TTE4M 176 be,pt %icc, 2f ! TTE4M => dtlb2 => ok! 177 nop 178 179#ifdef ZULUVM_STATS 180 lduw [%g7 + ZULUVM_ST_PAGESIZE], %g3 181 add %g3, 1, %g3 182 stuw %g3, [%g7 + ZULUVM_ST_PAGESIZE] 183 add %g7, ZULUVM_ST_MISS, %g3 184 sll %g2, 2, %g5 185 add %g5, %g3, %g5 186 lduw [%g5], %g3 187 add %g3, 1, %g3 188 stuw %g3, [%g5] 189#endif 190 ! set tte size to ZULUVM_BASE_PGSZ 191 sethi %hi(zuluvm_base_pgsize), %g3 192 lduw [%g3 + %lo(zuluvm_base_pgsize)], %g3 193 ba,pt %icc, 3f 194 mov %g3, %g2 1952: 196 197#ifdef ZULUVM_STATS 198 add %g7, ZULUVM_ST_MISS, %g3 199 sll %g2, 2, %g5 200 add %g3, %g5, %g5 201 lduw [%g5], %g3 202 add %g3, 1, %g3 203 stuw %g3, [%g5] 204#endif 205 206 ! we maintain data on the last pfns for the last 12 pfns that we 207 ! processed 2083: 209 lduw [%g7 + ZULUVM_PFNCNT], %g5 210 add %g5, 4, %g3 211 cmp %g3, 48 212 be,a,pn %icc, 1f 213 mov %g0, %g3 214 2151: 216 stuw %g3, [%g7 + ZULUVM_PFNCNT] 217 sllx %g5, 3, %g5 218 add %g7, ZULUVM_PFNBUF, %g3 219 add %g3, %g5, %g3 220 stx %g1, [%g3] 221 stx %g2, [%g3 + 8] 222 stx %g4, [%g3 + 16] 223 ldx [%g7 + ZULUVM_ASM_TLB_TYPE], %g5 224 stx %g5, [%g3 + 24] 225 226 ldx [%g7 + ZULUVM_ASM_TLB_TYPE], %g3 227 and %g3, 0x3, %g3 ! tlbtype 228 ldx [%g7 + ZULUVM_ARG], %g6 229 230 ! write tte to zulu mmu 231 ! %g1 pfn 232 ! %g2 tte size 233 ! %g3 tlbtype 234 ! %g4 tte wrperm 235 ! %g6 zulu device driver arg 236 ! %g7 devtab pointer 237 238 sllx %g1, ZULUVM_ZFB_MMU_TLB_D_PA_SHIFT, %g1 239 mov 0x1, %g5 240 sllx %g5, 63, %g5 ! ZFB_MMU_TLB_D_V_MASK 241 or %g1, %g5, %g1 242 or %g1, ZULUVM_ZFB_MMU_TLB_D_C_MASK, %g1 243 sllx %g2, ZULUVM_ZFB_MMU_TLB_D_SZ_SHIFT, %g2 244 245 brz,pt %g4, 3f ! write perm ?? 246 or %g2, %g1, %g1 247 248 or %g1, ZULUVM_ZFB_MMU_TLB_D_W_MASK, %g1 2493: 250 ! at this point %g1 is ready to be written to the corresponding 251 ! data_in register, let's see which if it was itlb or dtlb... 252 and %g3, ZULUVM_ITLB_FLAG, %g3 253 ! assumption is that data miss 254 brz,pt %g3, 4f ! is more likely than instr miss 255 ldx [%g7 + ZULUVM_PAMMU], %g2 ! physical addr of zulu mmu regs 256 257 ! instruction miss 258 mov ZULUVM_ZFB_MMU_TLB_CR_IMISS_MASK, %g5 259 add %g2, ZULUVM_ITLB_DATA_IN, %g4 260 !stxa %g1, [%g4]ASI_IO 261 ba,pt %xcc, 5f 262 stxa %g1, [%g4]ASI_IO 263 !ldxa [%g4]ASI_IO, %g4 2644: 265 ! data miss 266 mov ZULUVM_ZFB_MMU_TLB_CR_DMISS_MASK, %g5 267 add %g2, ZULUVM_DTLB_DATA_IN, %g4 268 stxa %g1, [%g4]ASI_IO 269 !ldxa [%g4]ASI_IO, %g4 2705: 271 add %g7, ZULUVM_STATE, %g4 272 mov ZULUVM_STATE_TLB_PENDING, %g6 273 mov ZULUVM_STATE_IDLE, %g1 274 casa [%g4]ASI_N, %g6, %g1 275 cmp %g6, %g1 276 bne,a,pn %icc, stopped 277 mov ZULUVM_STATE_STOPPED, %g3 278 279 ldx [%g7 + ZULUVM_PAMMU], %g2 280 add %g2, ZULUVM_TLB_CONTROL, %g2 281 stxa %g5, [%g2]ASI_IO 282 !ldxa [%g2]ASI_IO, %g3 283 retry 284 285send_intr: 286 add %g7, ZULUVM_STATE, %g4 287 mov ZULUVM_STATE_INTR_QUEUED, %g5 288 mov ZULUVM_STATE_TLB_PENDING, %g3 289 casa [%g4]ASI_N, %g3, %g5 290 cmp %g3, %g5 291 be,pt %icc, deliver_intr 292 mov ZULUVM_STATE_STOPPED, %g3 293 ba,pt %icc, stopped 294 nop 295#endif 296 297send_intr1: 298 add %g7, ZULUVM_STATE, %g4 299 mov ZULUVM_STATE_IDLE, %g3 300 mov ZULUVM_STATE_INTR_QUEUED, %g5 301 casa [%g4]ASI_N, %g3, %g5 302 cmp %g3, %g5 303 be,pt %icc, deliver_intr 304 mov ZULUVM_STATE_STOPPED, %g3 305stopped: 306 st %g3, [%g4] 307#ifdef ZULUVM_STATS 308 lduw [%g7 + ZULUVM_ST_TLBCANCEL], %g3 309 add %g3, 1, %g3 310 stuw %g3, [%g7 + ZULUVM_ST_TLBCANCEL] 311#endif 312 retry 313 314deliver_intr: 315 stx %g1, [%g7 + ZULUVM_ASM_TLB_ERRCODE] ! set the error field 316 stx %g6, [%g7 + ZULUVM_ASM_TLB_TTE] ! deliver tte in data_0 317 ! %g6 is invalid if error != SUCCESS 318 ! setsoftint_tl1(uint64_t inum, uint64_t dummy) 319 set setsoftint_tl1, %g5 320 jmp %g5 321 lduh [%g7 + ZULUVM_INTRNUM], %g1 322 323 SET_SIZE(zuluvm_dmv_tlbmiss_tl1) 324 325#endif /* lint */ 326 327