aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErhan Kurubas <erhan.kurubas@espressif.com>2023-07-18 00:51:54 +0200
committerErhan Kurubas <erhan.kurubas@espressif.com>2023-07-19 00:11:42 +0200
commitf21bd77dd122b75c056edfc7458f5dfe48fcdf29 (patch)
tree37dfb65e680e3c02e5c372456552bd5b50d510c4
parentc7500f9161220f87999738afb2a7950c896ba050 (diff)
downloadriscv-openocd-f21bd77dd122b75c056edfc7458f5dfe48fcdf29.zip
riscv-openocd-f21bd77dd122b75c056edfc7458f5dfe48fcdf29.tar.gz
riscv-openocd-f21bd77dd122b75c056edfc7458f5dfe48fcdf29.tar.bz2
tcl/target: add Espressif riscv targets (ESP32-C6, ESP32-H2)
ESP32-C6 and ESP32-H2 are single core riscv targets. Change-Id: If92429de4fb67a040f303a54177d61b70e1ea281 Signed-off-by: Erhan Kurubas <erhan.kurubas@espressif.com>
-rw-r--r--tcl/target/esp32c6.cfg142
-rw-r--r--tcl/target/esp32h2.cfg122
2 files changed, 264 insertions, 0 deletions
diff --git a/tcl/target/esp32c6.cfg b/tcl/target/esp32c6.cfg
new file mode 100644
index 0000000..e1ef10a
--- /dev/null
+++ b/tcl/target/esp32c6.cfg
@@ -0,0 +1,142 @@
+# 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 "riscv"
+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 riscv_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
+ }
+
+ # Timer Group 0 & 1 WDTs
+ mww 0x60008064 0x50D83AA1
+ mww 0x60008048 0
+ mww 0x60009064 0x50D83AA1
+ mww 0x60009048 0
+ # LP_WDT_RTC
+ mww 0x600b1c18 0x50D83AA1
+ mww 0x600B1C00 0
+ # LP_WDT_SWD
+ mww 0x600b1c20 0x50D83AA1
+ mww 0x600b1c1c 0x40000000
+}
+
+proc riscv_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
+ riscv_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 riscv_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 0000000..45f598f
--- /dev/null
+++ b/tcl/target/esp32h2.cfg
@@ -0,0 +1,122 @@
+# 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 "riscv"
+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 riscv_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
+ }
+
+ # Timer Group 0 & 1 WDTs
+ mww 0x60009064 0x50D83AA1
+ mww 0x60009048 0
+ mww 0x6000A064 0x50D83AA1
+ mww 0x6000A048 0
+ # WDT_RTC
+ #mww 0x600b1c18 0x50D83AA1
+ #mww 0x600B1C00 0
+ # WDT_SWD
+ #mww 0x600b1c20 0x8F1D312A
+ #mww 0x600b1c1c 0x84B00000
+}
+
+proc riscv_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
+ riscv_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 riscv_memprot_is_enabled { } {
+ global _RISCV_ABS_CMD _RISCV_ABS_DATA0
+ # If IRAM/DRAM split is enabled, PMPADDR 5-6 will cover valid IRAM region and 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