162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * swift.S: MicroSparc-II mmu/cache operations.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 1999 David S. Miller (davem@redhat.com)
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <asm/psr.h>
962306a36Sopenharmony_ci#include <asm/asi.h>
1062306a36Sopenharmony_ci#include <asm/page.h>
1162306a36Sopenharmony_ci#include <asm/pgtsrmmu.h>
1262306a36Sopenharmony_ci#include <asm/asm-offsets.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci	.text
1562306a36Sopenharmony_ci	.align	4
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#if 1	/* XXX screw this, I can't get the VAC flushes working
1862306a36Sopenharmony_ci	 * XXX reliably... -DaveM
1962306a36Sopenharmony_ci	 */
2062306a36Sopenharmony_ci	.globl	swift_flush_cache_all, swift_flush_cache_mm
2162306a36Sopenharmony_ci	.globl	swift_flush_cache_range, swift_flush_cache_page
2262306a36Sopenharmony_ci	.globl	swift_flush_page_for_dma
2362306a36Sopenharmony_ci	.globl	swift_flush_page_to_ram
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ciswift_flush_cache_all:
2662306a36Sopenharmony_ciswift_flush_cache_mm:
2762306a36Sopenharmony_ciswift_flush_cache_range:
2862306a36Sopenharmony_ciswift_flush_cache_page:
2962306a36Sopenharmony_ciswift_flush_page_for_dma:
3062306a36Sopenharmony_ciswift_flush_page_to_ram:
3162306a36Sopenharmony_ci	sethi	%hi(0x2000), %o0
3262306a36Sopenharmony_ci1:	subcc	%o0, 0x10, %o0
3362306a36Sopenharmony_ci	add	%o0, %o0, %o1
3462306a36Sopenharmony_ci	sta	%g0, [%o0] ASI_M_DATAC_TAG
3562306a36Sopenharmony_ci	bne	1b
3662306a36Sopenharmony_ci	 sta	%g0, [%o1] ASI_M_TXTC_TAG
3762306a36Sopenharmony_ci	retl
3862306a36Sopenharmony_ci	 nop
3962306a36Sopenharmony_ci#else
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	.globl	swift_flush_cache_all
4262306a36Sopenharmony_ciswift_flush_cache_all:
4362306a36Sopenharmony_ci	WINDOW_FLUSH(%g4, %g5)
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	/* Just clear out all the tags. */
4662306a36Sopenharmony_ci	sethi	%hi(16 * 1024), %o0
4762306a36Sopenharmony_ci1:	subcc	%o0, 16, %o0
4862306a36Sopenharmony_ci	sta	%g0, [%o0] ASI_M_TXTC_TAG
4962306a36Sopenharmony_ci	bne	1b
5062306a36Sopenharmony_ci	 sta	%g0, [%o0] ASI_M_DATAC_TAG
5162306a36Sopenharmony_ci	retl
5262306a36Sopenharmony_ci	 nop
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	.globl	swift_flush_cache_mm
5562306a36Sopenharmony_ciswift_flush_cache_mm:
5662306a36Sopenharmony_ci	ld	[%o0 + AOFF_mm_context], %g2
5762306a36Sopenharmony_ci	cmp	%g2, -1
5862306a36Sopenharmony_ci	be	swift_flush_cache_mm_out
5962306a36Sopenharmony_ci	WINDOW_FLUSH(%g4, %g5)
6062306a36Sopenharmony_ci	rd	%psr, %g1
6162306a36Sopenharmony_ci	andn	%g1, PSR_ET, %g3
6262306a36Sopenharmony_ci	wr	%g3, 0x0, %psr
6362306a36Sopenharmony_ci	nop
6462306a36Sopenharmony_ci	nop
6562306a36Sopenharmony_ci	mov	SRMMU_CTX_REG, %g7
6662306a36Sopenharmony_ci	lda	[%g7] ASI_M_MMUREGS, %g5
6762306a36Sopenharmony_ci	sta	%g2, [%g7] ASI_M_MMUREGS
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci#if 1
7062306a36Sopenharmony_ci	sethi	%hi(0x2000), %o0
7162306a36Sopenharmony_ci1:	subcc	%o0, 0x10, %o0
7262306a36Sopenharmony_ci	sta	%g0, [%o0] ASI_M_FLUSH_CTX
7362306a36Sopenharmony_ci	bne	1b
7462306a36Sopenharmony_ci	 nop
7562306a36Sopenharmony_ci#else
7662306a36Sopenharmony_ci	clr	%o0
7762306a36Sopenharmony_ci	or	%g0, 2048, %g7
7862306a36Sopenharmony_ci	or	%g0, 2048, %o1
7962306a36Sopenharmony_ci	add	%o1, 2048, %o2
8062306a36Sopenharmony_ci	add	%o2, 2048, %o3
8162306a36Sopenharmony_ci	mov	16, %o4
8262306a36Sopenharmony_ci	add	%o4, 2048, %o5
8362306a36Sopenharmony_ci	add	%o5, 2048, %g2
8462306a36Sopenharmony_ci	add	%g2, 2048, %g3
8562306a36Sopenharmony_ci1:	sta	%g0, [%o0      ] ASI_M_FLUSH_CTX
8662306a36Sopenharmony_ci	sta	%g0, [%o0 + %o1] ASI_M_FLUSH_CTX
8762306a36Sopenharmony_ci	sta	%g0, [%o0 + %o2] ASI_M_FLUSH_CTX
8862306a36Sopenharmony_ci	sta	%g0, [%o0 + %o3] ASI_M_FLUSH_CTX
8962306a36Sopenharmony_ci	sta	%g0, [%o0 + %o4] ASI_M_FLUSH_CTX
9062306a36Sopenharmony_ci	sta	%g0, [%o0 + %o5] ASI_M_FLUSH_CTX
9162306a36Sopenharmony_ci	sta	%g0, [%o0 + %g2] ASI_M_FLUSH_CTX
9262306a36Sopenharmony_ci	sta	%g0, [%o0 + %g3] ASI_M_FLUSH_CTX
9362306a36Sopenharmony_ci	subcc	%g7, 32, %g7
9462306a36Sopenharmony_ci	bne	1b
9562306a36Sopenharmony_ci	 add	%o0, 32, %o0
9662306a36Sopenharmony_ci#endif
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	mov	SRMMU_CTX_REG, %g7
9962306a36Sopenharmony_ci	sta	%g5, [%g7] ASI_M_MMUREGS
10062306a36Sopenharmony_ci	wr	%g1, 0x0, %psr
10162306a36Sopenharmony_ci	nop
10262306a36Sopenharmony_ci	nop
10362306a36Sopenharmony_ciswift_flush_cache_mm_out:
10462306a36Sopenharmony_ci	retl
10562306a36Sopenharmony_ci	 nop
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	.globl	swift_flush_cache_range
10862306a36Sopenharmony_ciswift_flush_cache_range:
10962306a36Sopenharmony_ci	ld	[%o0 + VMA_VM_MM], %o0
11062306a36Sopenharmony_ci	sub	%o2, %o1, %o2
11162306a36Sopenharmony_ci	sethi	%hi(4096), %o3
11262306a36Sopenharmony_ci	cmp	%o2, %o3
11362306a36Sopenharmony_ci	bgu	swift_flush_cache_mm
11462306a36Sopenharmony_ci	 nop
11562306a36Sopenharmony_ci	b	70f
11662306a36Sopenharmony_ci	 nop
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	.globl	swift_flush_cache_page
11962306a36Sopenharmony_ciswift_flush_cache_page:
12062306a36Sopenharmony_ci	ld	[%o0 + VMA_VM_MM], %o0
12162306a36Sopenharmony_ci70:
12262306a36Sopenharmony_ci	ld	[%o0 + AOFF_mm_context], %g2
12362306a36Sopenharmony_ci	cmp	%g2, -1
12462306a36Sopenharmony_ci	be	swift_flush_cache_page_out
12562306a36Sopenharmony_ci	WINDOW_FLUSH(%g4, %g5)
12662306a36Sopenharmony_ci	rd	%psr, %g1
12762306a36Sopenharmony_ci	andn	%g1, PSR_ET, %g3
12862306a36Sopenharmony_ci	wr	%g3, 0x0, %psr
12962306a36Sopenharmony_ci	nop
13062306a36Sopenharmony_ci	nop
13162306a36Sopenharmony_ci	mov	SRMMU_CTX_REG, %g7
13262306a36Sopenharmony_ci	lda	[%g7] ASI_M_MMUREGS, %g5
13362306a36Sopenharmony_ci	sta	%g2, [%g7] ASI_M_MMUREGS
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	andn	%o1, (PAGE_SIZE - 1), %o1
13662306a36Sopenharmony_ci#if 1
13762306a36Sopenharmony_ci	sethi	%hi(0x1000), %o0
13862306a36Sopenharmony_ci1:	subcc	%o0, 0x10, %o0
13962306a36Sopenharmony_ci	sta	%g0, [%o1 + %o0] ASI_M_FLUSH_PAGE
14062306a36Sopenharmony_ci	bne	1b
14162306a36Sopenharmony_ci	 nop
14262306a36Sopenharmony_ci#else
14362306a36Sopenharmony_ci	or	%g0, 512, %g7
14462306a36Sopenharmony_ci	or	%g0, 512, %o0
14562306a36Sopenharmony_ci	add	%o0, 512, %o2
14662306a36Sopenharmony_ci	add	%o2, 512, %o3
14762306a36Sopenharmony_ci	add	%o3, 512, %o4
14862306a36Sopenharmony_ci	add	%o4, 512, %o5
14962306a36Sopenharmony_ci	add	%o5, 512, %g3
15062306a36Sopenharmony_ci	add	%g3, 512, %g4
15162306a36Sopenharmony_ci1:	sta	%g0, [%o1      ] ASI_M_FLUSH_PAGE
15262306a36Sopenharmony_ci	sta	%g0, [%o1 + %o0] ASI_M_FLUSH_PAGE
15362306a36Sopenharmony_ci	sta	%g0, [%o1 + %o2] ASI_M_FLUSH_PAGE
15462306a36Sopenharmony_ci	sta	%g0, [%o1 + %o3] ASI_M_FLUSH_PAGE
15562306a36Sopenharmony_ci	sta	%g0, [%o1 + %o4] ASI_M_FLUSH_PAGE
15662306a36Sopenharmony_ci	sta	%g0, [%o1 + %o5] ASI_M_FLUSH_PAGE
15762306a36Sopenharmony_ci	sta	%g0, [%o1 + %g3] ASI_M_FLUSH_PAGE
15862306a36Sopenharmony_ci	sta	%g0, [%o1 + %g4] ASI_M_FLUSH_PAGE
15962306a36Sopenharmony_ci	subcc	%g7, 16, %g7
16062306a36Sopenharmony_ci	bne	1b
16162306a36Sopenharmony_ci	 add	%o1, 16, %o1
16262306a36Sopenharmony_ci#endif
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	mov	SRMMU_CTX_REG, %g7
16562306a36Sopenharmony_ci	sta	%g5, [%g7] ASI_M_MMUREGS
16662306a36Sopenharmony_ci	wr	%g1, 0x0, %psr
16762306a36Sopenharmony_ci	nop
16862306a36Sopenharmony_ci	nop
16962306a36Sopenharmony_ciswift_flush_cache_page_out:
17062306a36Sopenharmony_ci	retl
17162306a36Sopenharmony_ci	 nop
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	/* Swift is write-thru, however it is not
17462306a36Sopenharmony_ci	 * I/O nor TLB-walk coherent.  Also it has
17562306a36Sopenharmony_ci	 * caches which are virtually indexed and tagged.
17662306a36Sopenharmony_ci	 */
17762306a36Sopenharmony_ci	.globl	swift_flush_page_for_dma
17862306a36Sopenharmony_ci	.globl	swift_flush_page_to_ram
17962306a36Sopenharmony_ciswift_flush_page_for_dma:
18062306a36Sopenharmony_ciswift_flush_page_to_ram:
18162306a36Sopenharmony_ci	andn	%o0, (PAGE_SIZE - 1), %o1
18262306a36Sopenharmony_ci#if 1
18362306a36Sopenharmony_ci	sethi	%hi(0x1000), %o0
18462306a36Sopenharmony_ci1:	subcc	%o0, 0x10, %o0
18562306a36Sopenharmony_ci	sta	%g0, [%o1 + %o0] ASI_M_FLUSH_PAGE
18662306a36Sopenharmony_ci	bne	1b
18762306a36Sopenharmony_ci	 nop
18862306a36Sopenharmony_ci#else
18962306a36Sopenharmony_ci	or	%g0, 512, %g7
19062306a36Sopenharmony_ci	or	%g0, 512, %o0
19162306a36Sopenharmony_ci	add	%o0, 512, %o2
19262306a36Sopenharmony_ci	add	%o2, 512, %o3
19362306a36Sopenharmony_ci	add	%o3, 512, %o4
19462306a36Sopenharmony_ci	add	%o4, 512, %o5
19562306a36Sopenharmony_ci	add	%o5, 512, %g3
19662306a36Sopenharmony_ci	add	%g3, 512, %g4
19762306a36Sopenharmony_ci1:	sta	%g0, [%o1      ] ASI_M_FLUSH_PAGE
19862306a36Sopenharmony_ci	sta	%g0, [%o1 + %o0] ASI_M_FLUSH_PAGE
19962306a36Sopenharmony_ci	sta	%g0, [%o1 + %o2] ASI_M_FLUSH_PAGE
20062306a36Sopenharmony_ci	sta	%g0, [%o1 + %o3] ASI_M_FLUSH_PAGE
20162306a36Sopenharmony_ci	sta	%g0, [%o1 + %o4] ASI_M_FLUSH_PAGE
20262306a36Sopenharmony_ci	sta	%g0, [%o1 + %o5] ASI_M_FLUSH_PAGE
20362306a36Sopenharmony_ci	sta	%g0, [%o1 + %g3] ASI_M_FLUSH_PAGE
20462306a36Sopenharmony_ci	sta	%g0, [%o1 + %g4] ASI_M_FLUSH_PAGE
20562306a36Sopenharmony_ci	subcc	%g7, 16, %g7
20662306a36Sopenharmony_ci	bne	1b
20762306a36Sopenharmony_ci	 add	%o1, 16, %o1
20862306a36Sopenharmony_ci#endif
20962306a36Sopenharmony_ci	retl
21062306a36Sopenharmony_ci	 nop
21162306a36Sopenharmony_ci#endif
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	.globl	swift_flush_sig_insns
21462306a36Sopenharmony_ciswift_flush_sig_insns:
21562306a36Sopenharmony_ci	flush	%o1
21662306a36Sopenharmony_ci	retl
21762306a36Sopenharmony_ci	 flush	%o1 + 4
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci	.globl	swift_flush_tlb_mm
22062306a36Sopenharmony_ci	.globl	swift_flush_tlb_range
22162306a36Sopenharmony_ci	.globl	swift_flush_tlb_all
22262306a36Sopenharmony_ciswift_flush_tlb_range:
22362306a36Sopenharmony_ci	ld	[%o0 + VMA_VM_MM], %o0
22462306a36Sopenharmony_ciswift_flush_tlb_mm:
22562306a36Sopenharmony_ci	ld	[%o0 + AOFF_mm_context], %g2
22662306a36Sopenharmony_ci	cmp	%g2, -1
22762306a36Sopenharmony_ci	be	swift_flush_tlb_all_out
22862306a36Sopenharmony_ciswift_flush_tlb_all:
22962306a36Sopenharmony_ci	mov	0x400, %o1
23062306a36Sopenharmony_ci	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
23162306a36Sopenharmony_ciswift_flush_tlb_all_out:
23262306a36Sopenharmony_ci	retl
23362306a36Sopenharmony_ci	 nop
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	.globl	swift_flush_tlb_page
23662306a36Sopenharmony_ciswift_flush_tlb_page:
23762306a36Sopenharmony_ci	ld	[%o0 + VMA_VM_MM], %o0
23862306a36Sopenharmony_ci	mov	SRMMU_CTX_REG, %g1
23962306a36Sopenharmony_ci	ld	[%o0 + AOFF_mm_context], %o3
24062306a36Sopenharmony_ci	andn	%o1, (PAGE_SIZE - 1), %o1
24162306a36Sopenharmony_ci	cmp	%o3, -1
24262306a36Sopenharmony_ci	be	swift_flush_tlb_page_out
24362306a36Sopenharmony_ci	 nop
24462306a36Sopenharmony_ci#if 1
24562306a36Sopenharmony_ci	mov	0x400, %o1
24662306a36Sopenharmony_ci	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
24762306a36Sopenharmony_ci#else
24862306a36Sopenharmony_ci	lda	[%g1] ASI_M_MMUREGS, %g5
24962306a36Sopenharmony_ci	sta	%o3, [%g1] ASI_M_MMUREGS
25062306a36Sopenharmony_ci	sta	%g0, [%o1] ASI_M_FLUSH_PAGE	/* rem. virt. cache. prot. */
25162306a36Sopenharmony_ci	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
25262306a36Sopenharmony_ci	sta	%g5, [%g1] ASI_M_MMUREGS
25362306a36Sopenharmony_ci#endif
25462306a36Sopenharmony_ciswift_flush_tlb_page_out:
25562306a36Sopenharmony_ci	retl
25662306a36Sopenharmony_ci	 nop
257