cacheflush.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. #include <asm/tlbflush.h>
  14. #define PG_dcache_clean PG_arch_1
  15. void flush_dcache_folio(struct folio *folio)
  16. {
  17. struct address_space *mapping;
  18. if (is_zero_pfn(folio_pfn(folio)))
  19. return;
  20. mapping = folio_flush_mapping(folio);
  21. if (mapping && !folio_mapped(folio))
  22. clear_bit(PG_dcache_clean, &folio->flags);
  23. else {
  24. dcache_wbinv_all();
  25. if (mapping)
  26. icache_inv_all();
  27. set_bit(PG_dcache_clean, &folio->flags);
  28. }
  29. }
  30. EXPORT_SYMBOL(flush_dcache_folio);
  31. void flush_dcache_page(struct page *page)
  32. {
  33. flush_dcache_folio(page_folio(page));
  34. }
  35. EXPORT_SYMBOL(flush_dcache_page);
  36. void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma,
  37. unsigned long addr, pte_t *ptep, unsigned int nr)
  38. {
  39. unsigned long pfn = pte_pfn(*ptep);
  40. struct folio *folio;
  41. flush_tlb_page(vma, addr);
  42. if (!pfn_valid(pfn))
  43. return;
  44. if (is_zero_pfn(pfn))
  45. return;
  46. folio = page_folio(pfn_to_page(pfn));
  47. if (!test_and_set_bit(PG_dcache_clean, &folio->flags))
  48. dcache_wbinv_all();
  49. if (folio_flush_mapping(folio)) {
  50. if (vma->vm_flags & VM_EXEC)
  51. icache_inv_all();
  52. }
  53. }
  54. void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
  55. unsigned long end)
  56. {
  57. dcache_wbinv_all();
  58. if (vma->vm_flags & VM_EXEC)
  59. icache_inv_all();
  60. }