flush-sh4.c 2.6 KB

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