xref: /kernel/linux/linux-6.6/arch/sparc/mm/viking.S (revision 62306a36)
162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * viking.S: High speed Viking cache/mmu operations
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
662306a36Sopenharmony_ci * Copyright (C) 1997,1998,1999  Jakub Jelinek  (jj@ultra.linux.cz)
762306a36Sopenharmony_ci * Copyright (C) 1999  Pavel Semerad  (semerad@ss1000.ms.mff.cuni.cz)
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <asm/ptrace.h>
1162306a36Sopenharmony_ci#include <asm/psr.h>
1262306a36Sopenharmony_ci#include <asm/asm-offsets.h>
1362306a36Sopenharmony_ci#include <asm/asi.h>
1462306a36Sopenharmony_ci#include <asm/mxcc.h>
1562306a36Sopenharmony_ci#include <asm/page.h>
1662306a36Sopenharmony_ci#include <asm/pgtable.h>
1762306a36Sopenharmony_ci#include <asm/pgtsrmmu.h>
1862306a36Sopenharmony_ci#include <asm/viking.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#ifdef CONFIG_SMP
2162306a36Sopenharmony_ci	.data
2262306a36Sopenharmony_ci	.align	4
2362306a36Sopenharmony_cisun4dsmp_flush_tlb_spin:
2462306a36Sopenharmony_ci	.word	0
2562306a36Sopenharmony_ci#endif
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	.text
2862306a36Sopenharmony_ci	.align	4
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci	.globl	viking_flush_cache_all, viking_flush_cache_mm
3162306a36Sopenharmony_ci	.globl	viking_flush_cache_range, viking_flush_cache_page
3262306a36Sopenharmony_ci	.globl	viking_flush_page, viking_mxcc_flush_page
3362306a36Sopenharmony_ci	.globl	viking_flush_page_for_dma, viking_flush_page_to_ram
3462306a36Sopenharmony_ci	.globl	viking_flush_sig_insns
3562306a36Sopenharmony_ci	.globl	viking_flush_tlb_all, viking_flush_tlb_mm
3662306a36Sopenharmony_ci	.globl	viking_flush_tlb_range, viking_flush_tlb_page
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_civiking_flush_page:
3962306a36Sopenharmony_ci	sethi	%hi(PAGE_OFFSET), %g2
4062306a36Sopenharmony_ci	sub	%o0, %g2, %g3
4162306a36Sopenharmony_ci	srl	%g3, 12, %g1		! ppage >> 12
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	clr	%o1			! set counter, 0 - 127
4462306a36Sopenharmony_ci	sethi	%hi(PAGE_OFFSET + PAGE_SIZE - 0x80000000), %o3
4562306a36Sopenharmony_ci	sethi	%hi(0x80000000), %o4
4662306a36Sopenharmony_ci	sethi	%hi(VIKING_PTAG_VALID), %o5
4762306a36Sopenharmony_ci	sethi	%hi(2*PAGE_SIZE), %o0
4862306a36Sopenharmony_ci	sethi	%hi(PAGE_SIZE), %g7
4962306a36Sopenharmony_ci	clr	%o2			! block counter, 0 - 3
5062306a36Sopenharmony_ci5:
5162306a36Sopenharmony_ci	sll	%o1, 5, %g4
5262306a36Sopenharmony_ci	or	%g4, %o4, %g4		! 0x80000000 | (set << 5)
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	sll	%o2, 26, %g5		! block << 26
5562306a36Sopenharmony_ci6:
5662306a36Sopenharmony_ci	or	%g5, %g4, %g5
5762306a36Sopenharmony_ci	ldda	[%g5] ASI_M_DATAC_TAG, %g2
5862306a36Sopenharmony_ci	cmp	%g3, %g1		! ptag == ppage?
5962306a36Sopenharmony_ci	bne	7f
6062306a36Sopenharmony_ci	 inc	%o2
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	andcc	%g2, %o5, %g0		! ptag VALID?
6362306a36Sopenharmony_ci	be	7f
6462306a36Sopenharmony_ci	 add	%g4, %o3, %g2		! (PAGE_OFFSET + PAGE_SIZE) | (set << 5)
6562306a36Sopenharmony_ci	ld	[%g2], %g3
6662306a36Sopenharmony_ci	ld	[%g2 + %g7], %g3
6762306a36Sopenharmony_ci	add	%g2, %o0, %g2
6862306a36Sopenharmony_ci	ld	[%g2], %g3
6962306a36Sopenharmony_ci	ld	[%g2 + %g7], %g3
7062306a36Sopenharmony_ci	add	%g2, %o0, %g2
7162306a36Sopenharmony_ci	ld	[%g2], %g3
7262306a36Sopenharmony_ci	ld	[%g2 + %g7], %g3
7362306a36Sopenharmony_ci	add	%g2, %o0, %g2
7462306a36Sopenharmony_ci	ld	[%g2], %g3
7562306a36Sopenharmony_ci	b	8f
7662306a36Sopenharmony_ci	 ld	[%g2 + %g7], %g3
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci7:
7962306a36Sopenharmony_ci	cmp	%o2, 3
8062306a36Sopenharmony_ci	ble	6b
8162306a36Sopenharmony_ci	 sll	%o2, 26, %g5			! block << 26
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci8:	inc	%o1
8462306a36Sopenharmony_ci	cmp	%o1, 0x7f
8562306a36Sopenharmony_ci	ble	5b
8662306a36Sopenharmony_ci	 clr	%o2
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci9:	retl
8962306a36Sopenharmony_ci	 nop
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_civiking_mxcc_flush_page:
9262306a36Sopenharmony_ci	sethi	%hi(PAGE_OFFSET), %g2
9362306a36Sopenharmony_ci	sub	%o0, %g2, %g3
9462306a36Sopenharmony_ci	sub	%g3, -PAGE_SIZE, %g3		! ppage + PAGE_SIZE
9562306a36Sopenharmony_ci	sethi	%hi(MXCC_SRCSTREAM), %o3	! assume %hi(MXCC_SRCSTREAM) == %hi(MXCC_DESTSTREAM)
9662306a36Sopenharmony_ci	mov	0x10, %g2			! set cacheable bit
9762306a36Sopenharmony_ci	or	%o3, %lo(MXCC_SRCSTREAM), %o2
9862306a36Sopenharmony_ci	or	%o3, %lo(MXCC_DESSTREAM), %o3
9962306a36Sopenharmony_ci	sub	%g3, MXCC_STREAM_SIZE, %g3
10062306a36Sopenharmony_ci6:
10162306a36Sopenharmony_ci	stda	%g2, [%o2] ASI_M_MXCC
10262306a36Sopenharmony_ci	stda	%g2, [%o3] ASI_M_MXCC
10362306a36Sopenharmony_ci	andncc	%g3, PAGE_MASK, %g0
10462306a36Sopenharmony_ci	bne	6b
10562306a36Sopenharmony_ci	 sub	%g3, MXCC_STREAM_SIZE, %g3
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci9:	retl
10862306a36Sopenharmony_ci	 nop
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_civiking_flush_cache_page:
11162306a36Sopenharmony_civiking_flush_cache_range:
11262306a36Sopenharmony_ci#ifndef CONFIG_SMP
11362306a36Sopenharmony_ci	ld	[%o0 + VMA_VM_MM], %o0
11462306a36Sopenharmony_ci#endif
11562306a36Sopenharmony_civiking_flush_cache_mm:
11662306a36Sopenharmony_ci#ifndef CONFIG_SMP
11762306a36Sopenharmony_ci	ld	[%o0 + AOFF_mm_context], %g1
11862306a36Sopenharmony_ci	cmp	%g1, -1
11962306a36Sopenharmony_ci	bne	viking_flush_cache_all
12062306a36Sopenharmony_ci	 nop
12162306a36Sopenharmony_ci	b,a	viking_flush_cache_out
12262306a36Sopenharmony_ci#endif
12362306a36Sopenharmony_civiking_flush_cache_all:
12462306a36Sopenharmony_ci	WINDOW_FLUSH(%g4, %g5)
12562306a36Sopenharmony_civiking_flush_cache_out:
12662306a36Sopenharmony_ci	retl
12762306a36Sopenharmony_ci	 nop
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_civiking_flush_tlb_all:
13062306a36Sopenharmony_ci	mov	0x400, %g1
13162306a36Sopenharmony_ci	retl
13262306a36Sopenharmony_ci	 sta	%g0, [%g1] ASI_M_FLUSH_PROBE
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_civiking_flush_tlb_mm:
13562306a36Sopenharmony_ci	mov	SRMMU_CTX_REG, %g1
13662306a36Sopenharmony_ci	ld	[%o0 + AOFF_mm_context], %o1
13762306a36Sopenharmony_ci	lda	[%g1] ASI_M_MMUREGS, %g5
13862306a36Sopenharmony_ci#ifndef CONFIG_SMP
13962306a36Sopenharmony_ci	cmp	%o1, -1
14062306a36Sopenharmony_ci	be	1f
14162306a36Sopenharmony_ci#endif
14262306a36Sopenharmony_ci	mov	0x300, %g2
14362306a36Sopenharmony_ci	sta	%o1, [%g1] ASI_M_MMUREGS
14462306a36Sopenharmony_ci	sta	%g0, [%g2] ASI_M_FLUSH_PROBE
14562306a36Sopenharmony_ci	retl
14662306a36Sopenharmony_ci	 sta	%g5, [%g1] ASI_M_MMUREGS
14762306a36Sopenharmony_ci#ifndef CONFIG_SMP
14862306a36Sopenharmony_ci1:	retl
14962306a36Sopenharmony_ci	 nop
15062306a36Sopenharmony_ci#endif
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_civiking_flush_tlb_range:
15362306a36Sopenharmony_ci	ld	[%o0 + VMA_VM_MM], %o0
15462306a36Sopenharmony_ci	mov	SRMMU_CTX_REG, %g1
15562306a36Sopenharmony_ci	ld	[%o0 + AOFF_mm_context], %o3
15662306a36Sopenharmony_ci	lda	[%g1] ASI_M_MMUREGS, %g5
15762306a36Sopenharmony_ci#ifndef CONFIG_SMP
15862306a36Sopenharmony_ci	cmp	%o3, -1
15962306a36Sopenharmony_ci	be	2f
16062306a36Sopenharmony_ci#endif
16162306a36Sopenharmony_ci	sethi	%hi(~((1 << PGDIR_SHIFT) - 1)), %o4
16262306a36Sopenharmony_ci	sta	%o3, [%g1] ASI_M_MMUREGS
16362306a36Sopenharmony_ci	and	%o1, %o4, %o1
16462306a36Sopenharmony_ci	add	%o1, 0x200, %o1
16562306a36Sopenharmony_ci	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
16662306a36Sopenharmony_ci1:	sub	%o1, %o4, %o1
16762306a36Sopenharmony_ci	cmp	%o1, %o2
16862306a36Sopenharmony_ci	blu,a	1b
16962306a36Sopenharmony_ci	 sta	%g0, [%o1] ASI_M_FLUSH_PROBE
17062306a36Sopenharmony_ci	retl
17162306a36Sopenharmony_ci	 sta	%g5, [%g1] ASI_M_MMUREGS
17262306a36Sopenharmony_ci#ifndef CONFIG_SMP
17362306a36Sopenharmony_ci2:	retl
17462306a36Sopenharmony_ci	 nop
17562306a36Sopenharmony_ci#endif
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_civiking_flush_tlb_page:
17862306a36Sopenharmony_ci	ld	[%o0 + VMA_VM_MM], %o0
17962306a36Sopenharmony_ci	mov	SRMMU_CTX_REG, %g1
18062306a36Sopenharmony_ci	ld	[%o0 + AOFF_mm_context], %o3
18162306a36Sopenharmony_ci	lda	[%g1] ASI_M_MMUREGS, %g5
18262306a36Sopenharmony_ci#ifndef CONFIG_SMP
18362306a36Sopenharmony_ci	cmp	%o3, -1
18462306a36Sopenharmony_ci	be	1f
18562306a36Sopenharmony_ci#endif
18662306a36Sopenharmony_ci	and	%o1, PAGE_MASK, %o1
18762306a36Sopenharmony_ci	sta	%o3, [%g1] ASI_M_MMUREGS
18862306a36Sopenharmony_ci	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
18962306a36Sopenharmony_ci	retl
19062306a36Sopenharmony_ci	 sta	%g5, [%g1] ASI_M_MMUREGS
19162306a36Sopenharmony_ci#ifndef CONFIG_SMP
19262306a36Sopenharmony_ci1:	retl
19362306a36Sopenharmony_ci	 nop
19462306a36Sopenharmony_ci#endif
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_civiking_flush_page_to_ram:
19762306a36Sopenharmony_civiking_flush_page_for_dma:
19862306a36Sopenharmony_civiking_flush_sig_insns:
19962306a36Sopenharmony_ci	retl
20062306a36Sopenharmony_ci	 nop
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci#ifdef CONFIG_SMP
20362306a36Sopenharmony_ci	.globl	sun4dsmp_flush_tlb_all, sun4dsmp_flush_tlb_mm
20462306a36Sopenharmony_ci	.globl	sun4dsmp_flush_tlb_range, sun4dsmp_flush_tlb_page
20562306a36Sopenharmony_cisun4dsmp_flush_tlb_all:
20662306a36Sopenharmony_ci	sethi	%hi(sun4dsmp_flush_tlb_spin), %g3
20762306a36Sopenharmony_ci1:	ldstub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
20862306a36Sopenharmony_ci	tst	%g5
20962306a36Sopenharmony_ci	bne	2f
21062306a36Sopenharmony_ci	 mov	0x400, %g1
21162306a36Sopenharmony_ci	sta	%g0, [%g1] ASI_M_FLUSH_PROBE
21262306a36Sopenharmony_ci	retl
21362306a36Sopenharmony_ci	 stb	%g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
21462306a36Sopenharmony_ci2:	tst	%g5
21562306a36Sopenharmony_ci	bne,a	2b
21662306a36Sopenharmony_ci	 ldub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
21762306a36Sopenharmony_ci	b,a	1b
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_cisun4dsmp_flush_tlb_mm:
22062306a36Sopenharmony_ci	sethi	%hi(sun4dsmp_flush_tlb_spin), %g3
22162306a36Sopenharmony_ci1:	ldstub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
22262306a36Sopenharmony_ci	tst	%g5
22362306a36Sopenharmony_ci	bne	2f
22462306a36Sopenharmony_ci	 mov	SRMMU_CTX_REG, %g1
22562306a36Sopenharmony_ci	ld	[%o0 + AOFF_mm_context], %o1
22662306a36Sopenharmony_ci	lda	[%g1] ASI_M_MMUREGS, %g5
22762306a36Sopenharmony_ci	mov	0x300, %g2
22862306a36Sopenharmony_ci	sta	%o1, [%g1] ASI_M_MMUREGS
22962306a36Sopenharmony_ci	sta	%g0, [%g2] ASI_M_FLUSH_PROBE
23062306a36Sopenharmony_ci	sta	%g5, [%g1] ASI_M_MMUREGS
23162306a36Sopenharmony_ci	retl
23262306a36Sopenharmony_ci	 stb	%g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
23362306a36Sopenharmony_ci2:	tst	%g5
23462306a36Sopenharmony_ci	bne,a	2b
23562306a36Sopenharmony_ci	 ldub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
23662306a36Sopenharmony_ci	b,a	1b
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_cisun4dsmp_flush_tlb_range:
23962306a36Sopenharmony_ci	sethi	%hi(sun4dsmp_flush_tlb_spin), %g3
24062306a36Sopenharmony_ci1:	ldstub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
24162306a36Sopenharmony_ci	tst	%g5
24262306a36Sopenharmony_ci	bne	3f
24362306a36Sopenharmony_ci	 mov	SRMMU_CTX_REG, %g1
24462306a36Sopenharmony_ci	ld	[%o0 + VMA_VM_MM], %o0
24562306a36Sopenharmony_ci	ld	[%o0 + AOFF_mm_context], %o3
24662306a36Sopenharmony_ci	lda	[%g1] ASI_M_MMUREGS, %g5
24762306a36Sopenharmony_ci	sethi	%hi(~((1 << PGDIR_SHIFT) - 1)), %o4
24862306a36Sopenharmony_ci	sta	%o3, [%g1] ASI_M_MMUREGS
24962306a36Sopenharmony_ci	and	%o1, %o4, %o1
25062306a36Sopenharmony_ci	add	%o1, 0x200, %o1
25162306a36Sopenharmony_ci	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
25262306a36Sopenharmony_ci2:	sub	%o1, %o4, %o1
25362306a36Sopenharmony_ci	cmp	%o1, %o2
25462306a36Sopenharmony_ci	blu,a	2b
25562306a36Sopenharmony_ci	 sta	%g0, [%o1] ASI_M_FLUSH_PROBE
25662306a36Sopenharmony_ci	sta	%g5, [%g1] ASI_M_MMUREGS
25762306a36Sopenharmony_ci	retl
25862306a36Sopenharmony_ci	 stb	%g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
25962306a36Sopenharmony_ci3:	tst	%g5
26062306a36Sopenharmony_ci	bne,a	3b
26162306a36Sopenharmony_ci	 ldub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
26262306a36Sopenharmony_ci	b,a	1b
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_cisun4dsmp_flush_tlb_page:
26562306a36Sopenharmony_ci	sethi	%hi(sun4dsmp_flush_tlb_spin), %g3
26662306a36Sopenharmony_ci1:	ldstub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
26762306a36Sopenharmony_ci	tst	%g5
26862306a36Sopenharmony_ci	bne	2f
26962306a36Sopenharmony_ci	 mov	SRMMU_CTX_REG, %g1
27062306a36Sopenharmony_ci	ld	[%o0 + VMA_VM_MM], %o0
27162306a36Sopenharmony_ci	ld	[%o0 + AOFF_mm_context], %o3
27262306a36Sopenharmony_ci	lda	[%g1] ASI_M_MMUREGS, %g5
27362306a36Sopenharmony_ci	and	%o1, PAGE_MASK, %o1
27462306a36Sopenharmony_ci	sta	%o3, [%g1] ASI_M_MMUREGS
27562306a36Sopenharmony_ci	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
27662306a36Sopenharmony_ci	sta	%g5, [%g1] ASI_M_MMUREGS
27762306a36Sopenharmony_ci	retl
27862306a36Sopenharmony_ci	 stb	%g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
27962306a36Sopenharmony_ci2:	tst	%g5
28062306a36Sopenharmony_ci	bne,a	2b
28162306a36Sopenharmony_ci	 ldub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
28262306a36Sopenharmony_ci	b,a	1b
28362306a36Sopenharmony_ci	 nop
28462306a36Sopenharmony_ci#endif
285