11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt * arch/sh/mm/cache.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999, 2000, 2002 Niibe Yutaka 5a6198a238baceae9d4e0ce3915f6d239c89b5c08Paul Mundt * Copyright (C) 2002 - 2010 Paul Mundt 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Released under the terms of the GNU GPL v2.0. 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 10acca4f4d9bd657e8bc7e1665ba5077465138f133Paul Mundt#include <linux/init.h> 1152e27782e1c4afa1feca0fdf194d279595e0431cPaul Mundt#include <linux/mutex.h> 12e06c4e5775b1efc4e476f2430439e45867775f5fPaul Mundt#include <linux/fs.h> 13f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt#include <linux/smp.h> 147747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundt#include <linux/highmem.h> 157747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundt#include <linux/module.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mmu_context.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/cacheflush.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid (*local_flush_cache_all)(void *args) = cache_noop; 20f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid (*local_flush_cache_mm)(void *args) = cache_noop; 21f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid (*local_flush_cache_dup_mm)(void *args) = cache_noop; 22f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid (*local_flush_cache_page)(void *args) = cache_noop; 23f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid (*local_flush_cache_range)(void *args) = cache_noop; 24f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid (*local_flush_dcache_page)(void *args) = cache_noop; 25f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid (*local_flush_icache_range)(void *args) = cache_noop; 26f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid (*local_flush_icache_page)(void *args) = cache_noop; 27f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid (*local_flush_cache_sigtramp)(void *args) = cache_noop; 28f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 2937443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundtvoid (*__flush_wback_region)(void *start, int size); 300a993b0a290a2672500000b0ce811efc093f8467Paul MundtEXPORT_SYMBOL(__flush_wback_region); 3137443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundtvoid (*__flush_purge_region)(void *start, int size); 320a993b0a290a2672500000b0ce811efc093f8467Paul MundtEXPORT_SYMBOL(__flush_purge_region); 3337443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundtvoid (*__flush_invalidate_region)(void *start, int size); 340a993b0a290a2672500000b0ce811efc093f8467Paul MundtEXPORT_SYMBOL(__flush_invalidate_region); 3537443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundt 3637443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundtstatic inline void noop__flush_region(void *start, int size) 3737443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundt{ 3837443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundt} 3937443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundt 406f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundtstatic inline void cacheop_on_each_cpu(void (*func) (void *info), void *info, 416f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt int wait) 426f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt{ 436f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt preempt_disable(); 44a6198a238baceae9d4e0ce3915f6d239c89b5c08Paul Mundt 45a6198a238baceae9d4e0ce3915f6d239c89b5c08Paul Mundt /* 46a6198a238baceae9d4e0ce3915f6d239c89b5c08Paul Mundt * It's possible that this gets called early on when IRQs are 47a6198a238baceae9d4e0ce3915f6d239c89b5c08Paul Mundt * still disabled due to ioremapping by the boot CPU, so don't 48a6198a238baceae9d4e0ce3915f6d239c89b5c08Paul Mundt * even attempt IPIs unless there are other CPUs online. 49a6198a238baceae9d4e0ce3915f6d239c89b5c08Paul Mundt */ 50a6198a238baceae9d4e0ce3915f6d239c89b5c08Paul Mundt if (num_online_cpus() > 1) 51a6198a238baceae9d4e0ce3915f6d239c89b5c08Paul Mundt smp_call_function(func, info, wait); 52a6198a238baceae9d4e0ce3915f6d239c89b5c08Paul Mundt 536f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt func(info); 54a6198a238baceae9d4e0ce3915f6d239c89b5c08Paul Mundt 556f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt preempt_enable(); 566f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt} 576f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt 58ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundtvoid copy_to_user_page(struct vm_area_struct *vma, struct page *page, 59ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundt unsigned long vaddr, void *dst, const void *src, 60ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundt unsigned long len) 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 620dfae7d5a21901b28ec0452d71be64adf5ea323ePaul Mundt if (boot_cpu_data.dcache.n_aliases && page_mapped(page) && 6355661fc1f105ed75852e937bf8ea408270eb0ccaPaul Mundt test_bit(PG_dcache_clean, &page->flags)) { 642277ab4a1df50e05bc732fe9488d4e902bb8399aPaul Mundt void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); 652277ab4a1df50e05bc732fe9488d4e902bb8399aPaul Mundt memcpy(vto, src, len); 660906a3ad33a254094fb74828e3ddb9af8771a6daPaul Mundt kunmap_coherent(vto); 672277ab4a1df50e05bc732fe9488d4e902bb8399aPaul Mundt } else { 682277ab4a1df50e05bc732fe9488d4e902bb8399aPaul Mundt memcpy(dst, src, len); 690dfae7d5a21901b28ec0452d71be64adf5ea323ePaul Mundt if (boot_cpu_data.dcache.n_aliases) 7055661fc1f105ed75852e937bf8ea408270eb0ccaPaul Mundt clear_bit(PG_dcache_clean, &page->flags); 712277ab4a1df50e05bc732fe9488d4e902bb8399aPaul Mundt } 72ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundt 73ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundt if (vma->vm_flags & VM_EXEC) 74ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundt flush_cache_page(vma, vaddr, page_to_pfn(page)); 75ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundt} 76ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundt 77ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundtvoid copy_from_user_page(struct vm_area_struct *vma, struct page *page, 78ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundt unsigned long vaddr, void *dst, const void *src, 79ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundt unsigned long len) 80ba1789efea81acc6633f427bfeb871fd608965b5Paul Mundt{ 810dfae7d5a21901b28ec0452d71be64adf5ea323ePaul Mundt if (boot_cpu_data.dcache.n_aliases && page_mapped(page) && 8255661fc1f105ed75852e937bf8ea408270eb0ccaPaul Mundt test_bit(PG_dcache_clean, &page->flags)) { 832277ab4a1df50e05bc732fe9488d4e902bb8399aPaul Mundt void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); 842277ab4a1df50e05bc732fe9488d4e902bb8399aPaul Mundt memcpy(dst, vfrom, len); 850906a3ad33a254094fb74828e3ddb9af8771a6daPaul Mundt kunmap_coherent(vfrom); 862277ab4a1df50e05bc732fe9488d4e902bb8399aPaul Mundt } else { 872277ab4a1df50e05bc732fe9488d4e902bb8399aPaul Mundt memcpy(dst, src, len); 880dfae7d5a21901b28ec0452d71be64adf5ea323ePaul Mundt if (boot_cpu_data.dcache.n_aliases) 8955661fc1f105ed75852e937bf8ea408270eb0ccaPaul Mundt clear_bit(PG_dcache_clean, &page->flags); 902277ab4a1df50e05bc732fe9488d4e902bb8399aPaul Mundt } 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9239e688a94b94eaba768b1494e19e96f828fc2688Paul Mundt 937747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundtvoid copy_user_highpage(struct page *to, struct page *from, 947747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundt unsigned long vaddr, struct vm_area_struct *vma) 957747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundt{ 967747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundt void *vfrom, *vto; 977747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundt 98bc3e11be88010e09692ed1d214407d56caa90075Cong Wang vto = kmap_atomic(to); 997747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundt 1000dfae7d5a21901b28ec0452d71be64adf5ea323ePaul Mundt if (boot_cpu_data.dcache.n_aliases && page_mapped(from) && 10155661fc1f105ed75852e937bf8ea408270eb0ccaPaul Mundt test_bit(PG_dcache_clean, &from->flags)) { 1027e01c949989b984c074469e04ab99c47367c7187Paul Mundt vfrom = kmap_coherent(from, vaddr); 1032277ab4a1df50e05bc732fe9488d4e902bb8399aPaul Mundt copy_page(vto, vfrom); 1047e01c949989b984c074469e04ab99c47367c7187Paul Mundt kunmap_coherent(vfrom); 1057e01c949989b984c074469e04ab99c47367c7187Paul Mundt } else { 106bc3e11be88010e09692ed1d214407d56caa90075Cong Wang vfrom = kmap_atomic(from); 1077e01c949989b984c074469e04ab99c47367c7187Paul Mundt copy_page(vto, vfrom); 108bc3e11be88010e09692ed1d214407d56caa90075Cong Wang kunmap_atomic(vfrom); 1097e01c949989b984c074469e04ab99c47367c7187Paul Mundt } 1107747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundt 111a25bbe12224e649fe12cba7a2fa920180a35c8a9Stuart Menefy if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK) || 112a25bbe12224e649fe12cba7a2fa920180a35c8a9Stuart Menefy (vma->vm_flags & VM_EXEC)) 1137e01c949989b984c074469e04ab99c47367c7187Paul Mundt __flush_purge_region(vto, PAGE_SIZE); 11439ac11c1607f1d566e7cf885acd403fa4f07f8a2Stuart Menefy 115bc3e11be88010e09692ed1d214407d56caa90075Cong Wang kunmap_atomic(vto); 1167747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundt /* Make sure this page is cleared on other CPU's too before using it */ 1177747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundt smp_wmb(); 1187747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul Mundt} 1197747b9a493a197cb4db44c98d25ce6d3d9f586d1Paul MundtEXPORT_SYMBOL(copy_user_highpage); 120dfff0fa65ab15db45acd64b3189787d37ab163cdPaul Mundt 121dfff0fa65ab15db45acd64b3189787d37ab163cdPaul Mundtvoid clear_user_highpage(struct page *page, unsigned long vaddr) 122dfff0fa65ab15db45acd64b3189787d37ab163cdPaul Mundt{ 123bc3e11be88010e09692ed1d214407d56caa90075Cong Wang void *kaddr = kmap_atomic(page); 124dfff0fa65ab15db45acd64b3189787d37ab163cdPaul Mundt 1257e01c949989b984c074469e04ab99c47367c7187Paul Mundt clear_page(kaddr); 126dfff0fa65ab15db45acd64b3189787d37ab163cdPaul Mundt 1277e01c949989b984c074469e04ab99c47367c7187Paul Mundt if (pages_do_alias((unsigned long)kaddr, vaddr & PAGE_MASK)) 1287e01c949989b984c074469e04ab99c47367c7187Paul Mundt __flush_purge_region(kaddr, PAGE_SIZE); 129dfff0fa65ab15db45acd64b3189787d37ab163cdPaul Mundt 130bc3e11be88010e09692ed1d214407d56caa90075Cong Wang kunmap_atomic(kaddr); 131dfff0fa65ab15db45acd64b3189787d37ab163cdPaul Mundt} 132dfff0fa65ab15db45acd64b3189787d37ab163cdPaul MundtEXPORT_SYMBOL(clear_user_highpage); 1339cef7492696a416663b4edb953a4eade8517ebebPaul Mundt 1349cef7492696a416663b4edb953a4eade8517ebebPaul Mundtvoid __update_cache(struct vm_area_struct *vma, 1359cef7492696a416663b4edb953a4eade8517ebebPaul Mundt unsigned long address, pte_t pte) 1369cef7492696a416663b4edb953a4eade8517ebebPaul Mundt{ 1379cef7492696a416663b4edb953a4eade8517ebebPaul Mundt struct page *page; 1389cef7492696a416663b4edb953a4eade8517ebebPaul Mundt unsigned long pfn = pte_pfn(pte); 1399cef7492696a416663b4edb953a4eade8517ebebPaul Mundt 1409cef7492696a416663b4edb953a4eade8517ebebPaul Mundt if (!boot_cpu_data.dcache.n_aliases) 1419cef7492696a416663b4edb953a4eade8517ebebPaul Mundt return; 1429cef7492696a416663b4edb953a4eade8517ebebPaul Mundt 1439cef7492696a416663b4edb953a4eade8517ebebPaul Mundt page = pfn_to_page(pfn); 144964f7e5a56814b32c727821de77d22bd7ef782bcPaul Mundt if (pfn_valid(pfn)) { 14555661fc1f105ed75852e937bf8ea408270eb0ccaPaul Mundt int dirty = !test_and_set_bit(PG_dcache_clean, &page->flags); 14676382b5bdb77c29ab430e1b82ef1c604c8dd113bMarkus Pietrek if (dirty) 14776382b5bdb77c29ab430e1b82ef1c604c8dd113bMarkus Pietrek __flush_purge_region(page_address(page), PAGE_SIZE); 1489cef7492696a416663b4edb953a4eade8517ebebPaul Mundt } 1499cef7492696a416663b4edb953a4eade8517ebebPaul Mundt} 150c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt 151c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundtvoid __flush_anon_page(struct page *page, unsigned long vmaddr) 152c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt{ 153c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt unsigned long addr = (unsigned long) page_address(page); 154c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt 155c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt if (pages_do_alias(addr, vmaddr)) { 156c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt if (boot_cpu_data.dcache.n_aliases && page_mapped(page) && 15755661fc1f105ed75852e937bf8ea408270eb0ccaPaul Mundt test_bit(PG_dcache_clean, &page->flags)) { 158c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt void *kaddr; 159c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt 160c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt kaddr = kmap_coherent(page, vmaddr); 1616e4154d4c2dd3d7e61d19ddd2527322ce34c2f5aPaul Mundt /* XXX.. For now kunmap_coherent() does a purge */ 1626e4154d4c2dd3d7e61d19ddd2527322ce34c2f5aPaul Mundt /* __flush_purge_region((void *)kaddr, PAGE_SIZE); */ 1630906a3ad33a254094fb74828e3ddb9af8771a6daPaul Mundt kunmap_coherent(kaddr); 164c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt } else 1656e4154d4c2dd3d7e61d19ddd2527322ce34c2f5aPaul Mundt __flush_purge_region((void *)addr, PAGE_SIZE); 166c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt } 167c0fe478dbb14fd32e71d1383dbe302b54ce94134Paul Mundt} 168ecba1060583635ab55092072441ff903b5e9a659Paul Mundt 169f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid flush_cache_all(void) 170f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt{ 1716f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt cacheop_on_each_cpu(local_flush_cache_all, NULL, 1); 172f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt} 1730a993b0a290a2672500000b0ce811efc093f8467Paul MundtEXPORT_SYMBOL(flush_cache_all); 174f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 175f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid flush_cache_mm(struct mm_struct *mm) 176f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt{ 177654d364e26c797e8a5f9e2a1393607e6ca0106ebPaul Mundt if (boot_cpu_data.dcache.n_aliases == 0) 178654d364e26c797e8a5f9e2a1393607e6ca0106ebPaul Mundt return; 179654d364e26c797e8a5f9e2a1393607e6ca0106ebPaul Mundt 1806f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt cacheop_on_each_cpu(local_flush_cache_mm, mm, 1); 181f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt} 182f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 183f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid flush_cache_dup_mm(struct mm_struct *mm) 184f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt{ 185654d364e26c797e8a5f9e2a1393607e6ca0106ebPaul Mundt if (boot_cpu_data.dcache.n_aliases == 0) 186654d364e26c797e8a5f9e2a1393607e6ca0106ebPaul Mundt return; 187654d364e26c797e8a5f9e2a1393607e6ca0106ebPaul Mundt 1886f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt cacheop_on_each_cpu(local_flush_cache_dup_mm, mm, 1); 189f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt} 190f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 191f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid flush_cache_page(struct vm_area_struct *vma, unsigned long addr, 192f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt unsigned long pfn) 193f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt{ 194f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt struct flusher_data data; 195f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 196f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt data.vma = vma; 197f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt data.addr1 = addr; 198f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt data.addr2 = pfn; 199f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 2006f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt cacheop_on_each_cpu(local_flush_cache_page, (void *)&data, 1); 201f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt} 202f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 203f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid flush_cache_range(struct vm_area_struct *vma, unsigned long start, 204f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt unsigned long end) 205f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt{ 206f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt struct flusher_data data; 207f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 208f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt data.vma = vma; 209f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt data.addr1 = start; 210f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt data.addr2 = end; 211f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 2126f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt cacheop_on_each_cpu(local_flush_cache_range, (void *)&data, 1); 213f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt} 2140a993b0a290a2672500000b0ce811efc093f8467Paul MundtEXPORT_SYMBOL(flush_cache_range); 215f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 216f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid flush_dcache_page(struct page *page) 217f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt{ 2186f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt cacheop_on_each_cpu(local_flush_dcache_page, page, 1); 219f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt} 2200a993b0a290a2672500000b0ce811efc093f8467Paul MundtEXPORT_SYMBOL(flush_dcache_page); 221f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 222f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid flush_icache_range(unsigned long start, unsigned long end) 223f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt{ 224f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt struct flusher_data data; 225f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 226f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt data.vma = NULL; 227f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt data.addr1 = start; 228f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt data.addr2 = end; 229f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 2306f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt cacheop_on_each_cpu(local_flush_icache_range, (void *)&data, 1); 231f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt} 232e3560305192cd51b3c07206c85eb4231594dd58bPranith KumarEXPORT_SYMBOL(flush_icache_range); 233f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 234f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid flush_icache_page(struct vm_area_struct *vma, struct page *page) 235f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt{ 236f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt /* Nothing uses the VMA, so just pass the struct page along */ 2376f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt cacheop_on_each_cpu(local_flush_icache_page, page, 1); 238f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt} 239f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 240f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundtvoid flush_cache_sigtramp(unsigned long address) 241f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt{ 2426f3795788b030c3c190fa063adfe519e016cc6fdPaul Mundt cacheop_on_each_cpu(local_flush_cache_sigtramp, (void *)address, 1); 243f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt} 244f26b2a562b46ab186c8383993ab1332673ac4a47Paul Mundt 24527d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundtstatic void compute_alias(struct cache_info *c) 24627d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt{ 24727d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1); 24827d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt c->n_aliases = c->alias_mask ? (c->alias_mask >> PAGE_SHIFT) + 1 : 0; 24927d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt} 25027d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt 25127d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundtstatic void __init emit_cache_params(void) 25227d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt{ 25327d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt printk(KERN_NOTICE "I-cache : n_ways=%d n_sets=%d way_incr=%d\n", 25427d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.icache.ways, 25527d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.icache.sets, 25627d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.icache.way_incr); 25727d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt printk(KERN_NOTICE "I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", 25827d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.icache.entry_mask, 25927d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.icache.alias_mask, 26027d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.icache.n_aliases); 26127d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt printk(KERN_NOTICE "D-cache : n_ways=%d n_sets=%d way_incr=%d\n", 26227d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.dcache.ways, 26327d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.dcache.sets, 26427d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.dcache.way_incr); 26527d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt printk(KERN_NOTICE "D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", 26627d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.dcache.entry_mask, 26727d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.dcache.alias_mask, 26827d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.dcache.n_aliases); 26927d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt 27027d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt /* 27127d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt * Emit Secondary Cache parameters if the CPU has a probed L2. 27227d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt */ 27327d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) { 27427d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt printk(KERN_NOTICE "S-cache : n_ways=%d n_sets=%d way_incr=%d\n", 27527d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.scache.ways, 27627d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.scache.sets, 27727d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.scache.way_incr); 27827d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt printk(KERN_NOTICE "S-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", 27927d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.scache.entry_mask, 28027d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.scache.alias_mask, 28127d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt boot_cpu_data.scache.n_aliases); 28227d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt } 28327d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt} 28427d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt 285ecba1060583635ab55092072441ff903b5e9a659Paul Mundtvoid __init cpu_cache_init(void) 286ecba1060583635ab55092072441ff903b5e9a659Paul Mundt{ 2873af539e59cf3213cbe31ce7008f1db51c52665caPaul Mundt unsigned int cache_disabled = 0; 2883af539e59cf3213cbe31ce7008f1db51c52665caPaul Mundt 289a5f6ea29f9a918403629f8369ae55fac6b09cb53Geert Uytterhoeven#ifdef SH_CCR 290a5f6ea29f9a918403629f8369ae55fac6b09cb53Geert Uytterhoeven cache_disabled = !(__raw_readl(SH_CCR) & CCR_CACHE_ENABLE); 2913af539e59cf3213cbe31ce7008f1db51c52665caPaul Mundt#endif 2925fb80ae8bd7549034845ebfba694d483070b768bMagnus Damm 29327d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt compute_alias(&boot_cpu_data.icache); 29427d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt compute_alias(&boot_cpu_data.dcache); 29527d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt compute_alias(&boot_cpu_data.scache); 29627d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt 29737443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundt __flush_wback_region = noop__flush_region; 29837443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundt __flush_purge_region = noop__flush_region; 29937443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundt __flush_invalidate_region = noop__flush_region; 30037443ef3f0406e855e169c87ae3f4ffb4b6ff635Paul Mundt 3015fb80ae8bd7549034845ebfba694d483070b768bMagnus Damm /* 3025fb80ae8bd7549034845ebfba694d483070b768bMagnus Damm * No flushing is necessary in the disabled cache case so we can 3035fb80ae8bd7549034845ebfba694d483070b768bMagnus Damm * just keep the noop functions in local_flush_..() and __flush_..() 3045fb80ae8bd7549034845ebfba694d483070b768bMagnus Damm */ 3055fb80ae8bd7549034845ebfba694d483070b768bMagnus Damm if (unlikely(cache_disabled)) 3065fb80ae8bd7549034845ebfba694d483070b768bMagnus Damm goto skip; 3075fb80ae8bd7549034845ebfba694d483070b768bMagnus Damm 308109b44a82a7a8ae32d7fb257480f92f2d96f0dafPaul Mundt if (boot_cpu_data.family == CPU_FAMILY_SH2) { 309109b44a82a7a8ae32d7fb257480f92f2d96f0dafPaul Mundt extern void __weak sh2_cache_init(void); 310109b44a82a7a8ae32d7fb257480f92f2d96f0dafPaul Mundt 311109b44a82a7a8ae32d7fb257480f92f2d96f0dafPaul Mundt sh2_cache_init(); 312109b44a82a7a8ae32d7fb257480f92f2d96f0dafPaul Mundt } 313109b44a82a7a8ae32d7fb257480f92f2d96f0dafPaul Mundt 314a58e1a2ab4f6334c50dfbda83d3a5c6e0b2b4beePaul Mundt if (boot_cpu_data.family == CPU_FAMILY_SH2A) { 315a58e1a2ab4f6334c50dfbda83d3a5c6e0b2b4beePaul Mundt extern void __weak sh2a_cache_init(void); 316a58e1a2ab4f6334c50dfbda83d3a5c6e0b2b4beePaul Mundt 317a58e1a2ab4f6334c50dfbda83d3a5c6e0b2b4beePaul Mundt sh2a_cache_init(); 318a58e1a2ab4f6334c50dfbda83d3a5c6e0b2b4beePaul Mundt } 319a58e1a2ab4f6334c50dfbda83d3a5c6e0b2b4beePaul Mundt 32079f1c9da5e5fc5f4705836d8c1cee2213fc80640Paul Mundt if (boot_cpu_data.family == CPU_FAMILY_SH3) { 32179f1c9da5e5fc5f4705836d8c1cee2213fc80640Paul Mundt extern void __weak sh3_cache_init(void); 32279f1c9da5e5fc5f4705836d8c1cee2213fc80640Paul Mundt 32379f1c9da5e5fc5f4705836d8c1cee2213fc80640Paul Mundt sh3_cache_init(); 3240d051d90bb08b516b9d6c30d25f83d3c6b5b1c1dPaul Mundt 3250d051d90bb08b516b9d6c30d25f83d3c6b5b1c1dPaul Mundt if ((boot_cpu_data.type == CPU_SH7705) && 3260d051d90bb08b516b9d6c30d25f83d3c6b5b1c1dPaul Mundt (boot_cpu_data.dcache.sets == 512)) { 3270d051d90bb08b516b9d6c30d25f83d3c6b5b1c1dPaul Mundt extern void __weak sh7705_cache_init(void); 3280d051d90bb08b516b9d6c30d25f83d3c6b5b1c1dPaul Mundt 3290d051d90bb08b516b9d6c30d25f83d3c6b5b1c1dPaul Mundt sh7705_cache_init(); 3300d051d90bb08b516b9d6c30d25f83d3c6b5b1c1dPaul Mundt } 33179f1c9da5e5fc5f4705836d8c1cee2213fc80640Paul Mundt } 33279f1c9da5e5fc5f4705836d8c1cee2213fc80640Paul Mundt 333ecba1060583635ab55092072441ff903b5e9a659Paul Mundt if ((boot_cpu_data.family == CPU_FAMILY_SH4) || 334ecba1060583635ab55092072441ff903b5e9a659Paul Mundt (boot_cpu_data.family == CPU_FAMILY_SH4A) || 335ecba1060583635ab55092072441ff903b5e9a659Paul Mundt (boot_cpu_data.family == CPU_FAMILY_SH4AL_DSP)) { 336ecba1060583635ab55092072441ff903b5e9a659Paul Mundt extern void __weak sh4_cache_init(void); 337ecba1060583635ab55092072441ff903b5e9a659Paul Mundt 338ecba1060583635ab55092072441ff903b5e9a659Paul Mundt sh4_cache_init(); 3393cf6fa1e334a3a4af702f92229690195018b747fPaul Mundt 3403cf6fa1e334a3a4af702f92229690195018b747fPaul Mundt if ((boot_cpu_data.type == CPU_SH7786) || 3413cf6fa1e334a3a4af702f92229690195018b747fPaul Mundt (boot_cpu_data.type == CPU_SHX3)) { 3423cf6fa1e334a3a4af702f92229690195018b747fPaul Mundt extern void __weak shx3_cache_init(void); 3433cf6fa1e334a3a4af702f92229690195018b747fPaul Mundt 3443cf6fa1e334a3a4af702f92229690195018b747fPaul Mundt shx3_cache_init(); 3453cf6fa1e334a3a4af702f92229690195018b747fPaul Mundt } 346ecba1060583635ab55092072441ff903b5e9a659Paul Mundt } 34727d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt 3482b4315185a06414c4ab40fb0db50dce1b534a1d9Paul Mundt if (boot_cpu_data.family == CPU_FAMILY_SH5) { 3492b4315185a06414c4ab40fb0db50dce1b534a1d9Paul Mundt extern void __weak sh5_cache_init(void); 3502b4315185a06414c4ab40fb0db50dce1b534a1d9Paul Mundt 3512b4315185a06414c4ab40fb0db50dce1b534a1d9Paul Mundt sh5_cache_init(); 3522b4315185a06414c4ab40fb0db50dce1b534a1d9Paul Mundt } 3532b4315185a06414c4ab40fb0db50dce1b534a1d9Paul Mundt 3545fb80ae8bd7549034845ebfba694d483070b768bMagnus Dammskip: 35527d59ec1709817a90aa3ab7169f60994a89ad2f5Paul Mundt emit_cache_params(); 356ecba1060583635ab55092072441ff903b5e9a659Paul Mundt} 357