Skip to content

Commit 382f067

Browse files
gamelasterborneoa
authored andcommitted
tcl/target: add Bouffalo Lab BL616 chip series support
Adds support for BL616 series of chips, BL616 and BL618. No flash bank support yet. BL616 in comparison with BL602-series have new architecture, using T-Head E907 RISC-V cores, instead of SiFive ones. As BL602-series, the ndmreset bit in RISC-V Debug Module does not reset the chip as it should, so we need to do it manually with registers almost the same way as in BL602. Additionally, JTAG Debug Transport Module in the chip have wrongly implemented Test-Logic-Reset state, causing automatic chain scan not working at all after initial JTAG usage. This is because Test-Logic-State do not set IR instruction to IDCODE, as it should by JTAG spec. We can fix this by getting state machine to known state and configure IR instruction manually to IDCODE. This bug was so far found in T-Head C906 and E907 IP cores. This patch was tested heavily and works reliably on BL616, BL618 and QCC74X. Change-Id: Idc80a702e817d78fc0ca925572c68d4d0c28ce4e Signed-off-by: Marek Kraus <[email protected]> Reviewed-on: https://review.openocd.org/c/openocd/+/9145 Tested-by: jenkins Reviewed-by: Antonio Borneo <[email protected]>
1 parent 34d76b8 commit 382f067

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

tcl/target/bl616.cfg

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# SPDX-License-Identifier: GPL-2.0-or-later
2+
# Author: Marek Kraus <[email protected]>
3+
4+
#
5+
# Bouffalo Labs BL616 and BL618 target
6+
#
7+
# Default JTAG pins: (if not changed by eFuse configuration)
8+
# TMS - GPIO0
9+
# TCK - GPIO1
10+
# TDO - GPIO2
11+
# TDI - GPIO3
12+
#
13+
14+
source [find mem_helper.tcl]
15+
16+
transport select jtag
17+
18+
if { [info exists CHIPNAME] } {
19+
set _CHIPNAME $CHIPNAME
20+
} else {
21+
set _CHIPNAME bl616
22+
}
23+
24+
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10000b6f
25+
26+
set _TARGETNAME $_CHIPNAME.cpu
27+
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
28+
29+
riscv set_mem_access progbuf
30+
riscv set_enable_virt2phys off
31+
32+
$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x10000 -work-area-backup 1
33+
34+
adapter speed 4000
35+
36+
# Useful functions
37+
set dmcontrol 0x10
38+
set dmcontrol_dmactive [expr {1 << 0}]
39+
set dmcontrol_haltreq [expr {1 << 31}]
40+
41+
# By spec, ndmreset should reset whole chip. This implementation resets only few parts of the chip.
42+
# CTRL_PWRON_RESET register in GLB core triggers full "power-on like" reset, so we use it instead
43+
# for full software reset.
44+
$_TARGETNAME configure -event reset-assert {
45+
halt
46+
47+
# To stay in BootROM until JTAG re-attaches, we are using BootROM functionality
48+
# to force ISP mode, so BootROM looks out for external ISP communication.
49+
50+
# In HBN_RSV2, set HBN_RELEASE_CORE to HBN_RELEASE_CORE_FLAG (4)
51+
# and HBN_USER_BOOT_SEL to 1 (ISP)
52+
mww 0x2000f108 0x44000000
53+
54+
# Switch clock to internal RC32M
55+
# In HBN_GLB, set ROOT_CLK_SEL = 0
56+
mmw 0x2000f030 0x0 0x00000002
57+
58+
# In GLB_SYS_CFG0, set REG_BCLK_DIV and REG_HCLK_DIV = 0
59+
mmw 0x20000090 0x0 0x00FFFF00
60+
61+
# Trigger BCLK ACT pulse
62+
# In GLB_SYS_CFG1, set BCLK_DIV_ACT_PULSE = 1
63+
mmw 0x20000094 0x1 0x00000001
64+
# In GLB_SYS_CFG1, wait for GLB_STS_BCLK_PROT_DONE to become 1
65+
while { [expr {[mrw 0x20000094] & 4}] == 0 } { sleep 1 }
66+
67+
# In GLB_SWRST_CFG2, clear CTRL_PWRON_RESET
68+
mmw 0x20000548 0x0 0x00000001
69+
70+
# This Software reset method resets everything, so CPU as well.
71+
# It does that in not much good way, resulting in Debug Module being reset as well.
72+
# This also means, that right after CPU and Debug Module are turned on, we need to
73+
# enable Debug Module and halt CPU if needed. Additionally, we trigger this SW reset
74+
# through program buffer access directly with DMI commands, to avoid errors printed by
75+
# OpenOCD about unsuccessful register write.
76+
77+
# In GLB_SWRST_CFG2, set CTRL_PWRON_RESET to 1
78+
set_reg {fp 0x20000548 s1 0x01}
79+
riscv dmi_write 0x20 0x00942023
80+
riscv dmi_write 0x17 0x40000
81+
82+
# We need to wait for chip to finish reset and execute BootROM
83+
sleep 10
84+
85+
# JTAG Debug Transport Module is reset as well, so we need to get into RUN/IDLE state
86+
runtest 10
87+
88+
# We need to enable Debug Module and halt the CPU, so we can reset Program Counter
89+
# and to do additional clean-ups. If reset was called without halt, resume is handled
90+
# by reset-deassert-post event handler.
91+
92+
# In Debug Module Control (dmcontrol), set dmactive to 1 and then haltreq to 1
93+
riscv dmi_write $::dmcontrol $::dmcontrol_dmactive
94+
riscv dmi_write $::dmcontrol [ expr {$::dmcontrol_dmactive | $::dmcontrol_haltreq} ]
95+
}
96+
97+
$_TARGETNAME configure -event reset-deassert-post {
98+
# Set Program Counter to start of BootROM and execute one instruction
99+
step 0x90000000
100+
101+
# When using default JTAG pinout, BOOT pin is the same as JTAG TDO pin.
102+
# Since after reset we set PC to start of the BootROM,
103+
# BootROM will execute also check of BOOT pin, which will disable TDO pin,
104+
# to check the BOOT pin state. This leads to temporary loss of JTAG access
105+
# and causes (recoverable) errors in OpenOCD. We can bypass the BOOT pin check
106+
# function, by forcing booting from Media/SPI Flash.
107+
108+
# In HBN_RSV2, set HBN_RELEASE_CORE to HBN_RELEASE_CORE_FLAG (4)
109+
# and HBN_USER_BOOT_SEL to 2 (Media/SPI Flash)
110+
mww 0x2000f108 0x48000000
111+
112+
# Resume the processor if reset was triggered without halt request
113+
if {$halt == 0} {
114+
resume
115+
}
116+
}
117+
118+
# According to JTAG spec (IEEE 1149.1), when chip enters "Test-Logic-Reset" state,
119+
# the IR instruction should be set to "IDCODE" or "BYPASS" (when chip does not have IDCODE).
120+
# This is done so automatic chain scan can detect all the chips within JTAG chain without knowing IDCODE.
121+
# JTAG Debug Transport Module (DTM) used in this chip, developed by T-Head (formerly C-Sky)
122+
# does not implement this, so OpenOCD can't detect the chip anymore after the IR instruction is changed.
123+
# This workaround gets chip into known state, and manually set IR instruction to IDCODE,
124+
# which is 0x01, standardized by RISC-V Debug Specification.
125+
proc init_reset { mode } {
126+
if {[using_jtag]} {
127+
# Get JTAG SM to known state
128+
runtest 10
129+
# Set IR to IDCODE
130+
irscan $::_CHIPNAME.cpu 0x01
131+
jtag arp_init-reset
132+
}
133+
}
134+
135+
proc jtag_init {} {
136+
# Get JTAG SM to known state
137+
runtest 10
138+
# Set IR to IDCODE
139+
irscan $::_CHIPNAME.cpu 0x01
140+
141+
if {[catch {jtag arp_init} err]!=0} {
142+
# try resetting additionally
143+
init_reset startup
144+
}
145+
}

0 commit comments

Comments
 (0)