Files
openocd/tcl/target/bl616.cfg
Tomas Vanek d7fb95d800 tcl/target: update riscv commands in configs
Adjust configs for the changed command riscv virt2phys_mode.

Change-Id: Ib365bbb74b3b17e8f0b594e08ab73871f86cf89e
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: https://review.openocd.org/c/openocd/+/9190
Tested-by: jenkins
2025-11-12 20:52:47 +00:00

146 lines
4.8 KiB
INI

# SPDX-License-Identifier: GPL-2.0-or-later
# Author: Marek Kraus <gamelaster@gami.ee>
#
# Bouffalo Labs BL616 and BL618 target
#
# Default JTAG pins: (if not changed by eFuse configuration)
# TMS - GPIO0
# TCK - GPIO1
# TDO - GPIO2
# TDI - GPIO3
#
source [find mem_helper.tcl]
transport select jtag
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME bl616
}
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10000b6f
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
riscv set_mem_access progbuf
riscv virt2phys_mode off
$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x10000 -work-area-backup 1
adapter speed 4000
# Useful functions
set dmcontrol 0x10
set dmcontrol_dmactive [expr {1 << 0}]
set dmcontrol_haltreq [expr {1 << 31}]
# By spec, ndmreset should reset whole chip. This implementation resets only few parts of the chip.
# CTRL_PWRON_RESET register in GLB core triggers full "power-on like" reset, so we use it instead
# for full software reset.
$_TARGETNAME configure -event reset-assert {
halt
# To stay in BootROM until JTAG re-attaches, we are using BootROM functionality
# to force ISP mode, so BootROM looks out for external ISP communication.
# In HBN_RSV2, set HBN_RELEASE_CORE to HBN_RELEASE_CORE_FLAG (4)
# and HBN_USER_BOOT_SEL to 1 (ISP)
mww 0x2000f108 0x44000000
# Switch clock to internal RC32M
# In HBN_GLB, set ROOT_CLK_SEL = 0
mmw 0x2000f030 0x0 0x00000002
# In GLB_SYS_CFG0, set REG_BCLK_DIV and REG_HCLK_DIV = 0
mmw 0x20000090 0x0 0x00FFFF00
# Trigger BCLK ACT pulse
# In GLB_SYS_CFG1, set BCLK_DIV_ACT_PULSE = 1
mmw 0x20000094 0x1 0x00000001
# In GLB_SYS_CFG1, wait for GLB_STS_BCLK_PROT_DONE to become 1
while { [expr {[mrw 0x20000094] & 4}] == 0 } { sleep 1 }
# In GLB_SWRST_CFG2, clear CTRL_PWRON_RESET
mmw 0x20000548 0x0 0x00000001
# This Software reset method resets everything, so CPU as well.
# It does that in not much good way, resulting in Debug Module being reset as well.
# This also means, that right after CPU and Debug Module are turned on, we need to
# enable Debug Module and halt CPU if needed. Additionally, we trigger this SW reset
# through program buffer access directly with DMI commands, to avoid errors printed by
# OpenOCD about unsuccessful register write.
# In GLB_SWRST_CFG2, set CTRL_PWRON_RESET to 1
set_reg {fp 0x20000548 s1 0x01}
riscv dmi_write 0x20 0x00942023
riscv dmi_write 0x17 0x40000
# We need to wait for chip to finish reset and execute BootROM
sleep 10
# JTAG Debug Transport Module is reset as well, so we need to get into RUN/IDLE state
runtest 10
# We need to enable Debug Module and halt the CPU, so we can reset Program Counter
# and to do additional clean-ups. If reset was called without halt, resume is handled
# by reset-deassert-post event handler.
# In Debug Module Control (dmcontrol), set dmactive to 1 and then haltreq to 1
riscv dmi_write $::dmcontrol $::dmcontrol_dmactive
riscv dmi_write $::dmcontrol [ expr {$::dmcontrol_dmactive | $::dmcontrol_haltreq} ]
}
$_TARGETNAME configure -event reset-deassert-post {
# Set Program Counter to start of BootROM and execute one instruction
step 0x90000000
# When using default JTAG pinout, BOOT pin is the same as JTAG TDO pin.
# Since after reset we set PC to start of the BootROM,
# BootROM will execute also check of BOOT pin, which will disable TDO pin,
# to check the BOOT pin state. This leads to temporary loss of JTAG access
# and causes (recoverable) errors in OpenOCD. We can bypass the BOOT pin check
# function, by forcing booting from Media/SPI Flash.
# In HBN_RSV2, set HBN_RELEASE_CORE to HBN_RELEASE_CORE_FLAG (4)
# and HBN_USER_BOOT_SEL to 2 (Media/SPI Flash)
mww 0x2000f108 0x48000000
# Resume the processor if reset was triggered without halt request
if {$halt == 0} {
resume
}
}
# According to JTAG spec (IEEE 1149.1), when chip enters "Test-Logic-Reset" state,
# the IR instruction should be set to "IDCODE" or "BYPASS" (when chip does not have IDCODE).
# This is done so automatic chain scan can detect all the chips within JTAG chain without knowing IDCODE.
# JTAG Debug Transport Module (DTM) used in this chip, developed by T-Head (formerly C-Sky)
# does not implement this, so OpenOCD can't detect the chip anymore after the IR instruction is changed.
# This workaround gets chip into known state, and manually set IR instruction to IDCODE,
# which is 0x01, standardized by RISC-V Debug Specification.
proc init_reset { mode } {
if {[using_jtag]} {
# Get JTAG SM to known state
runtest 10
# Set IR to IDCODE
irscan $::_CHIPNAME.cpu 0x01
jtag arp_init-reset
}
}
proc jtag_init {} {
# Get JTAG SM to known state
runtest 10
# Set IR to IDCODE
irscan $::_CHIPNAME.cpu 0x01
if {[catch {jtag arp_init} err]!=0} {
# try resetting additionally
init_reset startup
}
}