cache.S 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * Blackfin cache control code
  3. *
  4. * Copyright 2003-2008 Analog Devices Inc.
  5. *
  6. * Enter bugs at http://blackfin.uclinux.org/
  7. *
  8. * Licensed under the GPL-2 or later.
  9. */
  10. #include <config.h>
  11. #include <linux/linkage.h>
  12. #include <asm/blackfin.h>
  13. .text
  14. /* Since all L1 caches work the same way, we use the same method for flushing
  15. * them. Only the actual flush instruction differs. We write this in asm as
  16. * GCC can be hard to coax into writing nice hardware loops.
  17. *
  18. * Also, we assume the following register setup:
  19. * R0 = start address
  20. * R1 = end address
  21. */
  22. .macro do_flush flushins:req optflushins optnopins label
  23. R2 = -L1_CACHE_BYTES;
  24. /* start = (start & -L1_CACHE_BYTES) */
  25. R0 = R0 & R2;
  26. /* end = ((end - 1) & -L1_CACHE_BYTES) + L1_CACHE_BYTES; */
  27. R1 += -1;
  28. R1 = R1 & R2;
  29. R1 += L1_CACHE_BYTES;
  30. /* count = (end - start) >> L1_CACHE_SHIFT */
  31. R2 = R1 - R0;
  32. R2 >>= L1_CACHE_SHIFT;
  33. P1 = R2;
  34. .ifnb \label
  35. \label :
  36. .endif
  37. P0 = R0;
  38. LSETUP (1f, 2f) LC1 = P1;
  39. 1:
  40. .ifnb \optflushins
  41. \optflushins [P0];
  42. .endif
  43. #if ANOMALY_05000443
  44. .ifb \optnopins
  45. 2:
  46. .endif
  47. \flushins [P0++];
  48. .ifnb \optnopins
  49. 2: \optnopins;
  50. .endif
  51. #else
  52. 2: \flushins [P0++];
  53. #endif
  54. RTS;
  55. .endm
  56. /* Invalidate all instruction cache lines assocoiated with this memory area */
  57. ENTRY(_blackfin_icache_flush_range)
  58. do_flush IFLUSH, , nop
  59. ENDPROC(_blackfin_icache_flush_range)
  60. /* Flush all cache lines assocoiated with this area of memory. */
  61. ENTRY(_blackfin_icache_dcache_flush_range)
  62. do_flush FLUSH, IFLUSH
  63. ENDPROC(_blackfin_icache_dcache_flush_range)
  64. /* Throw away all D-cached data in specified region without any obligation to
  65. * write them back. Since the Blackfin ISA does not have an "invalidate"
  66. * instruction, we use flush/invalidate. Perhaps as a speed optimization we
  67. * could bang on the DTEST MMRs ...
  68. */
  69. ENTRY(_blackfin_dcache_flush_invalidate_range)
  70. do_flush FLUSHINV
  71. ENDPROC(_blackfin_dcache_flush_invalidate_range)
  72. /* Flush all data cache lines assocoiated with this memory area */
  73. ENTRY(_blackfin_dcache_flush_range)
  74. do_flush FLUSH, , , .Ldfr
  75. ENDPROC(_blackfin_dcache_flush_range)