mp_exception.S revision 211071
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 211071 2010-08-08 14:00:21Z marius $");
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
41116567Sjake#define	IPI_DONE(r1, r2, r3, r4) \
4292199Sjake	lduw	[PCPU(CPUMASK)], r4 ;  \
43116567Sjake	ATOMIC_CLEAR_INT(r1, r2, r3, r4)
4489051Sjake
4589051Sjake/*
46112399Sjake * Invalidate a physical page in the data cache.  For UltraSPARC I and II.
4797001Sjake */
48112399SjakeENTRY(tl_ipi_spitfire_dcache_page_inval)
4997001Sjake#if KTR_COMPILE & KTR_SMP
50211071Smarius	CATR(KTR_SMP, "tl_ipi_spitfire_dcache_page_inval: pa=%#lx"
5197001Sjake	    , %g1, %g2, %g3, 7, 8, 9)
5297001Sjake	ldx	[%g5 + ICA_PA], %g2
5397001Sjake	stx	%g2, [%g1 + KTR_PARM1]
5497001Sjake9:
5597001Sjake#endif
5697001Sjake
5797001Sjake	ldx	[%g5 + ICA_PA], %g6
5897001Sjake	srlx	%g6, PAGE_SHIFT - DC_TAG_SHIFT, %g6
5997001Sjake
60182689Smarius	lduw	[PCPU(CACHE) + DC_SIZE], %g3
61182689Smarius	lduw	[PCPU(CACHE) + DC_LINESIZE], %g4
6297001Sjake	sub	%g3, %g4, %g2
6397001Sjake
6497001Sjake1:	ldxa	[%g2] ASI_DCACHE_TAG, %g1
6597001Sjake	srlx	%g1, DC_VALID_SHIFT, %g3
6697001Sjake	andcc	%g3, DC_VALID_MASK, %g0
6797001Sjake	bz,pt	%xcc, 2f
6897001Sjake	 set	DC_TAG_MASK, %g3
6997001Sjake	sllx	%g3, DC_TAG_SHIFT, %g3
7097001Sjake	and	%g1, %g3, %g1
7197001Sjake	cmp	%g1, %g6
7297001Sjake	bne,a,pt %xcc, 2f
7397001Sjake	 nop
7497001Sjake	stxa	%g1, [%g2] ASI_DCACHE_TAG
7597001Sjake	membar	#Sync
7697001Sjake
7797001Sjake2:	brgz,pt	%g2, 1b
7897001Sjake	 sub	%g2, %g4, %g2
7997001Sjake
80116567Sjake	IPI_DONE(%g5, %g1, %g2, %g3)
8197001Sjake	retry
82112399SjakeEND(tl_ipi_spitfire_dcache_page_inval)
8397001Sjake
8497001Sjake/*
85112399Sjake * Invalidate a physical page in the instruction cache.  For UltraSPARC I and
86112399Sjake * II.
8797001Sjake */
88112399SjakeENTRY(tl_ipi_spitfire_icache_page_inval)
8997001Sjake#if KTR_COMPILE & KTR_SMP
90211071Smarius	CATR(KTR_SMP, "tl_ipi_spitfire_icache_page_inval: pa=%#lx"
9197001Sjake	    , %g1, %g2, %g3, 7, 8, 9)
9297001Sjake	ldx	[%g5 + ICA_PA], %g2
9397001Sjake	stx	%g2, [%g1 + KTR_PARM1]
9497001Sjake9:
9597001Sjake#endif
9697001Sjake
9797001Sjake	ldx	[%g5 + ICA_PA], %g6
9897001Sjake	srlx	%g6, PAGE_SHIFT - IC_TAG_SHIFT, %g6
9997001Sjake
100182689Smarius	lduw	[PCPU(CACHE) + IC_SIZE], %g3
101182689Smarius	lduw	[PCPU(CACHE) + IC_LINESIZE], %g4
10297001Sjake	sub	%g3, %g4, %g2
10397001Sjake
10497001Sjake1:	ldda	[%g2] ASI_ICACHE_TAG, %g0 /*, %g1 */
10597001Sjake	srlx	%g1, IC_VALID_SHIFT, %g3
10697001Sjake	andcc	%g3, IC_VALID_MASK, %g0
10797001Sjake	bz,pt	%xcc, 2f
10897001Sjake	 set	IC_TAG_MASK, %g3
10997001Sjake	sllx	%g3, IC_TAG_SHIFT, %g3
11097001Sjake	and	%g1, %g3, %g1
11197001Sjake	cmp	%g1, %g6
11297001Sjake	bne,a,pt %xcc, 2f
11397001Sjake	 nop
11497001Sjake	stxa	%g1, [%g2] ASI_ICACHE_TAG
11597001Sjake	membar	#Sync
11697001Sjake
11797001Sjake2:	brgz,pt	%g2, 1b
11897001Sjake	 sub	%g2, %g4, %g2
11997001Sjake
120116567Sjake	IPI_DONE(%g5, %g1, %g2, %g3)
12197001Sjake	retry
122112399SjakeEND(tl_ipi_spitfire_icache_page_inval)
12397001Sjake
12497001Sjake/*
125112399Sjake * Invalidate a physical page in the data cache.  For UltraSPARC III.
126112399Sjake */
127112399SjakeENTRY(tl_ipi_cheetah_dcache_page_inval)
128112399Sjake#if KTR_COMPILE & KTR_SMP
129211071Smarius	CATR(KTR_SMP, "tl_ipi_cheetah_dcache_page_inval: pa=%#lx"
130112399Sjake	    , %g1, %g2, %g3, 7, 8, 9)
131112399Sjake	ldx	[%g5 + ICA_PA], %g2
132112399Sjake	stx	%g2, [%g1 + KTR_PARM1]
133112399Sjake9:
134112399Sjake#endif
135112399Sjake
136112399Sjake	ldx	[%g5 + ICA_PA], %g1
137112399Sjake
138112399Sjake	set	PAGE_SIZE, %g2
139112399Sjake	add	%g1, %g2, %g3
140112399Sjake
141182689Smarius	lduw	[PCPU(CACHE) + DC_LINESIZE], %g2
142112399Sjake
143112399Sjake1:	stxa	%g0, [%g1] ASI_DCACHE_INVALIDATE
144112399Sjake	membar	#Sync
145112399Sjake
146112399Sjake	add	%g1, %g2, %g1
147112399Sjake	cmp	%g1, %g3
148112399Sjake	blt,a,pt %xcc, 1b
149112399Sjake	 nop
150112399Sjake
151116567Sjake	IPI_DONE(%g5, %g1, %g2, %g3)
152112399Sjake	retry
153112399SjakeEND(tl_ipi_cheetah_dcache_page_inval)
154112399Sjake
155112399Sjake/*
15689051Sjake * Trigger a softint at the desired level.
15789051Sjake */
15889051SjakeENTRY(tl_ipi_level)
15992199Sjake#if KTR_COMPILE & KTR_SMP
16092199Sjake	CATR(KTR_SMP, "tl_ipi_level: cpuid=%d mid=%d d1=%#lx d2=%#lx"
16192199Sjake	    , %g1, %g2, %g3, 7, 8, 9)
16292199Sjake	lduw	[PCPU(CPUID)], %g2
16392199Sjake	stx	%g2, [%g1 + KTR_PARM1]
16492199Sjake	lduw	[PCPU(MID)], %g2
16592199Sjake	stx	%g2, [%g1 + KTR_PARM2]
16692199Sjake	stx	%g4, [%g1 + KTR_PARM3]
16792199Sjake	stx	%g5, [%g1 + KTR_PARM4]
16892199Sjake9:
16992199Sjake#endif
17089051Sjake
17189051Sjake	mov	1, %g1
17292199Sjake	sllx	%g1, %g5, %g1
173108379Sjake	wr	%g1, 0, %set_softint
17489051Sjake	retry
17589051SjakeEND(tl_ipi_level)
17689051Sjake
17789051Sjake/*
17889051Sjake * Demap a page from the dtlb and/or itlb.
17989051Sjake */
18089051SjakeENTRY(tl_ipi_tlb_page_demap)
18191783Sjake#if KTR_COMPILE & KTR_SMP
18291783Sjake	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
18391783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
18491783Sjake	ldx	[%g5 + ITA_PMAP], %g2
18591783Sjake	stx	%g2, [%g1 + KTR_PARM1]
18691783Sjake	ldx	[%g5 + ITA_VA], %g2
18791783Sjake	stx	%g2, [%g1 + KTR_PARM2]
18891783Sjake9:
18991783Sjake#endif
19089051Sjake
19191783Sjake	ldx	[%g5 + ITA_PMAP], %g1
19289051Sjake
19391783Sjake	SET(kernel_pmap_store, %g3, %g2)
19491783Sjake	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
19589051Sjake
19691783Sjake	cmp	%g1, %g2
19791783Sjake	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
19889051Sjake
19991783Sjake	ldx	[%g5 + ITA_VA], %g2
20091783Sjake	or	%g2, %g3, %g2
20189051Sjake
202182877Smarius	sethi	%hi(KERNBASE), %g3
20391783Sjake	stxa	%g0, [%g2] ASI_DMMU_DEMAP
20491783Sjake	stxa	%g0, [%g2] ASI_IMMU_DEMAP
205182877Smarius	flush	%g3
20689051Sjake
207116567Sjake	IPI_DONE(%g5, %g1, %g2, %g3)
20889051Sjake	retry
20989051SjakeEND(tl_ipi_tlb_page_demap)
21089051Sjake
21189051Sjake/*
21289051Sjake * Demap a range of pages from the dtlb and itlb.
21389051Sjake */
21489051SjakeENTRY(tl_ipi_tlb_range_demap)
21591783Sjake#if KTR_COMPILE & KTR_SMP
21691783Sjake	CATR(KTR_SMP, "ipi_tlb_range_demap: pm=%p start=%#lx end=%#lx"
21791783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
21891783Sjake	ldx	[%g5 + ITA_PMAP], %g2
21991783Sjake	stx	%g2, [%g1 + KTR_PARM1]
22089051Sjake	ldx	[%g5 + ITA_START], %g2
22191783Sjake	stx	%g2, [%g1 + KTR_PARM2]
22291783Sjake	ldx	[%g5 + ITA_END], %g2
22391783Sjake	stx	%g2, [%g1 + KTR_PARM3]
22491783Sjake9:
22591783Sjake#endif
22689051Sjake
22791783Sjake	ldx	[%g5 + ITA_PMAP], %g1
22889051Sjake
22991783Sjake	SET(kernel_pmap_store, %g3, %g2)
23091783Sjake	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
23189051Sjake
23291783Sjake	cmp	%g1, %g2
23391783Sjake	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
23489051Sjake
23591783Sjake	ldx	[%g5 + ITA_START], %g1
23691783Sjake	ldx	[%g5 + ITA_END], %g2
23789051Sjake
23891783Sjake1:	or	%g1, %g3, %g4
239182877Smarius	sethi	%hi(KERNBASE), %g6
24089051Sjake	stxa	%g0, [%g4] ASI_DMMU_DEMAP
24189051Sjake	stxa	%g0, [%g4] ASI_IMMU_DEMAP
242182877Smarius	flush	%g6
24389051Sjake
244182877Smarius	set	PAGE_SIZE, %g6
24591783Sjake	add	%g1, %g6, %g1
24691783Sjake	cmp	%g1, %g2
24791783Sjake	blt,a,pt %xcc, 1b
24889051Sjake	 nop
24989051Sjake
250116567Sjake	IPI_DONE(%g5, %g1, %g2, %g3)
25189051Sjake	retry
25289051SjakeEND(tl_ipi_tlb_range_demap)
25389051Sjake
25489051Sjake/*
25591783Sjake * Demap the primary context from the dtlb and itlb.
25689051Sjake */
25789051SjakeENTRY(tl_ipi_tlb_context_demap)
25891783Sjake#if KTR_COMPILE & KTR_SMP
259211071Smarius	CATR(KTR_SMP, "tl_ipi_tlb_context_demap: pm=%p va=%#lx"
26091783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
26191783Sjake	ldx	[%g5 + ITA_PMAP], %g2
26291783Sjake	stx	%g2, [%g1 + KTR_PARM1]
26391783Sjake	ldx	[%g5 + ITA_VA], %g2
26491783Sjake	stx	%g2, [%g1 + KTR_PARM2]
26591783Sjake9:
26691783Sjake#endif
26789051Sjake
26891783Sjake	mov	TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, %g1
269182877Smarius	sethi	%hi(KERNBASE), %g3
27091783Sjake	stxa	%g0, [%g1] ASI_DMMU_DEMAP
27191783Sjake	stxa	%g0, [%g1] ASI_IMMU_DEMAP
272182877Smarius	flush	%g3
27389051Sjake
274116567Sjake	IPI_DONE(%g5, %g1, %g2, %g3)
27589051Sjake	retry
27689051SjakeEND(tl_ipi_tlb_context_demap)
277211071Smarius
278211071Smarius/*
279211071Smarius * Read %stick.
280211071Smarius */
281211071SmariusENTRY(tl_ipi_stick_rd)
282211071Smarius	ldx	[%g5 + IRA_VAL], %g1
283211071Smarius	rd	%asr24, %g2
284211071Smarius	stx	%g2, [%g1]
285211071Smarius
286211071Smarius	IPI_DONE(%g5, %g1, %g2, %g3)
287211071Smarius	retry
288211071SmariusEND(tl_ipi_stick_rd)
289211071Smarius
290211071Smarius/*
291211071Smarius * Read %tick.
292211071Smarius */
293211071SmariusENTRY(tl_ipi_tick_rd)
294211071Smarius	ldx	[%g5 + IRA_VAL], %g1
295211071Smarius	rd	%tick, %g2
296211071Smarius	stx	%g2, [%g1]
297211071Smarius
298211071Smarius	IPI_DONE(%g5, %g1, %g2, %g3)
299211071Smarius	retry
300211071SmariusEND(tl_ipi_tick_rd)
301