1 /*
2  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include "sdkconfig.h"
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
15 #ifdef CONFIG_ESP_IPC_ISR_ENABLE
16 
17 /**
18  * @brief IPC ISR Callback
19  *
20  * A callback of this type should be provided as an argument when calling esp_ipc_isr_asm_call() or
21  * esp_ipc_isr_asm_call_blocking().
22  */
23 typedef void (*esp_ipc_isr_func_t)(void* arg);
24 
25 /**
26  * @brief Execute an assembly callback on the other CPU
27  *
28  * Execute a given callback on the other CPU in the context of a High Priority Interrupt.
29  *
30  * - This function will busy-wait in a critical section until the other CPU has started execution of the callback
31  * - The callback must be written in assembly, is invoked using a CALLX0 instruction, and has a2, a3, a4 as scratch
32  *   registers. See docs for more details
33  *
34  * @note This function is not available in single-core mode.
35  *
36  * @param[in]   func    Pointer to a function of type void func(void* arg) to be executed
37  * @param[in]   arg     Arbitrary argument of type void* to be passed into the function
38  */
39 void esp_ipc_isr_asm_call(esp_ipc_isr_func_t func, void* arg);
40 
41 /**
42  * @brief Execute an assembly callback on the other CPU and busy-wait until it completes
43  *
44  * This function is identical to esp_ipc_isr_asm_call() except that this function will busy-wait until the execution of
45  * the callback completes.
46  *
47  * @note This function is not available in single-core mode.
48  *
49  * @param[in]   func    Pointer to a function of type void func(void* arg) to be executed
50  * @param[in]   arg     Arbitrary argument of type void* to be passed into the function
51  */
52 void esp_ipc_isr_asm_call_blocking(esp_ipc_isr_func_t func, void* arg);
53 
54 /**
55  * @brief Stall the other CPU
56  *
57  * This function will stall the other CPU. The other CPU is stalled by busy-waiting in the context of a High Priority
58  * Interrupt. The other CPU will not be resumed until esp_ipc_isr_release_other_cpu() is called.
59  *
60  * - This function is internally implemented using IPC ISR
61  * - This function is used for DPORT workaround.
62  * - If the stall feature is paused using esp_ipc_isr_stall_pause(), this function will have no effect
63  *
64  * @note This function is not available in single-core mode.
65  * @note It is the caller's responsibility to avoid deadlocking on spinlocks
66  */
67 void esp_ipc_isr_stall_other_cpu(void);
68 
69 /**
70  * @brief Release the other CPU
71  *
72  * This function will release the other CPU that was previously stalled from calling esp_ipc_isr_stall_other_cpu()
73  *
74  * - This function is used for DPORT workaround.
75  * - If the stall feature is paused using esp_ipc_isr_stall_pause(), this function will have no effect
76  *
77  * @note This function is not available in single-core mode.
78  */
79 void esp_ipc_isr_release_other_cpu(void);
80 
81 /**
82  * @brief Puase the CPU stall feature
83  *
84  * This function will pause the CPU stall feature. Once paused, calls to esp_ipc_isr_stall_other_cpu() and
85  * esp_ipc_isr_release_other_cpu() will have no effect. If a IPC ISR call is already in progress, this function will
86  * busy-wait until the call completes before pausing the CPU stall feature.
87  */
88 void esp_ipc_isr_stall_pause(void);
89 
90 /**
91  * @brief Abort a CPU stall
92  *
93  * This function will abort any stalling routine of the other CPU due to a pervious call to
94  * esp_ipc_isr_stall_other_cpu(). This function aborts the stall in a non-recoverable manner, thus should only be called
95  * in case of a panic().
96  *
97  * - This function is used in panic handling code
98  */
99 void esp_ipc_isr_stall_abort(void);
100 
101 /**
102  * @brief Resume the CPU stall feature
103  *
104  * This function will resume the CPU stall feature that was previously paused by calling esp_ipc_isr_stall_pause(). Once
105  * resumed, calls to esp_ipc_isr_stall_other_cpu() and esp_ipc_isr_release_other_cpu() will have effect again.
106  */
107 void esp_ipc_isr_stall_resume(void);
108 
109 #else // CONFIG_ESP_IPC_ISR_ENABLE
110 
111 #define esp_ipc_isr_stall_other_cpu()
112 #define esp_ipc_isr_release_other_cpu()
113 #define esp_ipc_isr_stall_pause()
114 #define esp_ipc_isr_stall_abort()
115 #define esp_ipc_isr_stall_resume()
116 
117 #endif // CONFIG_ESP_IPC_ISR_ENABLE
118 
119 #ifdef __cplusplus
120 }
121 #endif
122