xref: /OK3568_Linux_fs/kernel/arch/sparc/mm/leon_mm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *  linux/arch/sparc/mm/leon_m.c
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2004 Konrad Eisele (eiselekd@web.de, konrad@gaisler.com) Gaisler Research
6*4882a593Smuzhiyun  * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
7*4882a593Smuzhiyun  * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * do srmmu probe in software
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <linux/kernel.h>
14*4882a593Smuzhiyun #include <linux/mm.h>
15*4882a593Smuzhiyun #include <asm/asi.h>
16*4882a593Smuzhiyun #include <asm/leon.h>
17*4882a593Smuzhiyun #include <asm/tlbflush.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include "mm_32.h"
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun int leon_flush_during_switch = 1;
22*4882a593Smuzhiyun static int srmmu_swprobe_trace;
23*4882a593Smuzhiyun 
leon_get_ctable_ptr(void)24*4882a593Smuzhiyun static inline unsigned long leon_get_ctable_ptr(void)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	unsigned int retval;
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	__asm__ __volatile__("lda [%1] %2, %0\n\t" :
29*4882a593Smuzhiyun 			     "=r" (retval) :
30*4882a593Smuzhiyun 			     "r" (SRMMU_CTXTBL_PTR),
31*4882a593Smuzhiyun 			     "i" (ASI_LEON_MMUREGS));
32*4882a593Smuzhiyun 	return (retval & SRMMU_CTX_PMASK) << 4;
33*4882a593Smuzhiyun }
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 
leon_swprobe(unsigned long vaddr,unsigned long * paddr)36*4882a593Smuzhiyun unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 	unsigned int ctxtbl;
40*4882a593Smuzhiyun 	unsigned int pgd, pmd, ped;
41*4882a593Smuzhiyun 	unsigned int ptr;
42*4882a593Smuzhiyun 	unsigned int lvl, pte, paddrbase;
43*4882a593Smuzhiyun 	unsigned int ctx;
44*4882a593Smuzhiyun 	unsigned int paddr_calc;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	paddrbase = 0;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	if (srmmu_swprobe_trace)
49*4882a593Smuzhiyun 		printk(KERN_INFO "swprobe: trace on\n");
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	ctxtbl = leon_get_ctable_ptr();
52*4882a593Smuzhiyun 	if (!(ctxtbl)) {
53*4882a593Smuzhiyun 		if (srmmu_swprobe_trace)
54*4882a593Smuzhiyun 			printk(KERN_INFO "swprobe: leon_get_ctable_ptr returned 0=>0\n");
55*4882a593Smuzhiyun 		return 0;
56*4882a593Smuzhiyun 	}
57*4882a593Smuzhiyun 	if (!_pfn_valid(PFN(ctxtbl))) {
58*4882a593Smuzhiyun 		if (srmmu_swprobe_trace)
59*4882a593Smuzhiyun 			printk(KERN_INFO
60*4882a593Smuzhiyun 			       "swprobe: !_pfn_valid(%x)=>0\n",
61*4882a593Smuzhiyun 			       PFN(ctxtbl));
62*4882a593Smuzhiyun 		return 0;
63*4882a593Smuzhiyun 	}
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	ctx = srmmu_get_context();
66*4882a593Smuzhiyun 	if (srmmu_swprobe_trace)
67*4882a593Smuzhiyun 		printk(KERN_INFO "swprobe:  --- ctx (%x) ---\n", ctx);
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	pgd = LEON_BYPASS_LOAD_PA(ctxtbl + (ctx * 4));
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	if (((pgd & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
72*4882a593Smuzhiyun 		if (srmmu_swprobe_trace)
73*4882a593Smuzhiyun 			printk(KERN_INFO "swprobe: pgd is entry level 3\n");
74*4882a593Smuzhiyun 		lvl = 3;
75*4882a593Smuzhiyun 		pte = pgd;
76*4882a593Smuzhiyun 		paddrbase = pgd & _SRMMU_PTE_PMASK_LEON;
77*4882a593Smuzhiyun 		goto ready;
78*4882a593Smuzhiyun 	}
79*4882a593Smuzhiyun 	if (((pgd & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
80*4882a593Smuzhiyun 		if (srmmu_swprobe_trace)
81*4882a593Smuzhiyun 			printk(KERN_INFO "swprobe: pgd is invalid => 0\n");
82*4882a593Smuzhiyun 		return 0;
83*4882a593Smuzhiyun 	}
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	if (srmmu_swprobe_trace)
86*4882a593Smuzhiyun 		printk(KERN_INFO "swprobe:  --- pgd (%x) ---\n", pgd);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	ptr = (pgd & SRMMU_PTD_PMASK) << 4;
89*4882a593Smuzhiyun 	ptr += ((((vaddr) >> LEON_PGD_SH) & LEON_PGD_M) * 4);
90*4882a593Smuzhiyun 	if (!_pfn_valid(PFN(ptr)))
91*4882a593Smuzhiyun 		return 0;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	pmd = LEON_BYPASS_LOAD_PA(ptr);
94*4882a593Smuzhiyun 	if (((pmd & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
95*4882a593Smuzhiyun 		if (srmmu_swprobe_trace)
96*4882a593Smuzhiyun 			printk(KERN_INFO "swprobe: pmd is entry level 2\n");
97*4882a593Smuzhiyun 		lvl = 2;
98*4882a593Smuzhiyun 		pte = pmd;
99*4882a593Smuzhiyun 		paddrbase = pmd & _SRMMU_PTE_PMASK_LEON;
100*4882a593Smuzhiyun 		goto ready;
101*4882a593Smuzhiyun 	}
102*4882a593Smuzhiyun 	if (((pmd & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
103*4882a593Smuzhiyun 		if (srmmu_swprobe_trace)
104*4882a593Smuzhiyun 			printk(KERN_INFO "swprobe: pmd is invalid => 0\n");
105*4882a593Smuzhiyun 		return 0;
106*4882a593Smuzhiyun 	}
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	if (srmmu_swprobe_trace)
109*4882a593Smuzhiyun 		printk(KERN_INFO "swprobe:  --- pmd (%x) ---\n", pmd);
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	ptr = (pmd & SRMMU_PTD_PMASK) << 4;
112*4882a593Smuzhiyun 	ptr += (((vaddr >> LEON_PMD_SH) & LEON_PMD_M) * 4);
113*4882a593Smuzhiyun 	if (!_pfn_valid(PFN(ptr))) {
114*4882a593Smuzhiyun 		if (srmmu_swprobe_trace)
115*4882a593Smuzhiyun 			printk(KERN_INFO "swprobe: !_pfn_valid(%x)=>0\n",
116*4882a593Smuzhiyun 			       PFN(ptr));
117*4882a593Smuzhiyun 		return 0;
118*4882a593Smuzhiyun 	}
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	ped = LEON_BYPASS_LOAD_PA(ptr);
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	if (((ped & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
123*4882a593Smuzhiyun 		if (srmmu_swprobe_trace)
124*4882a593Smuzhiyun 			printk(KERN_INFO "swprobe: ped is entry level 1\n");
125*4882a593Smuzhiyun 		lvl = 1;
126*4882a593Smuzhiyun 		pte = ped;
127*4882a593Smuzhiyun 		paddrbase = ped & _SRMMU_PTE_PMASK_LEON;
128*4882a593Smuzhiyun 		goto ready;
129*4882a593Smuzhiyun 	}
130*4882a593Smuzhiyun 	if (((ped & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
131*4882a593Smuzhiyun 		if (srmmu_swprobe_trace)
132*4882a593Smuzhiyun 			printk(KERN_INFO "swprobe: ped is invalid => 0\n");
133*4882a593Smuzhiyun 		return 0;
134*4882a593Smuzhiyun 	}
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	if (srmmu_swprobe_trace)
137*4882a593Smuzhiyun 		printk(KERN_INFO "swprobe:  --- ped (%x) ---\n", ped);
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	ptr = (ped & SRMMU_PTD_PMASK) << 4;
140*4882a593Smuzhiyun 	ptr += (((vaddr >> LEON_PTE_SH) & LEON_PTE_M) * 4);
141*4882a593Smuzhiyun 	if (!_pfn_valid(PFN(ptr)))
142*4882a593Smuzhiyun 		return 0;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	ptr = LEON_BYPASS_LOAD_PA(ptr);
145*4882a593Smuzhiyun 	if (((ptr & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
146*4882a593Smuzhiyun 		if (srmmu_swprobe_trace)
147*4882a593Smuzhiyun 			printk(KERN_INFO "swprobe: ptr is entry level 0\n");
148*4882a593Smuzhiyun 		lvl = 0;
149*4882a593Smuzhiyun 		pte = ptr;
150*4882a593Smuzhiyun 		paddrbase = ptr & _SRMMU_PTE_PMASK_LEON;
151*4882a593Smuzhiyun 		goto ready;
152*4882a593Smuzhiyun 	}
153*4882a593Smuzhiyun 	if (srmmu_swprobe_trace)
154*4882a593Smuzhiyun 		printk(KERN_INFO "swprobe: ptr is invalid => 0\n");
155*4882a593Smuzhiyun 	return 0;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun ready:
158*4882a593Smuzhiyun 	switch (lvl) {
159*4882a593Smuzhiyun 	case 0:
160*4882a593Smuzhiyun 		paddr_calc =
161*4882a593Smuzhiyun 		    (vaddr & ~(-1 << LEON_PTE_SH)) | ((pte & ~0xff) << 4);
162*4882a593Smuzhiyun 		break;
163*4882a593Smuzhiyun 	case 1:
164*4882a593Smuzhiyun 		paddr_calc =
165*4882a593Smuzhiyun 		    (vaddr & ~(-1 << LEON_PMD_SH)) | ((pte & ~0xff) << 4);
166*4882a593Smuzhiyun 		break;
167*4882a593Smuzhiyun 	case 2:
168*4882a593Smuzhiyun 		paddr_calc =
169*4882a593Smuzhiyun 		    (vaddr & ~(-1 << LEON_PGD_SH)) | ((pte & ~0xff) << 4);
170*4882a593Smuzhiyun 		break;
171*4882a593Smuzhiyun 	default:
172*4882a593Smuzhiyun 	case 3:
173*4882a593Smuzhiyun 		paddr_calc = vaddr;
174*4882a593Smuzhiyun 		break;
175*4882a593Smuzhiyun 	}
176*4882a593Smuzhiyun 	if (srmmu_swprobe_trace)
177*4882a593Smuzhiyun 		printk(KERN_INFO "swprobe: padde %x\n", paddr_calc);
178*4882a593Smuzhiyun 	if (paddr)
179*4882a593Smuzhiyun 		*paddr = paddr_calc;
180*4882a593Smuzhiyun 	return pte;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun 
leon_flush_icache_all(void)183*4882a593Smuzhiyun void leon_flush_icache_all(void)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun 	__asm__ __volatile__(" flush ");	/*iflush*/
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun 
leon_flush_dcache_all(void)188*4882a593Smuzhiyun void leon_flush_dcache_all(void)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun 	__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
191*4882a593Smuzhiyun 			     "i"(ASI_LEON_DFLUSH) : "memory");
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun 
leon_flush_pcache_all(struct vm_area_struct * vma,unsigned long page)194*4882a593Smuzhiyun void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page)
195*4882a593Smuzhiyun {
196*4882a593Smuzhiyun 	if (vma->vm_flags & VM_EXEC)
197*4882a593Smuzhiyun 		leon_flush_icache_all();
198*4882a593Smuzhiyun 	leon_flush_dcache_all();
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun 
leon_flush_cache_all(void)201*4882a593Smuzhiyun void leon_flush_cache_all(void)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun 	__asm__ __volatile__(" flush ");	/*iflush*/
204*4882a593Smuzhiyun 	__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
205*4882a593Smuzhiyun 			     "i"(ASI_LEON_DFLUSH) : "memory");
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun 
leon_flush_tlb_all(void)208*4882a593Smuzhiyun void leon_flush_tlb_all(void)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun 	leon_flush_cache_all();
211*4882a593Smuzhiyun 	__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : "r"(0x400),
212*4882a593Smuzhiyun 			     "i"(ASI_LEON_MMUFLUSH) : "memory");
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun /* get all cache regs */
leon3_getCacheRegs(struct leon3_cacheregs * regs)216*4882a593Smuzhiyun void leon3_getCacheRegs(struct leon3_cacheregs *regs)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun 	unsigned long ccr, iccr, dccr;
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	if (!regs)
221*4882a593Smuzhiyun 		return;
222*4882a593Smuzhiyun 	/* Get Cache regs from "Cache ASI" address 0x0, 0x8 and 0xC */
223*4882a593Smuzhiyun 	__asm__ __volatile__("lda [%%g0] %3, %0\n\t"
224*4882a593Smuzhiyun 			     "mov 0x08, %%g1\n\t"
225*4882a593Smuzhiyun 			     "lda [%%g1] %3, %1\n\t"
226*4882a593Smuzhiyun 			     "mov 0x0c, %%g1\n\t"
227*4882a593Smuzhiyun 			     "lda [%%g1] %3, %2\n\t"
228*4882a593Smuzhiyun 			     : "=r"(ccr), "=r"(iccr), "=r"(dccr)
229*4882a593Smuzhiyun 			       /* output */
230*4882a593Smuzhiyun 			     : "i"(ASI_LEON_CACHEREGS)	/* input */
231*4882a593Smuzhiyun 			     : "g1"	/* clobber list */
232*4882a593Smuzhiyun 	    );
233*4882a593Smuzhiyun 	regs->ccr = ccr;
234*4882a593Smuzhiyun 	regs->iccr = iccr;
235*4882a593Smuzhiyun 	regs->dccr = dccr;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun /* Due to virtual cache we need to check cache configuration if
239*4882a593Smuzhiyun  * it is possible to skip flushing in some cases.
240*4882a593Smuzhiyun  *
241*4882a593Smuzhiyun  * Leon2 and Leon3 differ in their way of telling cache information
242*4882a593Smuzhiyun  *
243*4882a593Smuzhiyun  */
leon_flush_needed(void)244*4882a593Smuzhiyun int __init leon_flush_needed(void)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun 	int flush_needed = -1;
247*4882a593Smuzhiyun 	unsigned int ssize, sets;
248*4882a593Smuzhiyun 	char *setStr[4] =
249*4882a593Smuzhiyun 	    { "direct mapped", "2-way associative", "3-way associative",
250*4882a593Smuzhiyun 		"4-way associative"
251*4882a593Smuzhiyun 	};
252*4882a593Smuzhiyun 	/* leon 3 */
253*4882a593Smuzhiyun 	struct leon3_cacheregs cregs;
254*4882a593Smuzhiyun 	leon3_getCacheRegs(&cregs);
255*4882a593Smuzhiyun 	sets = (cregs.dccr & LEON3_XCCR_SETS_MASK) >> 24;
256*4882a593Smuzhiyun 	/* (ssize=>realsize) 0=>1k, 1=>2k, 2=>4k, 3=>8k ... */
257*4882a593Smuzhiyun 	ssize = 1 << ((cregs.dccr & LEON3_XCCR_SSIZE_MASK) >> 20);
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	printk(KERN_INFO "CACHE: %s cache, set size %dk\n",
260*4882a593Smuzhiyun 	       sets > 3 ? "unknown" : setStr[sets], ssize);
261*4882a593Smuzhiyun 	if ((ssize <= (PAGE_SIZE / 1024)) && (sets == 0)) {
262*4882a593Smuzhiyun 		/* Set Size <= Page size  ==>
263*4882a593Smuzhiyun 		   flush on every context switch not needed. */
264*4882a593Smuzhiyun 		flush_needed = 0;
265*4882a593Smuzhiyun 		printk(KERN_INFO "CACHE: not flushing on every context switch\n");
266*4882a593Smuzhiyun 	}
267*4882a593Smuzhiyun 	return flush_needed;
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun 
leon_switch_mm(void)270*4882a593Smuzhiyun void leon_switch_mm(void)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun 	flush_tlb_mm((void *)0);
273*4882a593Smuzhiyun 	if (leon_flush_during_switch)
274*4882a593Smuzhiyun 		leon_flush_cache_all();
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun 
leon_flush_cache_mm(struct mm_struct * mm)277*4882a593Smuzhiyun static void leon_flush_cache_mm(struct mm_struct *mm)
278*4882a593Smuzhiyun {
279*4882a593Smuzhiyun 	leon_flush_cache_all();
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun 
leon_flush_cache_page(struct vm_area_struct * vma,unsigned long page)282*4882a593Smuzhiyun static void leon_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun 	leon_flush_pcache_all(vma, page);
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun 
leon_flush_cache_range(struct vm_area_struct * vma,unsigned long start,unsigned long end)287*4882a593Smuzhiyun static void leon_flush_cache_range(struct vm_area_struct *vma,
288*4882a593Smuzhiyun 				   unsigned long start,
289*4882a593Smuzhiyun 				   unsigned long end)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	leon_flush_cache_all();
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun 
leon_flush_tlb_mm(struct mm_struct * mm)294*4882a593Smuzhiyun static void leon_flush_tlb_mm(struct mm_struct *mm)
295*4882a593Smuzhiyun {
296*4882a593Smuzhiyun 	leon_flush_tlb_all();
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun 
leon_flush_tlb_page(struct vm_area_struct * vma,unsigned long page)299*4882a593Smuzhiyun static void leon_flush_tlb_page(struct vm_area_struct *vma,
300*4882a593Smuzhiyun 				unsigned long page)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun 	leon_flush_tlb_all();
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun 
leon_flush_tlb_range(struct vm_area_struct * vma,unsigned long start,unsigned long end)305*4882a593Smuzhiyun static void leon_flush_tlb_range(struct vm_area_struct *vma,
306*4882a593Smuzhiyun 				 unsigned long start,
307*4882a593Smuzhiyun 				 unsigned long end)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun 	leon_flush_tlb_all();
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun 
leon_flush_page_to_ram(unsigned long page)312*4882a593Smuzhiyun static void leon_flush_page_to_ram(unsigned long page)
313*4882a593Smuzhiyun {
314*4882a593Smuzhiyun 	leon_flush_cache_all();
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun 
leon_flush_sig_insns(struct mm_struct * mm,unsigned long page)317*4882a593Smuzhiyun static void leon_flush_sig_insns(struct mm_struct *mm, unsigned long page)
318*4882a593Smuzhiyun {
319*4882a593Smuzhiyun 	leon_flush_cache_all();
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun 
leon_flush_page_for_dma(unsigned long page)322*4882a593Smuzhiyun static void leon_flush_page_for_dma(unsigned long page)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun 	leon_flush_dcache_all();
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun 
poke_leonsparc(void)327*4882a593Smuzhiyun void __init poke_leonsparc(void)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun static const struct sparc32_cachetlb_ops leon_ops = {
332*4882a593Smuzhiyun 	.cache_all	= leon_flush_cache_all,
333*4882a593Smuzhiyun 	.cache_mm	= leon_flush_cache_mm,
334*4882a593Smuzhiyun 	.cache_page	= leon_flush_cache_page,
335*4882a593Smuzhiyun 	.cache_range	= leon_flush_cache_range,
336*4882a593Smuzhiyun 	.tlb_all	= leon_flush_tlb_all,
337*4882a593Smuzhiyun 	.tlb_mm		= leon_flush_tlb_mm,
338*4882a593Smuzhiyun 	.tlb_page	= leon_flush_tlb_page,
339*4882a593Smuzhiyun 	.tlb_range	= leon_flush_tlb_range,
340*4882a593Smuzhiyun 	.page_to_ram	= leon_flush_page_to_ram,
341*4882a593Smuzhiyun 	.sig_insns	= leon_flush_sig_insns,
342*4882a593Smuzhiyun 	.page_for_dma	= leon_flush_page_for_dma,
343*4882a593Smuzhiyun };
344*4882a593Smuzhiyun 
init_leon(void)345*4882a593Smuzhiyun void __init init_leon(void)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun 	srmmu_name = "LEON";
348*4882a593Smuzhiyun 	sparc32_cachetlb_ops = &leon_ops;
349*4882a593Smuzhiyun 	poke_srmmu = poke_leonsparc;
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	leon_flush_during_switch = leon_flush_needed();
352*4882a593Smuzhiyun }
353