cacheflush.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. */
  4. #ifndef _ASM_POWERPC_CACHEFLUSH_H
  5. #define _ASM_POWERPC_CACHEFLUSH_H
  6. #include <linux/mm.h>
  7. #include <asm/cputable.h>
  8. #include <asm/cpu_has_feature.h>
  9. /*
  10. * This flag is used to indicate that the page pointed to by a pte is clean
  11. * and does not require cleaning before returning it to the user.
  12. */
  13. #define PG_dcache_clean PG_arch_1
  14. #ifdef CONFIG_PPC_BOOK3S_64
  15. /*
  16. * Book3s has no ptesync after setting a pte, so without this ptesync it's
  17. * possible for a kernel virtual mapping access to return a spurious fault
  18. * if it's accessed right after the pte is set. The page fault handler does
  19. * not expect this type of fault. flush_cache_vmap is not exactly the right
  20. * place to put this, but it seems to work well enough.
  21. */
  22. static inline void flush_cache_vmap(unsigned long start, unsigned long end)
  23. {
  24. asm volatile("ptesync" ::: "memory");
  25. }
  26. #define flush_cache_vmap flush_cache_vmap
  27. #endif /* CONFIG_PPC_BOOK3S_64 */
  28. #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
  29. /*
  30. * This is called when a page has been modified by the kernel.
  31. * It just marks the page as not i-cache clean. We do the i-cache
  32. * flush later when the page is given to a user process, if necessary.
  33. */
  34. static inline void flush_dcache_page(struct page *page)
  35. {
  36. if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
  37. return;
  38. /* avoid an atomic op if possible */
  39. if (test_bit(PG_dcache_clean, &page->flags))
  40. clear_bit(PG_dcache_clean, &page->flags);
  41. }
  42. void flush_icache_range(unsigned long start, unsigned long stop);
  43. #define flush_icache_range flush_icache_range
  44. void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
  45. unsigned long addr, int len);
  46. #define flush_icache_user_page flush_icache_user_page
  47. void flush_dcache_icache_page(struct page *page);
  48. /**
  49. * flush_dcache_range(): Write any modified data cache blocks out to memory and
  50. * invalidate them. Does not invalidate the corresponding instruction cache
  51. * blocks.
  52. *
  53. * @start: the start address
  54. * @stop: the stop address (exclusive)
  55. */
  56. static inline void flush_dcache_range(unsigned long start, unsigned long stop)
  57. {
  58. unsigned long shift = l1_dcache_shift();
  59. unsigned long bytes = l1_dcache_bytes();
  60. void *addr = (void *)(start & ~(bytes - 1));
  61. unsigned long size = stop - (unsigned long)addr + (bytes - 1);
  62. unsigned long i;
  63. if (IS_ENABLED(CONFIG_PPC64))
  64. mb(); /* sync */
  65. for (i = 0; i < size >> shift; i++, addr += bytes)
  66. dcbf(addr);
  67. mb(); /* sync */
  68. }
  69. /*
  70. * Write any modified data cache blocks out to memory.
  71. * Does not invalidate the corresponding cache lines (especially for
  72. * any corresponding instruction cache).
  73. */
  74. static inline void clean_dcache_range(unsigned long start, unsigned long stop)
  75. {
  76. unsigned long shift = l1_dcache_shift();
  77. unsigned long bytes = l1_dcache_bytes();
  78. void *addr = (void *)(start & ~(bytes - 1));
  79. unsigned long size = stop - (unsigned long)addr + (bytes - 1);
  80. unsigned long i;
  81. for (i = 0; i < size >> shift; i++, addr += bytes)
  82. dcbst(addr);
  83. mb(); /* sync */
  84. }
  85. /*
  86. * Like above, but invalidate the D-cache. This is used by the 8xx
  87. * to invalidate the cache so the PPC core doesn't get stale data
  88. * from the CPM (no cache snooping here :-).
  89. */
  90. static inline void invalidate_dcache_range(unsigned long start,
  91. unsigned long stop)
  92. {
  93. unsigned long shift = l1_dcache_shift();
  94. unsigned long bytes = l1_dcache_bytes();
  95. void *addr = (void *)(start & ~(bytes - 1));
  96. unsigned long size = stop - (unsigned long)addr + (bytes - 1);
  97. unsigned long i;
  98. for (i = 0; i < size >> shift; i++, addr += bytes)
  99. dcbi(addr);
  100. mb(); /* sync */
  101. }
  102. #ifdef CONFIG_4xx
  103. static inline void flush_instruction_cache(void)
  104. {
  105. iccci((void *)KERNELBASE);
  106. isync();
  107. }
  108. #else
  109. void flush_instruction_cache(void);
  110. #endif
  111. #include <asm-generic/cacheflush.h>
  112. #endif /* _ASM_POWERPC_CACHEFLUSH_H */