10Sstevel@tonic-gate/* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*1991Sheppo * Common Development and Distribution License (the "License"). 6*1991Sheppo * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 21*1991Sheppo 220Sstevel@tonic-gate/* 23*1991Sheppo * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate#pragma ident "%Z%%M% %I% %E% SMI" 280Sstevel@tonic-gate 290Sstevel@tonic-gate#include <sys/asm_linkage.h> 300Sstevel@tonic-gate#include <sys/machasi.h> 310Sstevel@tonic-gate#include <sys/machtrap.h> 320Sstevel@tonic-gate#include <sys/privregs.h> 330Sstevel@tonic-gate#include <sys/mmu.h> 34*1991Sheppo#include <vm/mach_sfmmu.h> 35*1991Sheppo 36*1991Sheppo#if defined(sun4v) && !defined(lint) 37*1991Sheppo#include <sys/machparam.h> 38*1991Sheppo#endif 39*1991Sheppo 40*1991Sheppo#if defined(sun4v) && defined(KMDB_TRAPCOUNT) 41*1991Sheppo/* 42*1991Sheppo * The sun4v implemenations of the fast miss handlers are larger than those 43*1991Sheppo * of their sun4u kin. This is unfortunate because there is not enough space 44*1991Sheppo * remaining in the respective trap table entries for this debug feature. 45*1991Sheppo */ 46*1991Sheppo#error "KMDB_TRAPCOUNT not supported on sun4v" 47*1991Sheppo#endif 480Sstevel@tonic-gate 490Sstevel@tonic-gate/* 500Sstevel@tonic-gate * This file contains the trap handlers that will be copied to kmdb's trap 510Sstevel@tonic-gate * table. See kaif_activate.c for the code that does the actual copying. 520Sstevel@tonic-gate * 530Sstevel@tonic-gate * The handlers have a debugging feature, enabled when KMDB_TRAPCOUNT is 540Sstevel@tonic-gate * defined, which allows them to keep a running count of the number of times 550Sstevel@tonic-gate * a given trap has occurred. The counter is stored in the padding at the end 560Sstevel@tonic-gate * of the handler. Write access is of course required to allow the values to 570Sstevel@tonic-gate * be updated, so KMDB_TRAPCOUNT also enables the installation of DTLB entries 580Sstevel@tonic-gate * for each trap table page. Finally, the code in this file is copied into 590Sstevel@tonic-gate * the actual location used by the handler, so we can't perform compile-time 600Sstevel@tonic-gate * counter location calculations. The calculations are instead performed at 610Sstevel@tonic-gate * run-time, as A) we generally already derive the table location as part of 620Sstevel@tonic-gate * the trap processing and B) simplicity is more of a concern than is speed. 630Sstevel@tonic-gate */ 640Sstevel@tonic-gate 650Sstevel@tonic-gate#if defined(lint) 660Sstevel@tonic-gate#include <kmdb/kaif.h> 670Sstevel@tonic-gate 680Sstevel@tonic-gatevoid 690Sstevel@tonic-gatekaif_hdlr_dmiss(void) 700Sstevel@tonic-gate{ 710Sstevel@tonic-gate} 720Sstevel@tonic-gate 730Sstevel@tonic-gatevoid 740Sstevel@tonic-gatekaif_itlb_handler(void) 750Sstevel@tonic-gate{ 760Sstevel@tonic-gate} 77*1991Sheppo 78*1991Sheppo#else /* lint */ 790Sstevel@tonic-gate 800Sstevel@tonic-gate#ifdef sun4v 81*1991Sheppo 82*1991Sheppo#define GET_MMU_D_ADDR_CTX(daddr, ctx) \ 83*1991Sheppo MMU_FAULT_STATUS_AREA(ctx); \ 84*1991Sheppo ldx [ctx + MMFSA_D_ADDR], daddr; \ 85*1991Sheppo ldx [ctx + MMFSA_D_CTX], ctx 86*1991Sheppo 87*1991Sheppo#define GET_MMU_I_ADDR_CTX(iaddr, ctx) \ 88*1991Sheppo MMU_FAULT_STATUS_AREA(ctx); \ 89*1991Sheppo ldx [ctx + MMFSA_I_ADDR], iaddr; \ 90*1991Sheppo ldx [ctx + MMFSA_I_CTX], ctx 91*1991Sheppo 92*1991Sheppo/* 93*1991Sheppo * KAIF_ITLB_STUFF 94*1991Sheppo * derived from ITLB_STUFF in uts/sun4v/vm/mach_sfmmu.h 95*1991Sheppo * 96*1991Sheppo * Load ITLB entry 97*1991Sheppo * 98*1991Sheppo * In: 99*1991Sheppo * tte = reg containing tte 100*1991Sheppo * ouch = branch target label used if hcall fails (sun4v only) 101*1991Sheppo * scr1, scr2, scr3, scr4 = scratch registers (must not be %o0-%o3) 102*1991Sheppo */ 103*1991Sheppo#define KAIF_ITLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4) \ 104*1991Sheppo mov %o0, scr1; \ 105*1991Sheppo mov %o1, scr2; \ 106*1991Sheppo mov %o2, scr3; \ 107*1991Sheppo mov %o3, scr4; \ 108*1991Sheppo MMU_FAULT_STATUS_AREA(%o2); \ 109*1991Sheppo ldx [%o2 + MMFSA_I_ADDR], %o0; \ 110*1991Sheppo ldx [%o2 + MMFSA_I_CTX], %o1; \ 111*1991Sheppo srlx %o0, PAGESHIFT, %o0; \ 112*1991Sheppo sllx %o0, PAGESHIFT, %o0; \ 113*1991Sheppo mov tte, %o2; \ 114*1991Sheppo mov MAP_ITLB, %o3; \ 115*1991Sheppo ta MMU_MAP_ADDR; \ 116*1991Sheppo /* BEGIN CSTYLED */ \ 117*1991Sheppo brnz,a,pn %o0, ouch; \ 118*1991Sheppo nop; \ 119*1991Sheppo /* END CSTYLED */ \ 120*1991Sheppo mov scr1, %o0; \ 121*1991Sheppo mov scr2, %o1; \ 122*1991Sheppo mov scr3, %o2; \ 123*1991Sheppo mov scr4, %o3 124*1991Sheppo 125*1991Sheppo/* 126*1991Sheppo * KAIF_DTLB_STUFF 127*1991Sheppo * derived from DTLB_STUFF in uts/sun4v/vm/mach_sfmmu.h 128*1991Sheppo * 129*1991Sheppo * Load DTLB entry 130*1991Sheppo * 131*1991Sheppo * In: 132*1991Sheppo * tte = reg containing tte 133*1991Sheppo * ouch = branch target label used if hcall fails (sun4v only) 134*1991Sheppo * scr1, scr2, scr3, scr4 = scratch registers (must not be %o0-%o3) 135*1991Sheppo */ 136*1991Sheppo#define KAIF_DTLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4) \ 137*1991Sheppo mov %o0, scr1; \ 138*1991Sheppo mov %o1, scr2; \ 139*1991Sheppo mov %o2, scr3; \ 140*1991Sheppo mov %o3, scr4; \ 141*1991Sheppo MMU_FAULT_STATUS_AREA(%o2); \ 142*1991Sheppo ldx [%o2 + MMFSA_D_ADDR], %o0; \ 143*1991Sheppo ldx [%o2 + MMFSA_D_CTX], %o1; \ 144*1991Sheppo srlx %o0, PAGESHIFT, %o0; \ 145*1991Sheppo sllx %o0, PAGESHIFT, %o0; \ 146*1991Sheppo mov tte, %o2; \ 147*1991Sheppo mov MAP_DTLB, %o3; \ 148*1991Sheppo ta MMU_MAP_ADDR; \ 149*1991Sheppo /* BEGIN CSTYLED */ \ 150*1991Sheppo brnz,a,pn %o0, ouch; \ 151*1991Sheppo nop; \ 152*1991Sheppo /* END CSTYLED */ \ 153*1991Sheppo mov scr1, %o0; \ 154*1991Sheppo mov scr2, %o1; \ 155*1991Sheppo mov scr3, %o2; \ 156*1991Sheppo mov scr4, %o3 157*1991Sheppo 1580Sstevel@tonic-gate#else /* sun4v */ 1590Sstevel@tonic-gate 160*1991Sheppo#define GET_MMU_D_ADDR_CTX(daddr, ctx) \ 161*1991Sheppo mov MMU_TAG_ACCESS, ctx; \ 162*1991Sheppo ldxa [ctx]ASI_DMMU, daddr; \ 163*1991Sheppo sllx daddr, TAGACC_CTX_LSHIFT, ctx; \ 164*1991Sheppo srlx ctx, TAGACC_CTX_LSHIFT, ctx 1650Sstevel@tonic-gate 166*1991Sheppo#define GET_MMU_I_ADDR_CTX(iaddr, ctx) \ 167*1991Sheppo rdpr %tpc, iaddr; \ 168*1991Sheppo ldxa [%g0]ASI_IMMU, ctx; \ 169*1991Sheppo srlx ctx, TTARGET_CTX_SHIFT, ctx 170*1991Sheppo 171*1991Sheppo#define KAIF_DTLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4) \ 172*1991Sheppo DTLB_STUFF(tte, scr1, scr2, scr3, scr4) 173*1991Sheppo 174*1991Sheppo#define KAIF_ITLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4) \ 175*1991Sheppo ITLB_STUFF(tte, scr1, scr2, scr3, scr4) 1760Sstevel@tonic-gate 177*1991Sheppo#endif /* sun4v */ 178*1991Sheppo 179*1991Sheppo/* 180*1991Sheppo * KAIF_CALL_KDI_VATOTTE 181*1991Sheppo * 182*1991Sheppo * Use kdi_vatotte to look up the tte. We don't bother stripping the 183*1991Sheppo * context, as it won't change the tte we get. 184*1991Sheppo * 185*1991Sheppo * The two instruction at patch_lbl are modified during runtime 186*1991Sheppo * by kaif to point to kdi_vatotte 187*1991Sheppo * 188*1991Sheppo * Clobbers all globals. 189*1991Sheppo * Returns tte in %g1 if successful, otherwise 0 in %g1 190*1991Sheppo * Leaves address of next instruction following this macro in scr1 191*1991Sheppo */ 192*1991Sheppo#define KAIF_CALL_KDI_VATOTTE(addr, ctx, patch_lbl, scr0, scr1) \ 193*1991Sheppo .global patch_lbl; \ 194*1991Sheppopatch_lbl: \ 195*1991Sheppo sethi %hi(0), scr0; \ 196*1991Sheppo or scr0, %lo(0), scr0; \ 197*1991Sheppo jmpl scr0, scr1; \ 198*1991Sheppo add scr1, 8, scr1 1990Sstevel@tonic-gate 200*1991Sheppo 201*1991Sheppo ENTRY_NP(kaif_hdlr_dmiss) 202*1991Sheppo GET_MMU_D_ADDR_CTX(%g1, %g2) 203*1991Sheppo 204*1991Sheppo KAIF_CALL_KDI_VATOTTE(%g1, %g2, kaif_hdlr_dmiss_patch, %g3, %g7) 205*1991Sheppo0: brz %g1, 1f 2060Sstevel@tonic-gate nop 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate /* 2090Sstevel@tonic-gate * kdi_vatotte gave us a TTE to use. Load it up and head back 2100Sstevel@tonic-gate * into the world, but first bump a counter. 2110Sstevel@tonic-gate */ 212*1991Sheppo 213*1991Sheppo#ifdef KMDB_TRAPCOUNT /* Trap counter. See top comment */ 214*1991Sheppo ldx [%g7 + .count-0b], %g2 2150Sstevel@tonic-gate add %g2, 1, %g2 216*1991Sheppo stx %g2, [%g7 + .count-0b] 2170Sstevel@tonic-gate#endif 218*1991Sheppo 219*1991Sheppo KAIF_DTLB_STUFF(%g1, 1f, %g2, %g3, %g4, %g5) 2200Sstevel@tonic-gate retry 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate1: /* 2230Sstevel@tonic-gate * kdi_vatotte didn't give us a tte, which is unfortunate. We're 2240Sstevel@tonic-gate * going to need to jump into the debugger so as to allow it to 2250Sstevel@tonic-gate * handle the trap. The debugger itself isn't locked into the TLB, 2260Sstevel@tonic-gate * so we may well incur a TLB miss while trying to get into it. As 2270Sstevel@tonic-gate * such, we're going to switch off the MMU globals before setting foot 2280Sstevel@tonic-gate * into the debugger, thus allowing a TL>1 miss to be handled without 2290Sstevel@tonic-gate * clobbering our state. We'll also save off the tag just in case the 2300Sstevel@tonic-gate * world ends and someone wants to find out what happened. 2310Sstevel@tonic-gate * 2320Sstevel@tonic-gate * We will only reach this point at TL=1, as kdi_vatotte will always 2330Sstevel@tonic-gate * find the TTE for the debugger without missing. 2340Sstevel@tonic-gate */ 2350Sstevel@tonic-gate 236*1991Sheppo#ifdef KMDB_TRAPCOUNT /* Trap address "counter". */ 237*1991Sheppo GET_MMU_D_ADDR(%g2, %g3) 238*1991Sheppo stx %g2, [%g7 + .daddr-0b] 239*1991Sheppo stx %g1, [%g7 + .ecode-0b] 2400Sstevel@tonic-gate#endif 2410Sstevel@tonic-gate 242*1991Sheppo sethi %hi(kaif_dtrap), %g1 243*1991Sheppo jmp %g1 + %lo(kaif_dtrap) 2440Sstevel@tonic-gate nop 245*1991Sheppo /* NOTREACHED */ 246*1991Sheppo 247*1991Sheppo#ifdef KMDB_TRAPCOUNT 248*1991Sheppo .align 8 249*1991Sheppo.count: .xword 0 /* counter goes here */ 250*1991Sheppo.daddr: .xword 0 /* miss address goes here */ 251*1991Sheppo.ecode: .xword 0 /* sun4v: g1 contains err code */ 252*1991Sheppo#endif 253*1991Sheppo 254*1991Sheppo .align 32*4 /* force length to 32 instr. */ 2550Sstevel@tonic-gate SET_SIZE(kaif_hdlr_dmiss) 2560Sstevel@tonic-gate 257*1991Sheppo 2580Sstevel@tonic-gate 259*1991Sheppo ENTRY_NP(kaif_hdlr_imiss) 260*1991Sheppo GET_MMU_I_ADDR_CTX(%g1, %g2) 2610Sstevel@tonic-gate 262*1991Sheppo KAIF_CALL_KDI_VATOTTE(%g1, %g2, kaif_hdlr_imiss_patch, %g3, %g7) 263*1991Sheppo0: brz %g1, 1f 2640Sstevel@tonic-gate nop 2650Sstevel@tonic-gate 2660Sstevel@tonic-gate /* 2670Sstevel@tonic-gate * kdi_vatotte gave us a TTE to use. Load it up and head back 2680Sstevel@tonic-gate * into the world, but first bump a counter. 2690Sstevel@tonic-gate */ 270*1991Sheppo#ifdef KMDB_TRAPCOUNT /* Trap counter. See top comment */ 271*1991Sheppo ldx [%g7 + .count-0b], %g2 2720Sstevel@tonic-gate add %g2, 1, %g2 273*1991Sheppo stx %g2, [%g7 + .count-0b] 2740Sstevel@tonic-gate#endif 275*1991Sheppo 276*1991Sheppo KAIF_ITLB_STUFF(%g1, 1f, %g2, %g3, %g4, %g5) 2770Sstevel@tonic-gate retry 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate1: /* 2800Sstevel@tonic-gate * kdi_vatotte didn't give us a tte, which is unfortunate. We're 2810Sstevel@tonic-gate * going to need to jump into the debugger so as to allow it to 2820Sstevel@tonic-gate * handle the trap. The debugger itself isn't locked into the TLB, 2830Sstevel@tonic-gate * so we may well incur a TLB miss while trying to get into it. As 2840Sstevel@tonic-gate * such, we're going to switch off the MMU globals before setting foot 2850Sstevel@tonic-gate * into the debugger, thus allowing a TL>1 miss to be handled without 2860Sstevel@tonic-gate * clobbering our state. 2870Sstevel@tonic-gate * 2880Sstevel@tonic-gate * We will only reach this point at TL=1, as kdi_vatotte will always 2890Sstevel@tonic-gate * find the TTE for the debugger without missing. 2900Sstevel@tonic-gate */ 291*1991Sheppo 292*1991Sheppo sethi %hi(kaif_dtrap), %g1 293*1991Sheppo jmp %g1 + %lo(kaif_dtrap) 294*1991Sheppo nop 295*1991Sheppo /* NOTREACHED */ 296*1991Sheppo 297*1991Sheppo#ifdef KMDB_TRAPCOUNT 298*1991Sheppo .align 8 299*1991Sheppo.count: .xword 0 300*1991Sheppo#endif 301*1991Sheppo 302*1991Sheppo .align 32*4 /* force length to 32 instr. */ 3030Sstevel@tonic-gate SET_SIZE(kaif_hdlr_imiss) 304*1991Sheppo 305*1991Sheppo 3060Sstevel@tonic-gate 3070Sstevel@tonic-gate ENTRY_NP(kaif_hdlr_generic) 308*1991Sheppo#ifdef KMDB_TRAPCOUNT /* Trap counter. See top comment */ 309*1991Sheppo0: rd %pc, %g3 310*1991Sheppo ldx [%g3 + .count-0b], %g4 3110Sstevel@tonic-gate add %g4, 1, %g4 312*1991Sheppo stx %g4, [%g3 + .count-0b] 313*1991Sheppo#endif 314*1991Sheppo 315*1991Sheppo sethi %hi(kaif_dtrap), %g1 316*1991Sheppo jmp %g1 + %lo(kaif_dtrap) 3170Sstevel@tonic-gate nop 318*1991Sheppo /* NOTREACHED */ 319*1991Sheppo 320*1991Sheppo#ifdef KMDB_TRAPCOUNT 321*1991Sheppo .align 8 322*1991Sheppo.count: .xword 0 /* counter goes here */ 3230Sstevel@tonic-gate#endif 324*1991Sheppo 325*1991Sheppo .align 32*4 /* force length to 32 instr. */ 3260Sstevel@tonic-gate SET_SIZE(kaif_hdlr_generic) 3270Sstevel@tonic-gate 328*1991Sheppo#endif /* lint */ 329