mp_exception.S revision 112399
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 112399 2003-03-19 06:55:37Z 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/*
47112399Sjake * Invalidate a physical page in the data cache.  For UltraSPARC I and II.
4897001Sjake */
49112399SjakeENTRY(tl_ipi_spitfire_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
84112399SjakeEND(tl_ipi_spitfire_dcache_page_inval)
8597001Sjake
8697001Sjake/*
87112399Sjake * Invalidate a physical page in the instruction cache.  For UltraSPARC I and
88112399Sjake * II.
8997001Sjake */
90112399SjakeENTRY(tl_ipi_spitfire_icache_page_inval)
9197001Sjake#if KTR_COMPILE & KTR_SMP
9297001Sjake	CATR(KTR_SMP, "ipi_icache_page_inval: pa=%#lx"
9397001Sjake	    , %g1, %g2, %g3, 7, 8, 9)
9497001Sjake	ldx	[%g5 + ICA_PA], %g2
9597001Sjake	stx	%g2, [%g1 + KTR_PARM1]
9697001Sjake9:
9797001Sjake#endif
9897001Sjake
9997001Sjake	ldx	[%g5 + ICA_PA], %g6
10097001Sjake	srlx	%g6, PAGE_SHIFT - IC_TAG_SHIFT, %g6
10197001Sjake
10297001Sjake	SET(cache, %g3, %g2)
10397001Sjake	lduw	[%g2 + IC_SIZE], %g3
10497001Sjake	lduw	[%g2 + IC_LINESIZE], %g4
10597001Sjake	sub	%g3, %g4, %g2
10697001Sjake
10797001Sjake1:	ldda	[%g2] ASI_ICACHE_TAG, %g0 /*, %g1 */
10897001Sjake	srlx	%g1, IC_VALID_SHIFT, %g3
10997001Sjake	andcc	%g3, IC_VALID_MASK, %g0
11097001Sjake	bz,pt	%xcc, 2f
11197001Sjake	 set	IC_TAG_MASK, %g3
11297001Sjake	sllx	%g3, IC_TAG_SHIFT, %g3
11397001Sjake	and	%g1, %g3, %g1
11497001Sjake	cmp	%g1, %g6
11597001Sjake	bne,a,pt %xcc, 2f
11697001Sjake	 nop
11797001Sjake	stxa	%g1, [%g2] ASI_ICACHE_TAG
11897001Sjake	membar	#Sync
11997001Sjake
12097001Sjake2:	brgz,pt	%g2, 1b
12197001Sjake	 sub	%g2, %g4, %g2
12297001Sjake
12397001Sjake	IPI_WAIT(%g5, %g1, %g2, %g3)
12497001Sjake	retry
125112399SjakeEND(tl_ipi_spitfire_icache_page_inval)
12697001Sjake
12797001Sjake/*
128112399Sjake * Invalidate a physical page in the data cache.  For UltraSPARC III.
129112399Sjake */
130112399SjakeENTRY(tl_ipi_cheetah_dcache_page_inval)
131112399Sjake#if KTR_COMPILE & KTR_SMP
132112399Sjake	CATR(KTR_SMP, "ipi_dcache_page_inval: pa=%#lx"
133112399Sjake	    , %g1, %g2, %g3, 7, 8, 9)
134112399Sjake	ldx	[%g5 + ICA_PA], %g2
135112399Sjake	stx	%g2, [%g1 + KTR_PARM1]
136112399Sjake9:
137112399Sjake#endif
138112399Sjake
139112399Sjake	ldx	[%g5 + ICA_PA], %g1
140112399Sjake
141112399Sjake	set	PAGE_SIZE, %g2
142112399Sjake	add	%g1, %g2, %g3
143112399Sjake
144112399Sjake	SET(cache, %g4, %g2)
145112399Sjake	lduw	[%g2 + DC_LINESIZE], %g2
146112399Sjake
147112399Sjake1:	stxa	%g0, [%g1] ASI_DCACHE_INVALIDATE
148112399Sjake	membar	#Sync
149112399Sjake
150112399Sjake	add	%g1, %g2, %g1
151112399Sjake	cmp	%g1, %g3
152112399Sjake	blt,a,pt %xcc, 1b
153112399Sjake	 nop
154112399Sjake
155112399Sjake	IPI_WAIT(%g5, %g1, %g2, %g3)
156112399Sjake	retry
157112399SjakeEND(tl_ipi_cheetah_dcache_page_inval)
158112399Sjake
159112399Sjake/*
16089051Sjake * Trigger a softint at the desired level.
16189051Sjake */
16289051SjakeENTRY(tl_ipi_level)
16392199Sjake#if KTR_COMPILE & KTR_SMP
16492199Sjake	CATR(KTR_SMP, "tl_ipi_level: cpuid=%d mid=%d d1=%#lx d2=%#lx"
16592199Sjake	    , %g1, %g2, %g3, 7, 8, 9)
16692199Sjake	lduw	[PCPU(CPUID)], %g2
16792199Sjake	stx	%g2, [%g1 + KTR_PARM1]
16892199Sjake	lduw	[PCPU(MID)], %g2
16992199Sjake	stx	%g2, [%g1 + KTR_PARM2]
17092199Sjake	stx	%g4, [%g1 + KTR_PARM3]
17192199Sjake	stx	%g5, [%g1 + KTR_PARM4]
17292199Sjake9:
17392199Sjake#endif
17489051Sjake
17589051Sjake	mov	1, %g1
17692199Sjake	sllx	%g1, %g5, %g1
177108379Sjake	wr	%g1, 0, %set_softint
17889051Sjake	retry
17989051SjakeEND(tl_ipi_level)
18089051Sjake
18189051Sjake/*
18289051Sjake * Demap a page from the dtlb and/or itlb.
18389051Sjake */
18489051SjakeENTRY(tl_ipi_tlb_page_demap)
18591783Sjake#if KTR_COMPILE & KTR_SMP
18691783Sjake	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
18791783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
18891783Sjake	ldx	[%g5 + ITA_PMAP], %g2
18991783Sjake	stx	%g2, [%g1 + KTR_PARM1]
19091783Sjake	ldx	[%g5 + ITA_VA], %g2
19191783Sjake	stx	%g2, [%g1 + KTR_PARM2]
19291783Sjake9:
19391783Sjake#endif
19489051Sjake
19591783Sjake	ldx	[%g5 + ITA_PMAP], %g1
19689051Sjake
19791783Sjake	SET(kernel_pmap_store, %g3, %g2)
19891783Sjake	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
19989051Sjake
20091783Sjake	cmp	%g1, %g2
20191783Sjake	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
20289051Sjake
20391783Sjake	ldx	[%g5 + ITA_VA], %g2
20491783Sjake	or	%g2, %g3, %g2
20589051Sjake
20691783Sjake	stxa	%g0, [%g2] ASI_DMMU_DEMAP
20791783Sjake	stxa	%g0, [%g2] ASI_IMMU_DEMAP
20891783Sjake	membar	#Sync
20989051Sjake
210100718Sjake	IPI_WAIT(%g5, %g1, %g2, %g3)
21189051Sjake	retry
21289051SjakeEND(tl_ipi_tlb_page_demap)
21389051Sjake
21489051Sjake/*
21589051Sjake * Demap a range of pages from the dtlb and itlb.
21689051Sjake */
21789051SjakeENTRY(tl_ipi_tlb_range_demap)
21891783Sjake#if KTR_COMPILE & KTR_SMP
21991783Sjake	CATR(KTR_SMP, "ipi_tlb_range_demap: pm=%p start=%#lx end=%#lx"
22091783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
22191783Sjake	ldx	[%g5 + ITA_PMAP], %g2
22291783Sjake	stx	%g2, [%g1 + KTR_PARM1]
22389051Sjake	ldx	[%g5 + ITA_START], %g2
22491783Sjake	stx	%g2, [%g1 + KTR_PARM2]
22591783Sjake	ldx	[%g5 + ITA_END], %g2
22691783Sjake	stx	%g2, [%g1 + KTR_PARM3]
22791783Sjake9:
22891783Sjake#endif
22989051Sjake
23091783Sjake	ldx	[%g5 + ITA_PMAP], %g1
23189051Sjake
23291783Sjake	SET(kernel_pmap_store, %g3, %g2)
23391783Sjake	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
23489051Sjake
23591783Sjake	cmp	%g1, %g2
23691783Sjake	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
23789051Sjake
23891783Sjake	ldx	[%g5 + ITA_START], %g1
23991783Sjake	ldx	[%g5 + ITA_END], %g2
24089051Sjake
24191783Sjake	set	PAGE_SIZE, %g6
24291783Sjake
24391783Sjake1:	or	%g1, %g3, %g4
24489051Sjake	stxa	%g0, [%g4] ASI_DMMU_DEMAP
24589051Sjake	stxa	%g0, [%g4] ASI_IMMU_DEMAP
24691783Sjake	membar	#Sync
24789051Sjake
24891783Sjake	add	%g1, %g6, %g1
24991783Sjake	cmp	%g1, %g2
25091783Sjake	blt,a,pt %xcc, 1b
25189051Sjake	 nop
25289051Sjake
25392199Sjake	IPI_WAIT(%g5, %g1, %g2, %g3)
25489051Sjake	retry
25589051SjakeEND(tl_ipi_tlb_range_demap)
25689051Sjake
25789051Sjake/*
25891783Sjake * Demap the primary context from the dtlb and itlb.
25989051Sjake */
26089051SjakeENTRY(tl_ipi_tlb_context_demap)
26191783Sjake#if KTR_COMPILE & KTR_SMP
26291783Sjake	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
26391783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
26491783Sjake	ldx	[%g5 + ITA_PMAP], %g2
26591783Sjake	stx	%g2, [%g1 + KTR_PARM1]
26691783Sjake	ldx	[%g5 + ITA_VA], %g2
26791783Sjake	stx	%g2, [%g1 + KTR_PARM2]
26891783Sjake9:
26991783Sjake#endif
27089051Sjake
27191783Sjake	mov	TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, %g1
27291783Sjake	stxa	%g0, [%g1] ASI_DMMU_DEMAP
27391783Sjake	stxa	%g0, [%g1] ASI_IMMU_DEMAP
27489051Sjake	membar	#Sync
27589051Sjake
27692199Sjake	IPI_WAIT(%g5, %g1, %g2, %g3)
27789051Sjake	retry
27889051SjakeEND(tl_ipi_tlb_context_demap)
279