flush-sh4.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include <linux/mm.h>
  2. #include <asm/mmu_context.h>
  3. #include <asm/cacheflush.h>
  4. /*
  5. * Write back the dirty D-caches, but not invalidate them.
  6. *
  7. * START: Virtual Address (U0, P1, or P3)
  8. * SIZE: Size of the region.
  9. */
  10. static void sh4__flush_wback_region(void *start, int size)
  11. {
  12. reg_size_t aligned_start, v, cnt, end;
  13. aligned_start = register_align(start);
  14. v = aligned_start & ~(L1_CACHE_BYTES-1);
  15. end = (aligned_start + size + L1_CACHE_BYTES-1)
  16. & ~(L1_CACHE_BYTES-1);
  17. cnt = (end - v) / L1_CACHE_BYTES;
  18. while (cnt >= 8) {
  19. __ocbwb(v); v += L1_CACHE_BYTES;
  20. __ocbwb(v); v += L1_CACHE_BYTES;
  21. __ocbwb(v); v += L1_CACHE_BYTES;
  22. __ocbwb(v); v += L1_CACHE_BYTES;
  23. __ocbwb(v); v += L1_CACHE_BYTES;
  24. __ocbwb(v); v += L1_CACHE_BYTES;
  25. __ocbwb(v); v += L1_CACHE_BYTES;
  26. __ocbwb(v); v += L1_CACHE_BYTES;
  27. cnt -= 8;
  28. }
  29. while (cnt) {
  30. __ocbwb(v); v += L1_CACHE_BYTES;
  31. cnt--;
  32. }
  33. }
  34. /*
  35. * Write back the dirty D-caches and invalidate them.
  36. *
  37. * START: Virtual Address (U0, P1, or P3)
  38. * SIZE: Size of the region.
  39. */
  40. static void sh4__flush_purge_region(void *start, int size)
  41. {
  42. reg_size_t aligned_start, v, cnt, end;
  43. aligned_start = register_align(start);
  44. v = aligned_start & ~(L1_CACHE_BYTES-1);
  45. end = (aligned_start + size + L1_CACHE_BYTES-1)
  46. & ~(L1_CACHE_BYTES-1);
  47. cnt = (end - v) / L1_CACHE_BYTES;
  48. while (cnt >= 8) {
  49. __ocbp(v); v += L1_CACHE_BYTES;
  50. __ocbp(v); v += L1_CACHE_BYTES;
  51. __ocbp(v); v += L1_CACHE_BYTES;
  52. __ocbp(v); v += L1_CACHE_BYTES;
  53. __ocbp(v); v += L1_CACHE_BYTES;
  54. __ocbp(v); v += L1_CACHE_BYTES;
  55. __ocbp(v); v += L1_CACHE_BYTES;
  56. __ocbp(v); v += L1_CACHE_BYTES;
  57. cnt -= 8;
  58. }
  59. while (cnt) {
  60. __ocbp(v); v += L1_CACHE_BYTES;
  61. cnt--;
  62. }
  63. }
  64. /*
  65. * No write back please
  66. */
  67. static void sh4__flush_invalidate_region(void *start, int size)
  68. {
  69. reg_size_t aligned_start, v, cnt, end;
  70. aligned_start = register_align(start);
  71. v = aligned_start & ~(L1_CACHE_BYTES-1);
  72. end = (aligned_start + size + L1_CACHE_BYTES-1)
  73. & ~(L1_CACHE_BYTES-1);
  74. cnt = (end - v) / L1_CACHE_BYTES;
  75. while (cnt >= 8) {
  76. __ocbi(v); v += L1_CACHE_BYTES;
  77. __ocbi(v); v += L1_CACHE_BYTES;
  78. __ocbi(v); v += L1_CACHE_BYTES;
  79. __ocbi(v); v += L1_CACHE_BYTES;
  80. __ocbi(v); v += L1_CACHE_BYTES;
  81. __ocbi(v); v += L1_CACHE_BYTES;
  82. __ocbi(v); v += L1_CACHE_BYTES;
  83. __ocbi(v); v += L1_CACHE_BYTES;
  84. cnt -= 8;
  85. }
  86. while (cnt) {
  87. __ocbi(v); v += L1_CACHE_BYTES;
  88. cnt--;
  89. }
  90. }
  91. void __init sh4__flush_region_init(void)
  92. {
  93. __flush_wback_region = sh4__flush_wback_region;
  94. __flush_invalidate_region = sh4__flush_invalidate_region;
  95. __flush_purge_region = sh4__flush_purge_region;
  96. }