cacheflush.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
  3. #include <linux/kernel.h>
  4. #include <linux/mm.h>
  5. #include <linux/fs.h>
  6. #include <linux/pagemap.h>
  7. #include <linux/syscalls.h>
  8. #include <linux/spinlock.h>
  9. #include <asm/page.h>
  10. #include <asm/cache.h>
  11. #include <asm/cacheflush.h>
  12. #include <asm/cachectl.h>
  13. #define PG_dcache_clean PG_arch_1
  14. void flush_dcache_page(struct page *page)
  15. {
  16. struct address_space *mapping;
  17. if (page == ZERO_PAGE(0))
  18. return;
  19. mapping = page_mapping_file(page);
  20. if (mapping && !page_mapcount(page))
  21. clear_bit(PG_dcache_clean, &page->flags);
  22. else {
  23. dcache_wbinv_all();
  24. if (mapping)
  25. icache_inv_all();
  26. set_bit(PG_dcache_clean, &page->flags);
  27. }
  28. }
  29. EXPORT_SYMBOL(flush_dcache_page);
  30. void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
  31. pte_t *ptep)
  32. {
  33. unsigned long pfn = pte_pfn(*ptep);
  34. struct page *page;
  35. if (!pfn_valid(pfn))
  36. return;
  37. page = pfn_to_page(pfn);
  38. if (page == ZERO_PAGE(0))
  39. return;
  40. if (!test_and_set_bit(PG_dcache_clean, &page->flags))
  41. dcache_wbinv_all();
  42. if (page_mapping_file(page)) {
  43. if (vma->vm_flags & VM_EXEC)
  44. icache_inv_all();
  45. }
  46. }
  47. void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
  48. unsigned long end)
  49. {
  50. dcache_wbinv_all();
  51. if (vma->vm_flags & VM_EXEC)
  52. icache_inv_all();
  53. }