flush-sh4.c 2.6 KB

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