summaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm/tsunami.S
blob: f3678c0edc5b71c6e5db25a7fbf35c0739f0444f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* $Id: tsunami.S,v 1.6 2000/07/16 21:48:52 anton Exp $
 * tsunami.S: High speed MicroSparc-I mmu/cache operations.
 *
 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
 */

#include <linux/config.h>
#include <asm/ptrace.h>
#include <asm/psr.h>
#include <asm/asi.h>
#include <asm/page.h>
#include <asm/pgtsrmmu.h>

	.text
	.align	4

	.globl	tsunami_flush_cache_all, tsunami_flush_cache_mm
	.globl	tsunami_flush_cache_range, tsunami_flush_cache_page
	.globl	tsunami_flush_page_to_ram, tsunami_flush_page_for_dma
	.globl	tsunami_flush_sig_insns
	.globl	tsunami_flush_tlb_all, tsunami_flush_tlb_mm
	.globl	tsunami_flush_tlb_range, tsunami_flush_tlb_page

	/* Sliiick... */
tsunami_flush_cache_page:
	ld	[%o0 + 0x0], %o0	/* XXX vma->vm_mm, GROSS XXX */
tsunami_flush_cache_mm:
tsunami_flush_cache_range:
	ld	[%o0 + AOFF_mm_context], %g2
#ifndef CONFIG_SMP
	cmp	%g2, -1
	be	tsunami_flush_cache_out
#endif
tsunami_flush_cache_all:
	WINDOW_FLUSH(%g4, %g5)
tsunami_flush_page_for_dma:
	sta	%g0, [%g0] ASI_M_IC_FLCLEAR
	sta	%g0, [%g0] ASI_M_DC_FLCLEAR
tsunami_flush_cache_out:
tsunami_flush_page_to_ram:
	retl
	 nop

tsunami_flush_sig_insns:
	flush	%o1
	retl
	 flush	%o1 + 4

	/* More slick stuff... */
tsunami_flush_tlb_mm:
tsunami_flush_tlb_range:
#ifndef CONFIG_SMP
	ld	[%o0 + AOFF_mm_context], %g2
	cmp	%g2, -1
	be	tsunami_flush_tlb_out
#endif
tsunami_flush_tlb_all:
	 mov	0x400, %o1
	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
	nop
	nop
	nop
	nop
	nop
tsunami_flush_tlb_out:
	retl
	 nop

	/* This one can be done in a fine grained manner... */
tsunami_flush_tlb_page:
	ld	[%o0 + 0x00], %o0	/* XXX vma->vm_mm GROSS XXX */
	mov	SRMMU_CTX_REG, %g1
	ld	[%o0 + AOFF_mm_context], %o3
	andn	%o1, (PAGE_SIZE - 1), %o1
#ifndef CONFIG_SMP
	cmp	%o3, -1
	be	tsunami_flush_tlb_page_out
#endif
	 lda	[%g1] ASI_M_MMUREGS, %g5
	sta	%o3, [%g1] ASI_M_MMUREGS
	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
	nop
	nop
	nop
	nop
	nop
tsunami_flush_tlb_page_out:
	retl
	 sta	%g5, [%g1] ASI_M_MMUREGS

#define MIRROR_BLOCK(dst, src, offset, t0, t1, t2, t3) \
	ldd	[src + offset + 0x18], t0; \
	std	t0, [dst + offset + 0x18]; \
	ldd	[src + offset + 0x10], t2; \
	std	t2, [dst + offset + 0x10]; \
	ldd	[src + offset + 0x08], t0; \
	std	t0, [dst + offset + 0x08]; \
	ldd	[src + offset + 0x00], t2; \
	std	t2, [dst + offset + 0x00];

	.globl	tsunami_copy_1page
tsunami_copy_1page:
/* NOTE: This routine has to be shorter than 70insns --jj */
	or	%g0, (PAGE_SIZE >> 8), %g1
1:
	MIRROR_BLOCK(%o0, %o1, 0x00, %o2, %o3, %o4, %o5)
	MIRROR_BLOCK(%o0, %o1, 0x20, %o2, %o3, %o4, %o5)
	MIRROR_BLOCK(%o0, %o1, 0x40, %o2, %o3, %o4, %o5)
	MIRROR_BLOCK(%o0, %o1, 0x60, %o2, %o3, %o4, %o5)
	MIRROR_BLOCK(%o0, %o1, 0x80, %o2, %o3, %o4, %o5)
	MIRROR_BLOCK(%o0, %o1, 0xa0, %o2, %o3, %o4, %o5)
	MIRROR_BLOCK(%o0, %o1, 0xc0, %o2, %o3, %o4, %o5)
	MIRROR_BLOCK(%o0, %o1, 0xe0, %o2, %o3, %o4, %o5)
	subcc	%g1, 1, %g1
	add	%o0, 0x100, %o0
	bne	1b
	 add	%o1, 0x100, %o1

	.globl	tsunami_setup_blockops
tsunami_setup_blockops:
	sethi	%hi(__copy_1page), %o0
	or	%o0, %lo(__copy_1page), %o0
	sethi	%hi(tsunami_copy_1page), %o1
	or	%o1, %lo(tsunami_copy_1page), %o1
	sethi	%hi(tsunami_setup_blockops), %o2
	or	%o2, %lo(tsunami_setup_blockops), %o2
	ld	[%o1], %o4
1:	add	%o1, 4, %o1
	st	%o4, [%o0]
	add	%o0, 4, %o0
	cmp	%o1, %o2
	bne	1b
	ld	[%o1], %o4
	sta	%g0, [%g0] ASI_M_IC_FLCLEAR
	sta	%g0, [%g0] ASI_M_DC_FLCLEAR
	retl
	 nop