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