xref: /onnv-gate/usr/src/uts/sun4u/ml/zulu_asm.s (revision 2973:55b674bffad9)
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