mp_exception.S revision 100718
189051Sjake/*-
289051Sjake * Copyright (c) 2002 Jake Burkholder.
389051Sjake * All rights reserved.
489051Sjake *
589051Sjake * Redistribution and use in source and binary forms, with or without
689051Sjake * modification, are permitted provided that the following conditions
789051Sjake * are met:
889051Sjake * 1. Redistributions of source code must retain the above copyright
989051Sjake *    notice, this list of conditions and the following disclaimer.
1089051Sjake * 2. Redistributions in binary form must reproduce the above copyright
1189051Sjake *    notice, this list of conditions and the following disclaimer in the
1289051Sjake *    documentation and/or other materials provided with the distribution.
1389051Sjake *
1489051Sjake * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1589051Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1689051Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1789051Sjake * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1889051Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1989051Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2089051Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2189051Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2289051Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2389051Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2489051Sjake * SUCH DAMAGE.
2589051Sjake *
2689051Sjake * $FreeBSD: head/sys/sparc64/sparc64/mp_exception.S 100718 2002-07-26 15:54:04Z jake $
2789051Sjake */
2889051Sjake
2989051Sjake#include <machine/asi.h>
3089051Sjake#include <machine/ktr.h>
3189051Sjake#include <machine/asmacros.h>
3289051Sjake#include <machine/pstate.h>
3389051Sjake
3489051Sjake#include "assym.s"
3589051Sjake
3689051Sjake	.register	%g2, #ignore
3789051Sjake	.register	%g3, #ignore
3889051Sjake
3992199Sjake#define	IPI_WAIT(r1, r2, r3, r4) \
4092199Sjake	lduw	[PCPU(CPUMASK)], r4 ;  \
4192199Sjake	ATOMIC_CLEAR_INT(r1, r2, r3, r4) ; \
4291783Sjake9:	lduw	[r1], r2 ; \
4389051Sjake	brnz,a,pn r2, 9b ; \
4489051Sjake	 nop
4589051Sjake
4689051Sjake/*
4797001Sjake * Invalidate a phsyical page in the data cache.
4897001Sjake */
4997001SjakeENTRY(tl_ipi_dcache_page_inval)
5097001Sjake#if KTR_COMPILE & KTR_SMP
5197001Sjake	CATR(KTR_SMP, "ipi_dcache_page_inval: pa=%#lx"
5297001Sjake	    , %g1, %g2, %g3, 7, 8, 9)
5397001Sjake	ldx	[%g5 + ICA_PA], %g2
5497001Sjake	stx	%g2, [%g1 + KTR_PARM1]
5597001Sjake9:
5697001Sjake#endif
5797001Sjake
5897001Sjake	ldx	[%g5 + ICA_PA], %g6
5997001Sjake	srlx	%g6, PAGE_SHIFT - DC_TAG_SHIFT, %g6
6097001Sjake
6197001Sjake	SET(cache, %g3, %g2)
6297001Sjake	lduw	[%g2 + DC_SIZE], %g3
6397001Sjake	lduw	[%g2 + DC_LINESIZE], %g4
6497001Sjake	sub	%g3, %g4, %g2
6597001Sjake
6697001Sjake1:	ldxa	[%g2] ASI_DCACHE_TAG, %g1
6797001Sjake	srlx	%g1, DC_VALID_SHIFT, %g3
6897001Sjake	andcc	%g3, DC_VALID_MASK, %g0
6997001Sjake	bz,pt	%xcc, 2f
7097001Sjake	 set	DC_TAG_MASK, %g3
7197001Sjake	sllx	%g3, DC_TAG_SHIFT, %g3
7297001Sjake	and	%g1, %g3, %g1
7397001Sjake	cmp	%g1, %g6
7497001Sjake	bne,a,pt %xcc, 2f
7597001Sjake	 nop
7697001Sjake	stxa	%g1, [%g2] ASI_DCACHE_TAG
7797001Sjake	membar	#Sync
7897001Sjake
7997001Sjake2:	brgz,pt	%g2, 1b
8097001Sjake	 sub	%g2, %g4, %g2
8197001Sjake
8297001Sjake	IPI_WAIT(%g5, %g1, %g2, %g3)
8397001Sjake	retry
8497001SjakeEND(tl_ipi_dcache_page_inval)
8597001Sjake
8697001Sjake/*
8797001Sjake * Invalidate a phsyical page in the instruction cache.
8897001Sjake */
8997001SjakeENTRY(tl_ipi_icache_page_inval)
9097001Sjake#if KTR_COMPILE & KTR_SMP
9197001Sjake	CATR(KTR_SMP, "ipi_icache_page_inval: pa=%#lx"
9297001Sjake	    , %g1, %g2, %g3, 7, 8, 9)
9397001Sjake	ldx	[%g5 + ICA_PA], %g2
9497001Sjake	stx	%g2, [%g1 + KTR_PARM1]
9597001Sjake9:
9697001Sjake#endif
9797001Sjake
9897001Sjake	ldx	[%g5 + ICA_PA], %g6
9997001Sjake	srlx	%g6, PAGE_SHIFT - IC_TAG_SHIFT, %g6
10097001Sjake
10197001Sjake	SET(cache, %g3, %g2)
10297001Sjake	lduw	[%g2 + IC_SIZE], %g3
10397001Sjake	lduw	[%g2 + IC_LINESIZE], %g4
10497001Sjake	sub	%g3, %g4, %g2
10597001Sjake
10697001Sjake1:	ldda	[%g2] ASI_ICACHE_TAG, %g0 /*, %g1 */
10797001Sjake	srlx	%g1, IC_VALID_SHIFT, %g3
10897001Sjake	andcc	%g3, IC_VALID_MASK, %g0
10997001Sjake	bz,pt	%xcc, 2f
11097001Sjake	 set	IC_TAG_MASK, %g3
11197001Sjake	sllx	%g3, IC_TAG_SHIFT, %g3
11297001Sjake	and	%g1, %g3, %g1
11397001Sjake	cmp	%g1, %g6
11497001Sjake	bne,a,pt %xcc, 2f
11597001Sjake	 nop
11697001Sjake	stxa	%g1, [%g2] ASI_ICACHE_TAG
11797001Sjake	membar	#Sync
11897001Sjake
11997001Sjake2:	brgz,pt	%g2, 1b
12097001Sjake	 sub	%g2, %g4, %g2
12197001Sjake
12297001Sjake	IPI_WAIT(%g5, %g1, %g2, %g3)
12397001Sjake	retry
12497001SjakeEND(tl_ipi_icache_page_inval)
12597001Sjake
12697001Sjake/*
12789051Sjake * Trigger a softint at the desired level.
12889051Sjake */
12989051SjakeENTRY(tl_ipi_level)
13092199Sjake#if KTR_COMPILE & KTR_SMP
13192199Sjake	CATR(KTR_SMP, "tl_ipi_level: cpuid=%d mid=%d d1=%#lx d2=%#lx"
13292199Sjake	    , %g1, %g2, %g3, 7, 8, 9)
13392199Sjake	lduw	[PCPU(CPUID)], %g2
13492199Sjake	stx	%g2, [%g1 + KTR_PARM1]
13592199Sjake	lduw	[PCPU(MID)], %g2
13692199Sjake	stx	%g2, [%g1 + KTR_PARM2]
13792199Sjake	stx	%g4, [%g1 + KTR_PARM3]
13892199Sjake	stx	%g5, [%g1 + KTR_PARM4]
13992199Sjake9:
14092199Sjake#endif
14189051Sjake
14289051Sjake	mov	1, %g1
14392199Sjake	sllx	%g1, %g5, %g1
14489051Sjake	wr	%g1, 0, %asr20
14589051Sjake	retry
14689051SjakeEND(tl_ipi_level)
14789051Sjake
14889051Sjake/*
14989051Sjake * Demap a page from the dtlb and/or itlb.
15089051Sjake */
15189051SjakeENTRY(tl_ipi_tlb_page_demap)
15291783Sjake#if KTR_COMPILE & KTR_SMP
15391783Sjake	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
15491783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
15591783Sjake	ldx	[%g5 + ITA_PMAP], %g2
15691783Sjake	stx	%g2, [%g1 + KTR_PARM1]
15791783Sjake	ldx	[%g5 + ITA_VA], %g2
15891783Sjake	stx	%g2, [%g1 + KTR_PARM2]
15991783Sjake9:
16091783Sjake#endif
16189051Sjake
16291783Sjake	ldx	[%g5 + ITA_PMAP], %g1
16389051Sjake
16491783Sjake	SET(kernel_pmap_store, %g3, %g2)
16591783Sjake	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
16689051Sjake
16791783Sjake	cmp	%g1, %g2
16891783Sjake	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
16989051Sjake
17091783Sjake	ldx	[%g5 + ITA_VA], %g2
17191783Sjake	or	%g2, %g3, %g2
17289051Sjake
17391783Sjake	stxa	%g0, [%g2] ASI_DMMU_DEMAP
17491783Sjake	stxa	%g0, [%g2] ASI_IMMU_DEMAP
17591783Sjake	membar	#Sync
17689051Sjake
177100718Sjake	IPI_WAIT(%g5, %g1, %g2, %g3)
17889051Sjake	retry
17989051SjakeEND(tl_ipi_tlb_page_demap)
18089051Sjake
18189051Sjake/*
18289051Sjake * Demap a range of pages from the dtlb and itlb.
18389051Sjake */
18489051SjakeENTRY(tl_ipi_tlb_range_demap)
18591783Sjake#if KTR_COMPILE & KTR_SMP
18691783Sjake	CATR(KTR_SMP, "ipi_tlb_range_demap: pm=%p start=%#lx end=%#lx"
18791783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
18891783Sjake	ldx	[%g5 + ITA_PMAP], %g2
18991783Sjake	stx	%g2, [%g1 + KTR_PARM1]
19089051Sjake	ldx	[%g5 + ITA_START], %g2
19191783Sjake	stx	%g2, [%g1 + KTR_PARM2]
19291783Sjake	ldx	[%g5 + ITA_END], %g2
19391783Sjake	stx	%g2, [%g1 + KTR_PARM3]
19491783Sjake9:
19591783Sjake#endif
19689051Sjake
19791783Sjake	ldx	[%g5 + ITA_PMAP], %g1
19889051Sjake
19991783Sjake	SET(kernel_pmap_store, %g3, %g2)
20091783Sjake	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
20189051Sjake
20291783Sjake	cmp	%g1, %g2
20391783Sjake	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
20489051Sjake
20591783Sjake	ldx	[%g5 + ITA_START], %g1
20691783Sjake	ldx	[%g5 + ITA_END], %g2
20789051Sjake
20891783Sjake	set	PAGE_SIZE, %g6
20991783Sjake
21091783Sjake1:	or	%g1, %g3, %g4
21189051Sjake	stxa	%g0, [%g4] ASI_DMMU_DEMAP
21289051Sjake	stxa	%g0, [%g4] ASI_IMMU_DEMAP
21391783Sjake	membar	#Sync
21489051Sjake
21591783Sjake	add	%g1, %g6, %g1
21691783Sjake	cmp	%g1, %g2
21791783Sjake	blt,a,pt %xcc, 1b
21889051Sjake	 nop
21989051Sjake
22092199Sjake	IPI_WAIT(%g5, %g1, %g2, %g3)
22189051Sjake	retry
22289051SjakeEND(tl_ipi_tlb_range_demap)
22389051Sjake
22489051Sjake/*
22591783Sjake * Demap the primary context from the dtlb and itlb.
22689051Sjake */
22789051SjakeENTRY(tl_ipi_tlb_context_demap)
22891783Sjake#if KTR_COMPILE & KTR_SMP
22991783Sjake	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
23091783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
23191783Sjake	ldx	[%g5 + ITA_PMAP], %g2
23291783Sjake	stx	%g2, [%g1 + KTR_PARM1]
23391783Sjake	ldx	[%g5 + ITA_VA], %g2
23491783Sjake	stx	%g2, [%g1 + KTR_PARM2]
23591783Sjake9:
23691783Sjake#endif
23789051Sjake
23891783Sjake	mov	TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, %g1
23991783Sjake	stxa	%g0, [%g1] ASI_DMMU_DEMAP
24091783Sjake	stxa	%g0, [%g1] ASI_IMMU_DEMAP
24189051Sjake	membar	#Sync
24289051Sjake
24392199Sjake	IPI_WAIT(%g5, %g1, %g2, %g3)
24489051Sjake	retry
24589051SjakeEND(tl_ipi_tlb_context_demap)
246