cache.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-03-29 quanzhao the first version
  9. */
  10. #include <rthw.h>
  11. #include <rtdef.h>
  12. rt_inline rt_uint32_t rt_cpu_icache_line_size(void)
  13. {
  14. rt_uint32_t ctr;
  15. asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r"(ctr));
  16. return 4 << (ctr & 0xF);
  17. }
  18. rt_inline rt_uint32_t rt_cpu_dcache_line_size(void)
  19. {
  20. rt_uint32_t ctr;
  21. asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r"(ctr));
  22. return 4 << ((ctr >> 16) & 0xF);
  23. }
  24. void rt_hw_cpu_icache_invalidate(void *addr, int size)
  25. {
  26. rt_uint32_t line_size = rt_cpu_icache_line_size();
  27. rt_uint32_t start_addr = (rt_uint32_t)addr;
  28. rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1;
  29. start_addr &= ~(line_size-1);
  30. end_addr &= ~(line_size-1);
  31. while (start_addr < end_addr)
  32. {
  33. asm volatile ("mcr p15, 0, %0, c7, c5, 1" :: "r"(start_addr)); /* icimvau */
  34. start_addr += line_size;
  35. }
  36. }
  37. void rt_hw_cpu_dcache_invalidate(void *addr, int size)
  38. {
  39. rt_uint32_t line_size = rt_cpu_dcache_line_size();
  40. rt_uint32_t start_addr = (rt_uint32_t)addr;
  41. rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1;
  42. start_addr &= ~(line_size-1);
  43. end_addr &= ~(line_size-1);
  44. while (start_addr < end_addr)
  45. {
  46. asm volatile ("mcr p15, 0, %0, c7, c6, 1" :: "r"(start_addr)); /* dcimvac */
  47. start_addr += line_size;
  48. }
  49. }
  50. void rt_hw_cpu_dcache_clean(void *addr, int size)
  51. {
  52. rt_uint32_t line_size = rt_cpu_dcache_line_size();
  53. rt_uint32_t start_addr = (rt_uint32_t)addr;
  54. rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1;
  55. start_addr &= ~(line_size-1);
  56. end_addr &= ~(line_size-1);
  57. while (start_addr < end_addr)
  58. {
  59. asm volatile ("mcr p15, 0, %0, c7, c10, 1" :: "r"(start_addr)); /* dccmvac */
  60. start_addr += line_size;
  61. }
  62. }
  63. void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
  64. {
  65. if (ops == RT_HW_CACHE_INVALIDATE)
  66. rt_hw_cpu_icache_invalidate(addr, size);
  67. }
  68. void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
  69. {
  70. if (ops == RT_HW_CACHE_FLUSH)
  71. rt_hw_cpu_dcache_clean(addr, size);
  72. else if (ops == RT_HW_CACHE_INVALIDATE)
  73. rt_hw_cpu_dcache_invalidate(addr, size);
  74. }
  75. rt_base_t rt_hw_cpu_icache_status(void)
  76. {
  77. return 0;
  78. }
  79. rt_base_t rt_hw_cpu_dcache_status(void)
  80. {
  81. return 0;
  82. }