diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 9fab5014d9..9cf84cf871 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -66,6 +66,8 @@ - "tools/ci/check_esp_memory_utils_headers.sh" - "tools/ci/check_blobs.sh" - "tools/ci/check_public_headers.py" + - "tools/ci/check_register_rw_half_word.cmake" + - "tools/ci/check_register_rw_half_word.py" .patterns-host_test: &patterns-host_test - ".gitlab/ci/host-test.yml" diff --git a/components/esp_driver_gptimer/test_apps/gptimer/CMakeLists.txt b/components/esp_driver_gptimer/test_apps/gptimer/CMakeLists.txt index ba96212bd0..6e95a94e77 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/CMakeLists.txt +++ b/components/esp_driver_gptimer/test_apps/gptimer/CMakeLists.txt @@ -19,3 +19,8 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES) DEPENDS ${elf} ) endif() + +message(STATUS "Checking gptimer registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "timer_group" "pcr" "hp_sys_clkrst" + HAL_MODULES "timer") diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/CMakeLists.txt b/components/esp_driver_i2c/test_apps/i2c_test_apps/CMakeLists.txt index 3ebe26f85d..ec730ed174 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/CMakeLists.txt +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/CMakeLists.txt @@ -23,3 +23,8 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES) DEPENDS ${elf} ) endif() + +message(STATUS "Checking i2c registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "i2c" "pcr" "hp_sys_clkrst" "lpperi" "lp_clkrst" + HAL_MODULES "i2c") diff --git a/components/esp_driver_jpeg/test_apps/jpeg_test_apps/CMakeLists.txt b/components/esp_driver_jpeg/test_apps/jpeg_test_apps/CMakeLists.txt index 2d8fd6dc23..0de9616eba 100644 --- a/components/esp_driver_jpeg/test_apps/jpeg_test_apps/CMakeLists.txt +++ b/components/esp_driver_jpeg/test_apps/jpeg_test_apps/CMakeLists.txt @@ -12,3 +12,8 @@ project(jpeg_test) target_add_binary_data(jpeg_test.elf "${IDF_PATH}/examples/peripherals/jpeg/jpeg_decode/resources/esp720.jpg" BINARY) target_add_binary_data(jpeg_test.elf "${IDF_PATH}/examples/peripherals/jpeg/jpeg_decode/resources/esp1080.jpg" BINARY) target_add_binary_data(jpeg_test.elf "resources/esp480.rgb" BINARY) + +message(STATUS "Checking jpeg registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "jpeg" "hp_sys_clkrst" + HAL_MODULES "jpeg") diff --git a/components/esp_driver_mcpwm/test_apps/mcpwm/CMakeLists.txt b/components/esp_driver_mcpwm/test_apps/mcpwm/CMakeLists.txt index 9bd915a8ce..6a3fcc3a30 100644 --- a/components/esp_driver_mcpwm/test_apps/mcpwm/CMakeLists.txt +++ b/components/esp_driver_mcpwm/test_apps/mcpwm/CMakeLists.txt @@ -19,3 +19,8 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES) DEPENDS ${elf} ) endif() + +message(STATUS "Checking mcpwm registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "mcpwm" "pcr" "hp_sys_clkrst" + HAL_MODULES "mcpwm") diff --git a/components/esp_driver_parlio/test_apps/parlio/CMakeLists.txt b/components/esp_driver_parlio/test_apps/parlio/CMakeLists.txt index 91e4cdb68b..1848fb89df 100644 --- a/components/esp_driver_parlio/test_apps/parlio/CMakeLists.txt +++ b/components/esp_driver_parlio/test_apps/parlio/CMakeLists.txt @@ -19,3 +19,8 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES) DEPENDS ${elf} ) endif() + +message(STATUS "Checking parlio registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "parl*io" "pcr" "hp_sys_clkrst" + HAL_MODULES "parlio") diff --git a/components/esp_driver_ppa/test_apps/CMakeLists.txt b/components/esp_driver_ppa/test_apps/CMakeLists.txt index dde4141943..903732e97e 100644 --- a/components/esp_driver_ppa/test_apps/CMakeLists.txt +++ b/components/esp_driver_ppa/test_apps/CMakeLists.txt @@ -7,3 +7,8 @@ include($ENV{IDF_PATH}/tools/cmake/project.cmake) set(COMPONENTS main) project(ppa_test) + +message(STATUS "Checking ppa registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "ppa" "hp_sys_clkrst" + HAL_MODULES "ppa") diff --git a/components/esp_driver_rmt/test_apps/rmt/CMakeLists.txt b/components/esp_driver_rmt/test_apps/rmt/CMakeLists.txt index 6c44dbcf33..aec93de5d1 100644 --- a/components/esp_driver_rmt/test_apps/rmt/CMakeLists.txt +++ b/components/esp_driver_rmt/test_apps/rmt/CMakeLists.txt @@ -19,3 +19,8 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES) DEPENDS ${elf} ) endif() + +message(STATUS "Checking rmt registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "rmt" "pcr" "hp_sys_clkrst" + HAL_MODULES "rmt") diff --git a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/CMakeLists.txt b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/CMakeLists.txt index 40ea327d0b..f5becedb87 100644 --- a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/CMakeLists.txt +++ b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/sdio/CMakeLists.txt @@ -11,3 +11,8 @@ set(EXTRA_COMPONENT_DIRS include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(sdio) + +message(STATUS "Checking sdio registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "host" "hinf" "slc" "pcr" + HAL_MODULES "sdio") diff --git a/components/esp_hw_support/test_apps/dma/CMakeLists.txt b/components/esp_hw_support/test_apps/dma/CMakeLists.txt index 42e63786a1..52d2103edf 100644 --- a/components/esp_hw_support/test_apps/dma/CMakeLists.txt +++ b/components/esp_hw_support/test_apps/dma/CMakeLists.txt @@ -8,3 +8,8 @@ include($ENV{IDF_PATH}/tools/cmake/project.cmake) set(COMPONENTS main esp_psram) project(dma_test) + +message(STATUS "Checking dma registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "*gdma" "pcr" "hp_sys_clkrst" + HAL_MODULES "*gdma") diff --git a/components/esp_hw_support/test_apps/etm/CMakeLists.txt b/components/esp_hw_support/test_apps/etm/CMakeLists.txt index 0d009db679..4505a9f1a0 100644 --- a/components/esp_hw_support/test_apps/etm/CMakeLists.txt +++ b/components/esp_hw_support/test_apps/etm/CMakeLists.txt @@ -8,3 +8,8 @@ include($ENV{IDF_PATH}/tools/cmake/project.cmake) set(COMPONENTS main esp_pm) project(etm_test) + +message(STATUS "Checking etm registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "*etm" "pcr" "hp_sys_clkrst" + HAL_MODULES "etm") diff --git a/components/esp_lcd/test_apps/mipi_dsi_lcd/CMakeLists.txt b/components/esp_lcd/test_apps/mipi_dsi_lcd/CMakeLists.txt index 9a4ba3eaaa..30d912b096 100644 --- a/components/esp_lcd/test_apps/mipi_dsi_lcd/CMakeLists.txt +++ b/components/esp_lcd/test_apps/mipi_dsi_lcd/CMakeLists.txt @@ -19,3 +19,8 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES) DEPENDS ${elf} ) endif() + +message(STATUS "Checking mipi_dsi registers are not read-write by half-word") +include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) +check_register_rw_half_word(SOC_MODULES "*dsi*" "hp_sys_clkrst" + HAL_MODULES "*dsi*") diff --git a/components/hal/esp32/include/hal/sdio_slave_ll.h b/components/hal/esp32/include/hal/sdio_slave_ll.h index 2c94f217e7..aa0a001ca6 100644 --- a/components/hal/esp32/include/hal/sdio_slave_ll.h +++ b/components/hal/esp32/include/hal/sdio_slave_ll.h @@ -17,6 +17,7 @@ #pragma once #include "hal/sdio_slave_types.h" +#include "hal/misc.h" #include "soc/slc_struct.h" #include "soc/slc_reg.h" #include "soc/host_struct.h" @@ -514,7 +515,7 @@ static inline void sdio_slave_ll_host_send_int(slc_dev_t *slc, const sdio_slave_ { //use registers in SLC to trigger, rather than write HOST registers directly //other interrupts than tohost interrupts are not supported yet - slc->intvec_tohost.slc0_intvec = (*mask); + HAL_FORCE_MODIFY_U32_REG_FIELD(slc->intvec_tohost, slc0_intvec, *mask); } /** diff --git a/components/hal/esp32c6/include/hal/etm_ll.h b/components/hal/esp32c6/include/hal/etm_ll.h index a40dd68b12..9a46f46a1d 100644 --- a/components/hal/esp32c6/include/hal/etm_ll.h +++ b/components/hal/esp32c6/include/hal/etm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -98,7 +98,7 @@ static inline bool etm_ll_is_channel_enabled(soc_etm_dev_t *hw, uint32_t chan) */ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, uint32_t event) { - hw->channel[chan].evt_id.evt_id = event; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].eid, evt_id, event); } /** @@ -110,10 +110,10 @@ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, ui */ static inline void etm_ll_channel_set_task(soc_etm_dev_t *hw, uint32_t chan, uint32_t task) { - hw->channel[chan].task_id.task_id = task; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].tid, task_id, task); } -#define etm_ll_is_lpcore_wakeup_triggered() lp_aon_ll_get_lpcore_etm_wakeup_flag() +#define etm_ll_is_lpcore_wakeup_triggered() lp_aon_ll_get_lpcore_etm_wakeup_flag() #define etm_ll_clear_lpcore_wakeup_status() lp_aon_ll_clear_lpcore_etm_wakeup_flag() diff --git a/components/hal/esp32c6/include/hal/sdio_slave_ll.h b/components/hal/esp32c6/include/hal/sdio_slave_ll.h index 97c4b54410..2831edd57b 100644 --- a/components/hal/esp32c6/include/hal/sdio_slave_ll.h +++ b/components/hal/esp32c6/include/hal/sdio_slave_ll.h @@ -17,6 +17,7 @@ #pragma once #include "hal/sdio_slave_types.h" +#include "hal/misc.h" #include "soc/slc_struct.h" #include "soc/slc_reg.h" #include "soc/host_struct.h" @@ -503,7 +504,7 @@ static inline void sdio_slave_ll_host_send_int(slc_dev_t *slc, const sdio_slave_ { //use registers in SLC to trigger, rather than write HOST registers directly //other interrupts than tohost interrupts are not supported yet - slc->slcintvec_tohost.slc0_tohost_intvec = (*mask); + HAL_FORCE_MODIFY_U32_REG_FIELD(slc->slcintvec_tohost, slc0_tohost_intvec, *mask); } /** diff --git a/components/hal/esp32h2/include/hal/etm_ll.h b/components/hal/esp32h2/include/hal/etm_ll.h index 9d341ae2ed..210933eaba 100644 --- a/components/hal/esp32h2/include/hal/etm_ll.h +++ b/components/hal/esp32h2/include/hal/etm_ll.h @@ -97,7 +97,7 @@ static inline bool etm_ll_is_channel_enabled(soc_etm_dev_t *hw, uint32_t chan) */ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, uint32_t event) { - hw->channel[chan].evt_id.evt_id = event; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].eid, evt_id, event); } /** @@ -109,7 +109,7 @@ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, ui */ static inline void etm_ll_channel_set_task(soc_etm_dev_t *hw, uint32_t chan, uint32_t task) { - hw->channel[chan].task_id.task_id = task; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].tid, task_id, task); } #ifdef __cplusplus diff --git a/components/hal/esp32h2/include/hal/parlio_ll.h b/components/hal/esp32h2/include/hal/parlio_ll.h index e0236e0f8a..ac3f5d7470 100644 --- a/components/hal/esp32h2/include/hal/parlio_ll.h +++ b/components/hal/esp32h2/include/hal/parlio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -326,7 +326,7 @@ static inline void parlio_ll_rx_treat_data_line_as_en(parl_io_dev_t *dev, uint32 } /** - * @brief Wether to enable the RX clock gating + * @brief Whether to enable the RX clock gating * * @param dev Parallel IO register base address * @param en True to enable, False to disable @@ -457,7 +457,7 @@ static inline void parlio_ll_tx_set_trans_bit_len(parl_io_dev_t *dev, uint32_t b } /** - * @brief Wether to enable the TX clock gating + * @brief Whether to enable the TX clock gating * * @note The MSB of TXD will be taken as the gating enable signal * @@ -571,7 +571,7 @@ static inline void parlio_ll_tx_reset_fifo(parl_io_dev_t *dev) __attribute__((always_inline)) static inline void parlio_ll_tx_set_idle_data_value(parl_io_dev_t *dev, uint32_t value) { - dev->tx_genrl_cfg.tx_idle_value = value; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_genrl_cfg, tx_idle_value, value); } /** diff --git a/components/hal/esp32p4/include/hal/cpu_utility_ll.h b/components/hal/esp32p4/include/hal/cpu_utility_ll.h index 5c6b606488..38a21cfc3c 100644 --- a/components/hal/esp32p4/include/hal/cpu_utility_ll.h +++ b/components/hal/esp32p4/include/hal/cpu_utility_ll.h @@ -11,6 +11,7 @@ #include "soc/pmu_struct.h" #include "soc/hp_system_reg.h" #include "esp_attr.h" +#include "hal/misc.h" #ifdef __cplusplus extern "C" { @@ -29,18 +30,18 @@ FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no) FORCE_INLINE_ATTR void cpu_utility_ll_stall_cpu(uint32_t cpu_no) { if (cpu_no == 0) { - PMU.cpu_sw_stall.hpcore0_stall_code = 0x86; + HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore0_stall_code, 0x86); } else { - PMU.cpu_sw_stall.hpcore1_stall_code = 0x86; + HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore1_stall_code, 0x86); } } FORCE_INLINE_ATTR void cpu_utility_ll_unstall_cpu(uint32_t cpu_no) { if (cpu_no == 0) { - PMU.cpu_sw_stall.hpcore0_stall_code = 0xFF; + HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore0_stall_code, 0xFF); } else { - PMU.cpu_sw_stall.hpcore1_stall_code = 0xFF; + HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore1_stall_code, 0xFF); } } #endif // SOC_CPU_CORES_NUM > 1 diff --git a/components/hal/esp32p4/include/hal/dw_gdma_ll.h b/components/hal/esp32p4/include/hal/dw_gdma_ll.h index 6afcca79b3..efe817b8e3 100644 --- a/components/hal/esp32p4/include/hal/dw_gdma_ll.h +++ b/components/hal/esp32p4/include/hal/dw_gdma_ll.h @@ -1112,7 +1112,7 @@ __attribute__((always_inline)) static inline void dw_gdma_ll_lli_set_src_burst_len(dw_gdma_link_list_item_t *lli, uint8_t len) { lli->ctrl_hi.arlen_en = len > 0; - lli->ctrl_hi.arlen = len; + HAL_FORCE_MODIFY_U32_REG_FIELD(lli->ctrl_hi, arlen, len); } /** @@ -1125,7 +1125,7 @@ __attribute__((always_inline)) static inline void dw_gdma_ll_lli_set_dst_burst_len(dw_gdma_link_list_item_t *lli, uint8_t len) { lli->ctrl_hi.awlen_en = len > 0; - lli->ctrl_hi.awlen = len; + HAL_FORCE_MODIFY_U32_REG_FIELD(lli->ctrl_hi, awlen, len); } /** diff --git a/components/hal/esp32p4/include/hal/emac_ll.h b/components/hal/esp32p4/include/hal/emac_ll.h index 6f7e484edf..33a5ed8a5c 100644 --- a/components/hal/esp32p4/include/hal/emac_ll.h +++ b/components/hal/esp32p4/include/hal/emac_ll.h @@ -628,11 +628,11 @@ static inline void emac_ll_clock_enable_mii(void *ext_regs) HP_SYS_CLKRST.peri_clk_ctrl00.reg_emac_rx_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl00.reg_emac_rx_clk_src_sel = 1; // 0-pad_emac_txrx_clk, 1-pad_emac_rx_clk - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_rx_clk_div_num = 0; // 25MHz + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_rx_clk_div_num, 0); // 25MHz HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_src_sel = 1; // 0-pad_emac_txrx_clk, 1-pad_emac_tx_clk - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_div_num = 0; // 25MHz + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_tx_clk_div_num, 0); // 25MHz LP_AON_CLKRST.hp_clk_ctrl.hp_pad_emac_tx_clk_en = 1; LP_AON_CLKRST.hp_clk_ctrl.hp_pad_emac_rx_clk_en = 1; @@ -653,11 +653,11 @@ static inline void emac_ll_clock_enable_rmii_input(void *ext_regs) HP_SYS_CLKRST.peri_clk_ctrl00.reg_emac_rx_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl00.reg_emac_rx_clk_src_sel = 0; // 0-pad_emac_txrx_clk, 1-pad_emac_rx_clk - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_rx_clk_div_num = 1; // set default divider + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_rx_clk_div_num, 1); // set default divider HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_src_sel = 0; // 0-pad_emac_txrx_clk, 1-pad_emac_tx_clk - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_div_num = 1; // set default divider + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_tx_clk_div_num, 1); // set default divider LP_AON_CLKRST.hp_clk_ctrl.hp_pad_emac_tx_clk_en = 0; LP_AON_CLKRST.hp_clk_ctrl.hp_pad_emac_rx_clk_en = 0; @@ -670,8 +670,8 @@ static inline void emac_ll_clock_enable_rmii_input(void *ext_regs) static inline void emac_ll_clock_rmii_rx_tx_div(void *ext_regs, int div) { - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_rx_clk_div_num = div; - HP_SYS_CLKRST.peri_clk_ctrl01.reg_emac_tx_clk_div_num = div; + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_rx_clk_div_num, div); + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl01, reg_emac_tx_clk_div_num, div); } /// use a macro to wrap the function, force the caller to use it in a critical section diff --git a/components/hal/esp32p4/include/hal/etm_ll.h b/components/hal/esp32p4/include/hal/etm_ll.h index 6904d170ac..12e11d6432 100644 --- a/components/hal/esp32p4/include/hal/etm_ll.h +++ b/components/hal/esp32p4/include/hal/etm_ll.h @@ -106,7 +106,7 @@ static inline bool etm_ll_is_channel_enabled(soc_etm_dev_t *hw, uint32_t chan) */ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, uint32_t event) { - hw->channel[chan].evt_id.evt_id = event; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].eid, evt_id, event); } /** @@ -118,7 +118,7 @@ static inline void etm_ll_channel_set_event(soc_etm_dev_t *hw, uint32_t chan, ui */ static inline void etm_ll_channel_set_task(soc_etm_dev_t *hw, uint32_t chan, uint32_t task) { - hw->channel[chan].task_id.task_id = task; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[chan].tid, task_id, task); } /** diff --git a/components/hal/esp32p4/include/hal/parlio_ll.h b/components/hal/esp32p4/include/hal/parlio_ll.h index b7cc5558d5..f863acf277 100644 --- a/components/hal/esp32p4/include/hal/parlio_ll.h +++ b/components/hal/esp32p4/include/hal/parlio_ll.h @@ -636,7 +636,7 @@ static inline void parlio_ll_tx_reset_fifo(parl_io_dev_t *dev) __attribute__((always_inline)) static inline void parlio_ll_tx_set_idle_data_value(parl_io_dev_t *dev, uint32_t value) { - dev->tx_genrl_cfg.tx_idle_value = value; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_genrl_cfg, tx_idle_value, value); } /** diff --git a/components/hal/esp32p4/include/hal/ppa_ll.h b/components/hal/esp32p4/include/hal/ppa_ll.h index 687e63c5ef..60facd94fe 100644 --- a/components/hal/esp32p4/include/hal/ppa_ll.h +++ b/components/hal/esp32p4/include/hal/ppa_ll.h @@ -660,9 +660,9 @@ static inline void ppa_ll_blend_configure_filling_block(ppa_dev_t *dev, color_pi */ static inline void ppa_ll_blend_set_rx_fg_fix_rgb(ppa_dev_t *dev, color_pixel_rgb888_data_t *rgb) { - dev->blend_rgb.blend1_rx_b = rgb->b; - dev->blend_rgb.blend1_rx_g = rgb->g; - dev->blend_rgb.blend1_rx_r = rgb->r; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->blend_rgb, blend1_rx_b, rgb->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->blend_rgb, blend1_rx_g, rgb->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->blend_rgb, blend1_rx_r, rgb->r); } /* @@ -682,13 +682,13 @@ static inline void ppa_ll_blend_set_rx_fg_fix_rgb(ppa_dev_t *dev, color_pixel_rg */ static inline void ppa_ll_blend_configure_rx_bg_ck_range(ppa_dev_t *dev, color_pixel_rgb888_data_t *rgb_thres_low, color_pixel_rgb888_data_t *rgb_thres_high) { - dev->ck_bg_low.colorkey_bg_b_low = rgb_thres_low->b; - dev->ck_bg_low.colorkey_bg_g_low = rgb_thres_low->g; - dev->ck_bg_low.colorkey_bg_r_low = rgb_thres_low->r; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_low, colorkey_bg_b_low, rgb_thres_low->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_low, colorkey_bg_g_low, rgb_thres_low->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_low, colorkey_bg_r_low, rgb_thres_low->r); - dev->ck_bg_high.colorkey_bg_b_high = rgb_thres_high->b; - dev->ck_bg_high.colorkey_bg_g_high = rgb_thres_high->g; - dev->ck_bg_high.colorkey_bg_r_high = rgb_thres_high->r; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_high, colorkey_bg_b_high, rgb_thres_high->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_high, colorkey_bg_g_high, rgb_thres_high->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_bg_high, colorkey_bg_r_high, rgb_thres_high->r); } /** @@ -700,13 +700,13 @@ static inline void ppa_ll_blend_configure_rx_bg_ck_range(ppa_dev_t *dev, color_p */ static inline void ppa_ll_blend_configure_rx_fg_ck_range(ppa_dev_t *dev, color_pixel_rgb888_data_t *rgb_thres_low, color_pixel_rgb888_data_t *rgb_thres_high) { - dev->ck_fg_low.colorkey_fg_b_low = rgb_thres_low->b; - dev->ck_fg_low.colorkey_fg_g_low = rgb_thres_low->g; - dev->ck_fg_low.colorkey_fg_r_low = rgb_thres_low->r; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_low, colorkey_fg_b_low, rgb_thres_low->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_low, colorkey_fg_g_low, rgb_thres_low->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_low, colorkey_fg_r_low, rgb_thres_low->r); - dev->ck_fg_high.colorkey_fg_b_high = rgb_thres_high->b; - dev->ck_fg_high.colorkey_fg_g_high = rgb_thres_high->g; - dev->ck_fg_high.colorkey_fg_r_high = rgb_thres_high->r; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_high, colorkey_fg_b_high, rgb_thres_high->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_high, colorkey_fg_g_high, rgb_thres_high->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_fg_high, colorkey_fg_r_high, rgb_thres_high->r); } /** @@ -717,9 +717,9 @@ static inline void ppa_ll_blend_configure_rx_fg_ck_range(ppa_dev_t *dev, color_p */ static inline void ppa_ll_blend_set_ck_default_rgb(ppa_dev_t *dev, color_pixel_rgb888_data_t *rgb) { - dev->ck_default.colorkey_default_b = rgb->b; - dev->ck_default.colorkey_default_g = rgb->g; - dev->ck_default.colorkey_default_r = rgb->r; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_default, colorkey_default_b, rgb->b); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_default, colorkey_default_g, rgb->g); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->ck_default, colorkey_default_r, rgb->r); } /** diff --git a/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h b/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h index 438f474d52..822a4759be 100644 --- a/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h +++ b/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -53,7 +53,7 @@ static inline void psram_ctrlr_ll_set_wr_cmd(uint32_t mspi_id, uint32_t cmd_bitl HAL_ASSERT(cmd_bitlen > 0); SPIMEM2.mem_cache_sctrl.mem_cache_sram_usr_wcmd = 1; SPIMEM2.mem_sram_dwr_cmd.mem_cache_sram_usr_wr_cmd_bitlen = cmd_bitlen - 1; - SPIMEM2.mem_sram_dwr_cmd.mem_cache_sram_usr_wr_cmd_value = cmd_val; + HAL_FORCE_MODIFY_U32_REG_FIELD(SPIMEM2.mem_sram_dwr_cmd, mem_cache_sram_usr_wr_cmd_value, cmd_val); } /** @@ -70,7 +70,7 @@ static inline void psram_ctrlr_ll_set_rd_cmd(uint32_t mspi_id, uint32_t cmd_bitl HAL_ASSERT(cmd_bitlen > 0); SPIMEM2.mem_cache_sctrl.mem_cache_sram_usr_rcmd = 1; SPIMEM2.mem_sram_drd_cmd.mem_cache_sram_usr_rd_cmd_bitlen = cmd_bitlen - 1; - SPIMEM2.mem_sram_drd_cmd.mem_cache_sram_usr_rd_cmd_value = cmd_val; + HAL_FORCE_MODIFY_U32_REG_FIELD(SPIMEM2.mem_sram_drd_cmd, mem_cache_sram_usr_rd_cmd_value, cmd_val); } /** @@ -501,7 +501,7 @@ static inline void psram_ctrlr_ll_enable_skip_page_corner(uint32_t mspi_id, bool } /** - * @brief Enable spliting transactions + * @brief Enable splitting transactions * * @param mspi_id mspi_id * @param en enable / disable diff --git a/components/hal/esp32p4/include/hal/spimem_flash_ll.h b/components/hal/esp32p4/include/hal/spimem_flash_ll.h index 23de80140b..2fc156aaa2 100644 --- a/components/hal/esp32p4/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32p4/include/hal/spimem_flash_ll.h @@ -570,7 +570,7 @@ static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t static inline void spimem_flash_ll_set_extra_address(spi_mem_dev_t *dev, uint32_t extra_addr) { dev->cache_fctrl.cache_usr_addr_4byte = 0; - dev->rd_status.wb_mode = extra_addr; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rd_status, wb_mode, extra_addr); } /** diff --git a/components/soc/esp32c6/include/soc/soc_etm_struct.h b/components/soc/esp32c6/include/soc/soc_etm_struct.h index 5e8f2dea6b..3c62027ae5 100644 --- a/components/soc/esp32c6/include/soc/soc_etm_struct.h +++ b/components/soc/esp32c6/include/soc/soc_etm_struct.h @@ -735,8 +735,8 @@ typedef struct soc_etm_dev_t { volatile soc_etm_ch_ena_ad1_set_reg_t ch_ena_ad1_set; volatile soc_etm_ch_ena_ad1_clr_reg_t ch_ena_ad1_clr; volatile struct { - soc_etm_chn_evt_id_reg_t evt_id; - soc_etm_chn_task_id_reg_t task_id; + soc_etm_chn_evt_id_reg_t eid; + soc_etm_chn_task_id_reg_t tid; } channel[50]; volatile soc_etm_clk_en_reg_t clk_en; volatile soc_etm_date_reg_t date; diff --git a/components/soc/esp32h2/include/soc/soc_etm_struct.h b/components/soc/esp32h2/include/soc/soc_etm_struct.h index 5e8f2dea6b..3c62027ae5 100644 --- a/components/soc/esp32h2/include/soc/soc_etm_struct.h +++ b/components/soc/esp32h2/include/soc/soc_etm_struct.h @@ -735,8 +735,8 @@ typedef struct soc_etm_dev_t { volatile soc_etm_ch_ena_ad1_set_reg_t ch_ena_ad1_set; volatile soc_etm_ch_ena_ad1_clr_reg_t ch_ena_ad1_clr; volatile struct { - soc_etm_chn_evt_id_reg_t evt_id; - soc_etm_chn_task_id_reg_t task_id; + soc_etm_chn_evt_id_reg_t eid; + soc_etm_chn_task_id_reg_t tid; } channel[50]; volatile soc_etm_clk_en_reg_t clk_en; volatile soc_etm_date_reg_t date; diff --git a/components/soc/esp32p4/include/soc/soc_etm_struct.h b/components/soc/esp32p4/include/soc/soc_etm_struct.h index 93090a023d..1feb1950ec 100644 --- a/components/soc/esp32p4/include/soc/soc_etm_struct.h +++ b/components/soc/esp32p4/include/soc/soc_etm_struct.h @@ -5084,8 +5084,8 @@ typedef struct soc_etm_dev_t { volatile soc_etm_ch_ena_ad1_set_reg_t ch_ena_ad1_set; volatile soc_etm_ch_ena_ad1_clr_reg_t ch_ena_ad1_clr; volatile struct { - soc_etm_chn_evt_id_reg_t evt_id; - soc_etm_chn_task_id_reg_t task_id; + soc_etm_chn_evt_id_reg_t eid; + soc_etm_chn_task_id_reg_t tid; } channel[50]; volatile soc_etm_evt_st0_reg_t evt_st0; volatile soc_etm_evt_st0_clr_reg_t evt_st0_clr; diff --git a/tools/ci/check_register_rw_half_word.cmake b/tools/ci/check_register_rw_half_word.cmake new file mode 100644 index 0000000000..3a7cc2890e --- /dev/null +++ b/tools/ci/check_register_rw_half_word.cmake @@ -0,0 +1,33 @@ +function(check_register_rw_half_word) + set(options) + set(oneValueArgs) + set(multiValueArgs SOC_MODULES HAL_MODULES) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT ARG_SOC_MODULES) + message(FATAL_ERROR "SOC_MODULES are required") + endif() + + if(NOT ARG_HAL_MODULES) + message(FATAL_ERROR "HAL_MODULES are required") + endif() + + idf_build_get_property(python PYTHON) + idf_build_get_property(idf_target IDF_TARGET) + + execute_process( + COMMAND ${python} $ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.py + --target-chip ${idf_target} + --soc-modules ${ARG_SOC_MODULES} + --hal-modules ${ARG_HAL_MODULES} + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_VARIABLE error + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ) + + if(result) + message(FATAL_ERROR "${output}") + endif() +endfunction() diff --git a/tools/ci/check_register_rw_half_word.py b/tools/ci/check_register_rw_half_word.py new file mode 100644 index 0000000000..3a5aa569dd --- /dev/null +++ b/tools/ci/check_register_rw_half_word.py @@ -0,0 +1,99 @@ +# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import argparse +import os +import re +import sys +from pathlib import Path +from typing import Iterator +from typing import List + +idf_path = os.environ.get('IDF_PATH', None) + + +def find_files(base_path: str, patterns: List[str]) -> Iterator[Path]: + for pattern in patterns: + yield from Path(base_path).rglob(f'**/{pattern}') + + +def read_and_capture_suspicious_fields(file_path: Path) -> List[str]: + with open(file_path, 'r') as file: + content = file.read() + captures = re.findall(r'uint32_t\s+(\w+)\s*:\s*(16|8)\s*;', content) + return [capture[0] for capture in captures if not capture[0].startswith('reserve')] + + +def main( + target_chip: str, soc_module_patterns: List[str], hal_module_patterns: List[str] +) -> None: + soc_path = f'{idf_path}/components/soc/{target_chip}/' + hal_path = f'{idf_path}/components/hal/{target_chip}/' + struct_file_patterns = [f'{pattern}_struct.h' for pattern in soc_module_patterns] + ll_file_patterns = [f'{pattern}_ll.h' for pattern in hal_module_patterns] + + # Find `xxx_struct.h` files and `hal/yyy_ll.h` files + struct_files = find_files(soc_path, struct_file_patterns) + + no_violation_found = True + for struct_file in struct_files: + # Capture suspicious fields from `xxx_struct.h` + captures = read_and_capture_suspicious_fields(struct_file) + # if no suspicious fields found, continue to next struct file + if not captures: + continue + + # check if any of the captured fields are being read/written as half-words + ll_files = find_files(hal_path, ll_file_patterns) + for ll_file in ll_files: + with open(ll_file, 'r') as f: + content = f.read() + for capture in captures: + error_usages = [f'.{capture}', f'->{capture}'] + for error_usage in error_usages: + word_bound_pattern = rf'{re.escape(error_usage)}\b' + # print the line number where the error_usage is found + for match in re.finditer(word_bound_pattern, content, re.MULTILINE): + no_violation_found = False + start_line = content.count('\n', 0, match.start()) + 1 + print( + f'Found pattern {error_usage} at line {start_line} in file {ll_file}' + ) + + if no_violation_found: + print('No violations found') + else: + sys.exit(1) + + +if __name__ == '__main__': + if idf_path is None: + print('IDF_PATH must be set before running this script', file=sys.stderr) + sys.exit(1) + + parser = argparse.ArgumentParser( + description='Check if any register fields are being read/written as half-words.' + ) + parser.add_argument( + '--target-chip', + type=str, + required=True, + help='The name of the chip. e.g. esp32s3', + ) + parser.add_argument( + '--soc-modules', + required=True, + type=str, + nargs='+', # allow multiple soc modules + help='Name pattern for the SOC module. e.g. spi means spi_struct.h', + ) + parser.add_argument( + '--hal-modules', + required=True, + type=str, + nargs='+', # allow multiple hal modules + help='Name pattern for the HAL module. e.g. spi means spi_ll.h', + ) + + args = parser.parse_args() + + main(args.target_chip, args.soc_modules, args.hal_modules)