cpu_ll.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. /*
  8. Note: This is a compatibility header. Call the interfaces in esp_cpu.h instead
  9. */
  10. #include <stdint.h>
  11. #include <stdbool.h>
  12. #include "soc/soc_caps.h"
  13. #include "esp_attr.h"
  14. #include "esp_cpu.h"
  15. #ifdef __cplusplus
  16. extern "C" {
  17. #endif
  18. FORCE_INLINE_ATTR __attribute__((deprecated)) __attribute__((pure)) uint32_t cpu_ll_get_core_id(void)
  19. {
  20. return esp_cpu_get_core_id();
  21. }
  22. FORCE_INLINE_ATTR __attribute__((deprecated)) uint32_t cpu_ll_get_cycle_count(void)
  23. {
  24. return (uint32_t)esp_cpu_get_cycle_count();
  25. }
  26. FORCE_INLINE_ATTR __attribute__((deprecated)) void cpu_ll_set_cycle_count(uint32_t val)
  27. {
  28. esp_cpu_set_cycle_count((esp_cpu_cycle_count_t)val);
  29. }
  30. FORCE_INLINE_ATTR __attribute__((deprecated)) void *cpu_ll_get_sp(void)
  31. {
  32. return esp_cpu_get_sp();
  33. }
  34. FORCE_INLINE_ATTR __attribute__((deprecated)) void cpu_ll_init_hwloop(void)
  35. {
  36. ; // Nothing to do. Contents moved to bootloader directly
  37. }
  38. #if SOC_CPU_BREAKPOINTS_NUM > 0
  39. FORCE_INLINE_ATTR __attribute__((deprecated)) void cpu_ll_set_breakpoint(int id, uint32_t pc)
  40. {
  41. esp_cpu_set_breakpoint(id, (const void *)pc);
  42. }
  43. FORCE_INLINE_ATTR __attribute__((deprecated)) void cpu_ll_clear_breakpoint(int id)
  44. {
  45. esp_cpu_clear_breakpoint(id);
  46. }
  47. #endif // SOC_CPU_BREAKPOINTS_NUM > 0
  48. FORCE_INLINE_ATTR __attribute__((deprecated)) __attribute__((pure)) uint32_t cpu_ll_ptr_to_pc(const void *addr)
  49. {
  50. return ((uint32_t) addr);
  51. }
  52. FORCE_INLINE_ATTR __attribute__((deprecated)) __attribute__((pure)) void *cpu_ll_pc_to_ptr(uint32_t pc)
  53. {
  54. return esp_cpu_pc_to_addr(pc);
  55. }
  56. FORCE_INLINE_ATTR __attribute__((deprecated))
  57. void cpu_ll_set_watchpoint(int id, const void *addr, size_t size, bool on_read, bool on_write)
  58. {
  59. esp_cpu_watchpoint_trigger_t trigger;
  60. if (on_read && on_write) {
  61. trigger = ESP_CPU_WATCHPOINT_ACCESS;
  62. } else if (on_read) {
  63. trigger = ESP_CPU_WATCHPOINT_LOAD;
  64. } else {
  65. trigger = ESP_CPU_WATCHPOINT_STORE;
  66. }
  67. esp_cpu_set_watchpoint(id, addr, size, trigger);
  68. }
  69. FORCE_INLINE_ATTR __attribute__((deprecated)) void cpu_ll_clear_watchpoint(int id)
  70. {
  71. esp_cpu_clear_watchpoint(id);
  72. }
  73. FORCE_INLINE_ATTR __attribute__((deprecated)) bool cpu_ll_is_debugger_attached(void)
  74. {
  75. return esp_cpu_dbgr_is_attached();
  76. }
  77. FORCE_INLINE_ATTR __attribute__((deprecated)) void cpu_ll_break(void)
  78. {
  79. esp_cpu_dbgr_break();
  80. }
  81. FORCE_INLINE_ATTR __attribute__((deprecated)) void cpu_ll_set_vecbase(const void *base)
  82. {
  83. esp_cpu_intr_set_ivt_addr(base);
  84. }
  85. FORCE_INLINE_ATTR __attribute__((deprecated)) void cpu_ll_waiti(void)
  86. {
  87. esp_cpu_wait_for_intr();
  88. }
  89. FORCE_INLINE_ATTR __attribute__((deprecated))
  90. void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
  91. {
  92. #ifdef __clang_analyzer__
  93. //Teach clang-tidy that "addr" and "set" cannot be const as they can both be updated by S32C1I instruction
  94. volatile uint32_t temp;
  95. temp = *addr;
  96. *addr = temp;
  97. temp = *set;
  98. *set = temp;
  99. #endif
  100. #ifdef __XTENSA__
  101. #if XCHAL_HAVE_S32C1I
  102. __asm__ __volatile__ (
  103. "WSR %2, SCOMPARE1 \n"
  104. "S32C1I %0, %1, 0 \n"
  105. :"=r"(*set)
  106. :"r"(addr), "r"(compare), "0"(*set)
  107. );
  108. #else // XCHAL_HAVE_S32C1I
  109. uint32_t old_value;
  110. // No S32C1I, so do this by disabling and re-enabling interrupts (slower)
  111. uint32_t intlevel;
  112. __asm__ __volatile__ ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) "\n"
  113. : "=r"(intlevel));
  114. old_value = *addr;
  115. if (old_value == compare) {
  116. *addr = *set;
  117. }
  118. __asm__ __volatile__ ("memw \n"
  119. "wsr %0, ps\n"
  120. :: "r"(intlevel));
  121. *set = old_value;
  122. #endif // XCHAL_HAVE_S32C1I
  123. #else
  124. uint32_t old_value;
  125. unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
  126. old_value = *addr;
  127. if (old_value == compare) {
  128. *addr = *set;
  129. }
  130. RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
  131. *set = old_value;
  132. #endif
  133. }
  134. #ifdef __cplusplus
  135. }
  136. #endif