feat(build): add COMPILER_ENABLE_RISCV_ZCMP option

Applicable for chips affected by interrupt issue:
  - ESP32C5
  - ESP32C61
  - ESP32H4

For all other chips that support the ZCMP extension without issues,
it will be enabled unconditionally.
This commit is contained in:
Alexey Lapshin
2025-11-10 18:27:40 +07:00
parent 0c1d917f78
commit b0388ad4a5
11 changed files with 101 additions and 1 deletions
+21
View File
@@ -370,6 +370,27 @@ mainmenu "Espressif IoT Development Framework Configuration"
endchoice endchoice
config COMPILER_ENABLE_RISCV_ZCMP
bool "Enable RISCV ZCMP extension"
depends on SOC_CPU_ZCMP_WORKAROUND
default n
help
Enable the RISC-V ZCMP (Compressed Macro) extension to reduce binary size
by optimizing function prologue and epilogue sequences.
Note: Due to a hardware issue on some ESP32 chips (e.g., ESP32C5, ESP32C61,
ESP32H4), executing "cm.push" may re-enable interrupts even when global
interrupts are disabled (mstatus.mie = 0). This can cause unexpected interrupts
during CPU retention or within critical sections.
Workarounds are implemented in the IDF codebase. However, if user code
directly disables interrupts, additional actions may be required. Refer
to code examples under the SOC_CPU_ZCMP_WORKAROUND macro, or disable
the ZCMP extension for source files that contain functions which may
execute while mstatus.mie = 0.
Even with these workarounds, the issue may still affect dual-core variants.
choice COMPILER_OPTIMIZATION_ASSERTION_LEVEL choice COMPILER_OPTIMIZATION_ASSERTION_LEVEL
prompt "Assertion level" prompt "Assertion level"
default COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE default COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE
@@ -487,6 +487,14 @@ config SOC_CPU_ZCMP_WORKAROUND
bool bool
default y default y
config SOC_CPU_ZCMP_PUSH_REVERSED
bool
default y
config SOC_CPU_ZCMP_POPRET_ISSUE
bool
default y
config SOC_DS_SIGNATURE_MAX_BIT_LEN config SOC_DS_SIGNATURE_MAX_BIT_LEN
int int
default 3072 default 3072
@@ -183,6 +183,8 @@
#define SOC_CPU_HAS_LOCKUP_RESET 1 #define SOC_CPU_HAS_LOCKUP_RESET 1
#define SOC_CPU_ZCMP_WORKAROUND 1 #define SOC_CPU_ZCMP_WORKAROUND 1
#define SOC_CPU_ZCMP_PUSH_REVERSED 1
#define SOC_CPU_ZCMP_POPRET_ISSUE 1
/*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/ /*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/
/** The maximum length of a Digital Signature in bits. */ /** The maximum length of a Digital Signature in bits. */
@@ -375,6 +375,14 @@ config SOC_CPU_ZCMP_WORKAROUND
bool bool
default y default y
config SOC_CPU_ZCMP_PUSH_REVERSED
bool
default y
config SOC_CPU_ZCMP_POPRET_ISSUE
bool
default y
config SOC_DMA_CAN_ACCESS_FLASH config SOC_DMA_CAN_ACCESS_FLASH
bool bool
default y default y
@@ -150,6 +150,8 @@
#define SOC_CPU_HAS_LOCKUP_RESET 1 #define SOC_CPU_HAS_LOCKUP_RESET 1
#define SOC_CPU_ZCMP_WORKAROUND 1 #define SOC_CPU_ZCMP_WORKAROUND 1
#define SOC_CPU_ZCMP_PUSH_REVERSED 1
#define SOC_CPU_ZCMP_POPRET_ISSUE 1
/*-------------------------- DMA Common CAPS ----------------------------------------*/ /*-------------------------- DMA Common CAPS ----------------------------------------*/
#define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */ #define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */
@@ -243,10 +243,26 @@ config SOC_CPU_HAS_LOCKUP_RESET
bool bool
default y default y
config SOC_CPU_HAS_ZC_EXTENSIONS
bool
default y
config SOC_CPU_HAS_ZB_EXTENSIONS
bool
default y
config SOC_CPU_ZCMP_WORKAROUND config SOC_CPU_ZCMP_WORKAROUND
bool bool
default y default y
config SOC_CPU_ZCMP_PUSH_REVERSED
bool
default y
config SOC_CPU_ZCMP_POPRET_ISSUE
bool
default y
config SOC_DMA_CAN_ACCESS_FLASH config SOC_DMA_CAN_ACCESS_FLASH
bool bool
default y default y
@@ -175,7 +175,12 @@
#define SOC_HP_CPU_HAS_MULTIPLE_CORES 1 // Convenience boolean macro used to determine if a target has multiple cores. #define SOC_HP_CPU_HAS_MULTIPLE_CORES 1 // Convenience boolean macro used to determine if a target has multiple cores.
#define SOC_CPU_HAS_LOCKUP_RESET 1 #define SOC_CPU_HAS_LOCKUP_RESET 1
#define SOC_CPU_HAS_ZC_EXTENSIONS 1
#define SOC_CPU_HAS_ZB_EXTENSIONS 1
#define SOC_CPU_ZCMP_WORKAROUND 1 #define SOC_CPU_ZCMP_WORKAROUND 1
#define SOC_CPU_ZCMP_PUSH_REVERSED 1
#define SOC_CPU_ZCMP_POPRET_ISSUE 1
/*-------------------------- DMA Common CAPS ----------------------------------------*/ /*-------------------------- DMA Common CAPS ----------------------------------------*/
#define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */ #define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */
@@ -591,6 +591,18 @@ config SOC_CPU_HAS_LOCKUP_RESET
bool bool
default y default y
config SOC_CPU_HAS_ZC_EXTENSIONS
bool
default y
config SOC_CPU_ZCMP_PUSH_REVERSED
bool
default y
config SOC_CPU_ZCMP_POPRET_ISSUE
bool
default y
config SOC_SIMD_PREFERRED_DATA_ALIGNMENT config SOC_SIMD_PREFERRED_DATA_ALIGNMENT
int int
default 16 default 16
@@ -209,6 +209,11 @@
#define SOC_CPU_HAS_LOCKUP_RESET 1 #define SOC_CPU_HAS_LOCKUP_RESET 1
#define SOC_CPU_HAS_ZC_EXTENSIONS 1
#define SOC_CPU_ZCMP_PUSH_REVERSED 1
#define SOC_CPU_ZCMP_POPRET_ISSUE 1
#define SOC_SIMD_PREFERRED_DATA_ALIGNMENT 16 // The preferred data alignment accepted by the SIMD instructions, in bytes #define SOC_SIMD_PREFERRED_DATA_ALIGNMENT 16 // The preferred data alignment accepted by the SIMD instructions, in bytes
/*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/ /*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/
+21 -1
View File
@@ -34,7 +34,27 @@ if(CONFIG_IDF_TOOLCHAIN_GCC)
endif() endif()
# Clean compile options that were added by previous configurations and may be outdated # Clean compile options that were added by previous configurations and may be outdated
idf_toolchain_remove_flags(COMPILE_OPTIONS "-march=") idf_toolchain_remove_flags(COMPILE_OPTIONS "-march="
"-mno-cm-push-reverse"
"-mno-cm-popret")
if(CONFIG_SOC_CPU_HAS_ZB_EXTENSIONS)
set(_march "${_march}_zba_zbb_zbs")
endif()
if((CONFIG_SOC_CPU_HAS_ZC_EXTENSIONS AND NOT CONFIG_SOC_CPU_ZCMP_WORKAROUND) OR
CONFIG_COMPILER_ENABLE_RISCV_ZCMP)
if(NOT CONFIG_ESP32P4_SELECTS_REV_LESS_V3)
set(_march "${_march}_zcb_zcmp_zcmt")
if(CONFIG_SOC_CPU_ZCMP_PUSH_REVERSED)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mno-cm-push-reverse")
endif()
if(CONFIG_SOC_CPU_ZCMP_POPRET_ISSUE)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mno-cm-popret")
endif()
endif()
endif()
if(CONFIG_SOC_CPU_HAS_HWLOOP) if(CONFIG_SOC_CPU_HAS_HWLOOP)
set(_march "${_march}_xesploop") set(_march "${_march}_xesploop")
+1
View File
@@ -91,6 +91,7 @@ The following configuration options reduces the final binary size of almost any
- Setting :ref:`CONFIG_ESP_SYSTEM_PANIC` to ``Silent reboot`` saves a small amount of binary size, however this is **only** recommended if no one will use UART output to debug the device. - Setting :ref:`CONFIG_ESP_SYSTEM_PANIC` to ``Silent reboot`` saves a small amount of binary size, however this is **only** recommended if no one will use UART output to debug the device.
:CONFIG_IDF_TARGET_ARCH_RISCV: - Setting :ref:`CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS` reduces binary size by replacing inlined prologues/epilogues with library calls. :CONFIG_IDF_TARGET_ARCH_RISCV: - Setting :ref:`CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS` reduces binary size by replacing inlined prologues/epilogues with library calls.
- If the application binary uses only one of the security versions of the protocomm component, then the support for others can be disabled to save some code size. The support can be disabled through :ref:`CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0`, :ref:`CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1` or :ref:`CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2` respectively. - If the application binary uses only one of the security versions of the protocomm component, then the support for others can be disabled to save some code size. The support can be disabled through :ref:`CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0`, :ref:`CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1` or :ref:`CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2` respectively.
:CONFIG_SOC_CPU_ZCMP_WORKAROUND: - Enable :ref:`CONFIG_COMPILER_ENABLE_RISCV_ZCMP` to reduce binary size by using compressed function prologues/epilogues. Read the :ref:`CONFIG_COMPILER_ENABLE_RISCV_ZCMP` notes carefully before enabling this option!
.. note:: .. note::