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*2973Sgovinda * Common Development and Distribution License (the "License"). 6*2973Sgovinda * 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 */ 210Sstevel@tonic-gate/* 22*2973Sgovinda * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate#pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate#if defined(lint) 290Sstevel@tonic-gate#include <sys/types.h> 300Sstevel@tonic-gate#include <sys/thread.h> 310Sstevel@tonic-gate#else /* lint */ 320Sstevel@tonic-gate#include "assym.h" 330Sstevel@tonic-gate#endif /* lint */ 340Sstevel@tonic-gate 350Sstevel@tonic-gate#include <sys/asi.h> 360Sstevel@tonic-gate#include <sys/sun4asi.h> 370Sstevel@tonic-gate#include <sys/machasi.h> 380Sstevel@tonic-gate#include <sys/asm_linkage.h> 390Sstevel@tonic-gate#include <sys/pte.h> 400Sstevel@tonic-gate#include <sys/mmu.h> 410Sstevel@tonic-gate#include <sys/intreg.h> 420Sstevel@tonic-gate#include <sys/zulumod.h> 430Sstevel@tonic-gate#include <vm/hat_sfmmu.h> 440Sstevel@tonic-gate#include <sys/zulu_hat.h> 450Sstevel@tonic-gate#include <zuluvm_offsets.h> 460Sstevel@tonic-gate 470Sstevel@tonic-gate#ifdef lint 480Sstevel@tonic-gatevoid 490Sstevel@tonic-gatezuluvm_dmv_tlbmiss_tl1() 500Sstevel@tonic-gate{} 510Sstevel@tonic-gate 520Sstevel@tonic-gate#else /* lint */ 530Sstevel@tonic-gate 540Sstevel@tonic-gate DGDEF(zuluvm_base_pgsize) 550Sstevel@tonic-gate .word 0 560Sstevel@tonic-gate 570Sstevel@tonic-gate ENTRY_NP(zuluvm_dmv_tlbmiss_tl1) 580Sstevel@tonic-gate 590Sstevel@tonic-gate ! g1 - zuluvm_state_t pointer 600Sstevel@tonic-gate ! g2 - IRDR_0 610Sstevel@tonic-gate mov UIII_IRDR_1, %g3 620Sstevel@tonic-gate ldxa [%g3]ASI_INTR_RECEIVE, %g5 630Sstevel@tonic-gate stx %g5, [%g1 + ZULUVM_ASM_TLB_ADDR] 640Sstevel@tonic-gate mov UIII_IRDR_6, %g3 650Sstevel@tonic-gate ldxa [%g3]ASI_INTR_RECEIVE, %g5 660Sstevel@tonic-gate stx %g5, [%g1 + ZULUVM_ASM_TLB_TYPE] 670Sstevel@tonic-gate 680Sstevel@tonic-gate stxa %g0, [%g0]ASI_INTR_RECEIVE_STATUS ! clear the BUSY bit 690Sstevel@tonic-gate membar #Sync 700Sstevel@tonic-gate 710Sstevel@tonic-gate mov %g1, %g7 720Sstevel@tonic-gate 730Sstevel@tonic-gate ! check the fast tlb miss flag 740Sstevel@tonic-gate sethi %hi(zuluvm_fast_tlb), %g6 750Sstevel@tonic-gate lduw [%g6 + %lo(zuluvm_fast_tlb)], %g6 760Sstevel@tonic-gate brz,pn %g6, send_intr1 770Sstevel@tonic-gate mov ZULUVM_TTE_DELAY, %g1 780Sstevel@tonic-gate#if 1 790Sstevel@tonic-gate add %g7, ZULUVM_STATE, %g4 800Sstevel@tonic-gate mov ZULUVM_STATE_IDLE, %g1 810Sstevel@tonic-gate mov ZULUVM_STATE_TLB_PENDING, %g6 820Sstevel@tonic-gate casa [%g4]ASI_N, %g1, %g6 830Sstevel@tonic-gate cmp %g6, %g1 840Sstevel@tonic-gate be,pt %icc, 2f 850Sstevel@tonic-gate nop 860Sstevel@tonic-gate 870Sstevel@tonic-gate mov ZULUVM_STATE_CANCELED, %g1 880Sstevel@tonic-gate cmp %g6, %g1 890Sstevel@tonic-gate be,pt %icc, 1f 900Sstevel@tonic-gate mov ZULUVM_STATE_STOPPED, %g1 910Sstevel@tonic-gate retry 920Sstevel@tonic-gate1: 930Sstevel@tonic-gate st %g1, [%g4] 940Sstevel@tonic-gate#ifdef ZULUVM_STATS 950Sstevel@tonic-gate lduw [%g7 + ZULUVM_ST_TLBCANCEL], %g3 960Sstevel@tonic-gate add %g3, 1, %g3 970Sstevel@tonic-gate stuw %g3, [%g7 + ZULUVM_ST_TLBCANCEL] 980Sstevel@tonic-gate#endif 990Sstevel@tonic-gate retry 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate2: 1020Sstevel@tonic-gate ldx [%g7 + ZULUVM_ASM_TLB_TYPE], %g4 1030Sstevel@tonic-gate and %g4, ZULUVM_DMA_MASK, %g4 1040Sstevel@tonic-gate#ifdef ZULUVM_STATS 1050Sstevel@tonic-gate cmp %g4, ZULUVM_DMA2 1060Sstevel@tonic-gate be,a,pn %icc, 1f 1070Sstevel@tonic-gate add %g7, ZULUVM_ST_DTLB2MISS, %g1 1080Sstevel@tonic-gate cmp %g4, ZULUVM_ITLB1 1090Sstevel@tonic-gate be,a,pn %icc, 1f 1100Sstevel@tonic-gate add %g7, ZULUVM_ST_ITLB1MISS, %g1 1110Sstevel@tonic-gate cmp %g4, ZULUVM_ITLB2 1120Sstevel@tonic-gate be,a,pn %icc, 1f 1130Sstevel@tonic-gate add %g7, ZULUVM_ST_ITLB2MISS, %g1 1140Sstevel@tonic-gate add %g7, ZULUVM_ST_DTLB1MISS, %g1 1150Sstevel@tonic-gate1: 1160Sstevel@tonic-gate lduw [%g1], %g3 1170Sstevel@tonic-gate add %g3, 1, %g3 1180Sstevel@tonic-gate stuw %g3, [%g1] 1190Sstevel@tonic-gate#endif 1200Sstevel@tonic-gate /* 1210Sstevel@tonic-gate * lookup the tte in the tsb 1220Sstevel@tonic-gate * %g1 - vaddr[63:13], ctx[12:0] 1230Sstevel@tonic-gate * %g2 - our trap level 1240Sstevel@tonic-gate * %g3 - return address 1250Sstevel@tonic-gate * %g7 - zulu data pointer (needs to be preserved) 1260Sstevel@tonic-gate * return: 1270Sstevel@tonic-gate * %g1 - flags [63..58] and pfn [31..0] 1280Sstevel@tonic-gate * %g2 - status code if %g1 is null 1290Sstevel@tonic-gate * %g7 - zulu data pointer 1300Sstevel@tonic-gate */ 1310Sstevel@tonic-gate mov 1, %g2 1320Sstevel@tonic-gate set zulu_hat_tsb_lookup_tl1, %g3 1330Sstevel@tonic-gate jmpl %g3, %g3 1340Sstevel@tonic-gate ldx [%g7 + ZULUVM_ASM_TLB_ADDR], %g1 ! vaddr(tag) 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate /* 1370Sstevel@tonic-gate * did we find a tte ?? 1380Sstevel@tonic-gate * If not, %g2 has the error code 1390Sstevel@tonic-gate */ 1400Sstevel@tonic-gate brgez,a,pt %g1, send_intr 1410Sstevel@tonic-gate mov %g2, %g1 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate set zulu_tsb_hit, %g6 1440Sstevel@tonic-gate ldx [%g6], %g3 1450Sstevel@tonic-gate add %g3, 1, %g3 1460Sstevel@tonic-gate stx %g3, [%g6] 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate /* 1490Sstevel@tonic-gate * get flags and pfn 1500Sstevel@tonic-gate */ 1510Sstevel@tonic-gate sllx %g1, 32, %g6 1520Sstevel@tonic-gate srlx %g6, 32, %g6 ! %g6 pfn 1530Sstevel@tonic-gate srlx %g1, 59, %g3 1540Sstevel@tonic-gate and %g3, 0x7, %g2 ! %g2 page size 1550Sstevel@tonic-gate srlx %g3, 3, %g4 1560Sstevel@tonic-gate and %g4, 1, %g4 ! %g4 write perm 1570Sstevel@tonic-gate mov %g6, %g1 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate /* 1600Sstevel@tonic-gate * check if this is a dtlb2 miss(no itlb, pgsz != 8k) 1610Sstevel@tonic-gate * and if the current dtlb2 pgsz != tte pgsz 1620Sstevel@tonic-gate */ 1630Sstevel@tonic-gate ldx [%g7 + ZULUVM_ASM_TLB_TYPE], %g3 1640Sstevel@tonic-gate and %g3, 0x1, %g3 1650Sstevel@tonic-gate brnz,pt %g3, 3f ! not 0 => itlb => handles 1660Sstevel@tonic-gate nop 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate ! check page size, base page size is always handled by dtlb1, so we 1690Sstevel@tonic-gate ! only need to check against dtlb2 1700Sstevel@tonic-gate sethi %hi(zuluvm_base_pgsize), %g3 1710Sstevel@tonic-gate lduw [%g3 + %lo(zuluvm_base_pgsize)], %g3 1720Sstevel@tonic-gate cmp %g2, %g3 1730Sstevel@tonic-gate be,pt %icc, 2f 1740Sstevel@tonic-gate cmp %g2, ZULU_TTE4M 1750Sstevel@tonic-gate be,pt %icc, 2f ! TTE4M => dtlb2 => ok! 1760Sstevel@tonic-gate nop 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate#ifdef ZULUVM_STATS 1790Sstevel@tonic-gate lduw [%g7 + ZULUVM_ST_PAGESIZE], %g3 1800Sstevel@tonic-gate add %g3, 1, %g3 1810Sstevel@tonic-gate stuw %g3, [%g7 + ZULUVM_ST_PAGESIZE] 1820Sstevel@tonic-gate add %g7, ZULUVM_ST_MISS, %g3 1830Sstevel@tonic-gate sll %g2, 2, %g5 1840Sstevel@tonic-gate add %g5, %g3, %g5 1850Sstevel@tonic-gate lduw [%g5], %g3 1860Sstevel@tonic-gate add %g3, 1, %g3 1870Sstevel@tonic-gate stuw %g3, [%g5] 1880Sstevel@tonic-gate#endif 1890Sstevel@tonic-gate ! set tte size to ZULUVM_BASE_PGSZ 1900Sstevel@tonic-gate sethi %hi(zuluvm_base_pgsize), %g3 1910Sstevel@tonic-gate lduw [%g3 + %lo(zuluvm_base_pgsize)], %g3 1920Sstevel@tonic-gate ba,pt %icc, 3f 1930Sstevel@tonic-gate mov %g3, %g2 1940Sstevel@tonic-gate2: 1950Sstevel@tonic-gate 1960Sstevel@tonic-gate#ifdef ZULUVM_STATS 1970Sstevel@tonic-gate add %g7, ZULUVM_ST_MISS, %g3 1980Sstevel@tonic-gate sll %g2, 2, %g5 1990Sstevel@tonic-gate add %g3, %g5, %g5 2000Sstevel@tonic-gate lduw [%g5], %g3 2010Sstevel@tonic-gate add %g3, 1, %g3 2020Sstevel@tonic-gate stuw %g3, [%g5] 2030Sstevel@tonic-gate#endif 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate ! we maintain data on the last pfns for the last 12 pfns that we 2060Sstevel@tonic-gate ! processed 2070Sstevel@tonic-gate3: 2080Sstevel@tonic-gate lduw [%g7 + ZULUVM_PFNCNT], %g5 2090Sstevel@tonic-gate add %g5, 4, %g3 2100Sstevel@tonic-gate cmp %g3, 48 2110Sstevel@tonic-gate be,a,pn %icc, 1f 2120Sstevel@tonic-gate mov %g0, %g3 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate1: 2150Sstevel@tonic-gate stuw %g3, [%g7 + ZULUVM_PFNCNT] 2160Sstevel@tonic-gate sllx %g5, 3, %g5 2170Sstevel@tonic-gate add %g7, ZULUVM_PFNBUF, %g3 2180Sstevel@tonic-gate add %g3, %g5, %g3 2190Sstevel@tonic-gate stx %g1, [%g3] 2200Sstevel@tonic-gate stx %g2, [%g3 + 8] 2210Sstevel@tonic-gate stx %g4, [%g3 + 16] 2220Sstevel@tonic-gate ldx [%g7 + ZULUVM_ASM_TLB_TYPE], %g5 2230Sstevel@tonic-gate stx %g5, [%g3 + 24] 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate ldx [%g7 + ZULUVM_ASM_TLB_TYPE], %g3 2260Sstevel@tonic-gate and %g3, 0x3, %g3 ! tlbtype 2270Sstevel@tonic-gate ldx [%g7 + ZULUVM_ARG], %g6 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate ! write tte to zulu mmu 2300Sstevel@tonic-gate ! %g1 pfn 2310Sstevel@tonic-gate ! %g2 tte size 2320Sstevel@tonic-gate ! %g3 tlbtype 2330Sstevel@tonic-gate ! %g4 tte wrperm 2340Sstevel@tonic-gate ! %g6 zulu device driver arg 2350Sstevel@tonic-gate ! %g7 devtab pointer 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate sllx %g1, ZULUVM_ZFB_MMU_TLB_D_PA_SHIFT, %g1 2380Sstevel@tonic-gate mov 0x1, %g5 2390Sstevel@tonic-gate sllx %g5, 63, %g5 ! ZFB_MMU_TLB_D_V_MASK 2400Sstevel@tonic-gate or %g1, %g5, %g1 2410Sstevel@tonic-gate or %g1, ZULUVM_ZFB_MMU_TLB_D_C_MASK, %g1 2420Sstevel@tonic-gate sllx %g2, ZULUVM_ZFB_MMU_TLB_D_SZ_SHIFT, %g2 2430Sstevel@tonic-gate 2440Sstevel@tonic-gate brz,pt %g4, 3f ! write perm ?? 2450Sstevel@tonic-gate or %g2, %g1, %g1 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate or %g1, ZULUVM_ZFB_MMU_TLB_D_W_MASK, %g1 2480Sstevel@tonic-gate3: 2490Sstevel@tonic-gate ! at this point %g1 is ready to be written to the corresponding 2500Sstevel@tonic-gate ! data_in register, let's see which if it was itlb or dtlb... 2510Sstevel@tonic-gate and %g3, ZULUVM_ITLB_FLAG, %g3 2520Sstevel@tonic-gate ! assumption is that data miss 2530Sstevel@tonic-gate brz,pt %g3, 4f ! is more likely than instr miss 2540Sstevel@tonic-gate ldx [%g7 + ZULUVM_PAMMU], %g2 ! physical addr of zulu mmu regs 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate ! instruction miss 2570Sstevel@tonic-gate mov ZULUVM_ZFB_MMU_TLB_CR_IMISS_MASK, %g5 2580Sstevel@tonic-gate add %g2, ZULUVM_ITLB_DATA_IN, %g4 2590Sstevel@tonic-gate !stxa %g1, [%g4]ASI_IO 2600Sstevel@tonic-gate ba,pt %xcc, 5f 2610Sstevel@tonic-gate stxa %g1, [%g4]ASI_IO 2620Sstevel@tonic-gate !ldxa [%g4]ASI_IO, %g4 2630Sstevel@tonic-gate4: 2640Sstevel@tonic-gate ! data miss 2650Sstevel@tonic-gate mov ZULUVM_ZFB_MMU_TLB_CR_DMISS_MASK, %g5 2660Sstevel@tonic-gate add %g2, ZULUVM_DTLB_DATA_IN, %g4 2670Sstevel@tonic-gate stxa %g1, [%g4]ASI_IO 2680Sstevel@tonic-gate !ldxa [%g4]ASI_IO, %g4 2690Sstevel@tonic-gate5: 2700Sstevel@tonic-gate add %g7, ZULUVM_STATE, %g4 2710Sstevel@tonic-gate mov ZULUVM_STATE_TLB_PENDING, %g6 2720Sstevel@tonic-gate mov ZULUVM_STATE_IDLE, %g1 2730Sstevel@tonic-gate casa [%g4]ASI_N, %g6, %g1 2740Sstevel@tonic-gate cmp %g6, %g1 2750Sstevel@tonic-gate bne,a,pn %icc, stopped 2760Sstevel@tonic-gate mov ZULUVM_STATE_STOPPED, %g3 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate ldx [%g7 + ZULUVM_PAMMU], %g2 2790Sstevel@tonic-gate add %g2, ZULUVM_TLB_CONTROL, %g2 2800Sstevel@tonic-gate stxa %g5, [%g2]ASI_IO 2810Sstevel@tonic-gate !ldxa [%g2]ASI_IO, %g3 2820Sstevel@tonic-gate retry 2830Sstevel@tonic-gate 2840Sstevel@tonic-gatesend_intr: 2850Sstevel@tonic-gate add %g7, ZULUVM_STATE, %g4 2860Sstevel@tonic-gate mov ZULUVM_STATE_INTR_QUEUED, %g5 2870Sstevel@tonic-gate mov ZULUVM_STATE_TLB_PENDING, %g3 2880Sstevel@tonic-gate casa [%g4]ASI_N, %g3, %g5 2890Sstevel@tonic-gate cmp %g3, %g5 2900Sstevel@tonic-gate be,pt %icc, deliver_intr 2910Sstevel@tonic-gate mov ZULUVM_STATE_STOPPED, %g3 2920Sstevel@tonic-gate ba,pt %icc, stopped 2930Sstevel@tonic-gate nop 2940Sstevel@tonic-gate#endif 2950Sstevel@tonic-gate 2960Sstevel@tonic-gatesend_intr1: 2970Sstevel@tonic-gate add %g7, ZULUVM_STATE, %g4 2980Sstevel@tonic-gate mov ZULUVM_STATE_IDLE, %g3 2990Sstevel@tonic-gate mov ZULUVM_STATE_INTR_QUEUED, %g5 3000Sstevel@tonic-gate casa [%g4]ASI_N, %g3, %g5 3010Sstevel@tonic-gate cmp %g3, %g5 3020Sstevel@tonic-gate be,pt %icc, deliver_intr 3030Sstevel@tonic-gate mov ZULUVM_STATE_STOPPED, %g3 3040Sstevel@tonic-gatestopped: 3050Sstevel@tonic-gate st %g3, [%g4] 3060Sstevel@tonic-gate#ifdef ZULUVM_STATS 3070Sstevel@tonic-gate lduw [%g7 + ZULUVM_ST_TLBCANCEL], %g3 3080Sstevel@tonic-gate add %g3, 1, %g3 3090Sstevel@tonic-gate stuw %g3, [%g7 + ZULUVM_ST_TLBCANCEL] 3100Sstevel@tonic-gate#endif 3110Sstevel@tonic-gate retry 3120Sstevel@tonic-gate 3130Sstevel@tonic-gatedeliver_intr: 3140Sstevel@tonic-gate stx %g1, [%g7 + ZULUVM_ASM_TLB_ERRCODE] ! set the error field 3150Sstevel@tonic-gate stx %g6, [%g7 + ZULUVM_ASM_TLB_TTE] ! deliver tte in data_0 3160Sstevel@tonic-gate ! %g6 is invalid if error != SUCCESS 3170Sstevel@tonic-gate ! setsoftint_tl1(uint64_t inum, uint64_t dummy) 3180Sstevel@tonic-gate set setsoftint_tl1, %g5 3190Sstevel@tonic-gate jmp %g5 320*2973Sgovinda ldx [%g7 + ZULUVM_INTRNUM], %g1 3210Sstevel@tonic-gate 3220Sstevel@tonic-gate SET_SIZE(zuluvm_dmv_tlbmiss_tl1) 3230Sstevel@tonic-gate 3240Sstevel@tonic-gate#endif /* lint */ 3250Sstevel@tonic-gate 326