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/machasi.h>
  38 #include <sys/asm_linkage.h>
  39 #include <zuluvm_offsets.h>
  40 #include <sys/zulu_hat.h>
  41 #include <sys/zuluvm.h>
  42 
  43 /*
  44  * function to look up ttes in zulu_hat TSB.
  45  *
  46  * zulu_hat_tsb_lookup_tl1 is called from the zuluvm dmv interrupt handler
  47  * so we can only use the global registers.
  48  *
  49  * zulu_hat_tsb_lookup_tl0 is called from TL=0 
  50  */
  51 #ifdef lint
  52 
  53 /* ARGSUSED */
  54 uint64_t
  55 zulu_hat_tsb_lookup_tl1(caddr_t vaddr)
  56 {
  57         return (0);
  58 }
  59 
  60 /* ARGSUSED */
  61 uint64_t
  62 zulu_hat_tsb_lookup_tl0(struct zulu_hat *zhat, caddr_t vaddr)
  63 {
  64         return (0);
  65 }
  66 
  67 #else   /* lint */
  68 
  69         /*
  70          * %g1 - vaddr | ctx
  71          * %g3 - return address
  72          * Must preserve %g7 for caller
  73          *
  74          * returns:
  75          * %g1 - pfn and flags
  76          * %g2 - zuluvm error code if %g1 is null
  77          */
  78         ENTRY_NP(zulu_hat_tsb_lookup_tl1)
  79         set     ZULU_CTX_MASK, %g4
  80         and     %g1, %g4, %g4
  81 
  82         ! we're at trap level 1, (TL=1)
  83         ! if the context is already locked by another
  84         ! thread, punt to the TL=0 code
  85         ! it's not safe to spinloop now.
  86 
  87         set     zulu_ctx_tab, %g6
  88         sllx    %g4, 3, %g5
  89 #ifdef DEBUG
  90         mov     %g5, %g2        ! remember ctx * 8
  91 #endif
  92         add     %g5, %g6, %g6
  93 
  94         ldx     [%g6], %g4
  95         andcc   %g4, 1, %g0
  96         bne,a,pn %icc, ctx_busy
  97           mov   ZULUVM_CTX_LOCKED, %g2
  98         
  99         ! now do a compare and swap and make sure it's still not locked
 100         or      %g4, 1, %g5
 101         casxa   [%g6]ASI_N, %g4, %g5
 102         cmp     %g4, %g5
 103         bne,a,pn %icc, ctx_busy
 104           mov   ZULUVM_CTX_LOCKED, %g2
 105 
 106         brz,a,pn %g4, zulu_hat_tsb_exit
 107           mov   %g0, %g1
 108 
 109         ! we have the lock now proceed
 110 
 111         ! set lsb of g3 to indicate that we need to unlock the context
 112         ! before returning
 113         ba,pt   %xcc, zulu_hat_tsb_lookup
 114           or    %g3, 1, %g3
 115 
 116 ctx_busy:
 117         mov     %g0, %g1
 118         jmpl    %g3+8, %g0
 119         nop
 120 
 121 
 122         /*
 123          * zulu_hat_tsb_lookup_tl0 jumps here
 124          *
 125          * %g1 vaddr | ctx
 126          * %g3 return address | unlock flag (bit zero)
 127          * %g4 has the zulu hat ptr (locked)
 128          */
 129 zulu_hat_tsb_lookup:
 130         mov     %g1, %g2
 131         mov     %g4, %g1
 132           
 133         add     %g1, ZULU_HAT_TSB_SZ, %g5
 134         lduh    [%g5], %g5              ! tsb size
 135         sub     %g5, 1, %g5
 136 
 137         srlx    %g2, 22,  %g4           ! 4m page hash
 138         and     %g5, %g4, %g4           ! hash index
 139         sllx    %g4, 4, %g4
 140         add     %g1, ZULU_HAT_TSB, %g5
 141         ldx     [%g5], %g5
 142         add     %g5, %g4, %g4           ! ptr to struct zulu_tte
 143         ldx     [%g4], %g5              ! get the tag
 144 
 145         set     (0x1ff << 13), %g6
 146         andn    %g5, %g6, %g5
 147         andn    %g2, %g6, %g6
 148         cmp     %g5, %g6
 149         bne,pn  %xcc, zulu_hat_tsb_try_512k
 150           nop
 151 
 152         ldx     [%g4 + 8], %g4          ! flags and pfn 
 153         brgez,pn %g4, zulu_hat_tsb_try_512k ! check if entry is valid
 154           nop
 155 
 156         sllx    %g4, 2, %g5
 157         srlx    %g5, 61, %g5            ! tte size
 158         cmp     %g5, ZULU_TTE4M
 159         be,pn   %xcc, zulu_hat_tsb_found
 160           nop
 161 
 162 zulu_hat_tsb_try_512k:
 163         add     %g1, ZULU_HAT_TSB_SZ, %g5
 164         lduh    [%g5], %g5              ! tsb size
 165         sub     %g5, 1, %g5
 166 
 167         srlx    %g2, 19, %g4           ! 4m page hash
 168         and     %g5, %g4, %g4           ! hash index
 169         sllx    %g4, 4, %g4
 170         add     %g1, ZULU_HAT_TSB, %g5
 171         ldx     [%g5], %g5
 172         add     %g5, %g4, %g4           ! ptr to struct zulu_tte
 173         ldx     [%g4], %g5              ! get the tag
 174         
 175         set     (0x3f << 13), %g6
 176         andn    %g5, %g6, %g5
 177         andn    %g2, %g6, %g6
 178         cmp     %g5, %g6
 179         bne,pn  %xcc, zulu_hat_tsb_try_64k
 180           nop
 181  
 182         ldx     [%g4 + 8], %g4          ! flags and pfn
 183         brgez,pn %g4, zulu_hat_tsb_try_64k ! check if entry is valid
 184           nop
 185  
 186         sllx    %g4, 2, %g5
 187         srlx    %g5, 61, %g5            ! tte size
 188         cmp     %g5, ZULU_TTE512K 
 189         be,pn   %xcc, zulu_hat_tsb_found
 190           nop
 191 
 192 zulu_hat_tsb_try_64k:
 193         add     %g1, ZULU_HAT_TSB_SZ, %g5
 194         lduh    [%g5], %g5              ! tsb size
 195         sub     %g5, 1, %g5
 196  
 197         srlx    %g2, 16, %g4           ! 4m page hash
 198         and     %g5, %g4, %g4           ! hash index
 199         sllx    %g4, 4, %g4
 200         add     %g1, ZULU_HAT_TSB, %g5
 201         ldx     [%g5], %g5
 202         add     %g5, %g4, %g4           ! ptr to struct zulu_tte
 203         ldx     [%g4], %g5              ! get the tag
 204 
 205         set     (0x7 << 13), %g6
 206         andn    %g5, %g6, %g5
 207         andn    %g2, %g6, %g6
 208         cmp     %g5, %g6
 209         bne,pn  %xcc, zulu_hat_tsb_try_8k
 210           nop
 211  
 212         ldx     [%g4 + 8], %g4          ! flags and pfn
 213         brgez,pn %g4, zulu_hat_tsb_try_8k ! check if entry is valid
 214           nop
 215  
 216         sllx    %g4, 2, %g5
 217         srlx    %g5, 61, %g5            ! tte size
 218         cmp     %g5, ZULU_TTE64K
 219         be,pn   %xcc, zulu_hat_tsb_found
 220           nop 
 221 
 222 zulu_hat_tsb_try_8k:
 223         add     %g1, ZULU_HAT_TSB_SZ, %g5
 224         lduh    [%g5], %g5              ! tsb size
 225         sub     %g5, 1, %g5
 226 
 227         srlx    %g2, 13, %g4            ! calc hash
 228         and     %g5, %g4, %g4           ! hash index
 229         sllx    %g4, 4, %g4
 230         add     %g1, ZULU_HAT_TSB, %g5
 231         ldx     [%g5], %g5              ! tsb ptr
 232         add     %g5, %g4, %g4           ! ptr to struct tte
 233         ldx     [%g4], %g5              ! get the tag
 234         cmp     %g5, %g2
 235         bne,pn  %xcc, zulu_hat_tsb_exit
 236           mov   %g0, %g1
 237 
 238         ldx     [%g4 + 8], %g4          ! flags and pfn
 239         brgez,pn %g4, zulu_hat_tsb_exit ! check if entry is valid
 240           mov   %g0, %g1
 241 
 242         sllx    %g4, 2, %g5
 243         srlx    %g5, 61, %g5            ! tte size
 244         brnz,pn %g5, zulu_hat_tsb_exit
 245           mov   %g0, %g1
 246 
 247 zulu_hat_tsb_found:
 248         ! expect the tte size in %g5
 249         mulx    %g5, 3, %g5
 250         mov     1, %g1
 251         sllx    %g1, %g5, %g1
 252         sub     %g1, 1, %g1
 253         andn    %g4, %g1, %g4
 254         srlx    %g2, 13, %g5
 255         and     %g1, %g5, %g5
 256         or      %g5, %g4, %g4
 257         mov     %g4, %g1
 258 
 259         ! now fall through to exit
 260 
 261 zulu_hat_tsb_exit:
 262         ! if bit zero of %g3 is set, we're at TL=1 and need to unlock
 263         ! the context here
 264         andcc   %g3, 1, %g0
 265         be,pn   %xcc, after_unlock
 266           nop
 267 
 268         ! clear the context unlock flag
 269         andn    %g3, 1, %g3
 270 
 271         set     ZULU_CTX_MASK, %g6
 272         and     %g2, %g6, %g6           ! ctx num
 273 
 274         sllx    %g6, 3, %g6
 275         set     zulu_ctx_tab, %g5
 276         add     %g6, %g5, %g5           ! %g5 = &zulu_ctx_tab[ctx_num]
 277         ldx     [%g5], %g6
 278         andn    %g6, 1, %g6
 279         stx     %g6, [%g5]
 280 
 281 after_unlock:
 282 
 283         ! set the status code to ZULUVM_NO_TTE in case we are running at TL=1
 284         ! and no tte was found.
 285         !
 286         ! note: caller doesn't examine %g2 unless flags and pfn are null
 287         jmpl    %g3 + 0x8, %g0
 288           mov   ZULUVM_NO_TTE, %g2
 289 
 290 
 291 
 292 
 293         SET_SIZE(zulu_hat_tsb_lookup_tl1)
 294 
 295         /*
 296          * %o0 - zulu hat ptr (already locked)
 297          * %o1 - vaddr
 298          */
 299         ENTRY_NP(zulu_hat_tsb_lookup_tl0)
 300         mov     %o0, %g4
 301 
 302         set     zulu_hat_tsb_lookup, %g3
 303 
 304         ! note bit zero of g3 is zero which tells zulu_hat_tsb_lookup
 305         ! to not unlock tsb before returning
 306 
 307         jmpl    %g3, %g3
 308           mov   %o1, %g1
 309 
 310         retl
 311           mov   %g1, %o0
 312         SET_SIZE(zulu_hat_tsb_lookup_tl0)
 313 
 314 #endif  /* lint */