This is an automated email from Gerrit.

"Erhan Kurubas <[email protected]>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9195

-- gerrit

commit 9a4d929a7c864e73e0a8793ae7551df786d57c02
Author: Erhan Kurubas <[email protected]>
Date:   Sat Nov 1 14:36:27 2025 +0100

    tcl: add Espressif RISC-V config files
    
    Add configuration files for Espressif RISC-V based chips:
    - ESP32-C2, ESP32-C3, ESP32-C6, ESP32-H2 target configs
    - Board configs for builtin USB-JTAG and FTDI interfaces
    
    while adding the new config files:
    - Fix indentation in existing Espressif config files
    - Adapt esp_common.cfg with RISC-V support
    - Add explicit 'transport select jtag' to interface configs to avoid
      'DEPRECATED: auto-selecting transport' warning
    
    Change-Id: I45fcbca2fe50888750e2e98a0a6773de86aad6d0
    Signed-off-by: Erhan Kurubas <[email protected]>

diff --git a/doc/openocd.texi b/doc/openocd.texi
index 9540e69f3f..eab33b4ec4 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -630,7 +630,7 @@ emulation model of target hardware.
 This is deprecated from Linux v5.3; prefer using @b{linuxgpiod}.
 
 @item @b{esp_usb_jtag}
-@* A JTAG driver to communicate with builtin debug modules of Espressif 
ESP32-C3 and ESP32-S3 chips using OpenOCD.
+@* A JTAG driver to communicate with builtin debug modules of Espressif 
ESP32-C3, ESP32-C6, ESP32-H2 and ESP32-S3 chips using OpenOCD.
 
 @item @b{ch347}
 @* A JTAG driver that works with the WCH CH347F and CH347T chips.
@@ -3768,7 +3768,7 @@ buspirate led 1
 @end deffn
 
 @deffn {Interface Driver} {esp_usb_jtag}
-Espressif JTAG driver to communicate with ESP32-C3, ESP32-S3 chips and ESP USB 
Bridge board using OpenOCD.
+Espressif JTAG driver to communicate with ESP32-C3, ESP32-C6, ESP32-H2 and 
ESP32-S3 chips and ESP USB Bridge board using OpenOCD.
 These chips have built-in JTAG circuitry and can be debugged without any 
additional hardware.
 Only an USB cable connected to the D+/D- pins is necessary.
 
@@ -5146,6 +5146,10 @@ The current implementation supports eSi-32xx cores.
 @item @code{esp32} -- this is an Espressif SoC with dual Xtensa cores.
 @item @code{esp32s2} -- this is an Espressif SoC with single Xtensa core.
 @item @code{esp32s3} -- this is an Espressif SoC with dual Xtensa cores.
+@item @code{esp32c2} -- this is an Espressif SoC with single RISC-V core.
+@item @code{esp32c3} -- this is an Espressif SoC with single RISC-V core.
+@item @code{esp32c6} -- this is an Espressif SoC with single RISC-V core.
+@item @code{esp32h2} -- this is an Espressif SoC with single RISC-V core.
 @item @code{fa526} -- resembles arm920 (w/o Thumb).
 @item @code{feroceon} -- resembles arm926.
 @item @code{hla_target} -- a Cortex-M alternative to work with HL adapters 
like ST-Link.
diff --git a/tcl/board/esp32c2-ftdi.cfg b/tcl/board/esp32c2-ftdi.cfg
new file mode 100644
index 0000000000..bc2b82f5aa
--- /dev/null
+++ b/tcl/board/esp32c2-ftdi.cfg
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Example OpenOCD configuration file for ESP32-C2 connected via ESP-Prog.
+#
+# For example, OpenOCD can be started for ESP32-C2 debugging on
+#
+#   openocd -f board/esp32c2-ftdi.cfg
+#
+
+# Source the JTAG interface configuration file
+source [find interface/ftdi/esp32_devkitj_v1.cfg]
+# Source the ESP32-C2 configuration file
+source [find target/esp32c2.cfg]
+
+# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they
+# do not relate to OpenOCD trying to read from a memory range without physical
+# memory being present there), you can try lowering this.
+#
+# On DevKit-J, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz
+# if CPU frequency is 160MHz or 240MHz.
+adapter speed 20000
diff --git a/tcl/board/esp32c3-builtin.cfg b/tcl/board/esp32c3-builtin.cfg
new file mode 100644
index 0000000000..9e19b1b93c
--- /dev/null
+++ b/tcl/board/esp32c3-builtin.cfg
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Example OpenOCD configuration file for ESP32-C3 connected via builtin 
USB-JTAG adapter.
+#
+# For example, OpenOCD can be started for ESP32-C3 debugging on
+#
+#   openocd -f board/esp32c3-builtin.cfg
+#
+
+# Source the JTAG interface configuration file
+source [find interface/esp_usb_jtag.cfg]
+# Source the ESP32-C3 configuration file
+source [find target/esp32c3.cfg]
+
+adapter speed 40000
diff --git a/tcl/board/esp32c3-ftdi.cfg b/tcl/board/esp32c3-ftdi.cfg
new file mode 100644
index 0000000000..55953742c4
--- /dev/null
+++ b/tcl/board/esp32c3-ftdi.cfg
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Example OpenOCD configuration file for ESP32-C3 connected via ESP-Prog.
+#
+# For example, OpenOCD can be started for ESP32-C3 debugging on
+#
+#   openocd -f board/esp32c3-ftdi.cfg
+#
+
+# Source the JTAG interface configuration file
+source [find interface/ftdi/esp32_devkitj_v1.cfg]
+# Source the ESP32-C3 configuration file
+source [find target/esp32c3.cfg]
+
+# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they
+# do not relate to OpenOCD trying to read from a memory range without physical
+# memory being present there), you can try lowering this.
+#
+# On DevKit-J, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz
+# if CPU frequency is 160MHz or 240MHz.
+adapter speed 20000
diff --git a/tcl/board/esp32c6-builtin.cfg b/tcl/board/esp32c6-builtin.cfg
new file mode 100644
index 0000000000..abc96b2d14
--- /dev/null
+++ b/tcl/board/esp32c6-builtin.cfg
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Example OpenOCD configuration file for ESP32-C6 connected via builtin 
USB-JTAG adapter.
+#
+# For example, OpenOCD can be started for ESP32-C6 debugging on
+#
+#   openocd -f board/esp32c6-builtin.cfg
+#
+
+# Source the JTAG interface configuration file
+source [find interface/esp_usb_jtag.cfg]
+# Source the ESP32-C6 configuration file
+source [find target/esp32c6.cfg]
+
+adapter speed 40000
diff --git a/tcl/board/esp32h2-builtin.cfg b/tcl/board/esp32h2-builtin.cfg
new file mode 100644
index 0000000000..4455f99990
--- /dev/null
+++ b/tcl/board/esp32h2-builtin.cfg
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Example OpenOCD configuration file for ESP32-H2 connected via builtin 
USB-JTAG adapter.
+#
+# For example, OpenOCD can be started for ESP32-H2 debugging on
+#
+#   openocd -f board/esp32h2-builtin.cfg
+#
+
+# Source the JTAG interface configuration file
+source [find interface/esp_usb_jtag.cfg]
+# Source the ESP32-H2 configuration file
+source [find target/esp32h2.cfg]
+
+adapter speed 40000
diff --git a/tcl/interface/esp_usb_jtag.cfg b/tcl/interface/esp_usb_jtag.cfg
index 40427d0e3e..583a92d6a6 100644
--- a/tcl/interface/esp_usb_jtag.cfg
+++ b/tcl/interface/esp_usb_jtag.cfg
@@ -7,3 +7,5 @@ adapter driver esp_usb_jtag
 
 espusbjtag vid_pid 0x303a 0x1001
 espusbjtag caps_descriptor 0x2000
+
+transport select jtag
diff --git a/tcl/interface/ftdi/esp32_devkitj_v1.cfg 
b/tcl/interface/ftdi/esp32_devkitj_v1.cfg
index 1b455a9ac8..438d14be23 100644
--- a/tcl/interface/ftdi/esp32_devkitj_v1.cfg
+++ b/tcl/interface/ftdi/esp32_devkitj_v1.cfg
@@ -23,3 +23,5 @@ ftdi layout_signal LED4 -data 0x8000
 # The target code doesn't handle SRST reset properly yet, so this is commented 
out:
 # ftdi layout_signal nSRST -oe 0x0020
 # reset_config srst_only
+
+transport select jtag
diff --git a/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg 
b/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg
index 1880bcbc5f..c531f3da0c 100644
--- a/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg
+++ b/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg
@@ -27,3 +27,5 @@ ftdi layout_signal LED2 -ndata 0x1000
 # commented out:
 # ftdi layout_signal nSRST -oe 0x0020
 # reset_config srst_only
+
+transport select jtag
diff --git a/tcl/target/esp32.cfg b/tcl/target/esp32.cfg
index b30a170247..0803296127 100644
--- a/tcl/target/esp32.cfg
+++ b/tcl/target/esp32.cfg
@@ -5,14 +5,14 @@
 source [find target/esp_common.cfg]
 
 # Target specific global variables
-set _CHIPNAME                                  "esp32"
-set _CPUTAPID                                  0x120034e5
-set _ESP_ARCH                                  "xtensa"
-set _ONLYCPU                                   3
-set _FLASH_VOLTAGE                             3.3
-set _ESP_SMP_TARGET                            1
-set _ESP_SMP_BREAK                             1
-set _ESP_EFUSE_MAC_ADDR_REG    0x3ff5A004
+set _CHIPNAME                   "esp32"
+set _CPUTAPID                   0x120034e5
+set _ESP_ARCH                   "xtensa"
+set _ONLYCPU                    3
+set _FLASH_VOLTAGE              3.3
+set _ESP_SMP_TARGET             1
+set _ESP_SMP_BREAK              1
+set _ESP_EFUSE_MAC_ADDR_REG     0x3ff5A004
 
 if { [info exists ESP32_ONLYCPU] } {
        set _ONLYCPU $ESP32_ONLYCPU
diff --git a/tcl/target/esp32c2.cfg b/tcl/target/esp32c2.cfg
new file mode 100644
index 0000000000..a22fe7088c
--- /dev/null
+++ b/tcl/target/esp32c2.cfg
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+# Source the ESP common configuration file.
+source [find target/esp_common.cfg]
+
+# Target specific global variables
+set _CHIPNAME                   "esp32c2"
+set _CPUTAPID                   "0x0000cc25"
+set _ESP_ARCH                   "riscv"
+set _ONLYCPU                    1
+set _ESP_SMP_TARGET             0
+set _ESP_SMP_BREAK              0
+set _ESP_EFUSE_MAC_ADDR_REG     0x60008840
+
+# Target specific functions should be implemented for each riscv chips.
+proc esp32c2_wdt_disable { } {
+       # Halt event can occur during config phase (before "init" is done).
+       # Ignore it since mww commands don't work at that time.
+       if { [string compare [command mode] config] == 0 } {
+               return
+       }
+
+       # Disable Timer Group 0 WDT
+       mww 0x6001f064 0x50D83AA1
+       mww 0x6001F048 0
+       # Clear TG0 wdt interrupt state
+       mww 0x6001F07C 0x2
+
+       # Disable RTC WDT
+       mww 0x6000809C 0x50D83AA1
+       mww 0x60008084 0
+
+       # Disable Super WDT
+       mww 0x600080A4 0x8F1D312A
+       mww 0x600080A0 0x84B00000
+
+       # Clear RTC and Super wdt interrupt states
+       mww 0x60008044 0x8008
+}
+
+proc esp32c2_soc_reset { } {
+       global _RISCV_DMCONTROL
+
+       # This procedure does "digital system reset", i.e. resets
+       # all the peripherals except for the RTC block.
+       # It is called from reset-assert-post target event callback,
+       # after assert_reset procedure was called.
+       # Since we need the hart to execute a write to RTC_CNTL_SW_SYS_RST,
+       # temporarily take it out of reset. Save the dmcontrol state before
+       # doing so.
+       riscv dmi_write $_RISCV_DMCONTROL 0x80000001
+       # Trigger the reset
+       mww 0x60008000 0x9c00a000
+       # Workaround for stuck in cpu start during calibration.
+       # By writing zero to TIMG_RTCCALICFG_REG, we are disabling calibration
+       mww 0x6001F068 0
+       # Wait for the reset to happen
+       sleep 10
+       poll
+       # Disable the watchdogs again
+       esp32c2_wdt_disable
+
+       # Here debugger reads allresumeack and allhalted bits as set (0x330a2)
+       # We will clean allhalted state by resuming the core.
+       riscv dmi_write $_RISCV_DMCONTROL 0x40000001
+
+       # Put the hart back into reset state. Note that we need to keep haltreq 
set.
+       riscv dmi_write $_RISCV_DMCONTROL 0x80000003
+}
+
+proc esp32c2_memprot_is_enabled { } {
+       global _RISCV_ABS_CMD _RISCV_ABS_DATA0
+
+       # PMPADDR 0-1 covers entire valid IRAM range and PMPADDR 2-3 covers 
entire DRAM region
+       # pmpcfg0 holds the configuration for the PMP 0-3 address registers
+
+       # read pmpcfg0 and extract into 8-bit variables.
+       riscv dmi_write $_RISCV_ABS_CMD 0x2203a0
+       set pmpcfg0 [riscv dmi_read $_RISCV_ABS_DATA0]
+
+       set pmp0cfg [expr {($pmpcfg0 >> (8 * 0)) & 0xFF}]
+       set pmp1cfg [expr {($pmpcfg0 >> (8 * 1)) & 0xFF}]
+       set pmp2cfg [expr {($pmpcfg0 >> (8 * 2)) & 0xFF}]
+       set pmp3cfg [expr {($pmpcfg0 >> (8 * 3)) & 0xFF}]
+
+       # read PMPADDR 0-3
+       riscv dmi_write $_RISCV_ABS_CMD 0x2203b0
+       set pmpaddr0 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+       riscv dmi_write $_RISCV_ABS_CMD 0x2203b1
+       set pmpaddr1 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+       riscv dmi_write $_RISCV_ABS_CMD 0x2203b2
+       set pmpaddr2 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+       riscv dmi_write $_RISCV_ABS_CMD 0x2203b3
+       set pmpaddr3 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+
+       set IRAM_LOW    0x40380000
+       set IRAM_HIGH   0x403C0000
+       set DRAM_LOW    0x3FCA0000
+       set DRAM_HIGH   0x3FCE0000
+       set PMP_RWX     0x07
+       set PMP_RW      0x03
+
+       # The lock bit remains unset during the execution of the 2nd stage 
bootloader.
+       # Thus we do not perform a lock bit check for IRAM and DRAM regions.
+
+       # Check OpenOCD can write and execute from IRAM.
+       if {$pmpaddr0 >= $IRAM_LOW && $pmpaddr1 <= $IRAM_HIGH} {
+               if {($pmp0cfg & $PMP_RWX) != 0 || ($pmp1cfg & $PMP_RWX) != 
$PMP_RWX} {
+                       return 1
+               }
+       }
+
+       # Check OpenOCD can read/write entire DRAM region.
+       if {$pmpaddr2 >= $DRAM_LOW && $pmpaddr3 <= $DRAM_HIGH} {
+               if {($pmp2cfg & $PMP_RW) != 0 && ($pmp3cfg & $PMP_RW) != 
$PMP_RW} {
+                       return 1
+               }
+       }
+
+       return 0
+}
+
+create_esp_target $_ESP_ARCH
diff --git a/tcl/target/esp32c3.cfg b/tcl/target/esp32c3.cfg
new file mode 100644
index 0000000000..fea14d7c71
--- /dev/null
+++ b/tcl/target/esp32c3.cfg
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+# Source the ESP common configuration file.
+source [find target/esp_common.cfg]
+
+# Target specific global variables
+set _CHIPNAME                   "esp32c3"
+set _CPUTAPID                   "0x00005c25"
+set _ESP_ARCH                   "riscv"
+set _ONLYCPU                    1
+set _ESP_SMP_TARGET             0
+set _ESP_SMP_BREAK              0
+set _ESP_EFUSE_MAC_ADDR_REG     0x60008844
+
+# Target specific functions should be implemented for each riscv chips.
+proc esp32c3_wdt_disable { } {
+       # Halt event can occur during config phase (before "init" is done).
+       # Ignore it since mww commands don't work at that time.
+       if { [string compare [command mode] config] == 0 } {
+               return
+       }
+
+       # Disable Timer Group 0 WDT
+       mww 0x6001f064 0x50D83AA1
+       mww 0x6001F048 0
+       # Clear TG0 wdt interrupt state
+       mww 0x6001F07C 0x2
+
+       # Disable Timer Group 1 WDT
+       mww 0x60020064 0x50D83AA1
+       mww 0x60020048 0
+       # Clear TG1 wdt interrupt state
+       mww 0x6002007C 0x2
+
+       # Disable RTC WDT
+       mww 0x600080a8 0x50D83AA1
+       mww 0x60008090 0
+
+       # Disable Super WDT
+       mww 0x600080b0 0x8F1D312A
+       mww 0x600080ac 0x84B00000
+
+       # Clear RTC and Super wdt interrupt states
+       mww 0x6000804C 0x8008
+}
+
+# This is almost identical with the esp32c2_soc_reset.
+# Will be refactored with the other common settings.
+proc esp32c3_soc_reset { } {
+       global _RISCV_DMCONTROL
+
+       # This procedure does "digital system reset", i.e. resets
+       # all the peripherals except for the RTC block.
+       # It is called from reset-assert-post target event callback,
+       # after assert_reset procedure was called.
+       # Since we need the hart to execute a write to RTC_CNTL_SW_SYS_RST,
+       # temporarily take it out of reset. Save the dmcontrol state before
+       # doing so.
+       riscv dmi_write $_RISCV_DMCONTROL   0x80000001
+       # Trigger the reset
+       mww 0x60008000 0x9c00a000
+       # Workaround for stuck in cpu start during calibration.
+       # By writing zero to TIMG_RTCCALICFG_REG, we are disabling calibration
+       mww 0x6001F068 0
+       # Wait for the reset to happen
+       sleep 10
+       poll
+       # Disable the watchdogs again
+       esp32c3_wdt_disable
+
+       # Here debugger reads allresumeack and allhalted bits as set (0x330a2)
+       # We will clean allhalted state by resuming the core.
+       riscv dmi_write $_RISCV_DMCONTROL   0x40000001
+
+       # Put the hart back into reset state. Note that we need to keep haltreq 
set.
+       riscv dmi_write $_RISCV_DMCONTROL   0x80000003
+}
+
+proc esp32c3_memprot_is_enabled { } {
+       # IRAM0 PMS lock, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_0_REG
+       if { [get_mmr_bit 0x600C10A8 0] != 0 } {
+               return 1
+       }
+       # DRAM0 PMS lock, SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_0_REG
+       if { [get_mmr_bit 0x600C10C0 0] != 0 } {
+               return 1
+       }
+       return 0
+}
+
+create_esp_target $_ESP_ARCH
diff --git a/tcl/target/esp32c6.cfg b/tcl/target/esp32c6.cfg
new file mode 100644
index 0000000000..4299a0b551
--- /dev/null
+++ b/tcl/target/esp32c6.cfg
@@ -0,0 +1,152 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+# Source the ESP common configuration file.
+source [find target/esp_common.cfg]
+
+# Target specific global variables
+set _CHIPNAME                   "esp32c6"
+set _CPUTAPID                   0x0000dc25
+set _ESP_ARCH                   "riscv"
+set _ONLYCPU                    1
+set _ESP_SMP_TARGET             0
+set _ESP_SMP_BREAK              0
+set _ESP_EFUSE_MAC_ADDR_REG     0x600B0844
+
+# Target specific functions should be implemented for each riscv chips.
+proc esp32c6_wdt_disable { } {
+       # Halt event can occur during config phase (before "init" is done).
+       # Ignore it since mww commands don't work at that time.
+       if { [string compare [command mode] config] == 0 } {
+               return
+       }
+
+       # Disable Timer Group 0 WDT
+       mww 0x60008064 0x50D83AA1
+       mww 0x60008048 0
+       # Clear TG0 wdt interrupt state
+       mww 0x6000807C 0x2
+
+       # Disable Timer Group 1 WDT
+       mww 0x60009064 0x50D83AA1
+       mww 0x60009048 0
+       # Clear TG1 wdt interrupt state
+       mww 0x6000907C 0x2
+
+       # Disable LP_WDT_RTC
+       mww 0x600b1c18 0x50D83AA1
+       mww 0x600B1c00 0
+       # Disable LP_WDT_SWD
+       mww 0x600b1c20 0x50D83AA1
+       mww 0x600b1c1c 0x40000000
+
+       # Clear LP_WDT_RTC and LP_WDT_SWD interrupt states
+       mww 0x600B1c30 0xC0000000
+}
+
+proc esp32c6_soc_reset { } {
+       global _RISCV_DMCONTROL _RISCV_SB_CS _RISCV_SB_ADDR0 _RISCV_SB_DATA0
+
+       riscv dmi_write $_RISCV_DMCONTROL               0x80000001
+       riscv dmi_write $_RISCV_SB_CS                   0x48000
+       riscv dmi_write $_RISCV_SB_ADDR0                0x600b1034
+       riscv dmi_write $_RISCV_SB_DATA0                0x80000000
+       # clear dmactive to clear sbbusy otherwise debug module gets stuck
+       riscv dmi_write $_RISCV_DMCONTROL               0
+
+       riscv dmi_write $_RISCV_SB_CS                   0x48000
+       riscv dmi_write $_RISCV_SB_ADDR0                0x600b1038
+       riscv dmi_write $_RISCV_SB_DATA0                0x10000000
+
+       # clear dmactive to clear sbbusy otherwise debug module gets stuck
+       riscv dmi_write $_RISCV_DMCONTROL               0
+       riscv dmi_write $_RISCV_DMCONTROL               0x40000001
+       # Here debugger reads dmstatus as 0xc03a2
+
+       # Wait for the reset to happen
+       sleep 10
+       poll
+       # Here debugger reads dmstatus as 0x3a2
+
+       # Disable the watchdogs again
+       esp32c6_wdt_disable
+
+       # Here debugger reads anyhalted and allhalted bits as set (0x3a2)
+       # We will clean allhalted state by resuming the core.
+       riscv dmi_write $_RISCV_DMCONTROL               0x40000001
+
+       # Put the hart back into reset state. Note that we need to keep haltreq 
set.
+       riscv dmi_write $_RISCV_DMCONTROL               0x80000003
+}
+
+proc esp32c6_memprot_is_enabled { } {
+       global _RISCV_ABS_CMD _RISCV_ABS_DATA0
+
+       # If IRAM/DRAM split is enabled TOR address match mode is used.
+       # If IRAM/DRAM split is disabled NAPOT mode is used.
+       # In order to determine if the IRAM/DRAM regions are protected against 
RWX/RW,
+       # it is necessary to first read the mode and then apply the appropriate 
method for checking.
+       # We can understand the mode reading pmp5cfg in pmpcfg1 register.
+       # If it is none we know that pmp6cfg and pmp7cfg is in TOR mode.
+
+       # Read pmpcfg1 and extract into 8-bit variables.
+       riscv dmi_write $_RISCV_ABS_CMD 0x2203a1
+       set pmpcfg1 [riscv dmi_read $_RISCV_ABS_DATA0]
+
+       set pmp5cfg [expr {($pmpcfg1 >> (8 * 1)) & 0xFF}]
+       set pmp6cfg [expr {($pmpcfg1 >> (8 * 2)) & 0xFF}]
+       set pmp7cfg [expr {($pmpcfg1 >> (8 * 3)) & 0xFF}]
+
+       set IRAM_LOW    0x40800000
+       set IRAM_HIGH   0x40880000
+       set DRAM_LOW    0x40800000
+       set DRAM_HIGH   0x40880000
+       set PMP_RWX     0x07
+       set PMP_RW      0x03
+       set PMP_A       [expr {($pmp5cfg >> 3) & 0x03}]
+
+       if {$PMP_A == 0} {
+               # TOR mode used to protect valid address space.
+
+               # Read PMPADDR 5-7
+               riscv dmi_write $_RISCV_ABS_CMD 0x2203b5
+               set pmpaddr5 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+               riscv dmi_write $_RISCV_ABS_CMD 0x2203b6
+               set pmpaddr6 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+               riscv dmi_write $_RISCV_ABS_CMD 0x2203b7
+               set pmpaddr7 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+
+               # The lock bit remains unset during the execution of the 2nd 
stage bootloader.
+               # Thus we do not perform a lock bit check for IRAM and DRAM 
regions.
+
+               # Check OpenOCD can write and execute from IRAM.
+               if {$pmpaddr5 >= $IRAM_LOW && $pmpaddr6 <= $IRAM_HIGH} {
+                       if {($pmp5cfg & $PMP_RWX) != 0 || ($pmp6cfg & $PMP_RWX) 
!= $PMP_RWX} {
+                               return 1
+                       }
+               }
+
+               # Check OpenOCD can read/write  entire DRAM region.
+               if {$pmpaddr7 >= $DRAM_LOW && $pmpaddr7 <= $DRAM_HIGH} {
+                       if {($pmp7cfg & $PMP_RW) != $PMP_RW} {
+                               return 1
+                       }
+               }
+       } elseif {$PMP_A == 3} {
+               # NAPOT mode used to protect valid address space.
+
+               # Read PMPADDR 5
+               riscv dmi_write $_RISCV_ABS_CMD 0x2203b5
+               set pmpaddr5 [expr {[riscv dmi_read $_RISCV_ABS_DATA0]}]
+
+               # Expected value written to the pmpaddr5
+               set pmpaddr_napot [expr {($IRAM_LOW | (($IRAM_HIGH - $IRAM_LOW 
- 1) >> 1)) >> 2}]
+               if {($pmpaddr_napot != $pmpaddr5) ||  ($pmp5cfg & $PMP_RWX) != 
$PMP_RWX} {
+                       return 1
+               }
+       }
+
+       return 0
+}
+
+create_esp_target $_ESP_ARCH
diff --git a/tcl/target/esp32h2.cfg b/tcl/target/esp32h2.cfg
new file mode 100644
index 0000000000..4d3e9350b1
--- /dev/null
+++ b/tcl/target/esp32h2.cfg
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+# Source the ESP common configuration file.
+source [find target/esp_common.cfg]
+
+# Target specific global variables
+set _CHIPNAME                   "esp32h2"
+set _CPUTAPID                   0x00010c25
+set _ESP_ARCH                   "riscv"
+set _ONLYCPU                    1
+set _ESP_SMP_TARGET             0
+set _ESP_SMP_BREAK              0
+set _ESP_EFUSE_MAC_ADDR_REG     0x600B0844
+
+# Target specific functions should be implemented for each riscv chips.
+proc esp32h2_wdt_disable { } {
+       # Halt event can occur during config phase (before "init" is done).
+       # Ignore it since mww commands don't work at that time.
+       if { [string compare [command mode] config] == 0 } {
+               return
+       }
+
+       # Disable Timer Group 0 WDT
+       mww 0x60009064 0x50D83AA1
+       mww 0x60009048 0
+       # Clear TG0 wdt interrupt state
+       mww 0x6000907C 0x2
+
+       # Disable Timer Group 1 WDT
+       mww 0x6000A064 0x50D83AA1
+       mww 0x6000A048 0
+       # Clear TG1 wdt interrupt state
+       mww 0x6000A07C 0x2
+}
+
+proc esp32h2_soc_reset { } {
+       global _RISCV_DMCONTROL _RISCV_SB_CS _RISCV_SB_ADDR0 _RISCV_SB_DATA0
+
+       riscv dmi_write $_RISCV_DMCONTROL   0x80000001
+       riscv dmi_write $_RISCV_SB_CS       0x48000
+       riscv dmi_write $_RISCV_SB_ADDR0    0x600b1034
+       riscv dmi_write $_RISCV_SB_DATA0    0x80000000
+       # clear dmactive to clear sbbusy otherwise debug module gets stuck
+       riscv dmi_write $_RISCV_DMCONTROL   0
+
+       riscv dmi_write $_RISCV_SB_CS       0x48000
+       riscv dmi_write $_RISCV_SB_ADDR0    0x600b1038
+       riscv dmi_write $_RISCV_SB_DATA0    0x10000000
+
+       # clear dmactive to clear sbbusy otherwise debug module gets stuck
+       riscv dmi_write $_RISCV_DMCONTROL   0
+       riscv dmi_write $_RISCV_DMCONTROL   0x40000001
+       # Here debugger reads dmstatus as 0xc03a2
+
+       # Wait for the reset to happen
+       sleep 10
+       poll
+       # Here debugger reads dmstatus as 0x3a2
+
+       # Disable the watchdogs again
+       esp32h2_wdt_disable
+
+       # Here debugger reads anyhalted and allhalted bits as set (0x3a2)
+       # We will clean allhalted state by resuming the core.
+       riscv dmi_write $_RISCV_DMCONTROL   0x40000001
+
+       # Put the hart back into reset state. Note that we need to keep haltreq 
set.
+       riscv dmi_write $_RISCV_DMCONTROL   0x80000003
+}
+
+proc esp32h2_memprot_is_enabled { } {
+       global _RISCV_ABS_CMD _RISCV_ABS_DATA0
+       # If IRAM/DRAM split is enabled;
+       #   PMPADDR 5-6 will cover valid IRAM region;
+       #   PMPADDR 7 will cover valid DRAM region;
+       # Only TOR mode is used for IRAM and DRAM protections.
+
+       # Read pmpcfg1 and extract into 8-bit variables.
+       riscv dmi_write $_RISCV_ABS_CMD 0x2203a1
+       set pmpcfg1 [riscv dmi_read $_RISCV_ABS_DATA0]
+
+       set pmp5cfg [expr {($pmpcfg1 >> (8 * 1)) & 0xFF}]
+       set pmp6cfg [expr {($pmpcfg1 >> (8 * 2)) & 0xFF}]
+       set pmp7cfg [expr {($pmpcfg1 >> (8 * 3)) & 0xFF}]
+
+       # Read PMPADDR 5-7
+       riscv dmi_write $_RISCV_ABS_CMD 0x2203b5
+       set pmpaddr5 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+       riscv dmi_write $_RISCV_ABS_CMD 0x2203b6
+       set pmpaddr6 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+       riscv dmi_write $_RISCV_ABS_CMD 0x2203b7
+       set pmpaddr7 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+
+       set IRAM_LOW    0x40800000
+       set IRAM_HIGH   0x40850000
+       set DRAM_LOW    0x40800000
+       set DRAM_HIGH   0x40850000
+
+       set PMP_RWX     0x07
+       set PMP_RW      0x03
+
+       # The lock bit remains unset during the execution of the 2nd stage 
bootloader.
+       # Thus, we do not perform a lock bit check for IRAM and DRAM regions.
+
+       # Check OpenOCD can write and execute from IRAM.
+       if {$pmpaddr5 >= $IRAM_LOW && $pmpaddr6 <= $IRAM_HIGH} {
+               if {($pmp5cfg & $PMP_RWX) != 0 || ($pmp6cfg & $PMP_RWX) != 
$PMP_RWX} {
+                       return 1
+               }
+       }
+
+       # Check OpenOCD can read/write  entire DRAM region.
+       # If IRAM/DRAM split is disabled, pmpaddr7 will be zero, checking only 
IRAM region is enough.
+       if {$pmpaddr7 != 0 && $pmpaddr7 >= $DRAM_LOW && $pmpaddr7 <= 
$DRAM_HIGH} {
+               if {($pmp7cfg & $PMP_RW) != $PMP_RW} {
+                       return 1
+               }
+       }
+
+       return 0
+}
+
+create_esp_target $_ESP_ARCH
diff --git a/tcl/target/esp32s2.cfg b/tcl/target/esp32s2.cfg
index 4c1362a346..05b4b29f9b 100644
--- a/tcl/target/esp32s2.cfg
+++ b/tcl/target/esp32s2.cfg
@@ -5,13 +5,13 @@
 source [find target/esp_common.cfg]
 
 # Target specific global variables
-set _CHIPNAME                                  "esp32s2"
-set _CPUTAPID                                  0x120034e5
-set _ESP_ARCH                                  "xtensa"
-set _ONLYCPU                                   1
-set _ESP_SMP_TARGET                            0
-set _ESP_SMP_BREAK                             1
-set _ESP_EFUSE_MAC_ADDR_REG    0x3f41A004
+set _CHIPNAME                   "esp32s2"
+set _CPUTAPID                   0x120034e5
+set _ESP_ARCH                   "xtensa"
+set _ONLYCPU                    1
+set _ESP_SMP_TARGET             0
+set _ESP_SMP_BREAK              1
+set _ESP_EFUSE_MAC_ADDR_REG     0x3f41A004
 
 proc esp32s2_memprot_is_enabled { } {
        # IRAM0, DPORT_PMS_PRO_IRAM0_0_REG
diff --git a/tcl/target/esp32s3.cfg b/tcl/target/esp32s3.cfg
index 12c166c463..53a9742d63 100644
--- a/tcl/target/esp32s3.cfg
+++ b/tcl/target/esp32s3.cfg
@@ -5,13 +5,13 @@
 source [find target/esp_common.cfg]
 
 # Target specific global variables
-set _CHIPNAME                                  "esp32s3"
-set _CPUTAPID                                  0x120034e5
-set _ESP_ARCH                                  "xtensa"
-set _ONLYCPU                                   3
-set _ESP_SMP_TARGET                            1
-set _ESP_SMP_BREAK                             1
-set _ESP_EFUSE_MAC_ADDR_REG    0x60007044
+set _CHIPNAME                   "esp32s3"
+set _CPUTAPID                   0x120034e5
+set _ESP_ARCH                   "xtensa"
+set _ONLYCPU                    3
+set _ESP_SMP_TARGET             1
+set _ESP_SMP_BREAK              1
+set _ESP_EFUSE_MAC_ADDR_REG     0x60007044
 
 if { [info exists ESP32_S3_ONLYCPU] } {
        set _ONLYCPU $ESP32_S3_ONLYCPU
diff --git a/tcl/target/esp_common.cfg b/tcl/target/esp_common.cfg
index e9a188f9f6..f0aafa8058 100644
--- a/tcl/target/esp_common.cfg
+++ b/tcl/target/esp_common.cfg
@@ -6,6 +6,14 @@ source [find bitsbytes.tcl]
 source [find memory.tcl]
 source [find mmr_helpers.tcl]
 
+# Riscv Debug Module Registers which are used around esp configuration files.
+set _RISCV_ABS_DATA0   0x04
+set _RISCV_DMCONTROL   0x10
+set _RISCV_ABS_CMD             0x17
+set _RISCV_SB_CS               0x38
+set _RISCV_SB_ADDR0            0x39
+set _RISCV_SB_DATA0            0x3C
+
 # Common ESP chips definitions
 
 # Espressif supports only NuttX in the upstream.
@@ -25,24 +33,31 @@ proc set_esp_common_variables { } {
        global _CHIPNAME _ONLYCPU _ESP_SMP_TARGET
        global _CPUNAME_0 _CPUNAME_1 _TARGETNAME_0 _TARGETNAME_1 _TAPNAME_0 
_TAPNAME_1
        global _ESP_WDT_DISABLE _ESP_SOC_RESET _ESP_MEMPROT_IS_ENABLED
+    global _TARGET_TYPE _ESP_ARCH
 
        # For now we support dual core at most.
        if { $_ONLYCPU == 1 && $_ESP_SMP_TARGET == 0} {
-               set _TARGETNAME_0                               $_CHIPNAME
-               set _CPUNAME_0                                  cpu
-               set _TAPNAME_0                                  
$_CHIPNAME.$_CPUNAME_0
+               set _TARGETNAME_0               $_CHIPNAME
+               set _CPUNAME_0                  cpu
+               set _TAPNAME_0                  $_CHIPNAME.$_CPUNAME_0
+       } else {
+               set _CPUNAME_0                  cpu0
+               set _CPUNAME_1                  cpu1
+               set _TARGETNAME_0               $_CHIPNAME.$_CPUNAME_0
+               set _TARGETNAME_1               $_CHIPNAME.$_CPUNAME_1
+               set _TAPNAME_0                  $_TARGETNAME_0
+               set _TAPNAME_1                  $_TARGETNAME_1
+       }
+
+       if {$_ESP_ARCH == "riscv"} {
+               set _TARGET_TYPE $_ESP_ARCH
        } else {
-               set _CPUNAME_0                                  cpu0
-               set _CPUNAME_1                                  cpu1
-               set _TARGETNAME_0                               
$_CHIPNAME.$_CPUNAME_0
-               set _TARGETNAME_1                               
$_CHIPNAME.$_CPUNAME_1
-               set _TAPNAME_0                                  $_TARGETNAME_0
-               set _TAPNAME_1                                  $_TARGETNAME_1
+               set _TARGET_TYPE $_CHIPNAME
        }
 
-       set _ESP_WDT_DISABLE                    "${_CHIPNAME}_wdt_disable"
-       set _ESP_SOC_RESET                              "${_CHIPNAME}_soc_reset"
-       set _ESP_MEMPROT_IS_ENABLED     "${_CHIPNAME}_memprot_is_enabled"
+       set _ESP_WDT_DISABLE            "${_CHIPNAME}_wdt_disable"
+       set _ESP_SOC_RESET              "${_CHIPNAME}_soc_reset"
+       set _ESP_MEMPROT_IS_ENABLED     "${_CHIPNAME}_memprot_is_enabled"
 }
 
 proc create_esp_jtag { } {
@@ -56,11 +71,11 @@ proc create_esp_jtag { } {
 }
 
 proc create_openocd_targets  { } {
-       global _TARGETNAME_0 _TARGETNAME_1 _TAPNAME_0 _TAPNAME_1 _RTOS 
_CHIPNAME _ONLYCPU
+       global _TARGETNAME_0 _TARGETNAME_1 _TAPNAME_0 _TAPNAME_1 _RTOS 
_CHIPNAME _ONLYCPU _TARGET_TYPE
 
-       target create $_TARGETNAME_0 $_CHIPNAME -chain-position $_TAPNAME_0 
-coreid 0 -rtos $_RTOS
+       target create $_TARGETNAME_0 $_TARGET_TYPE -chain-position $_TAPNAME_0 
-coreid 0 -rtos $_RTOS
        if { $_ONLYCPU != 1 } {
-               target create $_TARGETNAME_1 $_CHIPNAME -chain-position 
$_TAPNAME_1 -coreid 1 -rtos $_RTOS
+               target create $_TARGETNAME_1 $_TARGET_TYPE -chain-position 
$_TAPNAME_1 -coreid 1 -rtos $_RTOS
                target smp $_TARGETNAME_0 $_TARGETNAME_1
        }
 }
@@ -69,13 +84,12 @@ proc create_esp_target { ARCH } {
        set_esp_common_variables
        create_esp_jtag
        create_openocd_targets
-       configure_openocd_events
+       configure_openocd_events $ARCH
 
        if { $ARCH == "xtensa"} {
                configure_esp_xtensa_default_settings
        } else {
-               # riscv targets are not upstreamed yet.
-               # they can be found at the official Espressif fork.
+               configure_esp_riscv_default_settings
        }
 }
 
@@ -131,7 +145,6 @@ proc configure_event_halted { } {
        $_TARGETNAME_0 configure -event halted {
                global _ESP_WDT_DISABLE
            $_ESP_WDT_DISABLE
-           esp halted_event_handler
        }
 }
 
@@ -167,12 +180,25 @@ proc configure_event_gdb_attach { } {
        }
 }
 
-proc configure_openocd_events { } {
+proc configure_openocd_events { ARCH } {
+       if { $ARCH == "riscv" } {
+               configure_event_halted
+       }
        configure_event_examine_end
        configure_event_reset_assert_post
        configure_event_gdb_attach
 }
 
+proc configure_esp_riscv_default_settings { } {
+       gdb breakpoint_override hard
+       riscv set_reset_timeout_sec 2
+       riscv set_command_timeout_sec 5
+       riscv set_mem_access sysbus progbuf abstract
+       riscv set_ebreakm on
+       riscv set_ebreaks on
+       riscv set_ebreaku on
+}
+
 proc configure_esp_xtensa_default_settings { } {
        global _TARGETNAME_0 _ESP_SMP_BREAK _FLASH_VOLTAGE _CHIPNAME
 

-- 

Reply via email to