xref: /linux/arch/sparc/mm/leon_mm.c (revision b2441318)
1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
25213a780SKonrad Eisele /*
35213a780SKonrad Eisele  *  linux/arch/sparc/mm/leon_m.c
45213a780SKonrad Eisele  *
55213a780SKonrad Eisele  * Copyright (C) 2004 Konrad Eisele (eiselekd@web.de, konrad@gaisler.com) Gaisler Research
65213a780SKonrad Eisele  * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
75213a780SKonrad Eisele  * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
85213a780SKonrad Eisele  *
95213a780SKonrad Eisele  * do srmmu probe in software
105213a780SKonrad Eisele  *
115213a780SKonrad Eisele  */
125213a780SKonrad Eisele 
135213a780SKonrad Eisele #include <linux/kernel.h>
145213a780SKonrad Eisele #include <linux/mm.h>
155213a780SKonrad Eisele #include <asm/asi.h>
165213a780SKonrad Eisele #include <asm/leon.h>
175213a780SKonrad Eisele #include <asm/tlbflush.h>
185213a780SKonrad Eisele 
19ddb7417eSSam Ravnborg #include "mm_32.h"
20accf032cSSam Ravnborg 
215213a780SKonrad Eisele int leon_flush_during_switch = 1;
22a2b0aa94SSam Ravnborg static int srmmu_swprobe_trace;
235213a780SKonrad Eisele 
leon_get_ctable_ptr(void)243d5f7d37SSam Ravnborg static inline unsigned long leon_get_ctable_ptr(void)
253d5f7d37SSam Ravnborg {
263d5f7d37SSam Ravnborg 	unsigned int retval;
273d5f7d37SSam Ravnborg 
283d5f7d37SSam Ravnborg 	__asm__ __volatile__("lda [%1] %2, %0\n\t" :
293d5f7d37SSam Ravnborg 			     "=r" (retval) :
303d5f7d37SSam Ravnborg 			     "r" (SRMMU_CTXTBL_PTR),
313d5f7d37SSam Ravnborg 			     "i" (ASI_LEON_MMUREGS));
323d5f7d37SSam Ravnborg 	return (retval & SRMMU_CTX_PMASK) << 4;
333d5f7d37SSam Ravnborg }
343d5f7d37SSam Ravnborg 
353d5f7d37SSam Ravnborg 
leon_swprobe(unsigned long vaddr,unsigned long * paddr)36805918f8SSam Ravnborg unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr)
375213a780SKonrad Eisele {
385213a780SKonrad Eisele 
395213a780SKonrad Eisele 	unsigned int ctxtbl;
405213a780SKonrad Eisele 	unsigned int pgd, pmd, ped;
415213a780SKonrad Eisele 	unsigned int ptr;
425213a780SKonrad Eisele 	unsigned int lvl, pte, paddrbase;
435213a780SKonrad Eisele 	unsigned int ctx;
445213a780SKonrad Eisele 	unsigned int paddr_calc;
455213a780SKonrad Eisele 
465213a780SKonrad Eisele 	paddrbase = 0;
475213a780SKonrad Eisele 
485213a780SKonrad Eisele 	if (srmmu_swprobe_trace)
495213a780SKonrad Eisele 		printk(KERN_INFO "swprobe: trace on\n");
505213a780SKonrad Eisele 
513d5f7d37SSam Ravnborg 	ctxtbl = leon_get_ctable_ptr();
525213a780SKonrad Eisele 	if (!(ctxtbl)) {
535213a780SKonrad Eisele 		if (srmmu_swprobe_trace)
543d5f7d37SSam Ravnborg 			printk(KERN_INFO "swprobe: leon_get_ctable_ptr returned 0=>0\n");
555213a780SKonrad Eisele 		return 0;
565213a780SKonrad Eisele 	}
575213a780SKonrad Eisele 	if (!_pfn_valid(PFN(ctxtbl))) {
585213a780SKonrad Eisele 		if (srmmu_swprobe_trace)
595213a780SKonrad Eisele 			printk(KERN_INFO
605213a780SKonrad Eisele 			       "swprobe: !_pfn_valid(%x)=>0\n",
615213a780SKonrad Eisele 			       PFN(ctxtbl));
625213a780SKonrad Eisele 		return 0;
635213a780SKonrad Eisele 	}
645213a780SKonrad Eisele 
655213a780SKonrad Eisele 	ctx = srmmu_get_context();
665213a780SKonrad Eisele 	if (srmmu_swprobe_trace)
675213a780SKonrad Eisele 		printk(KERN_INFO "swprobe:  --- ctx (%x) ---\n", ctx);
685213a780SKonrad Eisele 
695213a780SKonrad Eisele 	pgd = LEON_BYPASS_LOAD_PA(ctxtbl + (ctx * 4));
705213a780SKonrad Eisele 
715213a780SKonrad Eisele 	if (((pgd & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
725213a780SKonrad Eisele 		if (srmmu_swprobe_trace)
735213a780SKonrad Eisele 			printk(KERN_INFO "swprobe: pgd is entry level 3\n");
745213a780SKonrad Eisele 		lvl = 3;
755213a780SKonrad Eisele 		pte = pgd;
765213a780SKonrad Eisele 		paddrbase = pgd & _SRMMU_PTE_PMASK_LEON;
775213a780SKonrad Eisele 		goto ready;
785213a780SKonrad Eisele 	}
795213a780SKonrad Eisele 	if (((pgd & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
805213a780SKonrad Eisele 		if (srmmu_swprobe_trace)
815213a780SKonrad Eisele 			printk(KERN_INFO "swprobe: pgd is invalid => 0\n");
825213a780SKonrad Eisele 		return 0;
835213a780SKonrad Eisele 	}
845213a780SKonrad Eisele 
855213a780SKonrad Eisele 	if (srmmu_swprobe_trace)
865213a780SKonrad Eisele 		printk(KERN_INFO "swprobe:  --- pgd (%x) ---\n", pgd);
875213a780SKonrad Eisele 
885213a780SKonrad Eisele 	ptr = (pgd & SRMMU_PTD_PMASK) << 4;
895213a780SKonrad Eisele 	ptr += ((((vaddr) >> LEON_PGD_SH) & LEON_PGD_M) * 4);
905213a780SKonrad Eisele 	if (!_pfn_valid(PFN(ptr)))
915213a780SKonrad Eisele 		return 0;
925213a780SKonrad Eisele 
935213a780SKonrad Eisele 	pmd = LEON_BYPASS_LOAD_PA(ptr);
945213a780SKonrad Eisele 	if (((pmd & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
955213a780SKonrad Eisele 		if (srmmu_swprobe_trace)
965213a780SKonrad Eisele 			printk(KERN_INFO "swprobe: pmd is entry level 2\n");
975213a780SKonrad Eisele 		lvl = 2;
985213a780SKonrad Eisele 		pte = pmd;
995213a780SKonrad Eisele 		paddrbase = pmd & _SRMMU_PTE_PMASK_LEON;
1005213a780SKonrad Eisele 		goto ready;
1015213a780SKonrad Eisele 	}
1025213a780SKonrad Eisele 	if (((pmd & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
1035213a780SKonrad Eisele 		if (srmmu_swprobe_trace)
1045213a780SKonrad Eisele 			printk(KERN_INFO "swprobe: pmd is invalid => 0\n");
1055213a780SKonrad Eisele 		return 0;
1065213a780SKonrad Eisele 	}
1075213a780SKonrad Eisele 
1085213a780SKonrad Eisele 	if (srmmu_swprobe_trace)
1095213a780SKonrad Eisele 		printk(KERN_INFO "swprobe:  --- pmd (%x) ---\n", pmd);
1105213a780SKonrad Eisele 
1115213a780SKonrad Eisele 	ptr = (pmd & SRMMU_PTD_PMASK) << 4;
1125213a780SKonrad Eisele 	ptr += (((vaddr >> LEON_PMD_SH) & LEON_PMD_M) * 4);
1135213a780SKonrad Eisele 	if (!_pfn_valid(PFN(ptr))) {
1145213a780SKonrad Eisele 		if (srmmu_swprobe_trace)
1155213a780SKonrad Eisele 			printk(KERN_INFO "swprobe: !_pfn_valid(%x)=>0\n",
1165213a780SKonrad Eisele 			       PFN(ptr));
1175213a780SKonrad Eisele 		return 0;
1185213a780SKonrad Eisele 	}
1195213a780SKonrad Eisele 
1205213a780SKonrad Eisele 	ped = LEON_BYPASS_LOAD_PA(ptr);
1215213a780SKonrad Eisele 
1225213a780SKonrad Eisele 	if (((ped & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
1235213a780SKonrad Eisele 		if (srmmu_swprobe_trace)
1245213a780SKonrad Eisele 			printk(KERN_INFO "swprobe: ped is entry level 1\n");
1255213a780SKonrad Eisele 		lvl = 1;
1265213a780SKonrad Eisele 		pte = ped;
1275213a780SKonrad Eisele 		paddrbase = ped & _SRMMU_PTE_PMASK_LEON;
1285213a780SKonrad Eisele 		goto ready;
1295213a780SKonrad Eisele 	}
1305213a780SKonrad Eisele 	if (((ped & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
1315213a780SKonrad Eisele 		if (srmmu_swprobe_trace)
1325213a780SKonrad Eisele 			printk(KERN_INFO "swprobe: ped is invalid => 0\n");
1335213a780SKonrad Eisele 		return 0;
1345213a780SKonrad Eisele 	}
1355213a780SKonrad Eisele 
1365213a780SKonrad Eisele 	if (srmmu_swprobe_trace)
1375213a780SKonrad Eisele 		printk(KERN_INFO "swprobe:  --- ped (%x) ---\n", ped);
1385213a780SKonrad Eisele 
1395213a780SKonrad Eisele 	ptr = (ped & SRMMU_PTD_PMASK) << 4;
1405213a780SKonrad Eisele 	ptr += (((vaddr >> LEON_PTE_SH) & LEON_PTE_M) * 4);
1415213a780SKonrad Eisele 	if (!_pfn_valid(PFN(ptr)))
1425213a780SKonrad Eisele 		return 0;
1435213a780SKonrad Eisele 
1445213a780SKonrad Eisele 	ptr = LEON_BYPASS_LOAD_PA(ptr);
1455213a780SKonrad Eisele 	if (((ptr & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
1465213a780SKonrad Eisele 		if (srmmu_swprobe_trace)
1475213a780SKonrad Eisele 			printk(KERN_INFO "swprobe: ptr is entry level 0\n");
1485213a780SKonrad Eisele 		lvl = 0;
1495213a780SKonrad Eisele 		pte = ptr;
1505213a780SKonrad Eisele 		paddrbase = ptr & _SRMMU_PTE_PMASK_LEON;
1515213a780SKonrad Eisele 		goto ready;
1525213a780SKonrad Eisele 	}
1535213a780SKonrad Eisele 	if (srmmu_swprobe_trace)
1545213a780SKonrad Eisele 		printk(KERN_INFO "swprobe: ptr is invalid => 0\n");
1555213a780SKonrad Eisele 	return 0;
1565213a780SKonrad Eisele 
1575213a780SKonrad Eisele ready:
1585213a780SKonrad Eisele 	switch (lvl) {
1595213a780SKonrad Eisele 	case 0:
1605213a780SKonrad Eisele 		paddr_calc =
1615213a780SKonrad Eisele 		    (vaddr & ~(-1 << LEON_PTE_SH)) | ((pte & ~0xff) << 4);
1625213a780SKonrad Eisele 		break;
1635213a780SKonrad Eisele 	case 1:
1645213a780SKonrad Eisele 		paddr_calc =
1655213a780SKonrad Eisele 		    (vaddr & ~(-1 << LEON_PMD_SH)) | ((pte & ~0xff) << 4);
1665213a780SKonrad Eisele 		break;
1675213a780SKonrad Eisele 	case 2:
1685213a780SKonrad Eisele 		paddr_calc =
1695213a780SKonrad Eisele 		    (vaddr & ~(-1 << LEON_PGD_SH)) | ((pte & ~0xff) << 4);
1705213a780SKonrad Eisele 		break;
1715213a780SKonrad Eisele 	default:
1725213a780SKonrad Eisele 	case 3:
1735213a780SKonrad Eisele 		paddr_calc = vaddr;
1745213a780SKonrad Eisele 		break;
1755213a780SKonrad Eisele 	}
1765213a780SKonrad Eisele 	if (srmmu_swprobe_trace)
1775213a780SKonrad Eisele 		printk(KERN_INFO "swprobe: padde %x\n", paddr_calc);
1785213a780SKonrad Eisele 	if (paddr)
1795213a780SKonrad Eisele 		*paddr = paddr_calc;
180f22ed71cSDaniel Hellstrom 	return pte;
1815213a780SKonrad Eisele }
1825213a780SKonrad Eisele 
leon_flush_icache_all(void)1835213a780SKonrad Eisele void leon_flush_icache_all(void)
1845213a780SKonrad Eisele {
1855213a780SKonrad Eisele 	__asm__ __volatile__(" flush ");	/*iflush*/
1865213a780SKonrad Eisele }
1875213a780SKonrad Eisele 
leon_flush_dcache_all(void)1885213a780SKonrad Eisele void leon_flush_dcache_all(void)
1895213a780SKonrad Eisele {
1905213a780SKonrad Eisele 	__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
1915213a780SKonrad Eisele 			     "i"(ASI_LEON_DFLUSH) : "memory");
1925213a780SKonrad Eisele }
1935213a780SKonrad Eisele 
leon_flush_pcache_all(struct vm_area_struct * vma,unsigned long page)1945213a780SKonrad Eisele void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page)
1955213a780SKonrad Eisele {
1965213a780SKonrad Eisele 	if (vma->vm_flags & VM_EXEC)
1975213a780SKonrad Eisele 		leon_flush_icache_all();
1985213a780SKonrad Eisele 	leon_flush_dcache_all();
1995213a780SKonrad Eisele }
2005213a780SKonrad Eisele 
leon_flush_cache_all(void)2015213a780SKonrad Eisele void leon_flush_cache_all(void)
2025213a780SKonrad Eisele {
2035213a780SKonrad Eisele 	__asm__ __volatile__(" flush ");	/*iflush*/
2045213a780SKonrad Eisele 	__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
2055213a780SKonrad Eisele 			     "i"(ASI_LEON_DFLUSH) : "memory");
2065213a780SKonrad Eisele }
2075213a780SKonrad Eisele 
leon_flush_tlb_all(void)2085213a780SKonrad Eisele void leon_flush_tlb_all(void)
2095213a780SKonrad Eisele {
2105213a780SKonrad Eisele 	leon_flush_cache_all();
2115213a780SKonrad Eisele 	__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : "r"(0x400),
2125213a780SKonrad Eisele 			     "i"(ASI_LEON_MMUFLUSH) : "memory");
2135213a780SKonrad Eisele }
2145213a780SKonrad Eisele 
2155213a780SKonrad Eisele /* get all cache regs */
leon3_getCacheRegs(struct leon3_cacheregs * regs)2165213a780SKonrad Eisele void leon3_getCacheRegs(struct leon3_cacheregs *regs)
2175213a780SKonrad Eisele {
2185213a780SKonrad Eisele 	unsigned long ccr, iccr, dccr;
2195213a780SKonrad Eisele 
2205213a780SKonrad Eisele 	if (!regs)
2215213a780SKonrad Eisele 		return;
2225213a780SKonrad Eisele 	/* Get Cache regs from "Cache ASI" address 0x0, 0x8 and 0xC */
2235213a780SKonrad Eisele 	__asm__ __volatile__("lda [%%g0] %3, %0\n\t"
2245213a780SKonrad Eisele 			     "mov 0x08, %%g1\n\t"
2255213a780SKonrad Eisele 			     "lda [%%g1] %3, %1\n\t"
2265213a780SKonrad Eisele 			     "mov 0x0c, %%g1\n\t"
2275213a780SKonrad Eisele 			     "lda [%%g1] %3, %2\n\t"
2285213a780SKonrad Eisele 			     : "=r"(ccr), "=r"(iccr), "=r"(dccr)
2295213a780SKonrad Eisele 			       /* output */
2305213a780SKonrad Eisele 			     : "i"(ASI_LEON_CACHEREGS)	/* input */
2315213a780SKonrad Eisele 			     : "g1"	/* clobber list */
2325213a780SKonrad Eisele 	    );
2335213a780SKonrad Eisele 	regs->ccr = ccr;
2345213a780SKonrad Eisele 	regs->iccr = iccr;
2355213a780SKonrad Eisele 	regs->dccr = dccr;
2365213a780SKonrad Eisele }
2375213a780SKonrad Eisele 
2385213a780SKonrad Eisele /* Due to virtual cache we need to check cache configuration if
2395213a780SKonrad Eisele  * it is possible to skip flushing in some cases.
2405213a780SKonrad Eisele  *
2415213a780SKonrad Eisele  * Leon2 and Leon3 differ in their way of telling cache information
2425213a780SKonrad Eisele  *
2435213a780SKonrad Eisele  */
leon_flush_needed(void)2446d999da4SMatthias Rosenfelder int __init leon_flush_needed(void)
2455213a780SKonrad Eisele {
2465213a780SKonrad Eisele 	int flush_needed = -1;
2475213a780SKonrad Eisele 	unsigned int ssize, sets;
2485213a780SKonrad Eisele 	char *setStr[4] =
2495213a780SKonrad Eisele 	    { "direct mapped", "2-way associative", "3-way associative",
2505213a780SKonrad Eisele 		"4-way associative"
2515213a780SKonrad Eisele 	};
2525213a780SKonrad Eisele 	/* leon 3 */
2535213a780SKonrad Eisele 	struct leon3_cacheregs cregs;
2545213a780SKonrad Eisele 	leon3_getCacheRegs(&cregs);
2555213a780SKonrad Eisele 	sets = (cregs.dccr & LEON3_XCCR_SETS_MASK) >> 24;
2565213a780SKonrad Eisele 	/* (ssize=>realsize) 0=>1k, 1=>2k, 2=>4k, 3=>8k ... */
2575213a780SKonrad Eisele 	ssize = 1 << ((cregs.dccr & LEON3_XCCR_SSIZE_MASK) >> 20);
2585213a780SKonrad Eisele 
2595213a780SKonrad Eisele 	printk(KERN_INFO "CACHE: %s cache, set size %dk\n",
2605213a780SKonrad Eisele 	       sets > 3 ? "unknown" : setStr[sets], ssize);
2615213a780SKonrad Eisele 	if ((ssize <= (PAGE_SIZE / 1024)) && (sets == 0)) {
2625213a780SKonrad Eisele 		/* Set Size <= Page size  ==>
2635213a780SKonrad Eisele 		   flush on every context switch not needed. */
2645213a780SKonrad Eisele 		flush_needed = 0;
2655213a780SKonrad Eisele 		printk(KERN_INFO "CACHE: not flushing on every context switch\n");
2665213a780SKonrad Eisele 	}
2675213a780SKonrad Eisele 	return flush_needed;
2685213a780SKonrad Eisele }
2695213a780SKonrad Eisele 
leon_switch_mm(void)2705213a780SKonrad Eisele void leon_switch_mm(void)
2715213a780SKonrad Eisele {
2725213a780SKonrad Eisele 	flush_tlb_mm((void *)0);
2735213a780SKonrad Eisele 	if (leon_flush_during_switch)
2745213a780SKonrad Eisele 		leon_flush_cache_all();
2755213a780SKonrad Eisele }
276accf032cSSam Ravnborg 
leon_flush_cache_mm(struct mm_struct * mm)277accf032cSSam Ravnborg static void leon_flush_cache_mm(struct mm_struct *mm)
278accf032cSSam Ravnborg {
279accf032cSSam Ravnborg 	leon_flush_cache_all();
280accf032cSSam Ravnborg }
281accf032cSSam Ravnborg 
leon_flush_cache_page(struct vm_area_struct * vma,unsigned long page)282accf032cSSam Ravnborg static void leon_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
283accf032cSSam Ravnborg {
284accf032cSSam Ravnborg 	leon_flush_pcache_all(vma, page);
285accf032cSSam Ravnborg }
286accf032cSSam Ravnborg 
leon_flush_cache_range(struct vm_area_struct * vma,unsigned long start,unsigned long end)287accf032cSSam Ravnborg static void leon_flush_cache_range(struct vm_area_struct *vma,
288accf032cSSam Ravnborg 				   unsigned long start,
289accf032cSSam Ravnborg 				   unsigned long end)
290accf032cSSam Ravnborg {
291accf032cSSam Ravnborg 	leon_flush_cache_all();
292accf032cSSam Ravnborg }
293accf032cSSam Ravnborg 
leon_flush_tlb_mm(struct mm_struct * mm)294accf032cSSam Ravnborg static void leon_flush_tlb_mm(struct mm_struct *mm)
295accf032cSSam Ravnborg {
296accf032cSSam Ravnborg 	leon_flush_tlb_all();
297accf032cSSam Ravnborg }
298accf032cSSam Ravnborg 
leon_flush_tlb_page(struct vm_area_struct * vma,unsigned long page)299accf032cSSam Ravnborg static void leon_flush_tlb_page(struct vm_area_struct *vma,
300accf032cSSam Ravnborg 				unsigned long page)
301accf032cSSam Ravnborg {
302accf032cSSam Ravnborg 	leon_flush_tlb_all();
303accf032cSSam Ravnborg }
304accf032cSSam Ravnborg 
leon_flush_tlb_range(struct vm_area_struct * vma,unsigned long start,unsigned long end)305accf032cSSam Ravnborg static void leon_flush_tlb_range(struct vm_area_struct *vma,
306accf032cSSam Ravnborg 				 unsigned long start,
307accf032cSSam Ravnborg 				 unsigned long end)
308accf032cSSam Ravnborg {
309accf032cSSam Ravnborg 	leon_flush_tlb_all();
310accf032cSSam Ravnborg }
311accf032cSSam Ravnborg 
leon_flush_page_to_ram(unsigned long page)312accf032cSSam Ravnborg static void leon_flush_page_to_ram(unsigned long page)
313accf032cSSam Ravnborg {
314accf032cSSam Ravnborg 	leon_flush_cache_all();
315accf032cSSam Ravnborg }
316accf032cSSam Ravnborg 
leon_flush_sig_insns(struct mm_struct * mm,unsigned long page)317accf032cSSam Ravnborg static void leon_flush_sig_insns(struct mm_struct *mm, unsigned long page)
318accf032cSSam Ravnborg {
319accf032cSSam Ravnborg 	leon_flush_cache_all();
320accf032cSSam Ravnborg }
321accf032cSSam Ravnborg 
leon_flush_page_for_dma(unsigned long page)322accf032cSSam Ravnborg static void leon_flush_page_for_dma(unsigned long page)
323accf032cSSam Ravnborg {
324accf032cSSam Ravnborg 	leon_flush_dcache_all();
325accf032cSSam Ravnborg }
326accf032cSSam Ravnborg 
poke_leonsparc(void)327accf032cSSam Ravnborg void __init poke_leonsparc(void)
328accf032cSSam Ravnborg {
329accf032cSSam Ravnborg }
330accf032cSSam Ravnborg 
331accf032cSSam Ravnborg static const struct sparc32_cachetlb_ops leon_ops = {
332accf032cSSam Ravnborg 	.cache_all	= leon_flush_cache_all,
333accf032cSSam Ravnborg 	.cache_mm	= leon_flush_cache_mm,
334accf032cSSam Ravnborg 	.cache_page	= leon_flush_cache_page,
335accf032cSSam Ravnborg 	.cache_range	= leon_flush_cache_range,
336accf032cSSam Ravnborg 	.tlb_all	= leon_flush_tlb_all,
337accf032cSSam Ravnborg 	.tlb_mm		= leon_flush_tlb_mm,
338accf032cSSam Ravnborg 	.tlb_page	= leon_flush_tlb_page,
339accf032cSSam Ravnborg 	.tlb_range	= leon_flush_tlb_range,
340accf032cSSam Ravnborg 	.page_to_ram	= leon_flush_page_to_ram,
341accf032cSSam Ravnborg 	.sig_insns	= leon_flush_sig_insns,
342accf032cSSam Ravnborg 	.page_for_dma	= leon_flush_page_for_dma,
343accf032cSSam Ravnborg };
344accf032cSSam Ravnborg 
init_leon(void)345accf032cSSam Ravnborg void __init init_leon(void)
346accf032cSSam Ravnborg {
347accf032cSSam Ravnborg 	srmmu_name = "LEON";
348accf032cSSam Ravnborg 	sparc32_cachetlb_ops = &leon_ops;
349accf032cSSam Ravnborg 	poke_srmmu = poke_leonsparc;
350accf032cSSam Ravnborg 
351accf032cSSam Ravnborg 	leon_flush_during_switch = leon_flush_needed();
352accf032cSSam Ravnborg }
353