-
Notifications
You must be signed in to change notification settings - Fork 807
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tcl/target: add Marvell Octeon TX2 CN9130 target
This has a quite complex JTAG router chain requiring both a custom BYPASS instruction to access child taps, and JTAG configuration to enable individual DAP nodes. Change-Id: I6f5345764e1566d70c8526a7e8ec5d250185bd2c Signed-off-by: Henrik Nordström <[email protected]> Reviewed-on: https://review.openocd.org/c/openocd/+/8042 Tested-by: jenkins Reviewed-by: Antonio Borneo <[email protected]>
- Loading branch information
1 parent
8d3728f
commit 65fc586
Showing
1 changed file
with
178 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
# SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
# cn9130 -- support for the Marvell Octeon TX2 / CN9130 CPU family | ||
# | ||
# [email protected], Nov 2023 | ||
|
||
if { [info exists CHIPNAME] } { | ||
set _CHIPNAME $CHIPNAME | ||
} else { | ||
set _CHIPNAME cn9130 | ||
} | ||
|
||
if { [info exists MASTERTAPID] } { | ||
set _MASTERTAPID $MASTERTAPID | ||
} else { | ||
set _MASTERTAPID 0x07025357 | ||
} | ||
|
||
if { [info exists APTAPID] } { | ||
set _APTAPID $APTAPID | ||
} else { | ||
set _APTAPID 0x4ba00477 | ||
} | ||
|
||
if { [info exists SBTAPID] } { | ||
set _SBTAPID $SBTAPID | ||
} else { | ||
set _SBTAPID 0x4ba00477 | ||
} | ||
|
||
if { [info exists CORES] } { | ||
set _CORES $CORES | ||
} else { | ||
set _CORES 4 | ||
} | ||
|
||
# CTI base address should be possible to read from the CoreSight | ||
# ROM table like how the DBG base address is when not specified. | ||
if { [info exists CTIBASE] } { | ||
set _CTIBASE $CTIBASE | ||
} else { | ||
set _CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000} | ||
} | ||
|
||
# CN9130 is a multi-die chip and has a multi level hierarchical | ||
# JTAG TAP, where all the DAPs are disabled at reset, requiring | ||
# both configuration to enable access to the chip DAPs, and a | ||
# vendor specific bypass IR instruction to access the slave TAPs | ||
# via the master TAP. In addition there is a number of sample | ||
# bits that should be ignored. | ||
# | ||
# The default BYPASS instruction in the master TAP bypasses the | ||
# whole chip and not only the master TAP. And similarly on | ||
# IDCODE the master TAP only responds with it's own ID and | ||
# bypasses the other TAPs on the chip, while OpenOCD expects | ||
# ID from all enabled TAPs in the chain. | ||
|
||
# Bootstrap with the default boundary scan oriented TAP configuration | ||
# where the master,ap,sb TAPs are seen as one big fat TAP, which matches | ||
# what OpenOCD expects from IDCODE and BYPASS. | ||
|
||
jtag newtap $_CHIPNAME bs -irlen 19 -enable -expected-id $_MASTERTAPID | ||
|
||
# Declare the full JTAG chain, but in disabled state during setup | ||
|
||
jtag newtap $_CHIPNAME sample4 -irlen 1 -disable | ||
jtag newtap $_CHIPNAME sample3 -irlen 1 -disable | ||
jtag newtap $_CHIPNAME sample2 -irlen 1 -disable | ||
jtag newtap $_CHIPNAME ap.cpu -irlen 4 -disable -expected-id $_APTAPID | ||
jtag newtap $_CHIPNAME ap -irlen 5 -disable | ||
jtag newtap $_CHIPNAME sample1 -irlen 1 -disable | ||
jtag newtap $_CHIPNAME sb.cpu -irlen 4 -disable -expected-id $_SBTAPID | ||
jtag newtap $_CHIPNAME sb -irlen 5 -disable | ||
jtag newtap $_CHIPNAME master -irlen 5 -disable -ir-bypass 0x11 -expected-id $_MASTERTAPID | ||
|
||
# Once the iniial IDCODE scan has completed switch to more detailed | ||
# scan chain giving access to the individual chip TAPs. | ||
|
||
jtag configure $_CHIPNAME.bs -event setup "cn9130_enable_full_chain $_CHIPNAME" | ||
|
||
proc cn9130_enable_full_chain { _CHIPNAME } { | ||
# Switch to detailed TAP declaration | ||
jtag tapdisable $_CHIPNAME.bs | ||
jtag tapenable $_CHIPNAME.master | ||
jtag tapenable $_CHIPNAME.sb | ||
jtag tapenable $_CHIPNAME.sample1 | ||
jtag tapenable $_CHIPNAME.ap | ||
jtag tapenable $_CHIPNAME.sample2 | ||
jtag tapenable $_CHIPNAME.sample3 | ||
jtag tapenable $_CHIPNAME.sample4 | ||
} | ||
|
||
# AP & SB TAPs have a config register to enable/disable access to | ||
# the auxilary DAP TAP. Default off which hides the DAP TAP from | ||
# the scan chain. | ||
proc cn9130_dap_config { chip tap state } { | ||
irscan $chip.$tap 0x12 | ||
drscan $chip.$tap 32 $state | ||
} | ||
|
||
jtag configure $_CHIPNAME.bs -event tap-disable "" | ||
jtag configure $_CHIPNAME.bs -event tap-enable "" | ||
jtag configure $_CHIPNAME.sample4 -event tap-enable "" | ||
jtag configure $_CHIPNAME.sample3 -event tap-enable "" | ||
jtag configure $_CHIPNAME.sample2 -event tap-enable "" | ||
jtag configure $_CHIPNAME.ap.cpu -event tap-disable "cn9130_dap_config $_CHIPNAME ap 0" | ||
jtag configure cn9130.ap.cpu -event tap-enable "cn9130_dap_config $_CHIPNAME ap 1" | ||
jtag configure $_CHIPNAME.ap -event tap-enable "" | ||
jtag configure $_CHIPNAME.sample1 -event tap-enable "" | ||
jtag configure $_CHIPNAME.sb.cpu -event tap-disable "cn9130_dap_config $_CHIPNAME sb 0" | ||
jtag configure cn9130.sb.cpu -event tap-enable "cn9130_dap_config $_CHIPNAME sb 1" | ||
jtag configure $_CHIPNAME.sb -event tap-enable "" | ||
jtag configure $_CHIPNAME.master -event tap-enable "" | ||
|
||
dap create $_CHIPNAME.ap.dap -chain-position $_CHIPNAME.ap.cpu | ||
|
||
# Main bus | ||
target create $_CHIPNAME.ap.axi mem_ap \ | ||
-dap $_CHIPNAME.ap.dap \ | ||
-ap-num 0 | ||
|
||
# Periperials bus | ||
target create $_CHIPNAME.ap.apb mem_ap \ | ||
-dap $_CHIPNAME.ap.dap \ | ||
-ap-num 1 | ||
|
||
# MSS bus | ||
target create $_CHIPNAME.ap.ahb mem_ap \ | ||
-dap $_CHIPNAME.ap.dap \ | ||
-ap-num 2 | ||
|
||
# AP A72 CPU cores | ||
set _smp_command "" | ||
for { set _core 0 } { $_core < $_CORES } { incr _core 1 } { | ||
cti create $_CHIPNAME.ap.cti.$_core \ | ||
-dap $_CHIPNAME.ap.dap \ | ||
-baseaddr [ lindex $_CTIBASE $_core ] \ | ||
-ap-num 1 | ||
|
||
if { $_core == 0 } { | ||
target create $_CHIPNAME.ap.a72.$_core aarch64 \ | ||
-dap $_CHIPNAME.ap.dap \ | ||
-ap-num 1 \ | ||
-cti $_CHIPNAME.ap.cti.$_core \ | ||
-coreid $_core \ | ||
-rtos hwthread | ||
set _smp_command "target smp $_CHIPNAME.ap.a72.$_core" | ||
} else { | ||
# Defer non-boot cores. Held hard in reset until | ||
# SMP is activated. | ||
target create $_CHIPNAME.ap.a72.$_core aarch64 \ | ||
-dap $_CHIPNAME.ap.dap \ | ||
-ap-num 1 \ | ||
-cti $_CHIPNAME.ap.cti.$_core \ | ||
-coreid $_core \ | ||
-defer-examine | ||
set _smp_command "$_smp_command $_CHIPNAME.ap.a72.$_core" | ||
} | ||
|
||
} | ||
|
||
# Set up the A72 cluster as SMP | ||
# Note: Only the boot core is active by default. The other core DAPs can | ||
# be enabled by arp_examine after they have been released from hard reset. | ||
eval $_smp_command | ||
|
||
# AP MSS M3 CPU core. Defer as it is held in reset until firmware is loaded. | ||
target create $_CHIPNAME.ap.mss cortex_m -dap $_CHIPNAME.ap.dap -ap-num 2 -defer-examine | ||
|
||
# Why is this needed? reset fails with "Debug regions are unpowered" otherwise | ||
$_CHIPNAME.ap.axi configure -event examine-start "dap init" | ||
|
||
# Automate enabling the AP A72 DAP once the full scan chain is enabled | ||
proc cn9130_ap_setup { _CHIPNAME } { | ||
jtag tapenable $_CHIPNAME.ap.cpu | ||
targets $_CHIPNAME.ap.a72.0 | ||
} | ||
jtag configure $_CHIPNAME.ap -event setup "cn9130_ap_setup $_CHIPNAME" |