hpm_l1c_drv.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (c) 2021-2022 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include "hpm_l1c_drv.h"
  8. #include <assert.h>
  9. #define ASSERT_ADDR_SIZE(addr, size) do { \
  10. assert(address % HPM_L1C_CACHELINE_SIZE == 0); \
  11. assert(size % HPM_L1C_CACHELINE_SIZE == 0); \
  12. } while (0)
  13. static void l1c_op(uint8_t opcode, uint32_t address, uint32_t size)
  14. {
  15. register uint32_t i;
  16. register uint32_t next_address;
  17. register uint32_t tmp;
  18. register uint32_t csr;
  19. csr = read_clear_csr(CSR_MSTATUS, CSR_MSTATUS_MIE_MASK);
  20. #define CCTL_VERSION (3U << 18)
  21. if ((read_csr(CSR_MMSC_CFG) & CCTL_VERSION)) {
  22. l1c_cctl_address(address);
  23. next_address = address;
  24. while ((next_address < (address + size)) && (next_address >= address)) {
  25. l1c_cctl_cmd(opcode);
  26. next_address = l1c_cctl_get_address();
  27. }
  28. } else {
  29. for (i = 0, tmp = 0; tmp < size; i++) {
  30. l1c_cctl_address_cmd(opcode, address + i * HPM_L1C_CACHELINE_SIZE);
  31. tmp += HPM_L1C_CACHELINE_SIZE;
  32. }
  33. }
  34. write_csr(CSR_MSTATUS, csr);
  35. }
  36. void l1c_dc_enable(void)
  37. {
  38. if (!l1c_dc_is_enabled()) {
  39. clear_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_DC_WAROUND_MASK);
  40. set_csr(CSR_MCACHE_CTL,
  41. #ifdef L1C_DC_WAROUND_VALUE
  42. HPM_MCACHE_CTL_DC_WAROUND(L1C_DC_WAROUND_VALUE) |
  43. #endif
  44. HPM_MCACHE_CTL_DPREF_EN_MASK
  45. | HPM_MCACHE_CTL_DC_EN_MASK);
  46. }
  47. }
  48. void l1c_dc_disable(void)
  49. {
  50. if (l1c_dc_is_enabled()) {
  51. clear_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_DC_EN_MASK);
  52. }
  53. }
  54. void l1c_ic_enable(void)
  55. {
  56. if (!l1c_ic_is_enabled()) {
  57. set_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_IPREF_EN_MASK
  58. | HPM_MCACHE_CTL_CCTL_SUEN_MASK
  59. | HPM_MCACHE_CTL_IC_EN_MASK);
  60. }
  61. }
  62. void l1c_ic_disable(void)
  63. {
  64. if (l1c_ic_is_enabled()) {
  65. clear_csr(CSR_MCACHE_CTL, HPM_MCACHE_CTL_IC_EN_MASK);
  66. }
  67. }
  68. void l1c_fence_i(void)
  69. {
  70. __asm("fence.i");
  71. }
  72. void l1c_dc_invalidate_all(void)
  73. {
  74. l1c_cctl_cmd(HPM_L1C_CCTL_CMD_L1D_INVAL_ALL);
  75. }
  76. void l1c_dc_writeback_all(void)
  77. {
  78. l1c_cctl_cmd(HPM_L1C_CCTL_CMD_L1D_WB_ALL);
  79. }
  80. void l1c_dc_flush_all(void)
  81. {
  82. l1c_cctl_cmd(HPM_L1C_CCTL_CMD_L1D_WBINVAL_ALL);
  83. }
  84. void l1c_dc_fill_lock(uint32_t address, uint32_t size)
  85. {
  86. ASSERT_ADDR_SIZE(address, size);
  87. l1c_op(HPM_L1C_CCTL_CMD_L1D_VA_LOCK, address, size);
  88. }
  89. void l1c_dc_invalidate(uint32_t address, uint32_t size)
  90. {
  91. ASSERT_ADDR_SIZE(address, size);
  92. l1c_op(HPM_L1C_CCTL_CMD_L1D_VA_INVAL, address, size);
  93. }
  94. void l1c_dc_writeback(uint32_t address, uint32_t size)
  95. {
  96. ASSERT_ADDR_SIZE(address, size);
  97. l1c_op(HPM_L1C_CCTL_CMD_L1D_VA_WB, address, size);
  98. }
  99. void l1c_dc_flush(uint32_t address, uint32_t size)
  100. {
  101. ASSERT_ADDR_SIZE(address, size);
  102. l1c_op(HPM_L1C_CCTL_CMD_L1D_VA_WBINVAL, address, size);
  103. }
  104. void l1c_ic_invalidate(uint32_t address, uint32_t size)
  105. {
  106. ASSERT_ADDR_SIZE(address, size);
  107. l1c_op(HPM_L1C_CCTL_CMD_L1I_VA_INVAL, address, size);
  108. }
  109. void l1c_ic_fill_lock(uint32_t address, uint32_t size)
  110. {
  111. ASSERT_ADDR_SIZE(address, size);
  112. l1c_op(HPM_L1C_CCTL_CMD_L1I_VA_LOCK, address, size);
  113. }