1 /*
2 * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /* This header exists for performance reasons, in order to inline the
8 * implementation of vPortCPUAcquireMutexIntsDisabled and
9 * vPortCPUReleaseMutexIntsDisabled into the
10 * vTaskEnterCritical/vTaskExitCritical functions in task.c as well as the
11 * vPortCPUAcquireMutex/vPortCPUReleaseMutex implementations.
12 *
13 * Normally this kind of performance hack is over the top, but
14 * vTaskEnterCritical/vTaskExitCritical is called a great
15 * deal by FreeRTOS internals.
16 *
17 * It should be #included by freertos port.c or tasks.c, in esp-idf.
18 *
19 * The way it works is that it essentially uses portmux_impl.inc.h as a
20 * generator template of sorts. When no external memory is used, this
21 * template is only used to generate the vPortCPUAcquireMutexIntsDisabledInternal
22 * and vPortCPUReleaseMutexIntsDisabledInternal functions, which use S32C1 to
23 * do an atomic compare & swap. When external memory is used the functions
24 * vPortCPUAcquireMutexIntsDisabledExtram and vPortCPUReleaseMutexIntsDisabledExtram
25 * are also generated, which use uxPortCompareSetExtram to fake the S32C1 instruction.
26 * The wrapper functions vPortCPUAcquireMutexIntsDisabled and
27 * vPortCPUReleaseMutexIntsDisabled will then use the appropriate function to do the
28 * actual lock/unlock.
29 */
30 #include "soc/cpu.h"
31 #include "portable.h"
32
33 /* XOR one core ID with this value to get the other core ID */
34 #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
35 #define CORE_ID_XOR_SWAP ( CORE_ID_PRO ^ CORE_ID_APP )
36 #else
37 #define CORE_ID_REGVAL_XOR_SWAP (CORE_ID_REGVAL_PRO ^ CORE_ID_REGVAL_APP)
38 #endif
39
40
41
42 /*Define the mux routines for use with muxes in internal RAM */
43 #define PORTMUX_AQUIRE_MUX_FN_NAME vPortCPUAcquireMutexIntsDisabledInternal
44 #define PORTMUX_RELEASE_MUX_FN_NAME vPortCPUReleaseMutexIntsDisabledInternal
45 #define PORTMUX_COMPARE_SET_FN_NAME uxPortCompareSet
46 #include "portmux_impl.inc.h"
47 #undef PORTMUX_AQUIRE_MUX_FN_NAME
48 #undef PORTMUX_RELEASE_MUX_FN_NAME
49 #undef PORTMUX_COMPARE_SET_FN_NAME
50
51
52 #if defined( CONFIG_SPIRAM_SUPPORT )
53
54 #define PORTMUX_AQUIRE_MUX_FN_NAME vPortCPUAcquireMutexIntsDisabledExtram
55 #define PORTMUX_RELEASE_MUX_FN_NAME vPortCPUReleaseMutexIntsDisabledExtram
56 #define PORTMUX_COMPARE_SET_FN_NAME uxPortCompareSetExtram
57 #include "portmux_impl.inc.h"
58 #undef PORTMUX_AQUIRE_MUX_FN_NAME
59 #undef PORTMUX_RELEASE_MUX_FN_NAME
60 #undef PORTMUX_COMPARE_SET_FN_NAME
61
62 #endif
63
64
65 #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
66 #define PORTMUX_AQUIRE_MUX_FN_ARGS portMUX_TYPE * mux, int timeout_cycles, const char * fnName, int line
67 #define PORTMUX_RELEASE_MUX_FN_ARGS portMUX_TYPE * mux, const char * fnName, int line
68 #define PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( x ) x, timeout_cycles, fnName, line
69 #define PORTMUX_RELEASE_MUX_FN_CALL_ARGS( x ) x, fnName, line
70 #else
71 #define PORTMUX_AQUIRE_MUX_FN_ARGS portMUX_TYPE * mux, int timeout_cycles
72 #define PORTMUX_RELEASE_MUX_FN_ARGS portMUX_TYPE * mux
73 #define PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( x ) x, timeout_cycles
74 #define PORTMUX_RELEASE_MUX_FN_CALL_ARGS( x ) x
75 #endif
76
77
vPortCPUAcquireMutexIntsDisabled(PORTMUX_AQUIRE_MUX_FN_ARGS)78 static inline bool __attribute__( ( always_inline ) ) vPortCPUAcquireMutexIntsDisabled( PORTMUX_AQUIRE_MUX_FN_ARGS )
79 {
80 #if defined( CONFIG_SPIRAM_SUPPORT )
81 if( esp_ptr_external_ram( mux ) )
82 {
83 return vPortCPUAcquireMutexIntsDisabledExtram( PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( mux ) );
84 }
85 #endif
86 return vPortCPUAcquireMutexIntsDisabledInternal( PORTMUX_AQUIRE_MUX_FN_CALL_ARGS( mux ) );
87 }
88
89
vPortCPUReleaseMutexIntsDisabled(PORTMUX_RELEASE_MUX_FN_ARGS)90 static inline void vPortCPUReleaseMutexIntsDisabled( PORTMUX_RELEASE_MUX_FN_ARGS )
91 {
92 #if defined( CONFIG_SPIRAM_SUPPORT )
93 if( esp_ptr_external_ram( mux ) )
94 {
95 vPortCPUReleaseMutexIntsDisabledExtram( PORTMUX_RELEASE_MUX_FN_CALL_ARGS( mux ) );
96 return;
97 }
98 #endif
99 vPortCPUReleaseMutexIntsDisabledInternal( PORTMUX_RELEASE_MUX_FN_CALL_ARGS( mux ) );
100 }
101