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$");
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
41292943Smarius#define	IPI_DONE(r1, r2, r3, r4, r5)					\
42222813Sattilio	lduw	[PCPU(CPUID)], r2 ;					\
43222813Sattilio	mov	_NCPUBITS, r3 ;						\
44292943Smarius	udivx	r2, r3, r4 ;						\
45222813Sattilio	srl	r4, 0, r5 ;						\
46222813Sattilio	sllx	r5, PTR_SHIFT, r5 ;					\
47222813Sattilio	add	r1, r5, r1 ;						\
48222813Sattilio	smul	r4, r3, r3 ;						\
49222813Sattilio	sub	r2, r3, r3 ;						\
50222813Sattilio	mov	1, r4 ;							\
51222813Sattilio	sllx	r4, r3, r4 ;						\
52222813Sattilio	ATOMIC_CLEAR_LONG(r1, r2, r3, r4)
5389051Sjake
5489051Sjake/*
55112399Sjake * Invalidate a physical page in the data cache.  For UltraSPARC I and II.
5697001Sjake */
57112399SjakeENTRY(tl_ipi_spitfire_dcache_page_inval)
5897001Sjake#if KTR_COMPILE & KTR_SMP
59211071Smarius	CATR(KTR_SMP, "tl_ipi_spitfire_dcache_page_inval: pa=%#lx"
6097001Sjake	    , %g1, %g2, %g3, 7, 8, 9)
6197001Sjake	ldx	[%g5 + ICA_PA], %g2
6297001Sjake	stx	%g2, [%g1 + KTR_PARM1]
6397001Sjake9:
6497001Sjake#endif
6597001Sjake
6697001Sjake	ldx	[%g5 + ICA_PA], %g6
6797001Sjake	srlx	%g6, PAGE_SHIFT - DC_TAG_SHIFT, %g6
6897001Sjake
69182689Smarius	lduw	[PCPU(CACHE) + DC_SIZE], %g3
70182689Smarius	lduw	[PCPU(CACHE) + DC_LINESIZE], %g4
7197001Sjake	sub	%g3, %g4, %g2
7297001Sjake
7397001Sjake1:	ldxa	[%g2] ASI_DCACHE_TAG, %g1
7497001Sjake	srlx	%g1, DC_VALID_SHIFT, %g3
7597001Sjake	andcc	%g3, DC_VALID_MASK, %g0
7697001Sjake	bz,pt	%xcc, 2f
7797001Sjake	 set	DC_TAG_MASK, %g3
7897001Sjake	sllx	%g3, DC_TAG_SHIFT, %g3
7997001Sjake	and	%g1, %g3, %g1
8097001Sjake	cmp	%g1, %g6
8197001Sjake	bne,a,pt %xcc, 2f
8297001Sjake	 nop
8397001Sjake	stxa	%g1, [%g2] ASI_DCACHE_TAG
8497001Sjake	membar	#Sync
8597001Sjake
8697001Sjake2:	brgz,pt	%g2, 1b
8797001Sjake	 sub	%g2, %g4, %g2
8897001Sjake
89292943Smarius	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
9097001Sjake	retry
91112399SjakeEND(tl_ipi_spitfire_dcache_page_inval)
9297001Sjake
9397001Sjake/*
94112399Sjake * Invalidate a physical page in the instruction cache.  For UltraSPARC I and
95112399Sjake * II.
9697001Sjake */
97112399SjakeENTRY(tl_ipi_spitfire_icache_page_inval)
9897001Sjake#if KTR_COMPILE & KTR_SMP
99211071Smarius	CATR(KTR_SMP, "tl_ipi_spitfire_icache_page_inval: pa=%#lx"
10097001Sjake	    , %g1, %g2, %g3, 7, 8, 9)
10197001Sjake	ldx	[%g5 + ICA_PA], %g2
10297001Sjake	stx	%g2, [%g1 + KTR_PARM1]
10397001Sjake9:
10497001Sjake#endif
10597001Sjake
10697001Sjake	ldx	[%g5 + ICA_PA], %g6
10797001Sjake	srlx	%g6, PAGE_SHIFT - IC_TAG_SHIFT, %g6
10897001Sjake
109182689Smarius	lduw	[PCPU(CACHE) + IC_SIZE], %g3
110182689Smarius	lduw	[PCPU(CACHE) + IC_LINESIZE], %g4
11197001Sjake	sub	%g3, %g4, %g2
11297001Sjake
11397001Sjake1:	ldda	[%g2] ASI_ICACHE_TAG, %g0 /*, %g1 */
11497001Sjake	srlx	%g1, IC_VALID_SHIFT, %g3
11597001Sjake	andcc	%g3, IC_VALID_MASK, %g0
11697001Sjake	bz,pt	%xcc, 2f
11797001Sjake	 set	IC_TAG_MASK, %g3
11897001Sjake	sllx	%g3, IC_TAG_SHIFT, %g3
11997001Sjake	and	%g1, %g3, %g1
12097001Sjake	cmp	%g1, %g6
12197001Sjake	bne,a,pt %xcc, 2f
12297001Sjake	 nop
12397001Sjake	stxa	%g1, [%g2] ASI_ICACHE_TAG
12497001Sjake	membar	#Sync
12597001Sjake
12697001Sjake2:	brgz,pt	%g2, 1b
12797001Sjake	 sub	%g2, %g4, %g2
12897001Sjake
129292943Smarius	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
13097001Sjake	retry
131112399SjakeEND(tl_ipi_spitfire_icache_page_inval)
13297001Sjake
13397001Sjake/*
134112399Sjake * Invalidate a physical page in the data cache.  For UltraSPARC III.
135112399Sjake */
136112399SjakeENTRY(tl_ipi_cheetah_dcache_page_inval)
137112399Sjake#if KTR_COMPILE & KTR_SMP
138211071Smarius	CATR(KTR_SMP, "tl_ipi_cheetah_dcache_page_inval: pa=%#lx"
139112399Sjake	    , %g1, %g2, %g3, 7, 8, 9)
140112399Sjake	ldx	[%g5 + ICA_PA], %g2
141112399Sjake	stx	%g2, [%g1 + KTR_PARM1]
142112399Sjake9:
143112399Sjake#endif
144112399Sjake
145112399Sjake	ldx	[%g5 + ICA_PA], %g1
146112399Sjake
147112399Sjake	set	PAGE_SIZE, %g2
148112399Sjake	add	%g1, %g2, %g3
149112399Sjake
150182689Smarius	lduw	[PCPU(CACHE) + DC_LINESIZE], %g2
151112399Sjake
152112399Sjake1:	stxa	%g0, [%g1] ASI_DCACHE_INVALIDATE
153112399Sjake	membar	#Sync
154112399Sjake
155112399Sjake	add	%g1, %g2, %g1
156112399Sjake	cmp	%g1, %g3
157112399Sjake	blt,a,pt %xcc, 1b
158112399Sjake	 nop
159112399Sjake
160292943Smarius	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
161112399Sjake	retry
162112399SjakeEND(tl_ipi_cheetah_dcache_page_inval)
163112399Sjake
164112399Sjake/*
16589051Sjake * Trigger a softint at the desired level.
16689051Sjake */
16789051SjakeENTRY(tl_ipi_level)
16892199Sjake#if KTR_COMPILE & KTR_SMP
16992199Sjake	CATR(KTR_SMP, "tl_ipi_level: cpuid=%d mid=%d d1=%#lx d2=%#lx"
17092199Sjake	    , %g1, %g2, %g3, 7, 8, 9)
17192199Sjake	lduw	[PCPU(CPUID)], %g2
17292199Sjake	stx	%g2, [%g1 + KTR_PARM1]
17392199Sjake	lduw	[PCPU(MID)], %g2
17492199Sjake	stx	%g2, [%g1 + KTR_PARM2]
17592199Sjake	stx	%g4, [%g1 + KTR_PARM3]
17692199Sjake	stx	%g5, [%g1 + KTR_PARM4]
17792199Sjake9:
17892199Sjake#endif
17989051Sjake
18089051Sjake	mov	1, %g1
18192199Sjake	sllx	%g1, %g5, %g1
182108379Sjake	wr	%g1, 0, %set_softint
18389051Sjake	retry
18489051SjakeEND(tl_ipi_level)
18589051Sjake
18689051Sjake/*
18789051Sjake * Demap a page from the dtlb and/or itlb.
18889051Sjake */
18989051SjakeENTRY(tl_ipi_tlb_page_demap)
19091783Sjake#if KTR_COMPILE & KTR_SMP
19191783Sjake	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
19291783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
19391783Sjake	ldx	[%g5 + ITA_PMAP], %g2
19491783Sjake	stx	%g2, [%g1 + KTR_PARM1]
19591783Sjake	ldx	[%g5 + ITA_VA], %g2
19691783Sjake	stx	%g2, [%g1 + KTR_PARM2]
19791783Sjake9:
19891783Sjake#endif
19989051Sjake
20091783Sjake	ldx	[%g5 + ITA_PMAP], %g1
20189051Sjake
20291783Sjake	SET(kernel_pmap_store, %g3, %g2)
20391783Sjake	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
20489051Sjake
20591783Sjake	cmp	%g1, %g2
20691783Sjake	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
20789051Sjake
20891783Sjake	ldx	[%g5 + ITA_VA], %g2
20991783Sjake	or	%g2, %g3, %g2
21089051Sjake
211182877Smarius	sethi	%hi(KERNBASE), %g3
21291783Sjake	stxa	%g0, [%g2] ASI_DMMU_DEMAP
21391783Sjake	stxa	%g0, [%g2] ASI_IMMU_DEMAP
214182877Smarius	flush	%g3
21589051Sjake
216292943Smarius	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
21789051Sjake	retry
21889051SjakeEND(tl_ipi_tlb_page_demap)
21989051Sjake
22089051Sjake/*
22189051Sjake * Demap a range of pages from the dtlb and itlb.
22289051Sjake */
22389051SjakeENTRY(tl_ipi_tlb_range_demap)
22491783Sjake#if KTR_COMPILE & KTR_SMP
22591783Sjake	CATR(KTR_SMP, "ipi_tlb_range_demap: pm=%p start=%#lx end=%#lx"
22691783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
22791783Sjake	ldx	[%g5 + ITA_PMAP], %g2
22891783Sjake	stx	%g2, [%g1 + KTR_PARM1]
22989051Sjake	ldx	[%g5 + ITA_START], %g2
23091783Sjake	stx	%g2, [%g1 + KTR_PARM2]
23191783Sjake	ldx	[%g5 + ITA_END], %g2
23291783Sjake	stx	%g2, [%g1 + KTR_PARM3]
23391783Sjake9:
23491783Sjake#endif
23589051Sjake
23691783Sjake	ldx	[%g5 + ITA_PMAP], %g1
23789051Sjake
23891783Sjake	SET(kernel_pmap_store, %g3, %g2)
23991783Sjake	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
24089051Sjake
24191783Sjake	cmp	%g1, %g2
24291783Sjake	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
24389051Sjake
24491783Sjake	ldx	[%g5 + ITA_START], %g1
24591783Sjake	ldx	[%g5 + ITA_END], %g2
24689051Sjake
247223720Smarius	sethi	%hi(KERNBASE), %g6
24891783Sjake1:	or	%g1, %g3, %g4
24989051Sjake	stxa	%g0, [%g4] ASI_DMMU_DEMAP
25089051Sjake	stxa	%g0, [%g4] ASI_IMMU_DEMAP
251182877Smarius	flush	%g6
25289051Sjake
253182877Smarius	set	PAGE_SIZE, %g6
25491783Sjake	add	%g1, %g6, %g1
25591783Sjake	cmp	%g1, %g2
25691783Sjake	blt,a,pt %xcc, 1b
257223720Smarius	 sethi	%hi(KERNBASE), %g6
25889051Sjake
259292943Smarius	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
26089051Sjake	retry
26189051SjakeEND(tl_ipi_tlb_range_demap)
26289051Sjake
26389051Sjake/*
26491783Sjake * Demap the primary context from the dtlb and itlb.
26589051Sjake */
26689051SjakeENTRY(tl_ipi_tlb_context_demap)
26791783Sjake#if KTR_COMPILE & KTR_SMP
268211071Smarius	CATR(KTR_SMP, "tl_ipi_tlb_context_demap: pm=%p va=%#lx"
26991783Sjake	    , %g1, %g2, %g3, 7, 8, 9)
27091783Sjake	ldx	[%g5 + ITA_PMAP], %g2
27191783Sjake	stx	%g2, [%g1 + KTR_PARM1]
27291783Sjake	ldx	[%g5 + ITA_VA], %g2
27391783Sjake	stx	%g2, [%g1 + KTR_PARM2]
27491783Sjake9:
27591783Sjake#endif
27689051Sjake
27791783Sjake	mov	TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, %g1
278182877Smarius	sethi	%hi(KERNBASE), %g3
27991783Sjake	stxa	%g0, [%g1] ASI_DMMU_DEMAP
28091783Sjake	stxa	%g0, [%g1] ASI_IMMU_DEMAP
281182877Smarius	flush	%g3
28289051Sjake
283292943Smarius	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
28489051Sjake	retry
28589051SjakeEND(tl_ipi_tlb_context_demap)
286211071Smarius
287211071Smarius/*
288211071Smarius * Read %stick.
289211071Smarius */
290211071SmariusENTRY(tl_ipi_stick_rd)
291211071Smarius	ldx	[%g5 + IRA_VAL], %g1
292211071Smarius	rd	%asr24, %g2
293211071Smarius	stx	%g2, [%g1]
294211071Smarius
295292943Smarius	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
296211071Smarius	retry
297211071SmariusEND(tl_ipi_stick_rd)
298211071Smarius
299211071Smarius/*
300211071Smarius * Read %tick.
301211071Smarius */
302211071SmariusENTRY(tl_ipi_tick_rd)
303211071Smarius	ldx	[%g5 + IRA_VAL], %g1
304211071Smarius	rd	%tick, %g2
305211071Smarius	stx	%g2, [%g1]
306211071Smarius
307292943Smarius	IPI_DONE(%g5, %g1, %g2, %g3, %g4)
308211071Smarius	retry
309211071SmariusEND(tl_ipi_tick_rd)
310