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 2006 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#include <sys/asm_linkage.h> 30#include <sys/machasi.h> 31#include <sys/machtrap.h> 32#include <sys/privregs.h> 33#include <sys/mmu.h> 34#include <vm/mach_sfmmu.h> 35 36#if defined(sun4v) && !defined(lint) 37#include <sys/machparam.h> 38#endif 39 40#if defined(sun4v) && defined(KMDB_TRAPCOUNT) 41/* 42 * The sun4v implemenations of the fast miss handlers are larger than those 43 * of their sun4u kin. This is unfortunate because there is not enough space 44 * remaining in the respective trap table entries for this debug feature. 45 */ 46#error "KMDB_TRAPCOUNT not supported on sun4v" 47#endif 48 49/* 50 * This file contains the trap handlers that will be copied to kmdb's trap 51 * table. See kaif_activate.c for the code that does the actual copying. 52 * 53 * The handlers have a debugging feature, enabled when KMDB_TRAPCOUNT is 54 * defined, which allows them to keep a running count of the number of times 55 * a given trap has occurred. The counter is stored in the padding at the end 56 * of the handler. Write access is of course required to allow the values to 57 * be updated, so KMDB_TRAPCOUNT also enables the installation of DTLB entries 58 * for each trap table page. Finally, the code in this file is copied into 59 * the actual location used by the handler, so we can't perform compile-time 60 * counter location calculations. The calculations are instead performed at 61 * run-time, as A) we generally already derive the table location as part of 62 * the trap processing and B) simplicity is more of a concern than is speed. 63 */ 64 65#if defined(lint) 66#include <kmdb/kaif.h> 67 68void 69kaif_hdlr_dmiss(void) 70{ 71} 72 73void 74kaif_itlb_handler(void) 75{ 76} 77 78#else /* lint */ 79 80#ifdef sun4v 81 82#define GET_MMU_D_ADDR_CTX(daddr, ctx) \ 83 MMU_FAULT_STATUS_AREA(ctx); \ 84 ldx [ctx + MMFSA_D_ADDR], daddr; \ 85 ldx [ctx + MMFSA_D_CTX], ctx 86 87#define GET_MMU_I_ADDR_CTX(iaddr, ctx) \ 88 MMU_FAULT_STATUS_AREA(ctx); \ 89 ldx [ctx + MMFSA_I_ADDR], iaddr; \ 90 ldx [ctx + MMFSA_I_CTX], ctx 91 92/* 93 * KAIF_ITLB_STUFF 94 * derived from ITLB_STUFF in uts/sun4v/vm/mach_sfmmu.h 95 * 96 * Load ITLB entry 97 * 98 * In: 99 * tte = reg containing tte 100 * ouch = branch target label used if hcall fails (sun4v only) 101 * scr1, scr2, scr3, scr4 = scratch registers (must not be %o0-%o3) 102 */ 103#define KAIF_ITLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4) \ 104 mov %o0, scr1; \ 105 mov %o1, scr2; \ 106 mov %o2, scr3; \ 107 mov %o3, scr4; \ 108 MMU_FAULT_STATUS_AREA(%o2); \ 109 ldx [%o2 + MMFSA_I_ADDR], %o0; \ 110 ldx [%o2 + MMFSA_I_CTX], %o1; \ 111 srlx %o0, PAGESHIFT, %o0; \ 112 sllx %o0, PAGESHIFT, %o0; \ 113 mov tte, %o2; \ 114 mov MAP_ITLB, %o3; \ 115 ta MMU_MAP_ADDR; \ 116 /* BEGIN CSTYLED */ \ 117 brnz,a,pn %o0, ouch; \ 118 nop; \ 119 /* END CSTYLED */ \ 120 mov scr1, %o0; \ 121 mov scr2, %o1; \ 122 mov scr3, %o2; \ 123 mov scr4, %o3 124 125/* 126 * KAIF_DTLB_STUFF 127 * derived from DTLB_STUFF in uts/sun4v/vm/mach_sfmmu.h 128 * 129 * Load DTLB entry 130 * 131 * In: 132 * tte = reg containing tte 133 * ouch = branch target label used if hcall fails (sun4v only) 134 * scr1, scr2, scr3, scr4 = scratch registers (must not be %o0-%o3) 135 */ 136#define KAIF_DTLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4) \ 137 mov %o0, scr1; \ 138 mov %o1, scr2; \ 139 mov %o2, scr3; \ 140 mov %o3, scr4; \ 141 MMU_FAULT_STATUS_AREA(%o2); \ 142 ldx [%o2 + MMFSA_D_ADDR], %o0; \ 143 ldx [%o2 + MMFSA_D_CTX], %o1; \ 144 srlx %o0, PAGESHIFT, %o0; \ 145 sllx %o0, PAGESHIFT, %o0; \ 146 mov tte, %o2; \ 147 mov MAP_DTLB, %o3; \ 148 ta MMU_MAP_ADDR; \ 149 /* BEGIN CSTYLED */ \ 150 brnz,a,pn %o0, ouch; \ 151 nop; \ 152 /* END CSTYLED */ \ 153 mov scr1, %o0; \ 154 mov scr2, %o1; \ 155 mov scr3, %o2; \ 156 mov scr4, %o3 157 158#else /* sun4v */ 159 160#define GET_MMU_D_ADDR_CTX(daddr, ctx) \ 161 mov MMU_TAG_ACCESS, ctx; \ 162 ldxa [ctx]ASI_DMMU, daddr; \ 163 sllx daddr, TAGACC_CTX_LSHIFT, ctx; \ 164 srlx ctx, TAGACC_CTX_LSHIFT, ctx 165 166#define GET_MMU_I_ADDR_CTX(iaddr, ctx) \ 167 rdpr %tpc, iaddr; \ 168 ldxa [%g0]ASI_IMMU, ctx; \ 169 srlx ctx, TTARGET_CTX_SHIFT, ctx 170 171#define KAIF_DTLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4) \ 172 DTLB_STUFF(tte, scr1, scr2, scr3, scr4) 173 174#define KAIF_ITLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4) \ 175 ITLB_STUFF(tte, scr1, scr2, scr3, scr4) 176 177#endif /* sun4v */ 178 179/* 180 * KAIF_CALL_KDI_VATOTTE 181 * 182 * Use kdi_vatotte to look up the tte. We don't bother stripping the 183 * context, as it won't change the tte we get. 184 * 185 * The two instruction at patch_lbl are modified during runtime 186 * by kaif to point to kdi_vatotte 187 * 188 * Clobbers all globals. 189 * Returns tte in %g1 if successful, otherwise 0 in %g1 190 * Leaves address of next instruction following this macro in scr1 191 */ 192#define KAIF_CALL_KDI_VATOTTE(addr, ctx, patch_lbl, scr0, scr1) \ 193 .global patch_lbl; \ 194patch_lbl: \ 195 sethi %hi(0), scr0; \ 196 or scr0, %lo(0), scr0; \ 197 jmpl scr0, scr1; \ 198 add scr1, 8, scr1 199 200 201 ENTRY_NP(kaif_hdlr_dmiss) 202 GET_MMU_D_ADDR_CTX(%g1, %g2) 203 204 KAIF_CALL_KDI_VATOTTE(%g1, %g2, kaif_hdlr_dmiss_patch, %g3, %g7) 2050: brz %g1, 1f 206 nop 207 208 /* 209 * kdi_vatotte gave us a TTE to use. Load it up and head back 210 * into the world, but first bump a counter. 211 */ 212 213#ifdef KMDB_TRAPCOUNT /* Trap counter. See top comment */ 214 ldx [%g7 + .count-0b], %g2 215 add %g2, 1, %g2 216 stx %g2, [%g7 + .count-0b] 217#endif 218 219 KAIF_DTLB_STUFF(%g1, 1f, %g2, %g3, %g4, %g5) 220 retry 221 2221: /* 223 * kdi_vatotte didn't give us a tte, which is unfortunate. We're 224 * going to need to jump into the debugger so as to allow it to 225 * handle the trap. The debugger itself isn't locked into the TLB, 226 * so we may well incur a TLB miss while trying to get into it. As 227 * such, we're going to switch off the MMU globals before setting foot 228 * into the debugger, thus allowing a TL>1 miss to be handled without 229 * clobbering our state. We'll also save off the tag just in case the 230 * world ends and someone wants to find out what happened. 231 * 232 * We will only reach this point at TL=1, as kdi_vatotte will always 233 * find the TTE for the debugger without missing. 234 */ 235 236#ifdef KMDB_TRAPCOUNT /* Trap address "counter". */ 237 GET_MMU_D_ADDR(%g2, %g3) 238 stx %g2, [%g7 + .daddr-0b] 239 stx %g1, [%g7 + .ecode-0b] 240#endif 241 242 sethi %hi(kaif_dtrap), %g1 243 jmp %g1 + %lo(kaif_dtrap) 244 nop 245 /* NOTREACHED */ 246 247#ifdef KMDB_TRAPCOUNT 248 .align 8 249.count: .xword 0 /* counter goes here */ 250.daddr: .xword 0 /* miss address goes here */ 251.ecode: .xword 0 /* sun4v: g1 contains err code */ 252#endif 253 254 .align 32*4 /* force length to 32 instr. */ 255 SET_SIZE(kaif_hdlr_dmiss) 256 257 258 259 ENTRY_NP(kaif_hdlr_imiss) 260 GET_MMU_I_ADDR_CTX(%g1, %g2) 261 262 KAIF_CALL_KDI_VATOTTE(%g1, %g2, kaif_hdlr_imiss_patch, %g3, %g7) 2630: brz %g1, 1f 264 nop 265 266 /* 267 * kdi_vatotte gave us a TTE to use. Load it up and head back 268 * into the world, but first bump a counter. 269 */ 270#ifdef KMDB_TRAPCOUNT /* Trap counter. See top comment */ 271 ldx [%g7 + .count-0b], %g2 272 add %g2, 1, %g2 273 stx %g2, [%g7 + .count-0b] 274#endif 275 276 KAIF_ITLB_STUFF(%g1, 1f, %g2, %g3, %g4, %g5) 277 retry 278 2791: /* 280 * kdi_vatotte didn't give us a tte, which is unfortunate. We're 281 * going to need to jump into the debugger so as to allow it to 282 * handle the trap. The debugger itself isn't locked into the TLB, 283 * so we may well incur a TLB miss while trying to get into it. As 284 * such, we're going to switch off the MMU globals before setting foot 285 * into the debugger, thus allowing a TL>1 miss to be handled without 286 * clobbering our state. 287 * 288 * We will only reach this point at TL=1, as kdi_vatotte will always 289 * find the TTE for the debugger without missing. 290 */ 291 292 sethi %hi(kaif_dtrap), %g1 293 jmp %g1 + %lo(kaif_dtrap) 294 nop 295 /* NOTREACHED */ 296 297#ifdef KMDB_TRAPCOUNT 298 .align 8 299.count: .xword 0 300#endif 301 302 .align 32*4 /* force length to 32 instr. */ 303 SET_SIZE(kaif_hdlr_imiss) 304 305 306 307 ENTRY_NP(kaif_hdlr_generic) 308#ifdef KMDB_TRAPCOUNT /* Trap counter. See top comment */ 3090: rd %pc, %g3 310 ldx [%g3 + .count-0b], %g4 311 add %g4, 1, %g4 312 stx %g4, [%g3 + .count-0b] 313#endif 314 315 sethi %hi(kaif_dtrap), %g1 316 jmp %g1 + %lo(kaif_dtrap) 317 nop 318 /* NOTREACHED */ 319 320#ifdef KMDB_TRAPCOUNT 321 .align 8 322.count: .xword 0 /* counter goes here */ 323#endif 324 325 .align 32*4 /* force length to 32 instr. */ 326 SET_SIZE(kaif_hdlr_generic) 327 328#endif /* lint */ 329