mp_exception.S revision 222813
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
27114188Sjake#include <machine/asm.h>
28114188Sjake__FBSDID("$FreeBSD: head/sys/sparc64/sparc64/mp_exception.S 222813 2011-06-07 08:46:13Z attilio $");
29114188Sjake
3089051Sjake#include <machine/asi.h>
31166105Smarius#include <machine/asmacros.h>
32166105Smarius#include <machine/cache.h>
3389051Sjake#include <machine/ktr.h>
3489051Sjake#include <machine/pstate.h>
3589051Sjake
3689051Sjake#include "assym.s"
3789051Sjake
3889051Sjake	.register	%g2, #ignore
3989051Sjake	.register	%g3, #ignore
4089051Sjake
41222813Sattilio#define	IPI_DONE(r1, r2, r3, r4, r5)					\
42222813Sattilio	lduw	[PCPU(CPUID)], r2 ;					\
43222813Sattilio	mov	_NCPUBITS, r3 ;						\
44222813Sattilio	mov	%g0, %y ;						\
45222813Sattilio	udiv	r2, r3, r4 ;						\
46222813Sattilio	srl	r4, 0, r5 ;						\
47222813Sattilio	sllx	r5, PTR_SHIFT, r5 ;					\
48222813Sattilio	add	r1, r5, r1 ;						\
49222813Sattilio	smul	r4, r3, r3 ;						\
50222813Sattilio	sub	r2, r3, r3 ;						\
51222813Sattilio	mov	1, r4 ;							\
52222813Sattilio	sllx	r4, r3, r4 ;						\
53222813Sattilio	ATOMIC_CLEAR_LONG(r1, r2, r3, r4)
5489051Sjake
5589051Sjake/*
56112399Sjake * Invalidate a physical page in the data cache.  For UltraSPARC I and II.
5797001Sjake */
58112399SjakeENTRY(tl_ipi_spitfire_dcache_page_inval)
5997001Sjake#if KTR_COMPILE & KTR_SMP
60211071Smarius	CATR(KTR_SMP, "tl_ipi_spitfire_dcache_page_inval: pa=%#lx"
6197001Sjake	    , %g1, %g2, %g3, 7, 8, 9)
6297001Sjake	ldx	[%g5 + ICA_PA], %g2
6397001Sjake	stx	%g2, [%g1 + KTR_PARM1]
6497001Sjake9:
6597001Sjake#endif
6697001Sjake
6797001Sjake	ldx	[%g5 + ICA_PA], %g6
6897001Sjake	srlx	%g6, PAGE_SHIFT - DC_TAG_SHIFT, %g6
6997001Sjake
70182689Smarius	lduw	[PCPU(CACHE) + DC_SIZE], %g3
71182689Smarius	lduw	[PCPU(CACHE) + DC_LINESIZE], %g4
7297001Sjake	sub	%g3, %g4, %g2
7397001Sjake
7497001Sjake1:	ldxa	[%g2] ASI_DCACHE_TAG, %g1
7597001Sjake	srlx	%g1, DC_VALID_SHIFT, %g3
7697001Sjake	andcc	%g3, DC_VALID_MASK, %g0
7797001Sjake	bz,pt	%xcc, 2f
7897001Sjake	 set	DC_TAG_MASK, %g3
7997001Sjake	sllx	%g3, DC_TAG_SHIFT, %g3
8097001Sjake	and	%g1, %g3, %g1
8197001Sjake	cmp	%g1, %g6
8297001Sjake	bne,a,pt %xcc, 2f
8397001Sjake	 nop
8497001Sjake	stxa	%g1, [%g2] ASI_DCACHE_TAG
8597001Sjake	membar	#Sync
8697001Sjake
8797001Sjake2:	brgz,pt	%g2, 1b
8897001Sjake	 sub	%g2, %g4, %g2
8997001Sjake
90222813Sattilio	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
9197001Sjake	retry
92112399SjakeEND(tl_ipi_spitfire_dcache_page_inval)
9397001Sjake
9497001Sjake/*
95112399Sjake * Invalidate a physical page in the instruction cache.  For UltraSPARC I and
96112399Sjake * II.
9797001Sjake */
98112399SjakeENTRY(tl_ipi_spitfire_icache_page_inval)
9997001Sjake#if KTR_COMPILE & KTR_SMP
100211071Smarius	CATR(KTR_SMP, "tl_ipi_spitfire_icache_page_inval: pa=%#lx"
10197001Sjake	    , %g1, %g2, %g3, 7, 8, 9)
10297001Sjake	ldx	[%g5 + ICA_PA], %g2
10397001Sjake	stx	%g2, [%g1 + KTR_PARM1]
10497001Sjake9:
10597001Sjake#endif
10697001Sjake
10797001Sjake	ldx	[%g5 + ICA_PA], %g6
10897001Sjake	srlx	%g6, PAGE_SHIFT - IC_TAG_SHIFT, %g6
10997001Sjake
110182689Smarius	lduw	[PCPU(CACHE) + IC_SIZE], %g3
111182689Smarius	lduw	[PCPU(CACHE) + IC_LINESIZE], %g4
11297001Sjake	sub	%g3, %g4, %g2
11397001Sjake
11497001Sjake1:	ldda	[%g2] ASI_ICACHE_TAG, %g0 /*, %g1 */
11597001Sjake	srlx	%g1, IC_VALID_SHIFT, %g3
11697001Sjake	andcc	%g3, IC_VALID_MASK, %g0
11797001Sjake	bz,pt	%xcc, 2f
11897001Sjake	 set	IC_TAG_MASK, %g3
11997001Sjake	sllx	%g3, IC_TAG_SHIFT, %g3
12097001Sjake	and	%g1, %g3, %g1
12197001Sjake	cmp	%g1, %g6
12297001Sjake	bne,a,pt %xcc, 2f
12397001Sjake	 nop
12497001Sjake	stxa	%g1, [%g2] ASI_ICACHE_TAG
12597001Sjake	membar	#Sync
12697001Sjake
12797001Sjake2:	brgz,pt	%g2, 1b
12897001Sjake	 sub	%g2, %g4, %g2
12997001Sjake
130222813Sattilio	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
13197001Sjake	retry
132112399SjakeEND(tl_ipi_spitfire_icache_page_inval)
13397001Sjake
13497001Sjake/*
135112399Sjake * Invalidate a physical page in the data cache.  For UltraSPARC III.
136112399Sjake */
137112399SjakeENTRY(tl_ipi_cheetah_dcache_page_inval)
138112399Sjake#if KTR_COMPILE & KTR_SMP
139211071Smarius	CATR(KTR_SMP, "tl_ipi_cheetah_dcache_page_inval: pa=%#lx"
140112399Sjake	    , %g1, %g2, %g3, 7, 8, 9)
141112399Sjake	ldx	[%g5 + ICA_PA], %g2
142112399Sjake	stx	%g2, [%g1 + KTR_PARM1]
143112399Sjake9:
144112399Sjake#endif
145112399Sjake
146112399Sjake	ldx	[%g5 + ICA_PA], %g1
147112399Sjake
148112399Sjake	set	PAGE_SIZE, %g2
149112399Sjake	add	%g1, %g2, %g3
150112399Sjake
151182689Smarius	lduw	[PCPU(CACHE) + DC_LINESIZE], %g2
152112399Sjake
153112399Sjake1:	stxa	%g0, [%g1] ASI_DCACHE_INVALIDATE
154112399Sjake	membar	#Sync
155112399Sjake
156112399Sjake	add	%g1, %g2, %g1
157112399Sjake	cmp	%g1, %g3
158112399Sjake	blt,a,pt %xcc, 1b
159112399Sjake	 nop
160112399Sjake
161222813Sattilio	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
162112399Sjake	retry
163112399SjakeEND(tl_ipi_cheetah_dcache_page_inval)
164112399Sjake
165112399Sjake/*
16689051Sjake * Trigger a softint at the desired level.
16789051Sjake */
16889051SjakeENTRY(tl_ipi_level)
16992199Sjake#if KTR_COMPILE & KTR_SMP
17092199Sjake	CATR(KTR_SMP, "tl_ipi_level: cpuid=%d mid=%d d1=%#lx d2=%#lx"
17192199Sjake	    , %g1, %g2, %g3, 7, 8, 9)
17292199Sjake	lduw	[PCPU(CPUID)], %g2
17392199Sjake	stx	%g2, [%g1 + KTR_PARM1]
17492199Sjake	lduw	[PCPU(MID)], %g2
17592199Sjake	stx	%g2, [%g1 + KTR_PARM2]
17692199Sjake	stx	%g4, [%g1 + KTR_PARM3]
17792199Sjake	stx	%g5, [%g1 + KTR_PARM4]
17892199Sjake9:
17992199Sjake#endif
18089051Sjake
18189051Sjake	mov	1, %g1
18292199Sjake	sllx	%g1, %g5, %g1
183108379Sjake	wr	%g1, 0, %set_softint
18489051Sjake	retry
18589051SjakeEND(tl_ipi_level)
18689051Sjake
18789051Sjake/*
18889051Sjake * Demap a page from the dtlb and/or itlb.
18989051Sjake */
19089051SjakeENTRY(tl_ipi_tlb_page_demap)
19191783Sjake#if KTR_COMPILE & KTR_SMP
19291783Sjake	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
19391783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
19491783Sjake	ldx	[%g5 + ITA_PMAP], %g2
19591783Sjake	stx	%g2, [%g1 + KTR_PARM1]
19691783Sjake	ldx	[%g5 + ITA_VA], %g2
19791783Sjake	stx	%g2, [%g1 + KTR_PARM2]
19891783Sjake9:
19991783Sjake#endif
20089051Sjake
20191783Sjake	ldx	[%g5 + ITA_PMAP], %g1
20289051Sjake
20391783Sjake	SET(kernel_pmap_store, %g3, %g2)
20491783Sjake	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
20589051Sjake
20691783Sjake	cmp	%g1, %g2
20791783Sjake	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
20889051Sjake
20991783Sjake	ldx	[%g5 + ITA_VA], %g2
21091783Sjake	or	%g2, %g3, %g2
21189051Sjake
212182877Smarius	sethi	%hi(KERNBASE), %g3
21391783Sjake	stxa	%g0, [%g2] ASI_DMMU_DEMAP
21491783Sjake	stxa	%g0, [%g2] ASI_IMMU_DEMAP
215182877Smarius	flush	%g3
21689051Sjake
217222813Sattilio	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
21889051Sjake	retry
21989051SjakeEND(tl_ipi_tlb_page_demap)
22089051Sjake
22189051Sjake/*
22289051Sjake * Demap a range of pages from the dtlb and itlb.
22389051Sjake */
22489051SjakeENTRY(tl_ipi_tlb_range_demap)
22591783Sjake#if KTR_COMPILE & KTR_SMP
22691783Sjake	CATR(KTR_SMP, "ipi_tlb_range_demap: pm=%p start=%#lx end=%#lx"
22791783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
22891783Sjake	ldx	[%g5 + ITA_PMAP], %g2
22991783Sjake	stx	%g2, [%g1 + KTR_PARM1]
23089051Sjake	ldx	[%g5 + ITA_START], %g2
23191783Sjake	stx	%g2, [%g1 + KTR_PARM2]
23291783Sjake	ldx	[%g5 + ITA_END], %g2
23391783Sjake	stx	%g2, [%g1 + KTR_PARM3]
23491783Sjake9:
23591783Sjake#endif
23689051Sjake
23791783Sjake	ldx	[%g5 + ITA_PMAP], %g1
23889051Sjake
23991783Sjake	SET(kernel_pmap_store, %g3, %g2)
24091783Sjake	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
24189051Sjake
24291783Sjake	cmp	%g1, %g2
24391783Sjake	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
24489051Sjake
24591783Sjake	ldx	[%g5 + ITA_START], %g1
24691783Sjake	ldx	[%g5 + ITA_END], %g2
24789051Sjake
24891783Sjake1:	or	%g1, %g3, %g4
249182877Smarius	sethi	%hi(KERNBASE), %g6
25089051Sjake	stxa	%g0, [%g4] ASI_DMMU_DEMAP
25189051Sjake	stxa	%g0, [%g4] ASI_IMMU_DEMAP
252182877Smarius	flush	%g6
25389051Sjake
254182877Smarius	set	PAGE_SIZE, %g6
25591783Sjake	add	%g1, %g6, %g1
25691783Sjake	cmp	%g1, %g2
25791783Sjake	blt,a,pt %xcc, 1b
25889051Sjake	 nop
25989051Sjake
260222813Sattilio	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
26189051Sjake	retry
26289051SjakeEND(tl_ipi_tlb_range_demap)
26389051Sjake
26489051Sjake/*
26591783Sjake * Demap the primary context from the dtlb and itlb.
26689051Sjake */
26789051SjakeENTRY(tl_ipi_tlb_context_demap)
26891783Sjake#if KTR_COMPILE & KTR_SMP
269211071Smarius	CATR(KTR_SMP, "tl_ipi_tlb_context_demap: pm=%p va=%#lx"
27091783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
27191783Sjake	ldx	[%g5 + ITA_PMAP], %g2
27291783Sjake	stx	%g2, [%g1 + KTR_PARM1]
27391783Sjake	ldx	[%g5 + ITA_VA], %g2
27491783Sjake	stx	%g2, [%g1 + KTR_PARM2]
27591783Sjake9:
27691783Sjake#endif
27789051Sjake
27891783Sjake	mov	TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, %g1
279182877Smarius	sethi	%hi(KERNBASE), %g3
28091783Sjake	stxa	%g0, [%g1] ASI_DMMU_DEMAP
28191783Sjake	stxa	%g0, [%g1] ASI_IMMU_DEMAP
282182877Smarius	flush	%g3
28389051Sjake
284222813Sattilio	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
28589051Sjake	retry
28689051SjakeEND(tl_ipi_tlb_context_demap)
287211071Smarius
288211071Smarius/*
289211071Smarius * Read %stick.
290211071Smarius */
291211071SmariusENTRY(tl_ipi_stick_rd)
292211071Smarius	ldx	[%g5 + IRA_VAL], %g1
293211071Smarius	rd	%asr24, %g2
294211071Smarius	stx	%g2, [%g1]
295211071Smarius
296222813Sattilio	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
297211071Smarius	retry
298211071SmariusEND(tl_ipi_stick_rd)
299211071Smarius
300211071Smarius/*
301211071Smarius * Read %tick.
302211071Smarius */
303211071SmariusENTRY(tl_ipi_tick_rd)
304211071Smarius	ldx	[%g5 + IRA_VAL], %g1
305211071Smarius	rd	%tick, %g2
306211071Smarius	stx	%g2, [%g1]
307211071Smarius
308222813Sattilio	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
309211071Smarius	retry
310211071SmariusEND(tl_ipi_tick_rd)
311