11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 31da177e4SLinus Torvalds * License. See the file "COPYING" in the main directory of this archive 41da177e4SLinus Torvalds * for more details. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Copyright (C) 1994 - 2003 by Ralf Baechle 71da177e4SLinus Torvalds */ 81da177e4SLinus Torvalds #include <linux/config.h> 91da177e4SLinus Torvalds #include <linux/init.h> 101da177e4SLinus Torvalds #include <linux/kernel.h> 111da177e4SLinus Torvalds #include <linux/module.h> 121da177e4SLinus Torvalds #include <linux/sched.h> 131da177e4SLinus Torvalds #include <linux/mm.h> 141da177e4SLinus Torvalds 151da177e4SLinus Torvalds #include <asm/cacheflush.h> 161da177e4SLinus Torvalds #include <asm/processor.h> 171da177e4SLinus Torvalds #include <asm/cpu.h> 181da177e4SLinus Torvalds #include <asm/cpu-features.h> 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds /* Cache operations. */ 211da177e4SLinus Torvalds void (*flush_cache_all)(void); 221da177e4SLinus Torvalds void (*__flush_cache_all)(void); 231da177e4SLinus Torvalds void (*flush_cache_mm)(struct mm_struct *mm); 241da177e4SLinus Torvalds void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, 251da177e4SLinus Torvalds unsigned long end); 26*53de0d47SRalf Baechle void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, 27*53de0d47SRalf Baechle unsigned long pfn); 28fe00f943SRalf Baechle void (*flush_icache_range)(unsigned long __user start, 29fe00f943SRalf Baechle unsigned long __user end); 301da177e4SLinus Torvalds void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds /* MIPS specific cache operations */ 331da177e4SLinus Torvalds void (*flush_cache_sigtramp)(unsigned long addr); 341da177e4SLinus Torvalds void (*flush_data_cache_page)(unsigned long addr); 351da177e4SLinus Torvalds void (*flush_icache_all)(void); 361da177e4SLinus Torvalds 379ff77c46SRalf Baechle EXPORT_SYMBOL(flush_data_cache_page); 389ff77c46SRalf Baechle 391da177e4SLinus Torvalds #ifdef CONFIG_DMA_NONCOHERENT 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds /* DMA cache operations. */ 421da177e4SLinus Torvalds void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); 431da177e4SLinus Torvalds void (*_dma_cache_wback)(unsigned long start, unsigned long size); 441da177e4SLinus Torvalds void (*_dma_cache_inv)(unsigned long start, unsigned long size); 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds EXPORT_SYMBOL(_dma_cache_wback_inv); 471da177e4SLinus Torvalds EXPORT_SYMBOL(_dma_cache_wback); 481da177e4SLinus Torvalds EXPORT_SYMBOL(_dma_cache_inv); 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds #endif /* CONFIG_DMA_NONCOHERENT */ 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds /* 531da177e4SLinus Torvalds * We could optimize the case where the cache argument is not BCACHE but 541da177e4SLinus Torvalds * that seems very atypical use ... 551da177e4SLinus Torvalds */ 56fe00f943SRalf Baechle asmlinkage int sys_cacheflush(unsigned long __user addr, 57fe00f943SRalf Baechle unsigned long bytes, unsigned int cache) 581da177e4SLinus Torvalds { 59fe00f943SRalf Baechle if (!access_ok(VERIFY_WRITE, (void __user *) addr, bytes)) 601da177e4SLinus Torvalds return -EFAULT; 611da177e4SLinus Torvalds 621da177e4SLinus Torvalds flush_icache_range(addr, addr + bytes); 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds return 0; 651da177e4SLinus Torvalds } 661da177e4SLinus Torvalds 671da177e4SLinus Torvalds void __flush_dcache_page(struct page *page) 681da177e4SLinus Torvalds { 691da177e4SLinus Torvalds struct address_space *mapping = page_mapping(page); 701da177e4SLinus Torvalds unsigned long addr; 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds if (mapping && !mapping_mapped(mapping)) { 731da177e4SLinus Torvalds SetPageDcacheDirty(page); 741da177e4SLinus Torvalds return; 751da177e4SLinus Torvalds } 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds /* 781da177e4SLinus Torvalds * We could delay the flush for the !page_mapping case too. But that 791da177e4SLinus Torvalds * case is for exec env/arg pages and those are %99 certainly going to 801da177e4SLinus Torvalds * get faulted into the tlb (and thus flushed) anyways. 811da177e4SLinus Torvalds */ 821da177e4SLinus Torvalds addr = (unsigned long) page_address(page); 831da177e4SLinus Torvalds flush_data_cache_page(addr); 841da177e4SLinus Torvalds } 851da177e4SLinus Torvalds 861da177e4SLinus Torvalds EXPORT_SYMBOL(__flush_dcache_page); 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds void __update_cache(struct vm_area_struct *vma, unsigned long address, 891da177e4SLinus Torvalds pte_t pte) 901da177e4SLinus Torvalds { 911da177e4SLinus Torvalds struct page *page; 921da177e4SLinus Torvalds unsigned long pfn, addr; 931da177e4SLinus Torvalds 941da177e4SLinus Torvalds pfn = pte_pfn(pte); 951da177e4SLinus Torvalds if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page_mapping(page)) && 961da177e4SLinus Torvalds Page_dcache_dirty(page)) { 971da177e4SLinus Torvalds if (pages_do_alias((unsigned long)page_address(page), 981da177e4SLinus Torvalds address & PAGE_MASK)) { 991da177e4SLinus Torvalds addr = (unsigned long) page_address(page); 1001da177e4SLinus Torvalds flush_data_cache_page(addr); 1011da177e4SLinus Torvalds } 1021da177e4SLinus Torvalds 1031da177e4SLinus Torvalds ClearPageDcacheDirty(page); 1041da177e4SLinus Torvalds } 1051da177e4SLinus Torvalds } 1061da177e4SLinus Torvalds 1071da177e4SLinus Torvalds extern void ld_mmu_r23000(void); 1081da177e4SLinus Torvalds extern void ld_mmu_r4xx0(void); 1091da177e4SLinus Torvalds extern void ld_mmu_tx39(void); 1101da177e4SLinus Torvalds extern void ld_mmu_r6000(void); 1111da177e4SLinus Torvalds extern void ld_mmu_tfp(void); 1121da177e4SLinus Torvalds extern void ld_mmu_andes(void); 1131da177e4SLinus Torvalds extern void ld_mmu_sb1(void); 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds void __init cpu_cache_init(void) 1161da177e4SLinus Torvalds { 1171da177e4SLinus Torvalds if (cpu_has_4ktlb) { 1181da177e4SLinus Torvalds #if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \ 1191da177e4SLinus Torvalds defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \ 1201da177e4SLinus Torvalds defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432) || \ 1211da177e4SLinus Torvalds defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_MIPS32) || \ 1221da177e4SLinus Torvalds defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \ 1231da177e4SLinus Torvalds defined(CONFIG_CPU_RM7000) || defined(CONFIG_CPU_RM9000) 1241da177e4SLinus Torvalds ld_mmu_r4xx0(); 1251da177e4SLinus Torvalds #endif 1261da177e4SLinus Torvalds } else switch (current_cpu_data.cputype) { 1271da177e4SLinus Torvalds #ifdef CONFIG_CPU_R3000 1281da177e4SLinus Torvalds case CPU_R2000: 1291da177e4SLinus Torvalds case CPU_R3000: 1301da177e4SLinus Torvalds case CPU_R3000A: 1311da177e4SLinus Torvalds case CPU_R3081E: 1321da177e4SLinus Torvalds ld_mmu_r23000(); 1331da177e4SLinus Torvalds break; 1341da177e4SLinus Torvalds #endif 1351da177e4SLinus Torvalds #ifdef CONFIG_CPU_TX39XX 1361da177e4SLinus Torvalds case CPU_TX3912: 1371da177e4SLinus Torvalds case CPU_TX3922: 1381da177e4SLinus Torvalds case CPU_TX3927: 1391da177e4SLinus Torvalds ld_mmu_tx39(); 1401da177e4SLinus Torvalds break; 1411da177e4SLinus Torvalds #endif 1421da177e4SLinus Torvalds #ifdef CONFIG_CPU_R10000 1431da177e4SLinus Torvalds case CPU_R10000: 1441da177e4SLinus Torvalds case CPU_R12000: 1451da177e4SLinus Torvalds ld_mmu_r4xx0(); 1461da177e4SLinus Torvalds break; 1471da177e4SLinus Torvalds #endif 1481da177e4SLinus Torvalds #ifdef CONFIG_CPU_SB1 1491da177e4SLinus Torvalds case CPU_SB1: 1501da177e4SLinus Torvalds ld_mmu_sb1(); 1511da177e4SLinus Torvalds break; 1521da177e4SLinus Torvalds #endif 1531da177e4SLinus Torvalds 1541da177e4SLinus Torvalds case CPU_R8000: 1551da177e4SLinus Torvalds panic("R8000 is unsupported"); 1561da177e4SLinus Torvalds break; 1571da177e4SLinus Torvalds 1581da177e4SLinus Torvalds default: 1591da177e4SLinus Torvalds panic("Yeee, unsupported cache architecture."); 1601da177e4SLinus Torvalds } 1611da177e4SLinus Torvalds } 162