1*5d9d9091SRichard Lowe/* 2*5d9d9091SRichard Lowe * CDDL HEADER START 3*5d9d9091SRichard Lowe * 4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the 5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License"). 6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License. 7*5d9d9091SRichard Lowe * 8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing. 10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions 11*5d9d9091SRichard Lowe * and limitations under the License. 12*5d9d9091SRichard Lowe * 13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 18*5d9d9091SRichard Lowe * 19*5d9d9091SRichard Lowe * CDDL HEADER END 20*5d9d9091SRichard Lowe */ 21*5d9d9091SRichard Lowe 22*5d9d9091SRichard Lowe/* 23*5d9d9091SRichard Lowe * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*5d9d9091SRichard Lowe * Use is subject to license terms. 25*5d9d9091SRichard Lowe */ 26*5d9d9091SRichard Lowe 27*5d9d9091SRichard Lowe#include <sys/asm_linkage.h> 28*5d9d9091SRichard Lowe#include "assym.h" 29*5d9d9091SRichard Lowe 30*5d9d9091SRichard Lowe#include <sys/sun4asi.h> 31*5d9d9091SRichard Lowe#include <sys/machparam.h> 32*5d9d9091SRichard Lowe#include <vm/hat_sfmmu.h> 33*5d9d9091SRichard Lowe 34*5d9d9091SRichard Lowe/* 35*5d9d9091SRichard Lowe * This file contains a kmdb-support function which retrieves the TTE for a 36*5d9d9091SRichard Lowe * given VA/context pair, and returns it to the caller if the TTE is valid. 37*5d9d9091SRichard Lowe * The code here is essentially an assembly implementation of the unix-tte 38*5d9d9091SRichard Lowe * word used to allow OBP to do the same thing. 39*5d9d9091SRichard Lowe * 40*5d9d9091SRichard Lowe * Depending on the invocation context, the translator may be invoked either 41*5d9d9091SRichard Lowe * as a normal function (kdi_vatotte) or as a trap handler fragment 42*5d9d9091SRichard Lowe * (kdi_trap_vatotte). 43*5d9d9091SRichard Lowe */ 44*5d9d9091SRichard Lowe 45*5d9d9091SRichard Lowe/* 46*5d9d9091SRichard Lowe * uint64_t 47*5d9d9091SRichard Lowe * kdi_hme_hash_function(sfmmu_t *sfmmup, uintptr_t va, uint_t hmeshift) 48*5d9d9091SRichard Lowe * { 49*5d9d9091SRichard Lowe * uintptr_t hash = (uintptr_t)sfmmup ^ (va >> hmeshift); 50*5d9d9091SRichard Lowe * 51*5d9d9091SRichard Lowe * if (sfmmup == KHATID) { 52*5d9d9091SRichard Lowe * return (khme_hash_pa + (hash & KHMEHASH_SZ) * 53*5d9d9091SRichard Lowe * sizeof (struct hmehash_bucket)); 54*5d9d9091SRichard Lowe * } else { 55*5d9d9091SRichard Lowe * return (uhme_hash_pa + (hash & UHMEHASH_SZ) * 56*5d9d9091SRichard Lowe * sizeof (struct hmehash_bucket)); 57*5d9d9091SRichard Lowe * } 58*5d9d9091SRichard Lowe * } 59*5d9d9091SRichard Lowe */ 60*5d9d9091SRichard Lowe 61*5d9d9091SRichard Lowe/* 62*5d9d9091SRichard Lowe * Parameters: %g1: VA, %g2: sfmmup, %g4: hmeshift 63*5d9d9091SRichard Lowe * Scratch: %g4, %g5, %g6 available 64*5d9d9091SRichard Lowe * Return: Hash value in %g4 65*5d9d9091SRichard Lowe */ 66*5d9d9091SRichard Lowe 67*5d9d9091SRichard Lowe#define KDI_HME_HASH_FUNCTION \ 68*5d9d9091SRichard Lowe srlx %g1, %g4, %g4; /* va >> hmeshift */ \ 69*5d9d9091SRichard Lowe xor %g4, %g2, %g4; /* hash in g4 */ \ 70*5d9d9091SRichard Lowe set KHATID, %g5; \ 71*5d9d9091SRichard Lowe ldx [%g5], %g5; \ 72*5d9d9091SRichard Lowe cmp %g2, %g5; \ 73*5d9d9091SRichard Lowe be %xcc, is_khat; \ 74*5d9d9091SRichard Lowe nop; \ 75*5d9d9091SRichard Lowe \ 76*5d9d9091SRichard Lowe /* sfmmup != KHATID */ \ 77*5d9d9091SRichard Lowe set UHMEHASH_SZ, %g5; \ 78*5d9d9091SRichard Lowe ld [%g5], %g5; \ 79*5d9d9091SRichard Lowe and %g4, %g5, %g4; \ 80*5d9d9091SRichard Lowe mulx %g4, HMEBUCK_SIZE, %g4; /* g4 = off from hash_pa */ \ 81*5d9d9091SRichard Lowe set uhme_hash_pa, %g5; \ 82*5d9d9091SRichard Lowe ldx [%g5], %g5; \ 83*5d9d9091SRichard Lowe ba hash_done; \ 84*5d9d9091SRichard Lowe add %g4, %g5, %g4; \ 85*5d9d9091SRichard Lowe \ 86*5d9d9091SRichard Loweis_khat: /* sfmmup == KHATID */ \ 87*5d9d9091SRichard Lowe set KHMEHASH_SZ, %g5; \ 88*5d9d9091SRichard Lowe ld [%g5], %g5; \ 89*5d9d9091SRichard Lowe and %g4, %g5, %g4; \ 90*5d9d9091SRichard Lowe mulx %g4, HMEBUCK_SIZE, %g4; /* g4 = off from hash_pa */ \ 91*5d9d9091SRichard Lowe set khme_hash_pa, %g5; \ 92*5d9d9091SRichard Lowe ldx [%g5], %g5; \ 93*5d9d9091SRichard Lowe add %g4, %g5, %g4; \ 94*5d9d9091SRichard Lowe \ 95*5d9d9091SRichard Lowehash_done: 96*5d9d9091SRichard Lowe 97*5d9d9091SRichard Lowe/* 98*5d9d9091SRichard Lowe * uint64_t 99*5d9d9091SRichard Lowe * kdi_hme_hash_tag(uint64_t rehash, uintptr_t va) 100*5d9d9091SRichard Lowe * { 101*5d9d9091SRichard Lowe * uint_t hmeshift = HME_HASH_SHIFT(rehash); 102*5d9d9091SRichard Lowe * uint64_t bspage = HME_HASH_BSPAGE(va, hmeshift); 103*5d9d9091SRichard Lowe * return (rehash | (bspage << HTAG_BSPAGE_SHIFT)); 104*5d9d9091SRichard Lowe * } 105*5d9d9091SRichard Lowe */ 106*5d9d9091SRichard Lowe 107*5d9d9091SRichard Lowe/* 108*5d9d9091SRichard Lowe * Parameters: %g1: VA, %g3: rehash 109*5d9d9091SRichard Lowe * Scratch: %g5, %g6 available 110*5d9d9091SRichard Lowe * Return: hmeblk tag in %g5 111*5d9d9091SRichard Lowe */ 112*5d9d9091SRichard Lowe 113*5d9d9091SRichard Lowe#define KDI_HME_HASH_TAG \ 114*5d9d9091SRichard Lowe cmp %g3, TTE8K; \ 115*5d9d9091SRichard Lowe be,a %xcc, bspage; \ 116*5d9d9091SRichard Lowe mov HBLK_RANGE_SHIFT, %g5; \ 117*5d9d9091SRichard Lowe mulx %g3, 3, %g5; \ 118*5d9d9091SRichard Lowe add %g5, MMU_PAGESHIFT, %g5; \ 119*5d9d9091SRichard Lowe \ 120*5d9d9091SRichard Lowebspage: /* TTE_PAGE_SHIFT in %g5 */ \ 121*5d9d9091SRichard Lowe srlx %g1, %g5, %g6; \ 122*5d9d9091SRichard Lowe sub %g5, MMU_PAGESHIFT, %g5; \ 123*5d9d9091SRichard Lowe sllx %g6, %g5, %g5; \ 124*5d9d9091SRichard Lowe \ 125*5d9d9091SRichard Lowe /* BSPAGE in %g5 */ \ 126*5d9d9091SRichard Lowe sllx %g5, HTAG_BSPAGE_SHIFT, %g5; \ 127*5d9d9091SRichard Lowe sllx %g3, HTAG_REHASH_SHIFT, %g6; \ 128*5d9d9091SRichard Lowe or %g6, SFMMU_INVALID_SHMERID, %g6; \ 129*5d9d9091SRichard Lowe or %g5, %g6, %g5 130*5d9d9091SRichard Lowe 131*5d9d9091SRichard Lowe/* 132*5d9d9091SRichard Lowe * uint64_t 133*5d9d9091SRichard Lowe * kdi_hme_hash_table_search(sfmmu_t *sfmmup, uint64_t hmebpa, uint64_t hblktag) 134*5d9d9091SRichard Lowe * { 135*5d9d9091SRichard Lowe * struct hme_blk *hblkp; 136*5d9d9091SRichard Lowe * uint64_t blkpap = hmebpa + HMEBP_HBLK; 137*5d9d9091SRichard Lowe * uint64_t blkpa; 138*5d9d9091SRichard Lowe * 139*5d9d9091SRichard Lowe * while ((blkpa = lddphys(blkpap)) != HMEBLK_ENDPA) { 140*5d9d9091SRichard Lowe * if (lddphys(blkpa + HMEBLK_TAG) == hblktag) { 141*5d9d9091SRichard Lowe * if ((sfmmu_t *)lddphys(blkpa + HMEBLK_TAG + 8) == 142*5d9d9091SRichard Lowe * sfmmup) 143*5d9d9091SRichard Lowe * return (blkpa); 144*5d9d9091SRichard Lowe * } 145*5d9d9091SRichard Lowe * 146*5d9d9091SRichard Lowe * blkpap = blkpa + HMEBLK_NEXTPA; 147*5d9d9091SRichard Lowe * } 148*5d9d9091SRichard Lowe * 149*5d9d9091SRichard Lowe * return (NULL); 150*5d9d9091SRichard Lowe * } 151*5d9d9091SRichard Lowe */ 152*5d9d9091SRichard Lowe 153*5d9d9091SRichard Lowe/* 154*5d9d9091SRichard Lowe * Parameters: %g2: sfmmup, %g4: hmebp PA, %g5: hmeblk tag 155*5d9d9091SRichard Lowe * Scratch: %g4, %g5, %g6 available 156*5d9d9091SRichard Lowe * Return: hmeblk PA in %g4 157*5d9d9091SRichard Lowe */ 158*5d9d9091SRichard Lowe 159*5d9d9091SRichard Lowe#define KDI_HME_HASH_TABLE_SEARCH \ 160*5d9d9091SRichard Lowe add %g4, HMEBUCK_NEXTPA, %g4; /* %g4 is hmebucket PA */ \ 161*5d9d9091SRichard Lowesearch_loop: \ 162*5d9d9091SRichard Lowe ldxa [%g4]ASI_MEM, %g4; \ 163*5d9d9091SRichard Lowe cmp %g4, HMEBLK_ENDPA; \ 164*5d9d9091SRichard Lowe be,a,pn %xcc, search_done; \ 165*5d9d9091SRichard Lowe clr %g4; \ 166*5d9d9091SRichard Lowe \ 167*5d9d9091SRichard Lowe add %g4, HMEBLK_TAG, %g4; /* %g4 is now hmeblk PA */ \ 168*5d9d9091SRichard Lowe ldxa [%g4]ASI_MEM, %g6; \ 169*5d9d9091SRichard Lowe sub %g4, HMEBLK_TAG, %g4; \ 170*5d9d9091SRichard Lowe cmp %g5, %g6; \ 171*5d9d9091SRichard Lowe bne,a %xcc, search_loop; \ 172*5d9d9091SRichard Lowe add %g4, HMEBLK_NEXTPA, %g4; \ 173*5d9d9091SRichard Lowe \ 174*5d9d9091SRichard Lowe /* Found a match. Is it in the right address space? */ \ 175*5d9d9091SRichard Lowe add %g4, (HMEBLK_TAG + 8), %g4; \ 176*5d9d9091SRichard Lowe ldxa [%g4]ASI_MEM, %g6; \ 177*5d9d9091SRichard Lowe sub %g4, (HMEBLK_TAG + 8), %g4; \ 178*5d9d9091SRichard Lowe cmp %g6, %g2; \ 179*5d9d9091SRichard Lowe bne,a %xcc, search_loop; \ 180*5d9d9091SRichard Lowe add %g4, HMEBLK_NEXTPA, %g4; \ 181*5d9d9091SRichard Lowe \ 182*5d9d9091SRichard Lowesearch_done: 183*5d9d9091SRichard Lowe 184*5d9d9091SRichard Lowe/* 185*5d9d9091SRichard Lowe * uint64_t 186*5d9d9091SRichard Lowe * kdi_hblk_to_ttep(uint64_t hmeblkpa, uintptr_t va) 187*5d9d9091SRichard Lowe * { 188*5d9d9091SRichard Lowe * size_t ttesz = ldphys(hmeblkpa + HMEBLK_MISC) & HBLK_SZMASK; 189*5d9d9091SRichard Lowe * uint_t idx; 190*5d9d9091SRichard Lowe * 191*5d9d9091SRichard Lowe * if (ttesz == TTE8K) 192*5d9d9091SRichard Lowe * idx = (va >> MMU_PAGESHIFT) & (NHMENTS - 1); 193*5d9d9091SRichard Lowe * else 194*5d9d9091SRichard Lowe * idx = 0; 195*5d9d9091SRichard Lowe * 196*5d9d9091SRichard Lowe * return (hmeblkpa + (idx * sizeof (struct sf_hment)) + 197*5d9d9091SRichard Lowe * HMEBLK_HME + SFHME_TTE); 198*5d9d9091SRichard Lowe * } 199*5d9d9091SRichard Lowe */ 200*5d9d9091SRichard Lowe 201*5d9d9091SRichard Lowe/* 202*5d9d9091SRichard Lowe * Parameters: %g1: VA, %g4: hmeblk PA 203*5d9d9091SRichard Lowe * Scratch: %g1, %g2, %g3, %g4, %g5, %g6 available 204*5d9d9091SRichard Lowe * Return: TTE PA in %g2 205*5d9d9091SRichard Lowe */ 206*5d9d9091SRichard Lowe 207*5d9d9091SRichard Lowe#define KDI_HBLK_TO_TTEP \ 208*5d9d9091SRichard Lowe add %g4, HMEBLK_MISC, %g3; \ 209*5d9d9091SRichard Lowe lda [%g3]ASI_MEM, %g3; \ 210*5d9d9091SRichard Lowe and %g3, HBLK_SZMASK, %g3; /* ttesz in %g3 */ \ 211*5d9d9091SRichard Lowe \ 212*5d9d9091SRichard Lowe cmp %g3, TTE8K; \ 213*5d9d9091SRichard Lowe bne,a ttep_calc; \ 214*5d9d9091SRichard Lowe clr %g1; \ 215*5d9d9091SRichard Lowe srlx %g1, MMU_PAGESHIFT, %g1; \ 216*5d9d9091SRichard Lowe and %g1, NHMENTS - 1, %g1; \ 217*5d9d9091SRichard Lowe \ 218*5d9d9091SRichard Lowettep_calc: /* idx in %g1 */ \ 219*5d9d9091SRichard Lowe mulx %g1, SFHME_SIZE, %g2; \ 220*5d9d9091SRichard Lowe add %g2, %g4, %g2; \ 221*5d9d9091SRichard Lowe add %g2, (HMEBLK_HME1 + SFHME_TTE), %g2; 222*5d9d9091SRichard Lowe 223*5d9d9091SRichard Lowe/* 224*5d9d9091SRichard Lowe * uint64_t 225*5d9d9091SRichard Lowe * kdi_vatotte(uintptr_t va, int cnum) 226*5d9d9091SRichard Lowe * { 227*5d9d9091SRichard Lowe * sfmmu_t *sfmmup = ksfmmup; 228*5d9d9091SRichard Lowe * uint64_t hmebpa, hmetag, hmeblkpa; 229*5d9d9091SRichard Lowe * int i; 230*5d9d9091SRichard Lowe * 231*5d9d9091SRichard Lowe * for (i = 1; i < DEFAULT_MAX_HASHCNT + 1; i++) { 232*5d9d9091SRichard Lowe * hmebpa = kdi_c_hme_hash_function(sfmmup, va, HME_HASH_SHIFT(i)); 233*5d9d9091SRichard Lowe * hmetag = kdi_c_hme_hash_tag(i, va); 234*5d9d9091SRichard Lowe * hmeblkpa = kdi_c_hme_hash_table_search(sfmmup, hmebpa, hmetag); 235*5d9d9091SRichard Lowe * 236*5d9d9091SRichard Lowe * if (hmeblkpa != NULL) { 237*5d9d9091SRichard Lowe * uint64_t tte = lddphys(kdi_c_hblk_to_ttep(hmeblkpa, 238*5d9d9091SRichard Lowe * va)); 239*5d9d9091SRichard Lowe * 240*5d9d9091SRichard Lowe * if ((int64_t)tte < 0) 241*5d9d9091SRichard Lowe * return (tte); 242*5d9d9091SRichard Lowe * else 243*5d9d9091SRichard Lowe * return (0); 244*5d9d9091SRichard Lowe * } 245*5d9d9091SRichard Lowe * } 246*5d9d9091SRichard Lowe * 247*5d9d9091SRichard Lowe * return (0); 248*5d9d9091SRichard Lowe * } 249*5d9d9091SRichard Lowe */ 250*5d9d9091SRichard Lowe 251*5d9d9091SRichard Lowe /* 252*5d9d9091SRichard Lowe * Invocation in normal context as a VA-to-TTE translator 253*5d9d9091SRichard Lowe * for kernel context only. This routine returns 0 on 254*5d9d9091SRichard Lowe * success and -1 on error. 255*5d9d9091SRichard Lowe * 256*5d9d9091SRichard Lowe * %o0 = VA, input register 257*5d9d9091SRichard Lowe * %o1 = KCONTEXT 258*5d9d9091SRichard Lowe * %o2 = ttep, output register 259*5d9d9091SRichard Lowe */ 260*5d9d9091SRichard Lowe ENTRY_NP(kdi_vatotte) 261*5d9d9091SRichard Lowe mov %o0, %g1 /* VA in %g1 */ 262*5d9d9091SRichard Lowe mov %o1, %g2 /* cnum in %g2 */ 263*5d9d9091SRichard Lowe 264*5d9d9091SRichard Lowe set kdi_trap_vatotte, %g3 265*5d9d9091SRichard Lowe jmpl %g3, %g7 /* => %g1: TTE or 0 */ 266*5d9d9091SRichard Lowe add %g7, 8, %g7 267*5d9d9091SRichard Lowe 268*5d9d9091SRichard Lowe brz %g1, 1f 269*5d9d9091SRichard Lowe nop 270*5d9d9091SRichard Lowe 271*5d9d9091SRichard Lowe /* Got a valid TTE */ 272*5d9d9091SRichard Lowe stx %g1, [%o2] 273*5d9d9091SRichard Lowe retl 274*5d9d9091SRichard Lowe clr %o0 275*5d9d9091SRichard Lowe 276*5d9d9091SRichard Lowe /* Failed translation */ 277*5d9d9091SRichard Lowe1: retl 278*5d9d9091SRichard Lowe mov -1, %o0 279*5d9d9091SRichard Lowe SET_SIZE(kdi_vatotte) 280*5d9d9091SRichard Lowe 281*5d9d9091SRichard Lowe /* 282*5d9d9091SRichard Lowe * %g1 = vaddr passed in, tte or 0 (error) when return 283*5d9d9091SRichard Lowe * %g2 = KCONTEXT 284*5d9d9091SRichard Lowe * %g7 = return address 285*5d9d9091SRichard Lowe */ 286*5d9d9091SRichard Lowe ENTRY_NP(kdi_trap_vatotte) 287*5d9d9091SRichard Lowe 288*5d9d9091SRichard Lowe cmp %g2, KCONTEXT /* make sure called in kernel ctx */ 289*5d9d9091SRichard Lowe bne,a,pn %icc, 6f 290*5d9d9091SRichard Lowe clr %g1 291*5d9d9091SRichard Lowe 292*5d9d9091SRichard Lowe sethi %hi(ksfmmup), %g2 293*5d9d9091SRichard Lowe ldx [%g2 + %lo(ksfmmup)], %g2 294*5d9d9091SRichard Lowe 295*5d9d9091SRichard Lowe mov 1, %g3 /* VA %g1, ksfmmup %g2, idx %g3 */ 296*5d9d9091SRichard Lowe mov HBLK_RANGE_SHIFT, %g4 297*5d9d9091SRichard Lowe ba 3f 298*5d9d9091SRichard Lowe nop 299*5d9d9091SRichard Lowe 300*5d9d9091SRichard Lowe1: mulx %g3, 3, %g4 /* 3: see TTE_BSZS_SHIFT */ 301*5d9d9091SRichard Lowe add %g4, MMU_PAGESHIFT, %g4 302*5d9d9091SRichard Lowe 303*5d9d9091SRichard Lowe3: KDI_HME_HASH_FUNCTION /* %g1, %g2, %g4 => hash in %g4 */ 304*5d9d9091SRichard Lowe KDI_HME_HASH_TAG /* %g1, %g3 => tag in %g5 */ 305*5d9d9091SRichard Lowe KDI_HME_HASH_TABLE_SEARCH /* %g2, %g4, %g5 => hmeblk PA in %g4 */ 306*5d9d9091SRichard Lowe 307*5d9d9091SRichard Lowe brz %g4, 5f 308*5d9d9091SRichard Lowe nop 309*5d9d9091SRichard Lowe 310*5d9d9091SRichard Lowe KDI_HBLK_TO_TTEP /* %g1, %g4 => TTE PA in %g2 */ 311*5d9d9091SRichard Lowe ldxa [%g2]ASI_MEM, %g1 312*5d9d9091SRichard Lowe brgez,a %g1, 4f 313*5d9d9091SRichard Lowe clr %g1 314*5d9d9091SRichard Lowe4: ba,a 6f 315*5d9d9091SRichard Lowe 316*5d9d9091SRichard Lowe5: add %g3, 1, %g3 317*5d9d9091SRichard Lowe set mmu_hashcnt, %g4 318*5d9d9091SRichard Lowe lduw [%g4], %g4 319*5d9d9091SRichard Lowe cmp %g3, %g4 320*5d9d9091SRichard Lowe ble 1b 321*5d9d9091SRichard Lowe nop 322*5d9d9091SRichard Lowe 323*5d9d9091SRichard Lowe clr %g1 324*5d9d9091SRichard Lowe 325*5d9d9091SRichard Lowe6: jmp %g7 326*5d9d9091SRichard Lowe nop 327*5d9d9091SRichard Lowe SET_SIZE(kdi_trap_vatotte) 328*5d9d9091SRichard Lowe 329